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

Side by Side Diff: win_toolchain/get_toolchain_if_necessary.py

Issue 1588673004: Package/Install the Windows 10 Universal C Runtime for VS 2015 (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Fix Windows 10 support and don't install for VS 2013 Created 4 years, 11 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
11 you're trying to build an historical version of Chromium from before the 11 you're trying to build an historical version of Chromium from before the
12 toolchain upgrade, this will cause you to build with a newer toolchain than 12 toolchain upgrade, this will cause you to build with a newer toolchain than
13 was available when that code was committed. This is done for a two main 13 was available when that code was committed. This is done for a two main
14 reasons: 1) it would likely be annoying to have the up-to-date toolchain 14 reasons: 1) it would likely be annoying to have the up-to-date toolchain
15 removed and replaced by one without a service pack applied); 2) it would 15 removed and replaced by one without a service pack applied); 2) it would
16 require maintaining scripts that can build older not-up-to-date revisions of 16 require maintaining scripts that can build older not-up-to-date revisions of
17 the toolchain. This is likely to be a poorly tested code path that probably 17 the toolchain. This is likely to be a poorly tested code path that probably
18 won't be properly maintained. See http://crbug.com/323300. 18 won't be properly maintained. See http://crbug.com/323300.
19 19
20 This does not extend to major versions of the toolchain however, on the 20 This does not extend to major versions of the toolchain however, on the
21 assumption that there are more likely to be source incompatibilities between 21 assumption that there are more likely to be source incompatibilities between
22 major revisions. This script calls a subscript (currently, toolchain2013.py) 22 major revisions. This script calls a subscript (currently, toolchain2013.py)
23 to do the main work. It is expected that toolchain2013.py will always be able 23 to do the main work. It is expected that toolchain2013.py will always be able
24 to acquire/build the most current revision of a VS2013-based toolchain. In the 24 to acquire/build the most current revision of a VS2013-based toolchain. In the
25 future when a hypothetical VS2015 is released, the 2013 script will be 25 future when a hypothetical VS2015 is released, the 2013 script will be
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 _winreg
29 import hashlib 30 import hashlib
30 import json 31 import json
31 import optparse 32 import optparse
32 import os 33 import os
34 import platform
33 import shutil 35 import shutil
34 import subprocess 36 import subprocess
35 import sys 37 import sys
36 import tempfile 38 import tempfile
37 import time 39 import time
38 import zipfile 40 import zipfile
39 41
40 42
41 BASEDIR = os.path.dirname(os.path.abspath(__file__)) 43 BASEDIR = os.path.dirname(os.path.abspath(__file__))
42 DEPOT_TOOLS_PATH = os.path.join(BASEDIR, '..') 44 DEPOT_TOOLS_PATH = os.path.join(BASEDIR, '..')
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 else: 212 else:
211 temp_dir, local_zip = DownloadUsingGsutil(tree_sha1 + '.zip') 213 temp_dir, local_zip = DownloadUsingGsutil(tree_sha1 + '.zip')
212 sys.stdout.write('Extracting %s...\n' % local_zip) 214 sys.stdout.write('Extracting %s...\n' % local_zip)
213 sys.stdout.flush() 215 sys.stdout.flush()
214 with zipfile.ZipFile(local_zip, 'r', zipfile.ZIP_DEFLATED, True) as zf: 216 with zipfile.ZipFile(local_zip, 'r', zipfile.ZIP_DEFLATED, True) as zf:
215 zf.extractall(target_dir) 217 zf.extractall(target_dir)
216 if temp_dir: 218 if temp_dir:
217 RmDir(temp_dir) 219 RmDir(temp_dir)
218 220
219 221
222 def GetInstallerName():
223 """Return the name of the Windows 10 Universal C Runtime installer for the
224 current platform, or None if installer is not needed or not applicable.
225 The registry has to be used instead of sys.getwindowsversion() because
226 Python 2.7 is only manifested as being compatible up to Windows 8, so the
227 version APIs helpfully return a maximum of 6.2 (Windows 8).
228 """
229 key_name = r'Software\Microsoft\Windows NT\CurrentVersion'
230 key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key_name)
231 value, keytype = _winreg.QueryValueEx(key, "CurrentVersion")
232 key.Close()
233 if keytype != _winreg.REG_SZ:
234 raise Exception("Unexpected type in registry")
235 if value == '6.1':
236 # Windows 7 and Windows Server 2008 R2
237 return 'Windows6.1-KB2999226-x64.msu'
238 elif value == '6.2':
239 # Windows 8 and Windows Server 2012
240 return 'Windows8-RT-KB2999226-x64.msu'
241 elif value == '6.3':
242 # Windows 8.1, Windows Server 2012 R2, and Windows 10.
243 # The Windows 8.1 installer doesn't work on Windows 10, but it will never
244 # be used because the UCRT is always installed on Windows 10.
245 return 'Windows8.1-KB2999226-x64.msu'
246 else:
247 # Some future OS.
248 return None
249
250
251 def InstallUniversalCRTIfNeeded(abs_target_dir):
252 installer_name = GetInstallerName()
253 if not installer_name:
254 return
255
256 bitness = platform.architecture()[0]
257 # When running 64-bit python the x64 DLLs will be in System32
258 x64_path = 'System32' if bitness == '64bit' else 'Sysnative'
259 x64_path = os.path.join(r'C:\Windows', x64_path)
260 sample_crt_file = os.path.join(x64_path, 'ucrtbase.dll')
261
262 if os.path.exists(sample_crt_file):
263 # Nothing to do.
264 return
265
266 print ('%s does not exist - installing Windows 10 Universal C Runtime' %
267 sample_crt_file)
scottmg 2016/01/15 19:06:44 The indent should be after the (, aligned with '.
brucedawson 2016/01/15 19:16:46 Done.
268
269 installer = os.path.join(abs_target_dir, "installers", installer_name)
270 command = r'wusa.exe /quiet "%s"' % installer
271 print 'Running %s' % command
272
273 try:
274 subprocess.check_call(command)
275 except WindowsError as e:
276 if e.winerror == 740: # The requested operation requires elevation
277 print
278 print '-'*80
279 print
280 print 'Elevation required. You must manually install this update:'
281 print ' %s' % installer
282 print
283 print '-'*80
284 print
285 raise Exception('Elevation required. You must manually install %s' %
286 installer)
287 raise e
288
289
220 def main(): 290 def main():
221 parser = optparse.OptionParser(description=sys.modules[__name__].__doc__) 291 parser = optparse.OptionParser(description=sys.modules[__name__].__doc__)
222 parser.add_option('--output-json', metavar='FILE', 292 parser.add_option('--output-json', metavar='FILE',
223 help='write information about toolchain to FILE') 293 help='write information about toolchain to FILE')
224 parser.add_option('--force', action='store_true', 294 parser.add_option('--force', action='store_true',
225 help='force script to run on non-Windows hosts') 295 help='force script to run on non-Windows hosts')
226 options, args = parser.parse_args() 296 options, args = parser.parse_args()
227 297
228 if not (sys.platform.startswith(('cygwin', 'win32')) or options.force): 298 if not (sys.platform.startswith(('cygwin', 'win32')) or options.force):
229 return 0 299 return 0
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 print('\n\n\nPlease follow the instructions at ' 344 print('\n\n\nPlease follow the instructions at '
275 'https://www.chromium.org/developers/how-tos/' 345 'https://www.chromium.org/developers/how-tos/'
276 'build-instructions-windows\n\n') 346 'build-instructions-windows\n\n')
277 return 1 347 return 1
278 print('Windows toolchain out of date or doesn\'t exist, updating (Pro)...') 348 print('Windows toolchain out of date or doesn\'t exist, updating (Pro)...')
279 print(' current_hash: %s' % current_hash) 349 print(' current_hash: %s' % current_hash)
280 print(' desired_hashes: %s' % ', '.join(desired_hashes)) 350 print(' desired_hashes: %s' % ', '.join(desired_hashes))
281 sys.stdout.flush() 351 sys.stdout.flush()
282 DelayBeforeRemoving(target_dir) 352 DelayBeforeRemoving(target_dir)
283 if sys.platform == 'win32': 353 if sys.platform == 'win32':
284 # This stays resident and will make the rmdir below fail. 354 # These stay resident and will make the rmdir below fail.
285 with open(os.devnull, 'wb') as nul: 355 kill_list = [
286 subprocess.call(['taskkill', '/f', '/im', 'mspdbsrv.exe'], 356 'mspdbsrv.exe',
287 stdin=nul, stdout=nul, stderr=nul) 357 'vctip.exe', # Compiler and tools experience improvement data uploader.
358 ]
359 for process_name in kill_list:
360 with open(os.devnull, 'wb') as nul:
361 subprocess.call(['taskkill', '/f', '/im', process_name],
362 stdin=nul, stdout=nul, stderr=nul)
288 if os.path.isdir(target_dir): 363 if os.path.isdir(target_dir):
289 RmDir(target_dir) 364 RmDir(target_dir)
290 365
291 DoTreeMirror(target_dir, desired_hashes[0]) 366 DoTreeMirror(target_dir, desired_hashes[0])
292 367
293 got_new_toolchain = True 368 got_new_toolchain = True
294 369
295 win_sdk = os.path.join(abs_target_dir, 'win_sdk') 370 win_sdk = os.path.join(abs_target_dir, 'win_sdk')
296 try: 371 try:
297 with open(os.path.join(target_dir, 'VS_VERSION'), 'rb') as f: 372 with open(os.path.join(target_dir, 'VS_VERSION'), 'rb') as f:
(...skipping 26 matching lines...) Expand all
324 'Got wrong hash after pulling a new toolchain. ' 399 'Got wrong hash after pulling a new toolchain. '
325 'Wanted one of \'%s\', got \'%s\'.' % ( 400 'Wanted one of \'%s\', got \'%s\'.' % (
326 ', '.join(desired_hashes), current_hash)) 401 ', '.join(desired_hashes), current_hash))
327 return 1 402 return 1
328 SaveTimestampsAndHash(target_dir, current_hash) 403 SaveTimestampsAndHash(target_dir, current_hash)
329 404
330 if options.output_json: 405 if options.output_json:
331 shutil.copyfile(os.path.join(target_dir, '..', 'data.json'), 406 shutil.copyfile(os.path.join(target_dir, '..', 'data.json'),
332 options.output_json) 407 options.output_json)
333 408
409 if os.environ.get('GYP_MSVS_VERSION') == '2015':
410 InstallUniversalCRTIfNeeded(abs_target_dir)
411
334 return 0 412 return 0
335 413
336 414
337 if __name__ == '__main__': 415 if __name__ == '__main__':
338 sys.exit(main()) 416 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