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