| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """ | 5 """ |
| 6 From a system-installed copy of the toolchain, packages all the required bits | 6 From a system-installed copy of the toolchain, packages all the required bits |
| 7 into a .zip file. | 7 into a .zip file. |
| 8 | 8 |
| 9 It assumes default install locations for tools, in particular: | 9 It assumes default install locations for tools, in particular: |
| 10 - C:\Program Files (x86)\Microsoft Visual Studio 12.0\... | 10 - C:\Program Files (x86)\Microsoft Visual Studio 12.0\... |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 import tempfile | 32 import tempfile |
| 33 import zipfile | 33 import zipfile |
| 34 | 34 |
| 35 import get_toolchain_if_necessary | 35 import get_toolchain_if_necessary |
| 36 | 36 |
| 37 | 37 |
| 38 VS_VERSION = None | 38 VS_VERSION = None |
| 39 WIN_VERSION = None | 39 WIN_VERSION = None |
| 40 | 40 |
| 41 | 41 |
| 42 def BuildFileList(): | 42 def BuildFileList(override_dir): |
| 43 result = [] | 43 result = [] |
| 44 | 44 |
| 45 # Subset of VS corresponding roughly to VC. | 45 # Subset of VS corresponding roughly to VC. |
| 46 paths = [ | 46 paths = [ |
| 47 'DIA SDK/bin', | 47 'DIA SDK/bin', |
| 48 'DIA SDK/idl', | 48 'DIA SDK/idl', |
| 49 'DIA SDK/include', | 49 'DIA SDK/include', |
| 50 'DIA SDK/lib', | 50 'DIA SDK/lib', |
| 51 'VC/atlmfc', | 51 'VC/atlmfc', |
| 52 'VC/bin', | |
| 53 'VC/crt', | 52 'VC/crt', |
| 54 'VC/include', | |
| 55 'VC/lib', | |
| 56 'VC/redist', | 53 'VC/redist', |
| 57 ] | 54 ] |
| 58 | 55 |
| 56 if override_dir: |
| 57 paths += [ |
| 58 (os.path.join(override_dir, 'bin'), 'VC/bin'), |
| 59 (os.path.join(override_dir, 'include'), 'VC/include'), |
| 60 (os.path.join(override_dir, 'lib'), 'VC/lib'), |
| 61 ] |
| 62 else: |
| 63 paths += [ |
| 64 'VC/bin', |
| 65 'VC/include', |
| 66 'VC/lib', |
| 67 ] |
| 68 |
| 59 if VS_VERSION == '2013': | 69 if VS_VERSION == '2013': |
| 60 paths += [ | 70 paths += [ |
| 61 ('VC/redist/x86/Microsoft.VC120.CRT', 'sys32'), | 71 ('VC/redist/x86/Microsoft.VC120.CRT', 'sys32'), |
| 62 ('VC/redist/x86/Microsoft.VC120.MFC', 'sys32'), | 72 ('VC/redist/x86/Microsoft.VC120.MFC', 'sys32'), |
| 63 ('VC/redist/Debug_NonRedist/x86/Microsoft.VC120.DebugCRT', 'sys32'), | 73 ('VC/redist/Debug_NonRedist/x86/Microsoft.VC120.DebugCRT', 'sys32'), |
| 64 ('VC/redist/Debug_NonRedist/x86/Microsoft.VC120.DebugMFC', 'sys32'), | 74 ('VC/redist/Debug_NonRedist/x86/Microsoft.VC120.DebugMFC', 'sys32'), |
| 65 ('VC/redist/x64/Microsoft.VC120.CRT', 'sys64'), | 75 ('VC/redist/x64/Microsoft.VC120.CRT', 'sys64'), |
| 66 ('VC/redist/x64/Microsoft.VC120.MFC', 'sys64'), | 76 ('VC/redist/x64/Microsoft.VC120.MFC', 'sys64'), |
| 67 ('VC/redist/Debug_NonRedist/x64/Microsoft.VC120.DebugCRT', 'sys64'), | 77 ('VC/redist/Debug_NonRedist/x64/Microsoft.VC120.DebugCRT', 'sys64'), |
| 68 ('VC/redist/Debug_NonRedist/x64/Microsoft.VC120.DebugMFC', 'sys64'), | 78 ('VC/redist/Debug_NonRedist/x64/Microsoft.VC120.DebugMFC', 'sys64'), |
| (...skipping 16 matching lines...) Expand all Loading... |
| 85 else: | 95 else: |
| 86 raise ValueError('VS_VERSION %s' % VS_VERSION) | 96 raise ValueError('VS_VERSION %s' % VS_VERSION) |
| 87 | 97 |
| 88 if VS_VERSION == '2013': | 98 if VS_VERSION == '2013': |
| 89 vs_path = r'C:\Program Files (x86)\Microsoft Visual Studio 12.0' | 99 vs_path = r'C:\Program Files (x86)\Microsoft Visual Studio 12.0' |
| 90 else: | 100 else: |
| 91 vs_path = r'C:\Program Files (x86)\Microsoft Visual Studio 14.0' | 101 vs_path = r'C:\Program Files (x86)\Microsoft Visual Studio 14.0' |
| 92 | 102 |
| 93 for path in paths: | 103 for path in paths: |
| 94 src = path[0] if isinstance(path, tuple) else path | 104 src = path[0] if isinstance(path, tuple) else path |
| 95 combined = os.path.join(vs_path, src) | 105 # Note that vs_path is ignored if src is an absolute path. |
| 106 # normpath is needed to change '/' to '\\' characters. |
| 107 combined = os.path.normpath(os.path.join(vs_path, src)) |
| 96 assert os.path.exists(combined) and os.path.isdir(combined) | 108 assert os.path.exists(combined) and os.path.isdir(combined) |
| 97 for root, _, files in os.walk(combined): | 109 for root, _, files in os.walk(combined): |
| 98 for f in files: | 110 for f in files: |
| 99 final_from = os.path.normpath(os.path.join(root, f)) | 111 final_from = os.path.normpath(os.path.join(root, f)) |
| 100 if isinstance(path, tuple): | 112 if isinstance(path, tuple): |
| 113 assert final_from.startswith(combined) |
| 114 dest = final_from[len(combined) + 1:] |
| 101 result.append( | 115 result.append( |
| 102 (final_from, os.path.normpath(os.path.join(path[1], f)))) | 116 (final_from, os.path.normpath(os.path.join(path[1], dest)))) |
| 103 else: | 117 else: |
| 104 assert final_from.startswith(vs_path) | 118 assert final_from.startswith(vs_path) |
| 105 dest = final_from[len(vs_path) + 1:] | 119 dest = final_from[len(vs_path) + 1:] |
| 106 if VS_VERSION == '2013' and dest.lower().endswith('\\xtree'): | 120 if VS_VERSION == '2013' and dest.lower().endswith('\\xtree'): |
| 107 # Patch for C4702 in xtree on VS2013. http://crbug.com/346399. | 121 # Patch for C4702 in xtree on VS2013. http://crbug.com/346399. |
| 108 (handle, patched) = tempfile.mkstemp() | 122 (handle, patched) = tempfile.mkstemp() |
| 109 with open(final_from, 'rb') as unpatched_f: | 123 with open(final_from, 'rb') as unpatched_f: |
| 110 unpatched_contents = unpatched_f.read() | 124 unpatched_contents = unpatched_f.read() |
| 111 os.write(handle, | 125 os.write(handle, |
| 112 unpatched_contents.replace('warning(disable: 4127)', | 126 unpatched_contents.replace('warning(disable: 4127)', |
| (...skipping 20 matching lines...) Expand all Loading... |
| 133 # (uncompressed) per version and wastes time. Only copy the specified | 147 # (uncompressed) per version and wastes time. Only copy the specified |
| 134 # version. | 148 # version. |
| 135 if (tail.startswith('Include\\') or tail.startswith('Lib\\') or | 149 if (tail.startswith('Include\\') or tail.startswith('Lib\\') or |
| 136 tail.startswith('Source\\')): | 150 tail.startswith('Source\\')): |
| 137 if tail.count(WIN_VERSION) == 0: | 151 if tail.count(WIN_VERSION) == 0: |
| 138 continue | 152 continue |
| 139 to = os.path.join('win_sdk', tail) | 153 to = os.path.join('win_sdk', tail) |
| 140 result.append((combined, to)) | 154 result.append((combined, to)) |
| 141 | 155 |
| 142 if VS_VERSION == '2015': | 156 if VS_VERSION == '2015': |
| 143 # The Windows 10 Universal C Runtime installers are needed when packaging | 157 # Copy the x86 ucrt DLLs to all directories with 32-bit binaries that are |
| 144 # VS 2015. They can be download from here: | 158 # added to the path by SetEnv.cmd, and to sys32. |
| 145 # https://support.microsoft.com/en-us/kb/2999226 | 159 ucrt_paths = glob.glob(os.path.join(sdk_path, r'redist\ucrt\dlls\x86\*')) |
| 146 # and they must be downloaded to the current user's downloads directory. | 160 for ucrt_path in ucrt_paths: |
| 147 # The versions needed are those for 64-bit Windows 7, Windows 8, and | 161 ucrt_file = os.path.split(ucrt_path)[1] |
| 148 # Windows 8.1. The 64-bit Server 2008 R2, Server 2012, and Server 2012 R2 | 162 for dest_dir in [ r'win_sdk\bin\x86', 'sys32' ]: |
| 149 # versions are identical (same name and contents). | 163 result.append((ucrt_path, os.path.join(dest_dir, ucrt_file))) |
| 150 universal_runtime_installers = [ | 164 |
| 151 'Windows6.1-KB2999226-x64.msu', | 165 # Copy the x64 ucrt DLLs to all directories with 64-bit binaries that are |
| 152 'Windows8-RT-KB2999226-x64.msu', | 166 # added to the path by SetEnv.cmd, and to sys64. |
| 153 'Windows8.1-KB2999226-x64.msu', | 167 ucrt_paths = glob.glob(os.path.join(sdk_path, r'redist\ucrt\dlls\x64\*')) |
| 168 for ucrt_path in ucrt_paths: |
| 169 ucrt_file = os.path.split(ucrt_path)[1] |
| 170 for dest_dir in [ r'VC\bin\amd64_x86', r'VC\bin\amd64', |
| 171 r'win_sdk\bin\x64', 'sys64']: |
| 172 result.append((ucrt_path, os.path.join(dest_dir, ucrt_file))) |
| 173 |
| 174 system_crt_files = [ |
| 175 # Needed to let debug binaries run. |
| 176 'ucrtbased.dll', |
| 154 ] | 177 ] |
| 155 | 178 bitness = platform.architecture()[0] |
| 156 for installer in universal_runtime_installers: | 179 # When running 64-bit python the x64 DLLs will be in System32 |
| 157 result.append((os.path.join(os.environ['userprofile'], 'downloads', | 180 x64_path = 'System32' if bitness == '64bit' else 'Sysnative' |
| 158 installer), | 181 x64_path = os.path.join(r'C:\Windows', x64_path) |
| 159 os.path.join('installers', installer))) | 182 for system_crt_file in system_crt_files: |
| 160 | 183 result.append((os.path.join(r'C:\Windows\SysWOW64', system_crt_file), |
| 161 if VS_VERSION == '2015': | 184 os.path.join('sys32', system_crt_file))) |
| 162 # Copy the x86 ucrt DLLs to all directories with 32-bit binaries that are | 185 result.append((os.path.join(x64_path, system_crt_file), |
| 163 # added to the path by SetEnv.cmd, and to sys32. | 186 os.path.join('sys64', system_crt_file))) |
| 164 ucrt_paths = glob.glob(os.path.join(sdk_path, r'redist\ucrt\dlls\x86\*')) | |
| 165 for ucrt_path in ucrt_paths: | |
| 166 ucrt_file = os.path.split(ucrt_path)[1] | |
| 167 for dest_dir in [ r'win_sdk\bin\x86', 'sys32' ]: | |
| 168 result.append((ucrt_path, os.path.join(dest_dir, ucrt_file))) | |
| 169 | |
| 170 # Copy the x64 ucrt DLLs to all directories with 64-bit binaries that are | |
| 171 # added to the path by SetEnv.cmd, and to sys64. | |
| 172 ucrt_paths = glob.glob(os.path.join(sdk_path, r'redist\ucrt\dlls\x64\*')) | |
| 173 for ucrt_path in ucrt_paths: | |
| 174 ucrt_file = os.path.split(ucrt_path)[1] | |
| 175 for dest_dir in [ r'VC\bin\amd64_x86', r'VC\bin\amd64', | |
| 176 r'win_sdk\bin\x64', 'sys64']: | |
| 177 result.append((ucrt_path, os.path.join(dest_dir, ucrt_file))) | |
| 178 | |
| 179 system_crt_files = [ | |
| 180 # Needed to let debug binaries run. | |
| 181 'ucrtbased.dll', | |
| 182 ] | |
| 183 bitness = platform.architecture()[0] | |
| 184 # When running 64-bit python the x64 DLLs will be in System32 | |
| 185 x64_path = 'System32' if bitness == '64bit' else 'Sysnative' | |
| 186 x64_path = os.path.join(r'C:\Windows', x64_path) | |
| 187 for system_crt_file in system_crt_files: | |
| 188 result.append((os.path.join(r'C:\Windows\SysWOW64', system_crt_file), | |
| 189 os.path.join('sys32', system_crt_file))) | |
| 190 result.append((os.path.join(x64_path, system_crt_file), | |
| 191 os.path.join('sys64', system_crt_file))) | |
| 192 | 187 |
| 193 # Generically drop all arm stuff that we don't need, and | 188 # Generically drop all arm stuff that we don't need, and |
| 194 # drop .msi files because we don't need installers. | 189 # drop .msi files because we don't need installers, and drop windows.winmd |
| 190 # because it is unneeded and is different on every machine. |
| 195 return [(f, t) for f, t in result if 'arm\\' not in f.lower() and | 191 return [(f, t) for f, t in result if 'arm\\' not in f.lower() and |
| 196 'arm64\\' not in f.lower() and | 192 'arm64\\' not in f.lower() and |
| 197 not f.lower().endswith('.msi')] | 193 not f.lower().endswith('.msi') and |
| 194 not f.lower().endswith('windows.winmd')] |
| 198 | 195 |
| 199 | 196 |
| 200 def GenerateSetEnvCmd(target_dir): | 197 def GenerateSetEnvCmd(target_dir): |
| 201 """Generate a batch file that gyp expects to exist to set up the compiler | 198 """Generate a batch file that gyp expects to exist to set up the compiler |
| 202 environment. | 199 environment. |
| 203 | 200 |
| 204 This is normally generated by a full install of the SDK, but we | 201 This is normally generated by a full install of the SDK, but we |
| 205 do it here manually since we do not do a full install.""" | 202 do it here manually since we do not do a full install.""" |
| 206 # All these paths are relative to the directory containing SetEnv.cmd. | 203 # All these paths are relative to the directory containing SetEnv.cmd. |
| 207 include_dirs = [ | 204 include_dirs = [ |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 | 319 |
| 323 def main(): | 320 def main(): |
| 324 usage = 'usage: %prog [options] 2013|2015' | 321 usage = 'usage: %prog [options] 2013|2015' |
| 325 parser = optparse.OptionParser(usage) | 322 parser = optparse.OptionParser(usage) |
| 326 parser.add_option('-w', '--winver', action='store', type='string', | 323 parser.add_option('-w', '--winver', action='store', type='string', |
| 327 dest='winver', default='10.0.10586.0', | 324 dest='winver', default='10.0.10586.0', |
| 328 help='Windows SDK version, such as 10.0.10586.0') | 325 help='Windows SDK version, such as 10.0.10586.0') |
| 329 parser.add_option('-d', '--dryrun', action='store_true', dest='dryrun', | 326 parser.add_option('-d', '--dryrun', action='store_true', dest='dryrun', |
| 330 default=False, | 327 default=False, |
| 331 help='scan for file existence and prints statistics') | 328 help='scan for file existence and prints statistics') |
| 329 parser.add_option('--override', action='store', type='string', |
| 330 dest='override_dir', default=None, |
| 331 help='Specify alternate bin/include/lib directory') |
| 332 (options, args) = parser.parse_args() | 332 (options, args) = parser.parse_args() |
| 333 | 333 |
| 334 if len(args) != 1 or args[0] not in ('2013', '2015'): | 334 if len(args) != 1 or args[0] not in ('2013', '2015'): |
| 335 print 'Must specify 2013 or 2015' | 335 print 'Must specify 2013 or 2015' |
| 336 parser.print_help(); | 336 parser.print_help(); |
| 337 return 1 | 337 return 1 |
| 338 | 338 |
| 339 if options.override_dir: |
| 340 if (not os.path.exists(os.path.join(options.override_dir, 'bin')) or |
| 341 not os.path.exists(os.path.join(options.override_dir, 'include')) or |
| 342 not os.path.exists(os.path.join(options.override_dir, 'lib'))): |
| 343 print 'Invalid override directory - must contain bin/include/lib dirs' |
| 344 return 1 |
| 345 |
| 339 global VS_VERSION | 346 global VS_VERSION |
| 340 VS_VERSION = args[0] | 347 VS_VERSION = args[0] |
| 341 global WIN_VERSION | 348 global WIN_VERSION |
| 342 WIN_VERSION = options.winver | 349 WIN_VERSION = options.winver |
| 343 | 350 |
| 344 print 'Building file list for VS %s Windows %s...' % (VS_VERSION, WIN_VERSION) | 351 print 'Building file list for VS %s Windows %s...' % (VS_VERSION, WIN_VERSION) |
| 345 files = BuildFileList() | 352 files = BuildFileList(options.override_dir) |
| 346 | 353 |
| 347 AddEnvSetup(files) | 354 AddEnvSetup(files) |
| 348 | 355 |
| 349 if False: | 356 if False: |
| 350 for f in files: | 357 for f in files: |
| 351 print f[0], '->', f[1] | 358 print f[0], '->', f[1] |
| 352 return 0 | 359 return 0 |
| 353 | 360 |
| 354 output = 'out.zip' | 361 output = 'out.zip' |
| 355 if os.path.exists(output): | 362 if os.path.exists(output): |
| (...skipping 29 matching lines...) Expand all Loading... |
| 385 sys.stdout.write('\rWrote to %s.%s\n' % (output, ' '*50)) | 392 sys.stdout.write('\rWrote to %s.%s\n' % (output, ' '*50)) |
| 386 sys.stdout.flush() | 393 sys.stdout.flush() |
| 387 | 394 |
| 388 RenameToSha1(output) | 395 RenameToSha1(output) |
| 389 | 396 |
| 390 return 0 | 397 return 0 |
| 391 | 398 |
| 392 | 399 |
| 393 if __name__ == '__main__': | 400 if __name__ == '__main__': |
| 394 sys.exit(main()) | 401 sys.exit(main()) |
| OLD | NEW |