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 |