OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 | 2 |
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 # This script is wrapper for Chromium that adds some support for how GYP | 7 # This script is wrapper for Chromium that adds some support for how GYP |
8 # is invoked by Chromium beyond what can be done in the gclient hooks. | 8 # is invoked by Chromium beyond what can be done in the gclient hooks. |
9 | 9 |
10 import glob | 10 import glob |
11 import gyp_helper | 11 import gyp_helper |
12 import json | |
13 import os | 12 import os |
14 import pipes | |
15 import shlex | 13 import shlex |
16 import shutil | |
17 import subprocess | 14 import subprocess |
18 import string | 15 import string |
19 import sys | 16 import sys |
20 import tempfile | 17 import vs_toolchain |
21 | 18 |
22 script_dir = os.path.dirname(os.path.realpath(__file__)) | 19 script_dir = os.path.dirname(os.path.realpath(__file__)) |
23 chrome_src = os.path.abspath(os.path.join(script_dir, os.pardir)) | 20 chrome_src = os.path.abspath(os.path.join(script_dir, os.pardir)) |
24 | 21 |
25 sys.path.insert(0, os.path.join(chrome_src, 'tools', 'gyp', 'pylib')) | 22 sys.path.insert(0, os.path.join(chrome_src, 'tools', 'gyp', 'pylib')) |
26 import gyp | 23 import gyp |
27 | 24 |
28 # Assume this file is in a one-level-deep subdirectory of the source root. | 25 # Assume this file is in a one-level-deep subdirectory of the source root. |
29 SRC_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | 26 SRC_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
30 | 27 |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 # Need to pass both the source root (the bots don't run this command from | 328 # Need to pass both the source root (the bots don't run this command from |
332 # within the source tree) as well as set the is_gyp value so the BUILD files | 329 # within the source tree) as well as set the is_gyp value so the BUILD files |
333 # to know they're being run under GYP. | 330 # to know they're being run under GYP. |
334 args = [gnpath, 'gyp', '-q', | 331 args = [gnpath, 'gyp', '-q', |
335 '--root=' + chrome_src, | 332 '--root=' + chrome_src, |
336 '--args=' + GetArgsStringForGN(vars_dict), | 333 '--args=' + GetArgsStringForGN(vars_dict), |
337 '--output=//' + GetOutputDirectory() + '/gn_build/'] | 334 '--output=//' + GetOutputDirectory() + '/gn_build/'] |
338 return subprocess.call(args) == 0 | 335 return subprocess.call(args) == 0 |
339 | 336 |
340 | 337 |
341 def GetDesiredVsToolchainHashes(): | |
342 """Load a list of SHA1s corresponding to the toolchains that we want installed | |
343 to build with.""" | |
344 sha1path = os.path.join(script_dir, 'toolchain_vs2013.hash') | |
345 with open(sha1path, 'rb') as f: | |
346 return f.read().strip().splitlines() | |
347 | |
348 | |
349 def DownloadVsToolChain(): | |
350 """Download the Visual Studio toolchain on Windows. | |
351 | |
352 If on Windows, request that depot_tools install/update the automatic | |
353 toolchain, and then use it (unless opted-out) and return a tuple containing | |
354 the x64 and x86 paths. Otherwise return None. | |
355 """ | |
356 vs2013_runtime_dll_dirs = None | |
357 depot_tools_win_toolchain = \ | |
358 bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1'))) | |
359 if sys.platform in ('win32', 'cygwin') and depot_tools_win_toolchain: | |
360 import find_depot_tools | |
361 depot_tools_path = find_depot_tools.add_depot_tools_to_path() | |
362 temp_handle, data_file = tempfile.mkstemp(suffix='.json') | |
363 os.close(temp_handle) | |
364 get_toolchain_args = [ | |
365 sys.executable, | |
366 os.path.join(depot_tools_path, | |
367 'win_toolchain', | |
368 'get_toolchain_if_necessary.py'), | |
369 '--output-json', data_file, | |
370 ] + GetDesiredVsToolchainHashes() | |
371 subprocess.check_call(get_toolchain_args) | |
372 | |
373 with open(data_file, 'r') as tempf: | |
374 toolchain_data = json.load(tempf) | |
375 os.unlink(data_file) | |
376 | |
377 toolchain = toolchain_data['path'] | |
378 version = toolchain_data['version'] | |
379 version_is_pro = version[-1] != 'e' | |
380 win8sdk = toolchain_data['win8sdk'] | |
381 wdk = toolchain_data['wdk'] | |
382 # TODO(scottmg): The order unfortunately matters in these. They should be | |
383 # split into separate keys for x86 and x64. (See CopyVsRuntimeDlls call | |
384 # below). http://crbug.com/345992 | |
385 vs2013_runtime_dll_dirs = toolchain_data['runtime_dirs'] | |
386 | |
387 os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain | |
388 os.environ['GYP_MSVS_VERSION'] = version | |
389 # We need to make sure windows_sdk_path is set to the automated | |
390 # toolchain values in GYP_DEFINES, but don't want to override any | |
391 # otheroptions.express | |
392 # values there. | |
393 gyp_defines_dict = gyp.NameValueListToDict(gyp.ShlexEnv('GYP_DEFINES')) | |
394 gyp_defines_dict['windows_sdk_path'] = win8sdk | |
395 os.environ['GYP_DEFINES'] = ' '.join('%s=%s' % (k, pipes.quote(str(v))) | |
396 for k, v in gyp_defines_dict.iteritems()) | |
397 os.environ['WINDOWSSDKDIR'] = win8sdk | |
398 os.environ['WDK_DIR'] = wdk | |
399 # Include the VS runtime in the PATH in case it's not machine-installed. | |
400 runtime_path = ';'.join(vs2013_runtime_dll_dirs) | |
401 os.environ['PATH'] = runtime_path + ';' + os.environ['PATH'] | |
402 print('Using automatic toolchain in %s (%s edition).' % ( | |
403 toolchain, 'Pro' if version_is_pro else 'Express')) | |
404 return vs2013_runtime_dll_dirs | |
405 | |
406 | |
407 def CopyVsRuntimeDlls(output_dir, runtime_dirs): | |
408 """Copies the VS runtime DLLs from the given |runtime_dirs| to the output | |
409 directory so that even if not system-installed, built binaries are likely to | |
410 be able to run. | |
411 | |
412 This needs to be run after gyp has been run so that the expected target | |
413 output directories are already created. | |
414 """ | |
415 assert sys.platform.startswith(('win32', 'cygwin')) | |
416 | |
417 def copy_runtime(target_dir, source_dir, dll_pattern): | |
418 """Copy both the msvcr and msvcp runtime DLLs, only if the target doesn't | |
419 exist, but the target directory does exist.""" | |
420 for which in ('p', 'r'): | |
421 dll = dll_pattern % which | |
422 target = os.path.join(target_dir, dll) | |
423 source = os.path.join(source_dir, dll) | |
424 # If gyp generated to that output dir, and the runtime isn't already | |
425 # there, then copy it over. | |
426 if (os.path.isdir(target_dir) and | |
427 (not os.path.isfile(target) or | |
428 os.stat(target).st_mtime != os.stat(source).st_mtime)): | |
429 print 'Copying %s to %s...' % (source, target) | |
430 if os.path.exists(target): | |
431 os.unlink(target) | |
432 shutil.copy2(source, target) | |
433 | |
434 x86, x64 = runtime_dirs | |
435 out_debug = os.path.join(output_dir, 'Debug') | |
436 out_debug_nacl64 = os.path.join(output_dir, 'Debug', 'x64') | |
437 out_release = os.path.join(output_dir, 'Release') | |
438 out_release_nacl64 = os.path.join(output_dir, 'Release', 'x64') | |
439 out_debug_x64 = os.path.join(output_dir, 'Debug_x64') | |
440 out_release_x64 = os.path.join(output_dir, 'Release_x64') | |
441 | |
442 if os.path.exists(out_debug) and not os.path.exists(out_debug_nacl64): | |
443 os.makedirs(out_debug_nacl64) | |
444 if os.path.exists(out_release) and not os.path.exists(out_release_nacl64): | |
445 os.makedirs(out_release_nacl64) | |
446 copy_runtime(out_debug, x86, 'msvc%s120d.dll') | |
447 copy_runtime(out_release, x86, 'msvc%s120.dll') | |
448 copy_runtime(out_debug_x64, x64, 'msvc%s120d.dll') | |
449 copy_runtime(out_release_x64, x64, 'msvc%s120.dll') | |
450 copy_runtime(out_debug_nacl64, x64, 'msvc%s120d.dll') | |
451 copy_runtime(out_release_nacl64, x64, 'msvc%s120.dll') | |
452 | |
453 | |
454 if __name__ == '__main__': | 338 if __name__ == '__main__': |
455 args = sys.argv[1:] | 339 args = sys.argv[1:] |
456 | 340 |
457 if int(os.environ.get('GYP_CHROMIUM_NO_ACTION', 0)): | 341 if int(os.environ.get('GYP_CHROMIUM_NO_ACTION', 0)): |
458 print 'Skipping gyp_chromium due to GYP_CHROMIUM_NO_ACTION env var.' | 342 print 'Skipping gyp_chromium due to GYP_CHROMIUM_NO_ACTION env var.' |
459 sys.exit(0) | 343 sys.exit(0) |
460 | 344 |
461 # Use the Psyco JIT if available. | 345 # Use the Psyco JIT if available. |
462 if psyco: | 346 if psyco: |
463 psyco.profile() | 347 psyco.profile() |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 # . -f / --format has precedence over the env var, no need to check for it | 408 # . -f / --format has precedence over the env var, no need to check for it |
525 # . set the env var only if it hasn't been set yet | 409 # . set the env var only if it hasn't been set yet |
526 # . chromium.gyp_env has been applied to os.environ at this point already | 410 # . chromium.gyp_env has been applied to os.environ at this point already |
527 if sys.platform.startswith(('linux', 'win', 'freebsd')) and \ | 411 if sys.platform.startswith(('linux', 'win', 'freebsd')) and \ |
528 not os.environ.get('GYP_GENERATORS'): | 412 not os.environ.get('GYP_GENERATORS'): |
529 os.environ['GYP_GENERATORS'] = 'ninja' | 413 os.environ['GYP_GENERATORS'] = 'ninja' |
530 elif sys.platform == 'darwin' and not os.environ.get('GYP_GENERATORS') and \ | 414 elif sys.platform == 'darwin' and not os.environ.get('GYP_GENERATORS') and \ |
531 not 'OS=ios' in os.environ.get('GYP_DEFINES', []): | 415 not 'OS=ios' in os.environ.get('GYP_DEFINES', []): |
532 os.environ['GYP_GENERATORS'] = 'ninja' | 416 os.environ['GYP_GENERATORS'] = 'ninja' |
533 | 417 |
534 vs2013_runtime_dll_dirs = DownloadVsToolChain() | 418 vs2013_runtime_dll_dirs = vs_toolchain.DownloadVsToolchain() |
535 | 419 |
536 # If CHROMIUM_GYP_SYNTAX_CHECK is set to 1, it will invoke gyp with --check | 420 # If CHROMIUM_GYP_SYNTAX_CHECK is set to 1, it will invoke gyp with --check |
537 # to enfore syntax checking. | 421 # to enfore syntax checking. |
538 syntax_check = os.environ.get('CHROMIUM_GYP_SYNTAX_CHECK') | 422 syntax_check = os.environ.get('CHROMIUM_GYP_SYNTAX_CHECK') |
539 if syntax_check and int(syntax_check): | 423 if syntax_check and int(syntax_check): |
540 args.append('--check') | 424 args.append('--check') |
541 | 425 |
542 supplemental_includes = GetSupplementalFiles() | 426 supplemental_includes = GetSupplementalFiles() |
543 gn_vars_dict = GetGypVarsForGN(supplemental_includes) | 427 gn_vars_dict = GetGypVarsForGN(supplemental_includes) |
544 | 428 |
(...skipping 21 matching lines...) Expand all Loading... |
566 | 450 |
567 # Check for landmines (reasons to clobber the build). This must be run here, | 451 # Check for landmines (reasons to clobber the build). This must be run here, |
568 # rather than a separate runhooks step so that any environment modifications | 452 # rather than a separate runhooks step so that any environment modifications |
569 # from above are picked up. | 453 # from above are picked up. |
570 print 'Running build/landmines.py...' | 454 print 'Running build/landmines.py...' |
571 subprocess.check_call( | 455 subprocess.check_call( |
572 [sys.executable, os.path.join(script_dir, 'landmines.py')]) | 456 [sys.executable, os.path.join(script_dir, 'landmines.py')]) |
573 | 457 |
574 if vs2013_runtime_dll_dirs: | 458 if vs2013_runtime_dll_dirs: |
575 x64_runtime, x86_runtime = vs2013_runtime_dll_dirs | 459 x64_runtime, x86_runtime = vs2013_runtime_dll_dirs |
576 CopyVsRuntimeDlls(os.path.join(chrome_src, GetOutputDirectory()), | 460 vs_toolchain.CopyVsRuntimeDlls( |
577 (x86_runtime, x64_runtime)) | 461 os.path.join(chrome_src, GetOutputDirectory()), |
| 462 (x86_runtime, x64_runtime)) |
578 | 463 |
579 sys.exit(gyp_rc) | 464 sys.exit(gyp_rc) |
OLD | NEW |