| Index: build/mac_toolchain.py
|
| diff --git a/build/mac_toolchain.py b/build/mac_toolchain.py
|
| new file mode 100755
|
| index 0000000000000000000000000000000000000000..64d07169e80eaae489053ec8997a10de33b8c499
|
| --- /dev/null
|
| +++ b/build/mac_toolchain.py
|
| @@ -0,0 +1,154 @@
|
| +#!/usr/bin/env python
|
| +# Copyright 2016 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +"""Download necessary mac toolchain files under certain conditions. If
|
| +xcode-select is already set and points to an external folder
|
| +(e.g. /Application/Xcode.app), this script only runs if the GYP_DEFINE
|
| +|force_mac_toolchain| is set. To override the values in
|
| +|TOOLCHAIN_REVISION|-|TOOLCHAIN_SUB_REVISION| below, GYP_DEFINE
|
| +mac_toolchain_revision can be used instead.
|
| +
|
| +This script will only run on machines if /usr/bin/xcodebuild has been added to
|
| +the sudoers list so the license can be accepted.
|
| +
|
| +Otherwise, user input would be required to complete the script. Perhaps future
|
| +versions can be modified to allow for user input on developer machines.
|
| +"""
|
| +
|
| +import os
|
| +import shutil
|
| +import subprocess
|
| +import sys
|
| +import tarfile
|
| +import time
|
| +import tempfile
|
| +import urllib2
|
| +
|
| +# This can be changed after running /build/package_mac_toolchain.py.
|
| +TOOLCHAIN_REVISION = '5B1008'
|
| +TOOLCHAIN_SUB_REVISION = 2
|
| +TOOLCHAIN_VERSION = '%s-%s' % (TOOLCHAIN_REVISION, TOOLCHAIN_SUB_REVISION)
|
| +
|
| +BASE_DIR = os.path.abspath(os.path.dirname(__file__))
|
| +TOOLCHAIN_BUILD_DIR = os.path.join(BASE_DIR, 'mac_files', 'Xcode.app')
|
| +STAMP_FILE = os.path.join(BASE_DIR, 'mac_files', 'toolchain_build_revision')
|
| +TOOLCHAIN_URL = 'gs://chrome-mac-sdk/'
|
| +
|
| +
|
| +def GetToolchainDirectory():
|
| + if sys.platform == 'darwin' and not UseLocalMacSDK():
|
| + return TOOLCHAIN_BUILD_DIR
|
| +
|
| +
|
| +def ReadStampFile():
|
| + """Return the contents of the stamp file, or '' if it doesn't exist."""
|
| + try:
|
| + with open(STAMP_FILE, 'r') as f:
|
| + return f.read().rstrip()
|
| + except IOError:
|
| + return ''
|
| +
|
| +
|
| +def WriteStampFile(s):
|
| + """Write s to the stamp file."""
|
| + EnsureDirExists(os.path.dirname(STAMP_FILE))
|
| + with open(STAMP_FILE, 'w') as f:
|
| + f.write(s)
|
| + f.write('\n')
|
| +
|
| +
|
| +def EnsureDirExists(path):
|
| + if not os.path.exists(path):
|
| + os.makedirs(path)
|
| +
|
| +
|
| +def DownloadAndUnpack(url, output_dir):
|
| + """Decompresses |url| into a cleared |output_dir|."""
|
| + temp_name = tempfile.mktemp(prefix='mac_toolchain')
|
| + try:
|
| + print 'Downloading new toolchain.'
|
| + subprocess.check_call(['gsutil.py', 'cp', url, temp_name])
|
| + if os.path.exists(output_dir):
|
| + print 'Deleting old toolchain.'
|
| + shutil.rmtree(output_dir)
|
| + EnsureDirExists(output_dir)
|
| + print 'Unpacking new toolchain.'
|
| + tarfile.open(mode='r:gz', name=temp_name).extractall(path=output_dir)
|
| + finally:
|
| + if os.path.exists(temp_name):
|
| + os.unlink(temp_name)
|
| +
|
| +
|
| +def CanAccessToolchainBucket():
|
| + """Checks whether the user has access to |TOOLCHAIN_URL|."""
|
| + proc = subprocess.Popen(['gsutil.py', 'ls', TOOLCHAIN_URL],
|
| + stdout=subprocess.PIPE)
|
| + proc.communicate()
|
| + return proc.returncode == 0
|
| +
|
| +
|
| +def AcceptLicense(directory):
|
| + """Use xcodebuild to accept new toolchain license. This only
|
| + works if xcodebuild is in sudoers."""
|
| + xcodebuild = os.path.join(TOOLCHAIN_BUILD_DIR,
|
| + 'Contents/Developer/usr/bin/xcodebuild')
|
| + subprocess.check_call(['sudo', xcodebuild, '-license', 'accept'])
|
| +
|
| +
|
| +def UseLocalMacSDK():
|
| + force_pull = os.environ.has_key('FORCE_MAC_TOOLCHAIN')
|
| +
|
| + # Don't update the toolchain if there's already one installed outside of the
|
| + # expected location for a Chromium mac toolchain, unless |force_pull| is set.
|
| + proc = subprocess.Popen(['xcode-select', '-p'], stdout=subprocess.PIPE)
|
| + xcode_select_dir = proc.communicate()[0]
|
| + rc = proc.returncode
|
| + return (not force_pull and rc == 0 and
|
| + TOOLCHAIN_BUILD_DIR not in xcode_select_dir)
|
| +
|
| +
|
| +def main():
|
| + if sys.platform != 'darwin':
|
| + return 0
|
| +
|
| + # TODO(justincohen): Add support for GN per crbug.com/570091
|
| + if UseLocalMacSDK():
|
| + print 'Using local toolchain.'
|
| + return 0
|
| +
|
| + toolchain_revision = os.environ.get('MAC_TOOLCHAIN_REVISION',
|
| + TOOLCHAIN_VERSION)
|
| + if ReadStampFile() == toolchain_revision:
|
| + print 'Toolchain (%s) is already up to date.' % toolchain_revision
|
| + AcceptLicense(TOOLCHAIN_BUILD_DIR)
|
| + return 0
|
| +
|
| + if not CanAccessToolchainBucket():
|
| + print 'Cannot access toolchain bucket.'
|
| + return 0
|
| +
|
| + # Reset the stamp file in case the build is unsuccessful.
|
| + WriteStampFile('')
|
| +
|
| + toolchain_file = '%s.tgz' % toolchain_revision
|
| + toolchain_full_url = TOOLCHAIN_URL + toolchain_file
|
| +
|
| + print 'Updating toolchain to %s...' % toolchain_revision
|
| + try:
|
| + toolchain_file = 'toolchain-%s.tgz' % toolchain_revision
|
| + toolchain_full_url = TOOLCHAIN_URL + toolchain_file
|
| + DownloadAndUnpack(toolchain_full_url, TOOLCHAIN_BUILD_DIR)
|
| + AcceptLicense(TOOLCHAIN_BUILD_DIR)
|
| +
|
| + print 'Toolchain %s unpacked.' % toolchain_revision
|
| + WriteStampFile(toolchain_revision)
|
| + return 0
|
| + except:
|
| + print 'Failed to download toolchain %s.' % toolchain_file
|
| + print 'Exiting.'
|
| + return 1
|
| +
|
| +if __name__ == '__main__':
|
| + sys.exit(main())
|
|
|