| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2016 The Chromium Authors. All rights reserved. | 2 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Download necessary mac toolchain files under certain conditions. If | 6 """ |
| 7 xcode-select is already set and points to an external folder | 7 If should_use_hermetic_xcode.py emits "1", and the current toolchain is out of |
| 8 (e.g. /Application/Xcode.app), this script only runs if the GYP_DEFINE | 8 date: |
| 9 |force_mac_toolchain| is set. To override the values in | 9 * Downloads the hermetic mac toolchain |
| 10 |TOOLCHAIN_REVISION|-|TOOLCHAIN_SUB_REVISION| below, GYP_DEFINE | 10 * Requires gsutil to be configured. |
| 11 mac_toolchain_revision can be used instead. | 11 * Accepts the license. |
| 12 | 12 * If xcode-select and xcodebuild are not passwordless in sudoers, requires |
| 13 This script will only run on machines if /usr/bin/xcodebuild and | 13 user interaction. |
| 14 /usr/bin/xcode-select has been added to the sudoers list so the license can be | |
| 15 accepted. | |
| 16 | |
| 17 Otherwise, user input would be required to complete the script. Perhaps future | |
| 18 versions can be modified to allow for user input on developer machines. | |
| 19 """ | 14 """ |
| 20 | 15 |
| 21 import os | 16 import os |
| 22 import plistlib | 17 import plistlib |
| 23 import shutil | 18 import shutil |
| 24 import subprocess | 19 import subprocess |
| 25 import sys | 20 import sys |
| 26 import tarfile | 21 import tarfile |
| 27 import time | 22 import time |
| 28 import tempfile | 23 import tempfile |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 old_path = subprocess.Popen(['/usr/bin/xcode-select', '-p'], | 126 old_path = subprocess.Popen(['/usr/bin/xcode-select', '-p'], |
| 132 stdout=subprocess.PIPE).communicate()[0].strip() | 127 stdout=subprocess.PIPE).communicate()[0].strip() |
| 133 try: | 128 try: |
| 134 build_dir = os.path.join(TOOLCHAIN_BUILD_DIR, 'Contents/Developer') | 129 build_dir = os.path.join(TOOLCHAIN_BUILD_DIR, 'Contents/Developer') |
| 135 subprocess.check_call(['sudo', '/usr/bin/xcode-select', '-s', build_dir]) | 130 subprocess.check_call(['sudo', '/usr/bin/xcode-select', '-s', build_dir]) |
| 136 subprocess.check_call(['sudo', '/usr/bin/xcodebuild', '-license', 'accept']) | 131 subprocess.check_call(['sudo', '/usr/bin/xcodebuild', '-license', 'accept']) |
| 137 finally: | 132 finally: |
| 138 subprocess.check_call(['sudo', '/usr/bin/xcode-select', '-s', old_path]) | 133 subprocess.check_call(['sudo', '/usr/bin/xcode-select', '-s', old_path]) |
| 139 | 134 |
| 140 | 135 |
| 141 def _UseLocalMacSDK(): | 136 def _UseHermeticToolchain(): |
| 142 force_pull = os.environ.has_key('FORCE_MAC_TOOLCHAIN') | 137 current_dir = os.path.dirname(os.path.realpath(__file__)) |
| 138 script_path = os.path.join(current_dir, 'mac/should_use_hermetic_xcode.py') |
| 139 proc = subprocess.Popen([script_path], stdout=subprocess.PIPE) |
| 140 return '1' in proc.stdout.readline() |
| 143 | 141 |
| 144 # Don't update the toolchain if there's already one installed outside of the | 142 |
| 145 # expected location for a Chromium mac toolchain, unless |force_pull| is set. | 143 def RequestGsAuthentication(): |
| 146 proc = subprocess.Popen(['xcode-select', '-p'], stdout=subprocess.PIPE) | 144 """Requests that the user authenticate to be able to access gs://. |
| 147 xcode_select_dir = proc.communicate()[0] | 145 """ |
| 148 rc = proc.returncode | 146 print 'Access to ' + TOOLCHAIN_URL + ' not configured.' |
| 149 return (not force_pull and rc == 0 and | 147 print '-----------------------------------------------------------------' |
| 150 TOOLCHAIN_BUILD_DIR not in xcode_select_dir) | 148 print |
| 149 print 'You appear to be a Googler.' |
| 150 print |
| 151 print 'I\'m sorry for the hassle, but you need to do a one-time manual' |
| 152 print 'authentication. Please run:' |
| 153 print |
| 154 print ' download_from_google_storage --config' |
| 155 print |
| 156 print 'and follow the instructions.' |
| 157 print |
| 158 print 'NOTE 1: Use your google.com credentials, not chromium.org.' |
| 159 print 'NOTE 2: Enter 0 when asked for a "project-id".' |
| 160 print |
| 161 print '-----------------------------------------------------------------' |
| 162 print |
| 163 sys.stdout.flush() |
| 164 sys.exit(1) |
| 151 | 165 |
| 152 | 166 |
| 153 def main(): | 167 def main(): |
| 154 if sys.platform != 'darwin': | 168 if sys.platform != 'darwin': |
| 155 return 0 | 169 return 0 |
| 156 | 170 |
| 157 if _UseLocalMacSDK(): | 171 if not _UseHermeticToolchain(): |
| 158 print 'Using local toolchain.' | 172 print 'Using local toolchain.' |
| 159 return 0 | 173 return 0 |
| 160 | 174 |
| 161 toolchain_revision = os.environ.get('MAC_TOOLCHAIN_REVISION', | 175 toolchain_revision = os.environ.get('MAC_TOOLCHAIN_REVISION', |
| 162 TOOLCHAIN_VERSION) | 176 TOOLCHAIN_VERSION) |
| 163 if ReadStampFile() == toolchain_revision: | 177 if ReadStampFile() == toolchain_revision: |
| 164 print 'Toolchain (%s) is already up to date.' % toolchain_revision | 178 print 'Toolchain (%s) is already up to date.' % toolchain_revision |
| 165 AcceptLicense() | 179 AcceptLicense() |
| 166 return 0 | 180 return 0 |
| 167 | 181 |
| 168 if not CanAccessToolchainBucket(): | 182 if not CanAccessToolchainBucket(): |
| 169 print 'Cannot access toolchain bucket.' | 183 RequestGsAuthentication() |
| 170 return 0 | 184 return 1 |
| 171 | 185 |
| 172 # Reset the stamp file in case the build is unsuccessful. | 186 # Reset the stamp file in case the build is unsuccessful. |
| 173 WriteStampFile('') | 187 WriteStampFile('') |
| 174 | 188 |
| 175 toolchain_file = '%s.tgz' % toolchain_revision | 189 toolchain_file = '%s.tgz' % toolchain_revision |
| 176 toolchain_full_url = TOOLCHAIN_URL + toolchain_file | 190 toolchain_full_url = TOOLCHAIN_URL + toolchain_file |
| 177 | 191 |
| 178 print 'Updating toolchain to %s...' % toolchain_revision | 192 print 'Updating toolchain to %s...' % toolchain_revision |
| 179 try: | 193 try: |
| 180 toolchain_file = 'toolchain-%s.tgz' % toolchain_revision | 194 toolchain_file = 'toolchain-%s.tgz' % toolchain_revision |
| 181 toolchain_full_url = TOOLCHAIN_URL + toolchain_file | 195 toolchain_full_url = TOOLCHAIN_URL + toolchain_file |
| 182 DownloadAndUnpack(toolchain_full_url, TOOLCHAIN_BUILD_DIR) | 196 DownloadAndUnpack(toolchain_full_url, TOOLCHAIN_BUILD_DIR) |
| 183 AcceptLicense() | 197 AcceptLicense() |
| 184 | 198 |
| 185 print 'Toolchain %s unpacked.' % toolchain_revision | 199 print 'Toolchain %s unpacked.' % toolchain_revision |
| 186 WriteStampFile(toolchain_revision) | 200 WriteStampFile(toolchain_revision) |
| 187 return 0 | 201 return 0 |
| 188 except Exception as e: | 202 except Exception as e: |
| 189 print 'Failed to download toolchain %s.' % toolchain_file | 203 print 'Failed to download toolchain %s.' % toolchain_file |
| 190 print 'Exception %s' % e | 204 print 'Exception %s' % e |
| 191 print 'Exiting.' | 205 print 'Exiting.' |
| 192 return 1 | 206 return 1 |
| 193 | 207 |
| 194 if __name__ == '__main__': | 208 if __name__ == '__main__': |
| 195 sys.exit(main()) | 209 sys.exit(main()) |
| OLD | NEW |