diff options
-rw-r--r-- | .gitignore | 15 | ||||
-rw-r--r-- | DEPS | 340 | ||||
-rwxr-xr-x[-rw-r--r--] | PRESUBMIT.py | 1 | ||||
-rw-r--r-- | chromium/.gclient | 11 | ||||
-rwxr-xr-x | setup_links.py | 483 | ||||
-rwxr-xr-x | sync_chromium.py | 72 | ||||
-rw-r--r-- | webrtc/build/download_vs_toolchain.py | 30 | ||||
-rwxr-xr-x | webrtc/build/gyp_webrtc | 15 |
8 files changed, 602 insertions, 365 deletions
diff --git a/.gitignore b/.gitignore index 96556d73a0..64ccdd542b 100644 --- a/.gitignore +++ b/.gitignore @@ -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 @@ -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", diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 143d35f8f4..430628c180 100644..100755 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py @@ -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$', diff --git a/chromium/.gclient b/chromium/.gclient new file mode 100644 index 0000000000..68b9dd18c0 --- /dev/null +++ b/chromium/.gclient @@ -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 diff --git a/setup_links.py b/setup_links.py new file mode 100755 index 0000000000..2fea2c352a --- /dev/null +++ b/setup_links.py @@ -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()) diff --git a/sync_chromium.py b/sync_chromium.py new file mode 100755 index 0000000000..ab40c378e8 --- /dev/null +++ b/sync_chromium.py @@ -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()) diff --git a/webrtc/build/download_vs_toolchain.py b/webrtc/build/download_vs_toolchain.py index 2462bdceda..e69de29bb2 100644 --- a/webrtc/build/download_vs_toolchain.py +++ b/webrtc/build/download_vs_toolchain.py @@ -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()) diff --git a/webrtc/build/gyp_webrtc b/webrtc/build/gyp_webrtc index 4d5ae791ca..edc6b36e49 100755 --- a/webrtc/build/gyp_webrtc +++ b/webrtc/build/gyp_webrtc @@ -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. |