Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(444)

Side by Side Diff: win_toolchain/get_toolchain_if_necessary.py

Issue 1165563003: Rework/update toolchain script for vs2015 (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: add missing ucrt files Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | win_toolchain/package_from_installed.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2013 The Chromium Authors. All rights reserved. 2 # Copyright 2013 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 """Downloads and unpacks a toolchain for building on Windows. The contents are 6 """Downloads and unpacks a toolchain for building on Windows. The contents are
7 matched by sha1 which will be updated when the toolchain is updated. 7 matched by sha1 which will be updated when the toolchain is updated.
8 8
9 Having a toolchain script in depot_tools means that it's not versioned 9 Having a toolchain script in depot_tools means that it's not versioned
10 directly with the source code. That is, if the toolchain is upgraded, but 10 directly with the source code. That is, if the toolchain is upgraded, but
(...skipping 15 matching lines...) Expand all
26 maintained, and a new 2015 script would be added. 26 maintained, and a new 2015 script would be added.
27 """ 27 """
28 28
29 import hashlib 29 import hashlib
30 import json 30 import json
31 import optparse 31 import optparse
32 import os 32 import os
33 import shutil 33 import shutil
34 import subprocess 34 import subprocess
35 import sys 35 import sys
36 import tempfile
36 import time 37 import time
38 import zipfile
37 39
38 40
39 BASEDIR = os.path.dirname(os.path.abspath(__file__)) 41 BASEDIR = os.path.dirname(os.path.abspath(__file__))
40 DEPOT_TOOLS_PATH = os.path.join(BASEDIR, '..') 42 DEPOT_TOOLS_PATH = os.path.join(BASEDIR, '..')
41 sys.path.append(DEPOT_TOOLS_PATH) 43 sys.path.append(DEPOT_TOOLS_PATH)
42 import download_from_google_storage 44 try:
45 import download_from_google_storage
46 except ImportError:
47 # Allow use of utility functions in this script from package_from_installed
48 # on bare VM that doesn't have a full depot_tools.
49 pass
43 50
44 if sys.platform != 'cygwin': 51 if sys.platform != 'cygwin':
45 import ctypes.wintypes 52 import ctypes.wintypes
46 GetFileAttributes = ctypes.windll.kernel32.GetFileAttributesW 53 GetFileAttributes = ctypes.windll.kernel32.GetFileAttributesW
47 GetFileAttributes.argtypes = (ctypes.wintypes.LPWSTR,) 54 GetFileAttributes.argtypes = (ctypes.wintypes.LPWSTR,)
48 GetFileAttributes.restype = ctypes.wintypes.DWORD 55 GetFileAttributes.restype = ctypes.wintypes.DWORD
49 FILE_ATTRIBUTE_HIDDEN = 0x2 56 FILE_ATTRIBUTE_HIDDEN = 0x2
50 FILE_ATTRIBUTE_SYSTEM = 0x4 57 FILE_ATTRIBUTE_SYSTEM = 0x4
51 58
52 59
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 if (os.path.isdir(target_dir) and 186 if (os.path.isdir(target_dir) and
180 not bool(int(os.environ.get('CHROME_HEADLESS', '0')))): 187 not bool(int(os.environ.get('CHROME_HEADLESS', '0')))):
181 for i in range(9, 0, -1): 188 for i in range(9, 0, -1):
182 sys.stdout.write( 189 sys.stdout.write(
183 '\rRemoving old toolchain in %ds... (Ctrl-C to cancel)' % i) 190 '\rRemoving old toolchain in %ds... (Ctrl-C to cancel)' % i)
184 sys.stdout.flush() 191 sys.stdout.flush()
185 time.sleep(1) 192 time.sleep(1)
186 print 193 print
187 194
188 195
196 def DownloadUsingGsutil(filename):
197 """Downloads the given file from Google Storage chrome-wintoolchain bucket."""
198 temp_dir = tempfile.mkdtemp()
199 assert os.path.basename(filename) == filename
200 target_path = os.path.join(temp_dir, filename)
201 gsutil = download_from_google_storage.Gsutil(
202 download_from_google_storage.GSUTIL_DEFAULT_PATH, boto_path=None)
203 code = gsutil.call('cp', 'gs://chrome-wintoolchain/' + filename, target_path)
204 if code != 0:
205 sys.exit('gsutil failed')
206 return temp_dir, target_path
207
208
209 def DoTreeMirror(target_dir, tree_sha1):
210 """In order to save temporary space on bots that do not have enough space to
211 download ISOs, unpack them, and copy to the target location, the whole tree
212 is uploaded as a zip to internal storage, and then mirrored here."""
213 temp_dir, local_zip = DownloadUsingGsutil(tree_sha1 + '.zip')
214 sys.stdout.write('Extracting %s...\n' % local_zip)
215 sys.stdout.flush()
216 with zipfile.ZipFile(local_zip, 'r', zipfile.ZIP_DEFLATED, True) as zf:
217 zf.extractall(target_dir)
218 if temp_dir:
219 subprocess.check_call('rmdir /s/q "%s"' % temp_dir, shell=True)
220
221
189 def main(): 222 def main():
190 if not sys.platform.startswith(('cygwin', 'win32')): 223 if not sys.platform.startswith(('cygwin', 'win32')):
191 return 0 224 return 0
192 225
193 parser = optparse.OptionParser(description=sys.modules[__name__].__doc__) 226 parser = optparse.OptionParser(description=sys.modules[__name__].__doc__)
194 parser.add_option('--output-json', metavar='FILE', 227 parser.add_option('--output-json', metavar='FILE',
195 help='write information about toolchain to FILE') 228 help='write information about toolchain to FILE')
196 options, args = parser.parse_args() 229 options, args = parser.parse_args()
197 230
198 if sys.platform == 'cygwin': 231 if sys.platform == 'cygwin':
199 # This script requires Windows Python, so invoke with depot_tools' Python. 232 # This script requires Windows Python, so invoke with depot_tools' Python.
200 def winpath(path): 233 def winpath(path):
201 return subprocess.check_output(['cygpath', '-w', path]).strip() 234 return subprocess.check_output(['cygpath', '-w', path]).strip()
202 python = os.path.join(DEPOT_TOOLS_PATH, 'python.bat') 235 python = os.path.join(DEPOT_TOOLS_PATH, 'python.bat')
203 cmd = [python, winpath(__file__)] 236 cmd = [python, winpath(__file__)]
204 if options.output_json: 237 if options.output_json:
205 cmd.extend(['--output-json', winpath(options.output_json)]) 238 cmd.extend(['--output-json', winpath(options.output_json)])
206 cmd.extend(args) 239 cmd.extend(args)
207 sys.exit(subprocess.call(cmd)) 240 sys.exit(subprocess.call(cmd))
208 241
209 # We assume that the Pro hash is the first one. 242 # We assume that the Pro hash is the first one.
210 desired_hashes = args 243 desired_hashes = args
211 if len(desired_hashes) == 0: 244 if len(desired_hashes) == 0:
212 sys.exit('Desired hashes are required.') 245 sys.exit('Desired hashes are required.')
213 246
214 # Move to depot_tools\win_toolchain where we'll store our files, and where 247 # Move to depot_tools\win_toolchain where we'll store our files, and where
215 # the downloader script is. 248 # the downloader script is.
216 os.chdir(os.path.normpath(os.path.join(BASEDIR))) 249 os.chdir(os.path.normpath(os.path.join(BASEDIR)))
217 toolchain_dir = '.' 250 toolchain_dir = '.'
218 target_dir = os.path.normpath(os.path.join(toolchain_dir, 'vs2013_files')) 251 if os.environ.get('GYP_MSVS_VERSION') == '2015':
252 target_dir = os.path.normpath(os.path.join(toolchain_dir, 'vs_files'))
253 else:
254 target_dir = os.path.normpath(os.path.join(toolchain_dir, 'vs2013_files'))
255 abs_target_dir = os.path.abspath(target_dir)
256
257 got_new_toolchain = False
219 258
220 # If the current hash doesn't match what we want in the file, nuke and pave. 259 # If the current hash doesn't match what we want in the file, nuke and pave.
221 # Typically this script is only run when the .sha1 one file is updated, but 260 # Typically this script is only run when the .sha1 one file is updated, but
222 # directly calling "gclient runhooks" will also run it, so we cache 261 # directly calling "gclient runhooks" will also run it, so we cache
223 # based on timestamps to make that case fast. 262 # based on timestamps to make that case fast.
224 current_hash = CalculateHash(target_dir) 263 current_hash = CalculateHash(target_dir)
225 if current_hash not in desired_hashes: 264 if current_hash not in desired_hashes:
226 should_use_gs = False 265 should_use_gs = False
227 if (HaveSrcInternalAccess() or 266 if (HaveSrcInternalAccess() or
228 LooksLikeGoogler() or 267 LooksLikeGoogler() or
229 CanAccessToolchainBucket()): 268 CanAccessToolchainBucket()):
230 should_use_gs = True 269 should_use_gs = True
231 if not CanAccessToolchainBucket(): 270 if not CanAccessToolchainBucket():
232 RequestGsAuthentication() 271 RequestGsAuthentication()
233 if not should_use_gs: 272 if not should_use_gs:
234 print('Please follow the instructions at ' 273 print('Please follow the instructions at '
235 'http://www.chromium.org/developers/how-tos/' 274 'http://www.chromium.org/developers/how-tos/'
236 'build-instructions-windows') 275 'build-instructions-windows')
237 return 1 276 return 1
238 print('Windows toolchain out of date or doesn\'t exist, updating (Pro)...') 277 print('Windows toolchain out of date or doesn\'t exist, updating (Pro)...')
239 print(' current_hash: %s' % current_hash) 278 print(' current_hash: %s' % current_hash)
240 print(' desired_hashes: %s' % ', '.join(desired_hashes)) 279 print(' desired_hashes: %s' % ', '.join(desired_hashes))
241 sys.stdout.flush() 280 sys.stdout.flush()
242 DelayBeforeRemoving(target_dir) 281 DelayBeforeRemoving(target_dir)
243 # This stays resident and will make the rmdir below fail. 282 # This stays resident and will make the rmdir below fail.
244 with open(os.devnull, 'wb') as nul: 283 with open(os.devnull, 'wb') as nul:
245 subprocess.call(['taskkill', '/f', '/im', 'mspdbsrv.exe'], 284 subprocess.call(['taskkill', '/f', '/im', 'mspdbsrv.exe'],
246 stdin=nul, stdout=nul, stderr=nul) 285 stdin=nul, stdout=nul, stderr=nul)
247 if os.path.isdir(target_dir): 286 if os.path.isdir(target_dir):
248 subprocess.check_call('rmdir /s/q "%s"' % target_dir, shell=True) 287 subprocess.check_call('rmdir /s/q "%s"' % target_dir, shell=True)
249 args = [sys.executable, 288
250 'toolchain2013.py', 289 DoTreeMirror(target_dir, desired_hashes[0])
251 '--targetdir', target_dir, 290
252 '--sha1', desired_hashes[0], 291 got_new_toolchain = True
253 '--use-gs'] 292
254 subprocess.check_call(args) 293 win_sdk = os.path.join(abs_target_dir, 'win_sdk')
294 try:
295 with open(os.path.join(target_dir, 'VS_VERSION'), 'rb') as f:
296 vs_version = f.read().strip()
297 except IOError:
298 # Older toolchains didn't have the VS_VERSION file, and used 'win8sdk'
299 # instead of just 'win_sdk'.
300 vs_version = '2013'
301 win_sdk = os.path.join(abs_target_dir, 'win8sdk')
302
303 data = {
304 'path': abs_target_dir,
305 'version': vs_version,
306 'win_sdk': win_sdk,
307 'wdk': os.path.join(abs_target_dir, 'wdk'),
308 'runtime_dirs': [
309 os.path.join(abs_target_dir, 'sys64'),
310 os.path.join(abs_target_dir, 'sys32'),
311 ],
312 }
313 with open(os.path.join(target_dir, '..', 'data.json'), 'w') as f:
314 json.dump(data, f)
315
316 if got_new_toolchain:
255 current_hash = CalculateHash(target_dir) 317 current_hash = CalculateHash(target_dir)
256 if current_hash not in desired_hashes: 318 if current_hash not in desired_hashes:
257 print >> sys.stderr, ( 319 print >> sys.stderr, (
258 'Got wrong hash after pulling a new toolchain. ' 320 'Got wrong hash after pulling a new toolchain. '
259 'Wanted one of \'%s\', got \'%s\'.' % ( 321 'Wanted one of \'%s\', got \'%s\'.' % (
260 ', '.join(desired_hashes), current_hash)) 322 ', '.join(desired_hashes), current_hash))
261 return 1 323 return 1
262 SaveTimestampsAndHash(target_dir, current_hash) 324 SaveTimestampsAndHash(target_dir, current_hash)
263 325
264 if options.output_json: 326 if options.output_json:
265 shutil.copyfile(os.path.join(target_dir, '..', 'data.json'), 327 shutil.copyfile(os.path.join(target_dir, '..', 'data.json'),
266 options.output_json) 328 options.output_json)
267 329
268 return 0 330 return 0
269 331
270 332
271 if __name__ == '__main__': 333 if __name__ == '__main__':
272 sys.exit(main()) 334 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | win_toolchain/package_from_installed.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698