Make WebRTC work with Chromium Git checkouts
WebRTC standalone shares a lot of dependencies and build tools with Chromium. To make the build work, many of the paths of a Chromium checkout is now emulated by creating symlinks to files and directories. All DEPS entries that previously used Var("chromium_trunk") to reference a Chromium checkout or From("chromium_deps"..) to reference the Chromium DEPS file are now removed and replaced by symlink entries in setup_links.py. The script also handles cleanup of the legacy Subversion-based dependencies that's needed for the transition. Windows: One Windows-specific important change is that gclient sync|runhooks must now be run from a shell with Administrator privileges in order to be able to create symlinks. This also means that Windows XP is no longer supported. To transition a previously created checkout: Run "python setup_links.py --force" to cleanup the old SVN-based dependencies that have been synced by gclient sync. For Buildbots, the --force flag is automatically enabled for their syncs. BUG=2863, chromium:339647 TEST=Manual testing on Linux, Mac and Windows. R=andrew@webrtc.org, iannucci@chromium.org, phoglund@webrtc.org Review URL: https://webrtc-codereview.appspot.com/18379005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@6938 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
3fb2d0cd0e
commit
8925662318
15
.gitignore
vendored
15
.gitignore
vendored
@ -37,10 +37,13 @@
|
||||
/Makefile
|
||||
/build
|
||||
/buildtools
|
||||
/chromium_deps
|
||||
/chromium_gn
|
||||
/google_apis/build
|
||||
/chromium/.gclient_entries
|
||||
/chromium/.last_sync_chromium
|
||||
/chromium/src
|
||||
/google_apis
|
||||
/gyp-mac-tool
|
||||
/links
|
||||
/links.db
|
||||
/net
|
||||
/out
|
||||
/resources/*.*
|
||||
@ -56,12 +59,12 @@
|
||||
/third_party/asan
|
||||
/third_party/binutils
|
||||
/third_party/boringssl
|
||||
/third_party/build_gn
|
||||
/third_party/BUILD.gn
|
||||
/third_party/clang_format
|
||||
/third_party/colorama
|
||||
/third_party/cygwin
|
||||
/third_party/directxsdk
|
||||
/third_party/drmemory
|
||||
/third_party/expat
|
||||
/third_party/gaeunit
|
||||
/third_party/gflags/src
|
||||
@ -85,7 +88,7 @@
|
||||
/third_party/opus
|
||||
/third_party/protobuf
|
||||
/third_party/sqlite
|
||||
/third_party/syzygy/binaries
|
||||
/third_party/syzygy
|
||||
/third_party/usrsctp
|
||||
/third_party/valgrind
|
||||
/third_party/winsdk_samples/src
|
||||
@ -93,7 +96,7 @@
|
||||
/tools/android
|
||||
/tools/android-dummy-test
|
||||
/tools/clang
|
||||
/tools/find_depot_tools
|
||||
/tools/find_depot_tools.py
|
||||
/tools/generate_library_loader
|
||||
/tools/gn
|
||||
/tools/grit
|
||||
|
340
DEPS
340
DEPS
@ -1,5 +1,10 @@
|
||||
use_relative_paths = True
|
||||
|
||||
# This file contains dependencies for WebRTC that are not shared with Chromium.
|
||||
# If you wish to add a dependency that is present in Chromium's src/DEPS or a
|
||||
# directory from the Chromium checkout, you should add it to setup_links.py
|
||||
# instead.
|
||||
|
||||
vars = {
|
||||
# Override root_dir in your .gclient's custom_vars to specify a custom root
|
||||
# folder name.
|
||||
@ -9,212 +14,25 @@ vars = {
|
||||
# Use this googlecode_url variable only if there is an internal mirror for it.
|
||||
# If you do not know, use the full path while defining your new deps entry.
|
||||
"googlecode_url": "http://%s.googlecode.com/svn",
|
||||
"sourceforge_url": "http://svn.code.sf.net/p/%(repo)s/code",
|
||||
"chromium_trunk" : "http://src.chromium.org/svn/trunk",
|
||||
# chrome://version/ for revision of canary Chrome.
|
||||
# http://chromium-status.appspot.com/lkgr is a last known good revision.
|
||||
"chromium_revision": "289723",
|
||||
"chromium_revision": "3da41f9378f9d075a94cc278f99ce4344f9acc7b",
|
||||
}
|
||||
|
||||
# NOTE: Prefer revision numbers to tags for svn deps. Use http rather than
|
||||
# https; the latter can cause problems for users behind proxies.
|
||||
deps = {
|
||||
"../chromium_deps":
|
||||
File(Var("chromium_trunk") + "/src/DEPS@" + Var("chromium_revision")),
|
||||
|
||||
"../chromium_gn":
|
||||
File(Var("chromium_trunk") + "/src/.gn@" + Var("chromium_revision")),
|
||||
|
||||
"build":
|
||||
Var("chromium_trunk") + "/src/build@" + Var("chromium_revision"),
|
||||
|
||||
"buildtools":
|
||||
From("chromium_deps", "src/buildtools"),
|
||||
|
||||
# Needed by common.gypi.
|
||||
"google_apis/build":
|
||||
Var("chromium_trunk") + "/src/google_apis/build@" + Var("chromium_revision"),
|
||||
|
||||
"testing":
|
||||
Var("chromium_trunk") + "/src/testing@" + Var("chromium_revision"),
|
||||
|
||||
"testing/gmock":
|
||||
From("chromium_deps", "src/testing/gmock"),
|
||||
|
||||
"testing/gtest":
|
||||
From("chromium_deps", "src/testing/gtest"),
|
||||
|
||||
"third_party/binutils":
|
||||
Var("chromium_trunk") + "/src/third_party/binutils@" + Var("chromium_revision"),
|
||||
|
||||
"third_party/build_gn":
|
||||
File(Var("chromium_trunk") + "/src/third_party/BUILD.gn@" + Var("chromium_revision")),
|
||||
|
||||
"third_party/colorama/src":
|
||||
From("chromium_deps", "src/third_party/colorama/src"),
|
||||
|
||||
"third_party/expat":
|
||||
Var("chromium_trunk") + "/src/third_party/expat@" + Var("chromium_revision"),
|
||||
|
||||
# When rolling gflags, also update deps/third_party/webrtc/webrtc.DEPS/DEPS
|
||||
# in Chromium's repo.
|
||||
"third_party/gflags/src":
|
||||
(Var("googlecode_url") % "gflags") + "/trunk/src@84",
|
||||
|
||||
"third_party/icu/":
|
||||
From("chromium_deps", "src/third_party/icu"),
|
||||
|
||||
"third_party/jsoncpp/":
|
||||
Var("chromium_trunk") + "/src/third_party/jsoncpp@" + Var("chromium_revision"),
|
||||
|
||||
"third_party/jsoncpp/source":
|
||||
(Var("sourceforge_url") % {"repo": "jsoncpp"}) + "/trunk/jsoncpp@248",
|
||||
|
||||
"third_party/junit/":
|
||||
(Var("googlecode_url") % "webrtc") + "/deps/third_party/junit@3367",
|
||||
|
||||
"third_party/libc++":
|
||||
Var("chromium_trunk") + "/src/third_party/libc++@" + Var("chromium_revision"),
|
||||
|
||||
"third_party/libc++/trunk":
|
||||
From("chromium_deps", "src/third_party/libc++/trunk"),
|
||||
|
||||
"third_party/libc++abi":
|
||||
Var("chromium_trunk") + "/src/third_party/libc++abi@" + Var("chromium_revision"),
|
||||
|
||||
"third_party/libc++abi/trunk":
|
||||
From("chromium_deps", "src/third_party/libc++abi/trunk"),
|
||||
|
||||
"third_party/openmax_dl/":
|
||||
(Var("googlecode_url") % "webrtc") + "/deps/third_party/openmax@6096",
|
||||
|
||||
"third_party/libjpeg":
|
||||
Var("chromium_trunk") + "/src/third_party/libjpeg@" + Var("chromium_revision"),
|
||||
|
||||
"third_party/libjpeg_turbo":
|
||||
From("chromium_deps", "src/third_party/libjpeg_turbo"),
|
||||
|
||||
"third_party/libsrtp/":
|
||||
From("chromium_deps", "src/third_party/libsrtp"),
|
||||
|
||||
"third_party/libvpx":
|
||||
From("chromium_deps", "src/third_party/libvpx"),
|
||||
|
||||
"third_party/libyuv":
|
||||
(Var("googlecode_url") % "libyuv") + "/trunk@1038",
|
||||
|
||||
"third_party/opus":
|
||||
Var("chromium_trunk") + "/src/third_party/opus@" + Var("chromium_revision"),
|
||||
|
||||
"third_party/opus/src":
|
||||
From("chromium_deps", "src/third_party/opus/src"),
|
||||
|
||||
"third_party/protobuf":
|
||||
Var("chromium_trunk") + "/src/third_party/protobuf@" + Var("chromium_revision"),
|
||||
|
||||
"third_party/sqlite/":
|
||||
Var("chromium_trunk") + "/src/third_party/sqlite@" + Var("chromium_revision"),
|
||||
|
||||
"third_party/yasm":
|
||||
Var("chromium_trunk") + "/src/third_party/yasm@" + Var("chromium_revision"),
|
||||
|
||||
"third_party/yasm/source/patched-yasm":
|
||||
From("chromium_deps", "src/third_party/yasm/source/patched-yasm"),
|
||||
|
||||
"tools/clang":
|
||||
Var("chromium_trunk") + "/src/tools/clang@" + Var("chromium_revision"),
|
||||
|
||||
"tools/generate_library_loader":
|
||||
Var("chromium_trunk") + "/src/tools/generate_library_loader@" + Var("chromium_revision"),
|
||||
|
||||
"tools/gn":
|
||||
Var("chromium_trunk") + "/src/tools/gn@" + Var("chromium_revision"),
|
||||
|
||||
"tools/gyp":
|
||||
From("chromium_deps", "src/tools/gyp"),
|
||||
|
||||
"tools/memory":
|
||||
Var("chromium_trunk") + "/src/tools/memory@" + Var("chromium_revision"),
|
||||
|
||||
"tools/protoc_wrapper":
|
||||
Var("chromium_trunk") + "/src/tools/protoc_wrapper@" + Var("chromium_revision"),
|
||||
|
||||
"tools/python":
|
||||
Var("chromium_trunk") + "/src/tools/python@" + Var("chromium_revision"),
|
||||
|
||||
"tools/sanitizer_options":
|
||||
File(Var("chromium_trunk") + "/src/base/debug/sanitizer_options.cc@" + Var("chromium_revision")),
|
||||
|
||||
"tools/swarming_client":
|
||||
From("chromium_deps", "src/tools/swarming_client"),
|
||||
|
||||
"tools/valgrind":
|
||||
Var("chromium_trunk") + "/src/tools/valgrind@" + Var("chromium_revision"),
|
||||
|
||||
# Needed by build/common.gypi.
|
||||
"tools/win/supalink":
|
||||
Var("chromium_trunk") + "/src/tools/win/supalink@" + Var("chromium_revision"),
|
||||
|
||||
"net/third_party/nss":
|
||||
Var("chromium_trunk") + "/src/net/third_party/nss@" + Var("chromium_revision"),
|
||||
|
||||
"third_party/boringssl":
|
||||
Var("chromium_trunk") + "/src/third_party/boringssl@" + Var("chromium_revision"),
|
||||
|
||||
"third_party/boringssl/src":
|
||||
From("chromium_deps", "src/third_party/boringssl/src"),
|
||||
|
||||
"third_party/usrsctp/":
|
||||
Var("chromium_trunk") + "/src/third_party/usrsctp@" + Var("chromium_revision"),
|
||||
|
||||
"third_party/usrsctp/usrsctplib":
|
||||
From("chromium_deps", "src/third_party/usrsctp/usrsctplib"),
|
||||
}
|
||||
|
||||
deps_os = {
|
||||
"win": {
|
||||
"third_party/drmemory":
|
||||
Var("chromium_trunk") + "/src/third_party/drmemory@" + Var("chromium_revision"),
|
||||
|
||||
"third_party/winsdk_samples/src":
|
||||
(Var("googlecode_url") % "webrtc") + "/deps/third_party/winsdk_samples_v71@3145",
|
||||
|
||||
# Used by libjpeg-turbo.
|
||||
"third_party/yasm/binaries":
|
||||
From("chromium_deps", "src/third_party/yasm/binaries"),
|
||||
|
||||
# NSS, for SSLClientSocketNSS.
|
||||
"third_party/nss":
|
||||
From("chromium_deps", "src/third_party/nss"),
|
||||
|
||||
"tools/find_depot_tools":
|
||||
File(Var("chromium_trunk") + "/src/tools/find_depot_tools.py@" + Var("chromium_revision")),
|
||||
},
|
||||
|
||||
"mac": {
|
||||
# NSS, for SSLClientSocketNSS.
|
||||
"third_party/nss":
|
||||
From("chromium_deps", "src/third_party/nss"),
|
||||
|
||||
# TODO(kjellander): remove once bug 2152 is fixed.
|
||||
# This needs to specify the path directly (instead of using the
|
||||
# chromium_deps version) because chromium_deps only defines this for ios.
|
||||
"testing/iossim/third_party/class-dump":
|
||||
Var("chromium_trunk") + "/deps/third_party/class-dump@199203",
|
||||
},
|
||||
|
||||
"ios": {
|
||||
# NSS, for SSLClientSocketNSS.
|
||||
"third_party/nss":
|
||||
From("chromium_deps", "src/third_party/nss"),
|
||||
|
||||
# class-dump utility to generate header files for undocumented SDKs.
|
||||
"testing/iossim/third_party/class-dump":
|
||||
From("chromium_deps", "src/testing/iossim/third_party/class-dump"),
|
||||
|
||||
# Helper for running under the simulator.
|
||||
"testing/iossim":
|
||||
Var("chromium_trunk") + "/src/testing/iossim@" + Var("chromium_revision"),
|
||||
},
|
||||
|
||||
"android": {
|
||||
@ -222,156 +40,26 @@ deps_os = {
|
||||
# compile them from source in WebRTC since they depend on Chromium's base.
|
||||
"tools/android":
|
||||
(Var("googlecode_url") % "webrtc") + "/deps/tools/android@6306",
|
||||
|
||||
"third_party/android_tools":
|
||||
From("chromium_deps", "src/third_party/android_tools"),
|
||||
|
||||
"third_party/android_testrunner":
|
||||
Var("chromium_trunk") + "/src/third_party/android_testrunner@" + Var("chromium_revision"),
|
||||
},
|
||||
}
|
||||
|
||||
hooks = [
|
||||
{
|
||||
# Copy .gn from temporary place (../chromium_gn) to root_dir.
|
||||
"name": "copy .gn",
|
||||
# Clone chromium and its deps.
|
||||
"name": "sync chromium",
|
||||
"pattern": ".",
|
||||
"action": ["python", Var("root_dir") + "/build/cp.py",
|
||||
Var("root_dir") + "/../chromium_gn/.gn",
|
||||
Var("root_dir")],
|
||||
"action": ["python", "-u", Var("root_dir") + "/sync_chromium.py",
|
||||
"--target-revision", Var("chromium_revision")],
|
||||
},
|
||||
{
|
||||
# Copy BUILD.gn from temporary place (third_party/build_gn) to third_party.
|
||||
"name": "copy third_party/BUILD.gn",
|
||||
# Create links to shared dependencies in Chromium.
|
||||
"name": "setup_links",
|
||||
"pattern": ".",
|
||||
"action": ["python", Var("root_dir") + "/build/cp.py",
|
||||
Var("root_dir") + "/third_party/build_gn/BUILD.gn",
|
||||
Var("root_dir") + "/third_party"],
|
||||
},
|
||||
# Pull GN binaries. This needs to be before running GYP below.
|
||||
{
|
||||
"name": "gn_win",
|
||||
"pattern": ".",
|
||||
"action": [ "download_from_google_storage",
|
||||
"--no_resume",
|
||||
"--platform=win32",
|
||||
"--no_auth",
|
||||
"--bucket", "chromium-gn",
|
||||
"-s", Var("root_dir") + "/buildtools/win/gn.exe.sha1",
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "gn_mac",
|
||||
"pattern": ".",
|
||||
"action": [ "download_from_google_storage",
|
||||
"--no_resume",
|
||||
"--platform=darwin",
|
||||
"--no_auth",
|
||||
"--bucket", "chromium-gn",
|
||||
"-s", Var("root_dir") + "/buildtools/mac/gn.sha1",
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "gn_linux",
|
||||
"pattern": ".",
|
||||
"action": [ "download_from_google_storage",
|
||||
"--no_resume",
|
||||
"--platform=linux*",
|
||||
"--no_auth",
|
||||
"--bucket", "chromium-gn",
|
||||
"-s", Var("root_dir") + "/buildtools/linux64/gn.sha1",
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "gn_linux32",
|
||||
"pattern": ".",
|
||||
"action": [ "download_from_google_storage",
|
||||
"--no_resume",
|
||||
"--platform=linux*",
|
||||
"--no_auth",
|
||||
"--bucket", "chromium-gn",
|
||||
"-s", Var("root_dir") + "/buildtools/linux32/gn.sha1",
|
||||
],
|
||||
},
|
||||
# Pull clang-format binaries using checked-in hashes.
|
||||
{
|
||||
"name": "clang_format_win",
|
||||
"pattern": ".",
|
||||
"action": [ "download_from_google_storage",
|
||||
"--no_resume",
|
||||
"--platform=win32",
|
||||
"--no_auth",
|
||||
"--bucket", "chromium-clang-format",
|
||||
"-s", Var("root_dir") + "/buildtools/win/clang-format.exe.sha1",
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "clang_format_mac",
|
||||
"pattern": ".",
|
||||
"action": [ "download_from_google_storage",
|
||||
"--no_resume",
|
||||
"--platform=darwin",
|
||||
"--no_auth",
|
||||
"--bucket", "chromium-clang-format",
|
||||
"-s", Var("root_dir") + "/buildtools/mac/clang-format.sha1",
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "clang_format_linux",
|
||||
"pattern": ".",
|
||||
"action": [ "download_from_google_storage",
|
||||
"--no_resume",
|
||||
"--platform=linux*",
|
||||
"--no_auth",
|
||||
"--bucket", "chromium-clang-format",
|
||||
"-s", Var("root_dir") + "/buildtools/linux64/clang-format.sha1",
|
||||
],
|
||||
},
|
||||
{
|
||||
# Pull clang if on Mac or clang is requested via GYP_DEFINES.
|
||||
"pattern": ".",
|
||||
"action": ["python", Var("root_dir") + "/tools/clang/scripts/update.py",
|
||||
"--if-needed"],
|
||||
},
|
||||
{
|
||||
# Update the Windows toolchain if necessary.
|
||||
"name": "win_toolchain",
|
||||
"pattern": ".",
|
||||
"action": ["python",
|
||||
Var("root_dir") + "/webrtc/build/download_vs_toolchain.py",
|
||||
"update"],
|
||||
},
|
||||
{
|
||||
# Pull binutils for gold.
|
||||
"name": "binutils",
|
||||
"pattern": ".",
|
||||
"action": ["python", Var("root_dir") + "/third_party/binutils/download.py"],
|
||||
},
|
||||
{
|
||||
"name": "drmemory",
|
||||
"pattern": ".",
|
||||
"action": [ "download_from_google_storage",
|
||||
"--no_resume",
|
||||
"--platform=win32",
|
||||
"--no_auth",
|
||||
"--bucket", "chromium-drmemory",
|
||||
"-s", Var("root_dir") + "/third_party/drmemory/drmemory-windows-sfx.exe.sha1",
|
||||
],
|
||||
},
|
||||
{
|
||||
# Pull the Syzygy binaries, used for optimization and instrumentation.
|
||||
"name": "syzygy-binaries",
|
||||
"pattern": ".",
|
||||
"action": ["python",
|
||||
Var("root_dir") + "/build/get_syzygy_binaries.py",
|
||||
"--output-dir=%s/third_party/syzygy/binaries" % Var("root_dir"),
|
||||
"--revision=b08fb72610963d31cc3eae33f746a04e263bd860",
|
||||
"--overwrite",
|
||||
],
|
||||
"action": ["python", Var("root_dir") + "/setup_links.py"],
|
||||
},
|
||||
{
|
||||
# Download test resources, i.e. video and audio files from Google Storage.
|
||||
"pattern": "\\.sha1",
|
||||
"pattern": ".",
|
||||
"action": ["download_from_google_storage",
|
||||
"--directory",
|
||||
"--recursive",
|
||||
|
1
PRESUBMIT.py
Normal file → Executable file
1
PRESUBMIT.py
Normal file → Executable file
@ -123,6 +123,7 @@ def _CommonChecks(input_api, output_api):
|
||||
# Embedded shell-script fakes out pylint.
|
||||
r'^build/.*\.py$',
|
||||
r'^buildtools/.*\.py$',
|
||||
r'^chromium/.*\.py$',
|
||||
r'^out.*/.*\.py$',
|
||||
r'^talk/site_scons/site_tools/talk_linux.py$',
|
||||
r'^testing/.*\.py$',
|
||||
|
11
chromium/.gclient
Normal file
11
chromium/.gclient
Normal file
@ -0,0 +1,11 @@
|
||||
solutions = [
|
||||
{ "name" : "src",
|
||||
"url" : "https://chromium.googlesource.com/chromium/src.git",
|
||||
"deps_file" : ".DEPS.git",
|
||||
"managed" : True,
|
||||
"custom_deps" : {
|
||||
},
|
||||
"safesync_url": "",
|
||||
},
|
||||
]
|
||||
cache_dir = None
|
483
setup_links.py
Executable file
483
setup_links.py
Executable file
@ -0,0 +1,483 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style license
|
||||
# that can be found in the LICENSE file in the root of the source
|
||||
# tree. An additional intellectual property rights grant can be found
|
||||
# in the file PATENTS. All contributing project authors may
|
||||
# be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
"""Setup links to a Chromium checkout for WebRTC.
|
||||
|
||||
WebRTC standalone shares a lot of dependencies and build tools with Chromium.
|
||||
To do this, many of the paths of a Chromium checkout is emulated by creating
|
||||
symlinks to files and directories. This script handles the setup of symlinks to
|
||||
achieve this.
|
||||
|
||||
It also handles cleanup of the legacy Subversion-based approach that was used
|
||||
before Chrome switched over their master repo from Subversion to Git.
|
||||
"""
|
||||
|
||||
|
||||
import ctypes
|
||||
import errno
|
||||
import logging
|
||||
import optparse
|
||||
import os
|
||||
import shelve
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
|
||||
DIRECTORIES = [
|
||||
'build',
|
||||
'buildtools',
|
||||
'google_apis', # Needed by build/common.gypi.
|
||||
'net',
|
||||
'testing',
|
||||
'third_party/android_testrunner',
|
||||
'third_party/android_tools',
|
||||
'third_party/binutils',
|
||||
'third_party/boringssl',
|
||||
'third_party/colorama',
|
||||
'third_party/drmemory',
|
||||
'third_party/expat',
|
||||
'third_party/icu',
|
||||
'third_party/jsoncpp',
|
||||
'third_party/libc++',
|
||||
'third_party/libc++abi',
|
||||
'third_party/libjpeg',
|
||||
'third_party/libjpeg_turbo',
|
||||
'third_party/libsrtp',
|
||||
'third_party/libvpx',
|
||||
'third_party/libyuv',
|
||||
'third_party/llvm-build',
|
||||
'third_party/nss',
|
||||
'third_party/openmax_dl',
|
||||
'third_party/opus',
|
||||
'third_party/protobuf',
|
||||
'third_party/sqlite',
|
||||
'third_party/syzygy',
|
||||
'third_party/usrsctp',
|
||||
'third_party/yasm',
|
||||
'tools/clang',
|
||||
'tools/generate_library_loader',
|
||||
'tools/gn',
|
||||
'tools/gyp',
|
||||
'tools/memory',
|
||||
'tools/protoc_wrapper',
|
||||
'tools/python',
|
||||
'tools/swarming_client',
|
||||
'tools/valgrind',
|
||||
'tools/win',
|
||||
]
|
||||
|
||||
FILES = {
|
||||
'.gn': None,
|
||||
'tools/find_depot_tools.py': None,
|
||||
'third_party/BUILD.gn': None,
|
||||
|
||||
# This can be removed after https://codereview.chromium.org/357623003/ is
|
||||
# landed and WebRTC is refactored+rolled past that Chromium revision.
|
||||
'base/debug/sanitizer_options.cc': (
|
||||
'tools/sanitizer_options/sanitizer_options.cc'),
|
||||
}
|
||||
|
||||
CHROMIUM_CHECKOUT = os.path.join('chromium', 'src')
|
||||
LINKS_DB = 'links'
|
||||
|
||||
# Version management to make future upgrades/downgrades easier to support.
|
||||
SCHEMA_VERSION = 1
|
||||
|
||||
|
||||
def query_yes_no(question, default=False):
|
||||
"""Ask a yes/no question via raw_input() and return their answer.
|
||||
|
||||
Modified from http://stackoverflow.com/a/3041990.
|
||||
"""
|
||||
prompt = " [%s/%%s]: "
|
||||
prompt = prompt % ('Y' if default is True else 'y')
|
||||
prompt = prompt % ('N' if default is False else 'n')
|
||||
|
||||
if default is None:
|
||||
default = 'INVALID'
|
||||
|
||||
while True:
|
||||
sys.stdout.write(question + prompt)
|
||||
choice = raw_input().lower()
|
||||
if choice == '' and default != 'INVALID':
|
||||
return default
|
||||
|
||||
if 'yes'.startswith(choice):
|
||||
return True
|
||||
elif 'no'.startswith(choice):
|
||||
return False
|
||||
|
||||
print "Please respond with 'yes' or 'no' (or 'y' or 'n')."
|
||||
|
||||
|
||||
# Actions
|
||||
class Action(object):
|
||||
def __init__(self, dangerous):
|
||||
self.dangerous = dangerous
|
||||
|
||||
def announce(self, planning):
|
||||
"""Log a description of this action.
|
||||
|
||||
Args:
|
||||
planning - True iff we're in the planning stage, False if we're in the
|
||||
doit stage.
|
||||
"""
|
||||
pass
|
||||
|
||||
def doit(self, links_db):
|
||||
"""Execute the action, recording what we did to links_db, if necessary."""
|
||||
pass
|
||||
|
||||
|
||||
class Remove(Action):
|
||||
def __init__(self, path, dangerous):
|
||||
super(Remove, self).__init__(dangerous)
|
||||
self._priority = 0
|
||||
self._path = path
|
||||
|
||||
def announce(self, planning):
|
||||
log = logging.warn
|
||||
filesystem_type = 'file'
|
||||
if not self.dangerous:
|
||||
log = logging.info
|
||||
filesystem_type = 'link'
|
||||
if planning:
|
||||
log('Planning to remove %s: %s', filesystem_type, self._path)
|
||||
else:
|
||||
log('Removing %s: %s', filesystem_type, self._path)
|
||||
|
||||
def doit(self, _links_db):
|
||||
os.remove(self._path)
|
||||
|
||||
|
||||
class Rmtree(Action):
|
||||
def __init__(self, path):
|
||||
super(Rmtree, self).__init__(dangerous=True)
|
||||
self._priority = 0
|
||||
self._path = path
|
||||
|
||||
def announce(self, planning):
|
||||
if planning:
|
||||
logging.warn('Planning to remove directory: %s', self._path)
|
||||
else:
|
||||
logging.warn('Removing directory: %s', self._path)
|
||||
|
||||
def doit(self, _links_db):
|
||||
if sys.platform.startswith('win'):
|
||||
# shutil.rmtree() doesn't work on Windows if any of the directories are
|
||||
# read-only, which svn repositories are.
|
||||
subprocess.check_call(['rd', '/q', '/s', self._path], shell=True)
|
||||
else:
|
||||
shutil.rmtree(self._path)
|
||||
|
||||
|
||||
class Makedirs(Action):
|
||||
def __init__(self, path):
|
||||
super(Makedirs, self).__init__(dangerous=False)
|
||||
self._priority = 1
|
||||
self._path = path
|
||||
|
||||
def doit(self, _links_db):
|
||||
try:
|
||||
os.makedirs(self._path)
|
||||
except OSError as e:
|
||||
if e.errno != errno.EEXIST:
|
||||
raise
|
||||
|
||||
|
||||
class Symlink(Action):
|
||||
def __init__(self, source_path, link_path):
|
||||
super(Symlink, self).__init__(dangerous=False)
|
||||
self._priority = 2
|
||||
self._source_path = source_path
|
||||
self._link_path = link_path
|
||||
|
||||
def announce(self, planning):
|
||||
if planning:
|
||||
logging.info(
|
||||
'Planning to create link from %s to %s', self._link_path,
|
||||
self._source_path)
|
||||
else:
|
||||
logging.debug(
|
||||
'Linking from %s to %s', self._link_path, self._source_path)
|
||||
|
||||
def doit(self, links_db):
|
||||
# Files not in the root directory need relative path calculation.
|
||||
# On Windows, use absolute paths instead since NTFS doesn't seem to support
|
||||
# relative paths for symlinks.
|
||||
if sys.platform.startswith('win'):
|
||||
source_path = os.path.abspath(self._source_path)
|
||||
else:
|
||||
if os.path.dirname(self._link_path) != self._link_path:
|
||||
source_path = os.path.relpath(self._source_path,
|
||||
os.path.dirname(self._link_path))
|
||||
|
||||
os.symlink(source_path, os.path.abspath(self._link_path))
|
||||
links_db[self._source_path] = self._link_path
|
||||
|
||||
|
||||
class LinkError(IOError):
|
||||
"""Failed to create a link."""
|
||||
pass
|
||||
|
||||
|
||||
# Handles symlink creation on the different platforms.
|
||||
if sys.platform.startswith('win'):
|
||||
def symlink(source_path, link_path):
|
||||
flag = 1 if os.path.isdir(source_path) else 0
|
||||
if not ctypes.windll.kernel32.CreateSymbolicLinkW(
|
||||
unicode(link_path), unicode(source_path), flag):
|
||||
raise OSError('Failed to create symlink to %s. Notice that only NTFS '
|
||||
'version 5.0 and up has all the needed APIs for '
|
||||
'creating symlinks.' % source_path)
|
||||
os.symlink = symlink
|
||||
|
||||
|
||||
class WebRTCLinkSetup():
|
||||
def __init__(self, links_db, force=False, dry_run=False, prompt=False):
|
||||
self._force = force
|
||||
self._dry_run = dry_run
|
||||
self._prompt = prompt
|
||||
self._links_db = links_db
|
||||
|
||||
def CreateLinks(self, on_bot):
|
||||
logging.debug('CreateLinks')
|
||||
# First, make a plan of action
|
||||
actions = []
|
||||
|
||||
for source_path, link_path in FILES.iteritems():
|
||||
actions += self._ActionForPath(
|
||||
source_path, link_path, check_fn=os.path.isfile, check_msg='files')
|
||||
for source_dir in DIRECTORIES:
|
||||
actions += self._ActionForPath(
|
||||
source_dir, None, check_fn=os.path.isdir,
|
||||
check_msg='directories')
|
||||
|
||||
actions.sort()
|
||||
|
||||
if self._dry_run:
|
||||
for action in actions:
|
||||
action.announce(planning=True)
|
||||
logging.info('Not doing anything because dry-run was specified.')
|
||||
sys.exit(0)
|
||||
|
||||
if any(a.dangerous for a in actions):
|
||||
logging.warn('Dangerous actions:')
|
||||
for action in (a for a in actions if a.dangerous):
|
||||
action.announce(planning=True)
|
||||
print
|
||||
|
||||
if not self._force:
|
||||
logging.error(textwrap.dedent("""\
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
A C T I O N R E Q I R E D
|
||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
|
||||
Because chromium/src is transitioning to Git (from SVN), we needed to
|
||||
change the way that the WebRTC standalone checkout works. Instead of
|
||||
individually syncing subdirectories of Chromium in SVN, we're now
|
||||
syncing Chromium (and all of its DEPS, as defined by its own DEPS file),
|
||||
into the `chromium/src` directory.
|
||||
|
||||
As such, all Chromium directories which are currently pulled by DEPS are
|
||||
now replaced with a symlink into the full Chromium checkout.
|
||||
|
||||
To avoid disrupting developers, we've chosen to not delete your
|
||||
directories forcibly, in case you have some work in progress in one of
|
||||
them :).
|
||||
|
||||
ACTION REQUIRED:
|
||||
Before running `gclient sync|runhooks` again, you must run:
|
||||
%s%s --force
|
||||
|
||||
Which will replace all directories which now must be symlinks, after
|
||||
prompting with a summary of the work-to-be-done.
|
||||
"""), 'python ' if sys.platform.startswith('win') else '', sys.argv[0])
|
||||
sys.exit(1)
|
||||
elif self._prompt:
|
||||
if not query_yes_no('Would you like to perform the above plan?'):
|
||||
sys.exit(1)
|
||||
|
||||
for action in actions:
|
||||
action.announce(planning=False)
|
||||
action.doit(self._links_db)
|
||||
|
||||
if not on_bot and self._force:
|
||||
logging.info('Completed!\n\nNow run `gclient sync|runhooks` again to '
|
||||
'let the remaining hooks (that probably were interrupted) '
|
||||
'execute.')
|
||||
|
||||
def CleanupLinks(self):
|
||||
logging.debug('CleanupLinks')
|
||||
for source, link_path in self._links_db.iteritems():
|
||||
if source == 'SCHEMA_VERSION':
|
||||
continue
|
||||
if os.path.islink(link_path) or sys.platform.startswith('win'):
|
||||
# os.path.islink() always returns false on Windows
|
||||
# See http://bugs.python.org/issue13143.
|
||||
logging.debug('Removing link to %s at %s', source, link_path)
|
||||
if not self._dry_run:
|
||||
if os.path.exists(link_path):
|
||||
if sys.platform.startswith('win') and os.path.isdir(link_path):
|
||||
subprocess.check_call(['rmdir', '/q', link_path], shell=True)
|
||||
else:
|
||||
os.remove(link_path)
|
||||
del self._links_db[source]
|
||||
|
||||
@staticmethod
|
||||
def _ActionForPath(source_path, link_path=None, check_fn=None,
|
||||
check_msg=None):
|
||||
"""Create zero or more Actions to link to a file or directory.
|
||||
|
||||
This will be a symlink on POSIX platforms. On Windows this requires
|
||||
that NTFS is version 5.0 or higher (Vista or newer).
|
||||
|
||||
Args:
|
||||
source_path: Path relative to the Chromium checkout root.
|
||||
For readability, the path may contain slashes, which will
|
||||
automatically be converted to the right path delimiter on Windows.
|
||||
link_path: The location for the link to create. If omitted it will be the
|
||||
same path as source_path.
|
||||
check_fn: A function returning true if the type of filesystem object is
|
||||
correct for the attempted call. Otherwise an error message with
|
||||
check_msg will be printed.
|
||||
check_msg: String used to inform the user of an invalid attempt to create
|
||||
a file.
|
||||
Returns:
|
||||
A list of Action objects.
|
||||
"""
|
||||
def fix_separators(path):
|
||||
if sys.platform.startswith('win'):
|
||||
return path.replace(os.altsep, os.sep)
|
||||
else:
|
||||
return path
|
||||
|
||||
assert check_fn
|
||||
assert check_msg
|
||||
link_path = link_path or source_path
|
||||
link_path = fix_separators(link_path)
|
||||
|
||||
source_path = fix_separators(source_path)
|
||||
source_path = os.path.join(CHROMIUM_CHECKOUT, source_path)
|
||||
if os.path.exists(source_path) and not check_fn:
|
||||
raise LinkError('_LinkChromiumPath can only be used to link to %s: '
|
||||
'Tried to link to: %s' % (check_msg, source_path))
|
||||
|
||||
if not os.path.exists(source_path):
|
||||
logging.debug('Silently ignoring missing source: %s. This is to avoid '
|
||||
'errors on platform-specific dependencies.', source_path)
|
||||
return []
|
||||
|
||||
actions = []
|
||||
|
||||
if os.path.exists(link_path) or os.path.islink(link_path):
|
||||
if os.path.islink(link_path):
|
||||
actions.append(Remove(link_path, dangerous=False))
|
||||
elif os.path.isfile(link_path):
|
||||
actions.append(Remove(link_path, dangerous=True))
|
||||
elif os.path.isdir(link_path):
|
||||
actions.append(Rmtree(link_path))
|
||||
else:
|
||||
raise LinkError('Don\'t know how to plan: %s' % link_path)
|
||||
|
||||
# Create parent directories to the target link if needed.
|
||||
target_parent_dirs = os.path.dirname(link_path)
|
||||
if (target_parent_dirs and
|
||||
target_parent_dirs != link_path and
|
||||
not os.path.exists(target_parent_dirs)):
|
||||
actions.append(Makedirs(target_parent_dirs))
|
||||
|
||||
actions.append(Symlink(source_path, link_path))
|
||||
|
||||
return actions
|
||||
|
||||
def _initialize_database(filename):
|
||||
links_database = shelve.open(filename)
|
||||
|
||||
# Wipe the database if this version of the script ends up looking at a
|
||||
# newer (future) version of the links db, just to be sure.
|
||||
version = links_database.get('SCHEMA_VERSION')
|
||||
if version and version != SCHEMA_VERSION:
|
||||
logging.info('Found database with schema version %s while this script only '
|
||||
'supports %s. Wiping previous database contents.', version,
|
||||
SCHEMA_VERSION)
|
||||
links_database.clear()
|
||||
links_database['SCHEMA_VERSION'] = SCHEMA_VERSION
|
||||
return links_database
|
||||
|
||||
|
||||
def main():
|
||||
on_bot = os.environ.get('CHROME_HEADLESS') == '1'
|
||||
|
||||
parser = optparse.OptionParser()
|
||||
parser.add_option('-d', '--dry-run', action='store_true', default=False,
|
||||
help='Print what would be done, but don\'t perform any '
|
||||
'operations. This will automatically set logging to '
|
||||
'verbose.')
|
||||
parser.add_option('-c', '--clean-only', action='store_true', default=False,
|
||||
help='Only clean previously created links, don\'t create '
|
||||
'new ones. This will automatically set logging to '
|
||||
'verbose.')
|
||||
parser.add_option('-f', '--force', action='store_true', default=on_bot,
|
||||
help='Force link creation. CAUTION: This deletes existing '
|
||||
'folders and files in the locations where links are '
|
||||
'about to be created.')
|
||||
parser.add_option('-n', '--no-prompt', action='store_false', dest='prompt',
|
||||
default=(not on_bot),
|
||||
help='Prompt if we\'re planning to do a dangerous action')
|
||||
parser.add_option('-v', '--verbose', action='store_const',
|
||||
const=logging.DEBUG, default=logging.INFO,
|
||||
help='Print verbose output for debugging.')
|
||||
options, _ = parser.parse_args()
|
||||
|
||||
if options.dry_run or options.force or options.clean_only:
|
||||
options.verbose = logging.DEBUG
|
||||
logging.basicConfig(format='%(message)s', level=options.verbose)
|
||||
|
||||
# Work from the root directory of the checkout.
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
os.chdir(script_dir)
|
||||
|
||||
if sys.platform.startswith('win'):
|
||||
def is_admin():
|
||||
try:
|
||||
return os.getuid() == 0
|
||||
except AttributeError:
|
||||
return ctypes.windll.shell32.IsUserAnAdmin() != 0
|
||||
if not is_admin():
|
||||
logging.error('On Windows, you now need to have administrator '
|
||||
'privileges for the shell running %s (or '
|
||||
'`gclient sync|runhooks`).\nPlease start another command '
|
||||
'prompt as Administrator and try again.' % sys.argv[0])
|
||||
return 1
|
||||
|
||||
if not os.path.exists(CHROMIUM_CHECKOUT):
|
||||
logging.error('Cannot find a Chromium checkout at %s. Did you run "gclient '
|
||||
'sync" before running this script?', CHROMIUM_CHECKOUT)
|
||||
return 2
|
||||
|
||||
links_database = _initialize_database(LINKS_DB)
|
||||
try:
|
||||
symlink_creator = WebRTCLinkSetup(links_database, options.force,
|
||||
options.dry_run, options.prompt)
|
||||
symlink_creator.CleanupLinks()
|
||||
if not options.clean_only:
|
||||
symlink_creator.CreateLinks(on_bot)
|
||||
except LinkError as e:
|
||||
print >> sys.stderr, e.message
|
||||
return 3
|
||||
finally:
|
||||
links_database.close()
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
72
sync_chromium.py
Executable file
72
sync_chromium.py
Executable file
@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style license
|
||||
# that can be found in the LICENSE file in the root of the source
|
||||
# tree. An additional intellectual property rights grant can be found
|
||||
# in the file PATENTS. All contributing project authors may
|
||||
# be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
def get_target_os_list():
|
||||
try:
|
||||
main_gclient = os.path.join(os.path.dirname(ROOT_DIR), '.gclient')
|
||||
config_dict = {}
|
||||
with open(main_gclient, 'rb') as deps_content:
|
||||
exec(deps_content, config_dict)
|
||||
return ','.join(config_dict.get('target_os', []))
|
||||
except Exception as e:
|
||||
print >> sys.stderr, "error while parsing .gclient:", e
|
||||
|
||||
|
||||
def main():
|
||||
CR_DIR = os.path.join(ROOT_DIR, 'chromium')
|
||||
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument('--target-revision', required=True,
|
||||
help='The target chromium git revision [REQUIRED]')
|
||||
p.add_argument('--chromium-dir', default=CR_DIR,
|
||||
help=('The path to the chromium directory to sync '
|
||||
'(default: %(default)r)'))
|
||||
opts = p.parse_args()
|
||||
opts.chromium_dir = os.path.abspath(opts.chromium_dir)
|
||||
|
||||
# Do a quick check to see if we were successful last time to make runhooks
|
||||
# sooper fast.
|
||||
flag_file = os.path.join(opts.chromium_dir, '.last_sync_chromium')
|
||||
if os.path.exists(flag_file):
|
||||
with open(flag_file, 'r') as f:
|
||||
if f.read() == opts.target_revision:
|
||||
print "Chromium already up to date:", opts.target_revision
|
||||
return 0
|
||||
os.unlink(flag_file)
|
||||
|
||||
env = os.environ.copy()
|
||||
env['GYP_CHROMIUM_NO_ACTION'] = '1'
|
||||
gclient_cmd = 'gclient.bat' if sys.platform.startswith('win') else 'gclient'
|
||||
args = [
|
||||
gclient_cmd, 'sync', '--no-history', '--force', '--revision',
|
||||
'src@'+opts.target_revision]
|
||||
target_os_list = get_target_os_list()
|
||||
if target_os_list:
|
||||
args += ['--deps=' + target_os_list]
|
||||
|
||||
print 'Running "%s" in %s' % (' '.join(args), opts.chromium_dir)
|
||||
ret = subprocess.call(args, cwd=opts.chromium_dir, env=env)
|
||||
if ret == 0:
|
||||
with open(flag_file, 'wb') as f:
|
||||
f.write(opts.target_revision)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
@ -1,30 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style license
|
||||
# that can be found in the LICENSE file in the root of the source
|
||||
# tree. An additional intellectual property rights grant can be found
|
||||
# in the file PATENTS. All contributing project authors may
|
||||
# be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
# This script is used to run the vs_toolchain.py script to download the
|
||||
# Visual Studio toolchain. It's just a temporary measure while waiting for the
|
||||
# Chrome team to move find_depot_tools into src/build to get rid of these
|
||||
# workarounds (similar one in gyp_webrtc).
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
checkout_root = os.path.abspath(os.path.join(script_dir, os.pardir, os.pardir))
|
||||
sys.path.insert(0, os.path.join(checkout_root, 'build'))
|
||||
sys.path.insert(0, os.path.join(checkout_root, 'tools', 'find_depot_tools'))
|
||||
|
||||
|
||||
import vs_toolchain
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(vs_toolchain.main())
|
@ -20,7 +20,6 @@ script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
checkout_root = os.path.abspath(os.path.join(script_dir, os.pardir, os.pardir))
|
||||
|
||||
sys.path.insert(0, os.path.join(checkout_root, 'build'))
|
||||
sys.path.insert(0, os.path.join(checkout_root, 'tools', 'find_depot_tools'))
|
||||
import gyp_chromium
|
||||
import gyp_helper
|
||||
import vs_toolchain
|
||||
@ -28,6 +27,13 @@ import vs_toolchain
|
||||
sys.path.insert(0, os.path.join(checkout_root, 'tools', 'gyp', 'pylib'))
|
||||
import gyp
|
||||
|
||||
def GetSupplementalFiles():
|
||||
"""Returns a list of the supplemental files that are included in all GYP
|
||||
sources."""
|
||||
# Can't use the one in gyp_chromium since the directory location of the root
|
||||
# is different.
|
||||
return glob.glob(os.path.join(checkout_root, '*', 'supplement.gypi'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = sys.argv[1:]
|
||||
@ -52,7 +58,10 @@ if __name__ == '__main__':
|
||||
|
||||
# If we didn't get a file, assume 'all.gyp' in the root of the checkout.
|
||||
if not gyp_file_specified:
|
||||
args.append(os.path.join(checkout_root, 'all.gyp'))
|
||||
# Because of a bug in gyp, simply adding the abspath to all.gyp doesn't
|
||||
# work, but chdir'ing and adding the relative path does. Spooky :/
|
||||
os.chdir(checkout_root)
|
||||
args.append('all.gyp')
|
||||
|
||||
# There shouldn't be a circular dependency relationship between .gyp files,
|
||||
args.append('--no-circular-check')
|
||||
@ -68,7 +77,7 @@ if __name__ == '__main__':
|
||||
# Enforce gyp syntax checking. This adds about 20% execution time.
|
||||
args.append('--check')
|
||||
|
||||
supplemental_includes = gyp_chromium.GetSupplementalFiles()
|
||||
supplemental_includes = GetSupplementalFiles()
|
||||
gn_vars_dict = gyp_chromium.GetGypVars(supplemental_includes)
|
||||
|
||||
# Automatically turn on crosscompile support for platforms that need it.
|
||||
|
Loading…
x
Reference in New Issue
Block a user