OLD | NEW |
(Empty) | |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 import json |
| 6 import os |
| 7 import pipes |
| 8 import shutil |
| 9 import subprocess |
| 10 import sys |
| 11 import tempfile |
| 12 |
| 13 |
| 14 script_dir = os.path.dirname(os.path.realpath(__file__)) |
| 15 chrome_src = os.path.abspath(os.path.join(script_dir, os.pardir)) |
| 16 SRC_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| 17 sys.path.insert(1, os.path.join(chrome_src, 'tools')) |
| 18 sys.path.insert(0, os.path.join(chrome_src, 'tools', 'gyp', 'pylib')) |
| 19 |
| 20 |
| 21 import gyp |
| 22 |
| 23 |
| 24 def GetDesiredVsToolchainHashes(): |
| 25 """Load a list of SHA1s corresponding to the toolchains that we want installed |
| 26 to build with.""" |
| 27 sha1path = os.path.join(script_dir, 'toolchain_vs2013.hash') |
| 28 with open(sha1path, 'rb') as f: |
| 29 return f.read().strip().splitlines() |
| 30 |
| 31 |
| 32 def DownloadVsToolchain(): |
| 33 """Download the Visual Studio toolchain on Windows. |
| 34 |
| 35 If on Windows, request that depot_tools install/update the automatic |
| 36 toolchain, and then use it (unless opted-out) and return a tuple containing |
| 37 the x64 and x86 paths. Otherwise return None. |
| 38 """ |
| 39 vs2013_runtime_dll_dirs = None |
| 40 depot_tools_win_toolchain = \ |
| 41 bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1'))) |
| 42 if sys.platform in ('win32', 'cygwin') and depot_tools_win_toolchain: |
| 43 import find_depot_tools |
| 44 depot_tools_path = find_depot_tools.add_depot_tools_to_path() |
| 45 temp_handle, data_file = tempfile.mkstemp(suffix='.json') |
| 46 os.close(temp_handle) |
| 47 get_toolchain_args = [ |
| 48 sys.executable, |
| 49 os.path.join(depot_tools_path, |
| 50 'win_toolchain', |
| 51 'get_toolchain_if_necessary.py'), |
| 52 '--output-json', data_file, |
| 53 ] + GetDesiredVsToolchainHashes() |
| 54 subprocess.check_call(get_toolchain_args) |
| 55 |
| 56 with open(data_file, 'r') as tempf: |
| 57 toolchain_data = json.load(tempf) |
| 58 os.unlink(data_file) |
| 59 |
| 60 toolchain = toolchain_data['path'] |
| 61 version = toolchain_data['version'] |
| 62 version_is_pro = version[-1] != 'e' |
| 63 win8sdk = toolchain_data['win8sdk'] |
| 64 wdk = toolchain_data['wdk'] |
| 65 # TODO(scottmg): The order unfortunately matters in these. They should be |
| 66 # split into separate keys for x86 and x64. (See CopyVsRuntimeDlls call |
| 67 # below). http://crbug.com/345992 |
| 68 vs2013_runtime_dll_dirs = toolchain_data['runtime_dirs'] |
| 69 |
| 70 os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain |
| 71 os.environ['GYP_MSVS_VERSION'] = version |
| 72 # We need to make sure windows_sdk_path is set to the automated |
| 73 # toolchain values in GYP_DEFINES, but don't want to override any |
| 74 # otheroptions.express |
| 75 # values there. |
| 76 gyp_defines_dict = gyp.NameValueListToDict(gyp.ShlexEnv('GYP_DEFINES')) |
| 77 gyp_defines_dict['windows_sdk_path'] = win8sdk |
| 78 os.environ['GYP_DEFINES'] = ' '.join('%s=%s' % (k, pipes.quote(str(v))) |
| 79 for k, v in gyp_defines_dict.iteritems()) |
| 80 os.environ['WINDOWSSDKDIR'] = win8sdk |
| 81 os.environ['WDK_DIR'] = wdk |
| 82 # Include the VS runtime in the PATH in case it's not machine-installed. |
| 83 runtime_path = ';'.join(vs2013_runtime_dll_dirs) |
| 84 os.environ['PATH'] = runtime_path + ';' + os.environ['PATH'] |
| 85 print('Using automatic toolchain in %s (%s edition).' % ( |
| 86 toolchain, 'Pro' if version_is_pro else 'Express')) |
| 87 return vs2013_runtime_dll_dirs |
| 88 |
| 89 |
| 90 def CopyVsRuntimeDlls(output_dir, runtime_dirs): |
| 91 """Copies the VS runtime DLLs from the given |runtime_dirs| to the output |
| 92 directory so that even if not system-installed, built binaries are likely to |
| 93 be able to run. |
| 94 |
| 95 This needs to be run after gyp has been run so that the expected target |
| 96 output directories are already created. |
| 97 """ |
| 98 assert sys.platform.startswith(('win32', 'cygwin')) |
| 99 |
| 100 def copy_runtime(target_dir, source_dir, dll_pattern): |
| 101 """Copy both the msvcr and msvcp runtime DLLs, only if the target doesn't |
| 102 exist, but the target directory does exist.""" |
| 103 for which in ('p', 'r'): |
| 104 dll = dll_pattern % which |
| 105 target = os.path.join(target_dir, dll) |
| 106 source = os.path.join(source_dir, dll) |
| 107 # If gyp generated to that output dir, and the runtime isn't already |
| 108 # there, then copy it over. |
| 109 if (os.path.isdir(target_dir) and |
| 110 (not os.path.isfile(target) or |
| 111 os.stat(target).st_mtime != os.stat(source).st_mtime)): |
| 112 print 'Copying %s to %s...' % (source, target) |
| 113 if os.path.exists(target): |
| 114 os.unlink(target) |
| 115 shutil.copy2(source, target) |
| 116 |
| 117 x86, x64 = runtime_dirs |
| 118 out_debug = os.path.join(output_dir, 'Debug') |
| 119 out_debug_nacl64 = os.path.join(output_dir, 'Debug', 'x64') |
| 120 out_release = os.path.join(output_dir, 'Release') |
| 121 out_release_nacl64 = os.path.join(output_dir, 'Release', 'x64') |
| 122 out_debug_x64 = os.path.join(output_dir, 'Debug_x64') |
| 123 out_release_x64 = os.path.join(output_dir, 'Release_x64') |
| 124 |
| 125 if os.path.exists(out_debug) and not os.path.exists(out_debug_nacl64): |
| 126 os.makedirs(out_debug_nacl64) |
| 127 if os.path.exists(out_release) and not os.path.exists(out_release_nacl64): |
| 128 os.makedirs(out_release_nacl64) |
| 129 copy_runtime(out_debug, x86, 'msvc%s120d.dll') |
| 130 copy_runtime(out_release, x86, 'msvc%s120.dll') |
| 131 copy_runtime(out_debug_x64, x64, 'msvc%s120d.dll') |
| 132 copy_runtime(out_release_x64, x64, 'msvc%s120.dll') |
| 133 copy_runtime(out_debug_nacl64, x64, 'msvc%s120d.dll') |
| 134 copy_runtime(out_release_nacl64, x64, 'msvc%s120.dll') |
| 135 |
| 136 |
| 137 def main(): |
| 138 return 0 |
| 139 |
| 140 if __name__ == '__main__': |
| 141 sys.exit(main()) |
OLD | NEW |