Chromium Code Reviews| 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 13 matching lines...) Expand all Loading... | |
| 24 import os | 24 import os |
| 25 import shutil | 25 import shutil |
| 26 import sys | 26 import sys |
| 27 import tempfile | 27 import tempfile |
| 28 import zipfile | 28 import zipfile |
| 29 | 29 |
| 30 import get_toolchain_if_necessary | 30 import get_toolchain_if_necessary |
| 31 | 31 |
| 32 | 32 |
| 33 VS_VERSION = None | 33 VS_VERSION = None |
| 34 WIN_VERSION = None | |
| 34 | 35 |
| 35 | 36 |
| 36 def BuildFileList(): | 37 def BuildFileList(): |
| 37 result = [] | 38 result = [] |
| 38 | 39 |
| 39 # Subset of VS corresponding roughly to VC. | 40 # Subset of VS corresponding roughly to VC. |
| 40 paths = [ | 41 paths = [ |
| 41 'DIA SDK/bin', | 42 'DIA SDK/bin', |
| 42 'DIA SDK/idl', | 43 'DIA SDK/idl', |
| 43 'DIA SDK/include', | 44 'DIA SDK/include', |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 else: | 106 else: |
| 106 result.append((final_from, dest)) | 107 result.append((final_from, dest)) |
| 107 | 108 |
| 108 # Just copy the whole SDK. | 109 # Just copy the whole SDK. |
| 109 sdk_path = r'C:\Program Files (x86)\Windows Kits\10' | 110 sdk_path = r'C:\Program Files (x86)\Windows Kits\10' |
| 110 for root, _, files in os.walk(sdk_path): | 111 for root, _, files in os.walk(sdk_path): |
| 111 for f in files: | 112 for f in files: |
| 112 combined = os.path.normpath(os.path.join(root, f)) | 113 combined = os.path.normpath(os.path.join(root, f)) |
| 113 # Some of the files in this directory are exceedingly long (and exceed | 114 # Some of the files in this directory are exceedingly long (and exceed |
| 114 #_MAX_PATH for any moderately long root), so exclude them. We don't need | 115 #_MAX_PATH for any moderately long root), so exclude them. We don't need |
| 115 # them anyway. | 116 # them anyway. Exclude the Windows Performance Toolkit just to save space. |
| 116 tail = combined[len(sdk_path) + 1:] | 117 tail = combined[len(sdk_path) + 1:] |
| 117 if tail.startswith('References\\'): | 118 if tail.startswith('References\\') or \ |
|
scottmg
2015/12/07 20:58:04
Put () around this if instead of using \.
brucedawson
2015/12/08 01:13:49
Done.
| |
| 119 tail.startswith('Windows Performance Toolkit\\'): | |
| 118 continue | 120 continue |
| 121 if VS_VERSION == '2015': | |
| 122 # There may be many Include\Lib\Source directories for many different | |
| 123 # versions of Windows and packaging them all wastes ~450 MB | |
| 124 # (uncompressed) per version and wastes time. Only copy the specified | |
| 125 # version. | |
| 126 if tail.startswith('Include\\') or tail.startswith('Lib\\') or \ | |
| 127 tail.startswith('Source\\'): | |
|
scottmg
2015/12/07 20:58:04
Same here.
brucedawson
2015/12/08 01:13:49
Done.
| |
| 128 if tail.count(WIN_VERSION) == 0: | |
| 129 continue | |
| 119 to = os.path.join('win_sdk', tail) | 130 to = os.path.join('win_sdk', tail) |
| 120 result.append((combined, to)) | 131 result.append((combined, to)) |
| 121 | 132 |
| 122 if VS_VERSION == '2015': | 133 if VS_VERSION == '2015': |
| 123 for ucrt_path in ( | |
| 124 (r'C:\Program Files (x86)\Windows Kits\10\Include', 'Include'), | |
| 125 (r'C:\Program Files (x86)\Windows Kits\10\Lib', 'Lib'), | |
| 126 (r'C:\Program Files (x86)\Windows Kits\10\Source', 'Source')): | |
| 127 src, target = ucrt_path | |
| 128 for root, _, files in os.walk(src): | |
| 129 for f in files: | |
| 130 combined = os.path.normpath(os.path.join(root, f)) | |
| 131 to = os.path.join('ucrt', target, combined[len(src) + 1:]) | |
| 132 result.append((combined, to)) | |
| 133 | 134 |
| 134 system_crt_files = [ | 135 system_crt_files = [ |
|
scottmg
2015/12/07 20:58:04
Have you tried the package on a non-redist install
brucedawson
2015/12/08 01:13:49
I have not yet tried using the package on a machin
| |
| 135 'api-ms-win-core-file-l1-2-0.dll', | 136 'api-ms-win-core-file-l1-2-0.dll', |
| 136 'api-ms-win-core-file-l2-1-0.dll', | 137 'api-ms-win-core-file-l2-1-0.dll', |
| 137 'api-ms-win-core-localization-l1-2-0.dll', | 138 'api-ms-win-core-localization-l1-2-0.dll', |
| 138 'api-ms-win-core-processthreads-l1-1-1.dll', | 139 'api-ms-win-core-processthreads-l1-1-1.dll', |
| 139 'api-ms-win-core-synch-l1-2-0.dll', | 140 'api-ms-win-core-synch-l1-2-0.dll', |
| 140 'api-ms-win-core-timezone-l1-1-0.dll', | 141 'api-ms-win-core-timezone-l1-1-0.dll', |
| 141 'api-ms-win-core-xstate-l2-1-0.dll', | 142 'api-ms-win-core-xstate-l2-1-0.dll', |
| 142 'api-ms-win-crt-conio-l1-1-0.dll', | 143 'api-ms-win-crt-conio-l1-1-0.dll', |
| 143 'api-ms-win-crt-convert-l1-1-0.dll', | 144 'api-ms-win-crt-convert-l1-1-0.dll', |
| 144 'api-ms-win-crt-environment-l1-1-0.dll', | 145 'api-ms-win-crt-environment-l1-1-0.dll', |
| 145 'api-ms-win-crt-filesystem-l1-1-0.dll', | 146 'api-ms-win-crt-filesystem-l1-1-0.dll', |
| 146 'api-ms-win-crt-heap-l1-1-0.dll', | 147 'api-ms-win-crt-heap-l1-1-0.dll', |
| 147 'api-ms-win-crt-locale-l1-1-0.dll', | 148 'api-ms-win-crt-locale-l1-1-0.dll', |
| 148 'api-ms-win-crt-math-l1-1-0.dll', | 149 'api-ms-win-crt-math-l1-1-0.dll', |
| 149 'api-ms-win-crt-multibyte-l1-1-0.dll', | 150 'api-ms-win-crt-multibyte-l1-1-0.dll', |
| 150 'api-ms-win-crt-private-l1-1-0.dll', | 151 'api-ms-win-crt-private-l1-1-0.dll', |
| 151 'api-ms-win-crt-process-l1-1-0.dll', | 152 'api-ms-win-crt-process-l1-1-0.dll', |
| 152 'api-ms-win-crt-runtime-l1-1-0.dll', | 153 'api-ms-win-crt-runtime-l1-1-0.dll', |
| 153 'api-ms-win-crt-stdio-l1-1-0.dll', | 154 'api-ms-win-crt-stdio-l1-1-0.dll', |
| 154 'api-ms-win-crt-string-l1-1-0.dll', | 155 'api-ms-win-crt-string-l1-1-0.dll', |
| 155 'api-ms-win-crt-time-l1-1-0.dll', | 156 'api-ms-win-crt-time-l1-1-0.dll', |
| 156 'api-ms-win-crt-utility-l1-1-0.dll', | 157 'api-ms-win-crt-utility-l1-1-0.dll', |
| 157 'api-ms-win-eventing-provider-l1-1-0.dll', | 158 'api-ms-win-eventing-provider-l1-1-0.dll', |
| 158 'ucrtbase.dll', | 159 'ucrtbase.dll', |
| 159 'ucrtbased.dll', | 160 'ucrtbased.dll', |
| 160 ] | 161 ] |
| 162 x64_path = r'C:\Windows\Sysnative' | |
|
scottmg
2015/12/07 20:58:04
Maybe rather that exists(), something like:
x64_p
| |
| 163 if not os.path.exists(x64_path): | |
| 164 # When running 64-bit python the x64 DLLs will be found here | |
| 165 x64_path = r'C:\Windows\System32' | |
| 161 for system_crt_file in system_crt_files: | 166 for system_crt_file in system_crt_files: |
| 162 result.append((os.path.join(r'C:\Windows\SysWOW64', system_crt_file), | 167 result.append((os.path.join(r'C:\Windows\SysWOW64', system_crt_file), |
| 163 os.path.join('sys32', system_crt_file))) | 168 os.path.join('sys32', system_crt_file))) |
| 164 result.append((os.path.join(r'C:\Windows\Sysnative', system_crt_file), | 169 result.append((os.path.join(x64_path, system_crt_file), |
| 165 os.path.join('sys64', system_crt_file))) | 170 os.path.join('sys64', system_crt_file))) |
| 166 | 171 |
| 167 # Generically drop all arm stuff that we don't need. | 172 # Generically drop all arm stuff that we don't need, and |
| 173 # drop .msi files because we don't need installers. | |
| 168 return [(f, t) for f, t in result if 'arm\\' not in f.lower() and | 174 return [(f, t) for f, t in result if 'arm\\' not in f.lower() and |
| 169 'arm64\\' not in f.lower()] | 175 'arm64\\' not in f.lower() and |
| 176 not f.lower().endswith('.msi')] | |
| 170 | 177 |
| 171 | 178 |
| 172 def GenerateSetEnvCmd(target_dir): | 179 def GenerateSetEnvCmd(target_dir): |
| 173 """Generate a batch file that gyp expects to exist to set up the compiler | 180 """Generate a batch file that gyp expects to exist to set up the compiler |
| 174 environment. | 181 environment. |
| 175 | 182 |
| 176 This is normally generated by a full install of the SDK, but we | 183 This is normally generated by a full install of the SDK, but we |
| 177 do it here manually since we do not do a full install.""" | 184 do it here manually since we do not do a full install.""" |
| 178 with open(os.path.join( | 185 with open(os.path.join( |
| 179 target_dir, r'win_sdk\bin\SetEnv.cmd'), 'w') as f: | 186 target_dir, r'win_sdk\bin\SetEnv.cmd'), 'w') as f: |
| 180 f.write('@echo off\n' | 187 f.write('@echo off\n' |
| 181 ':: Generated by win_toolchain\\package_from_installed.py.\n' | 188 ':: Generated by win_toolchain\\package_from_installed.py.\n' |
| 182 # Common to x86 and x64 | 189 # Common to x86 and x64 |
| 183 'set PATH=%~dp0..\\..\\Common7\\IDE;%PATH%\n' | 190 'set PATH=%~dp0..\\..\\Common7\\IDE;%PATH%\n' |
| 184 'set INCLUDE=%~dp0..\\..\\win_sdk\\Include\\10.0.10240.0\\um;' | 191 'set INCLUDE=%~dp0..\\..\\win_sdk\\Include\\WINVERSION\\um;' |
| 185 '%~dp0..\\..\\win_sdk\\Include\\10.0.10240.0\\shared;' | 192 '%~dp0..\\..\\win_sdk\\Include\\WINVERSION\\shared;' |
| 186 '%~dp0..\\..\\win_sdk\\Include\\10.0.10240.0\\winrt;' | 193 '%~dp0..\\..\\win_sdk\\Include\\WINVERSION\\winrt;' |
| 194 '%~dp0..\\..\\win_sdk\\Include\\WINVERSION\\ucrt;' # VS 2015 | |
|
scottmg
2015/12/07 20:58:04
I guess we're going to get a different package for
brucedawson
2015/12/08 01:13:49
It's true that the exact package we're using can't
| |
| 187 '%~dp0..\\..\\VC\\include;' | 195 '%~dp0..\\..\\VC\\include;' |
| 188 '%~dp0..\\..\\VC\\atlmfc\\include\n' | 196 '%~dp0..\\..\\VC\\atlmfc\\include\n' |
| 189 'if "%1"=="/x64" goto x64\n') | 197 'if "%1"=="/x64" goto x64\n'.replace("WINVERSION", WIN_VERSION)) |
| 190 | 198 |
| 191 # x86. Always use amd64_x86 cross, not x86 on x86. | 199 # x86. Always use amd64_x86 cross, not x86 on x86. |
| 192 f.write('set PATH=%~dp0..\\..\\win_sdk\\bin\\x86;' | 200 f.write('set PATH=%~dp0..\\..\\win_sdk\\bin\\x86;' |
| 193 '%~dp0..\\..\\VC\\bin\\amd64_x86;' | 201 '%~dp0..\\..\\VC\\bin\\amd64_x86;' |
| 194 '%~dp0..\\..\\VC\\bin\\amd64;' # Needed for mspdb1x0.dll. | 202 '%~dp0..\\..\\VC\\bin\\amd64;' # Needed for mspdb1x0.dll. |
| 195 '%PATH%\n') | 203 '%PATH%\n') |
| 196 f.write('set LIB=%~dp0..\\..\\VC\\lib;' | 204 f.write('set LIB=%~dp0..\\..\\VC\\lib;' |
| 197 '%~dp0..\\..\\win_sdk\\Lib\\10.0.10240.0\\um\\x86;' | 205 '%~dp0..\\..\\win_sdk\\Lib\\WINVERSION\\um\\x86;' |
| 206 '%~dp0..\\..\\win_sdk\\Lib\\WINVERSION\\ucrt\\x86;' # VS 2015 | |
| 198 '%~dp0..\\..\\VC\\atlmfc\\lib\n' | 207 '%~dp0..\\..\\VC\\atlmfc\\lib\n' |
| 199 'goto :EOF\n') | 208 'goto :EOF\n'.replace("WINVERSION", WIN_VERSION)) |
| 200 | 209 |
| 201 # x64. | 210 # x64. |
| 202 f.write(':x64\n' | 211 f.write(':x64\n' |
| 203 'set PATH=%~dp0..\\..\\win_sdk\\bin\\x64;' | 212 'set PATH=%~dp0..\\..\\win_sdk\\bin\\x64;' |
| 204 '%~dp0..\\..\\VC\\bin\\amd64;' | 213 '%~dp0..\\..\\VC\\bin\\amd64;' |
| 205 '%PATH%\n') | 214 '%PATH%\n') |
| 206 f.write('set LIB=%~dp0..\\..\\VC\\lib\\amd64;' | 215 f.write('set LIB=%~dp0..\\..\\VC\\lib\\amd64;' |
| 207 '%~dp0..\\..\\win_sdk\\Lib\\10.0.10240.0\\um\\x64;' | 216 '%~dp0..\\..\\win_sdk\\Lib\\WINVERSION\\um\\x64;' |
| 208 '%~dp0..\\..\\VC\\atlmfc\\lib\\amd64\n') | 217 '%~dp0..\\..\\win_sdk\\Lib\\WINVERSION\\ucrt\\x64;' # VS 2015 |
| 218 '%~dp0..\\..\\VC\\atlmfc\\lib\\amd64\n' | |
| 219 .replace("WINVERSION", WIN_VERSION)) | |
| 209 | 220 |
| 210 | 221 |
| 211 def AddEnvSetup(files): | 222 def AddEnvSetup(files): |
| 212 """We need to generate this file in the same way that the "from pieces" | 223 """We need to generate this file in the same way that the "from pieces" |
| 213 script does, so pull that in here.""" | 224 script does, so pull that in here.""" |
| 214 tempdir = tempfile.mkdtemp() | 225 tempdir = tempfile.mkdtemp() |
| 215 os.makedirs(os.path.join(tempdir, 'win_sdk', 'bin')) | 226 os.makedirs(os.path.join(tempdir, 'win_sdk', 'bin')) |
| 216 GenerateSetEnvCmd(tempdir) | 227 GenerateSetEnvCmd(tempdir) |
| 217 files.append((os.path.join(tempdir, 'win_sdk', 'bin', 'SetEnv.cmd'), | 228 files.append((os.path.join(tempdir, 'win_sdk', 'bin', 'SetEnv.cmd'), |
| 218 'win_sdk\\bin\\SetEnv.cmd')) | 229 'win_sdk\\bin\\SetEnv.cmd')) |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 239 print 'Hashing...' | 250 print 'Hashing...' |
| 240 sha1 = get_toolchain_if_necessary.CalculateHash(rel_dir) | 251 sha1 = get_toolchain_if_necessary.CalculateHash(rel_dir) |
| 241 os.chdir(old_dir) | 252 os.chdir(old_dir) |
| 242 shutil.rmtree(tempdir) | 253 shutil.rmtree(tempdir) |
| 243 final_name = sha1 + '.zip' | 254 final_name = sha1 + '.zip' |
| 244 os.rename(output, final_name) | 255 os.rename(output, final_name) |
| 245 print 'Renamed %s to %s.' % (output, final_name) | 256 print 'Renamed %s to %s.' % (output, final_name) |
| 246 | 257 |
| 247 | 258 |
| 248 def main(): | 259 def main(): |
| 249 if len(sys.argv) != 2 or sys.argv[1] not in ('2013', '2015'): | 260 if len(sys.argv) < 3 or sys.argv[1] not in ('2013', '2015'): |
|
scottmg
2015/12/07 20:58:04
This is a bit much once it's more than 1. Can you
| |
| 250 print 'Usage: package_from_installed.py 2013|2015' | 261 print 'Usage: package_from_installed.py 2013|2015 winversion dryrun' |
| 262 print 'winversion should be 10.0.10240.0 or similar' | |
|
scottmg
2015/12/07 20:58:04
Can we not default to 10586? (w/ optparse we can h
| |
| 263 print 'Specify dryrun to just scan for all files without packaging them.' | |
| 251 return 1 | 264 return 1 |
| 252 | 265 |
| 253 global VS_VERSION | 266 global VS_VERSION |
| 254 VS_VERSION = sys.argv[1] | 267 VS_VERSION = sys.argv[1] |
| 268 global WIN_VERSION | |
| 269 WIN_VERSION = sys.argv[2] | |
| 270 | |
| 271 dry_run = False | |
| 272 if len(sys.argv) > 3 and sys.argv[3].lower() == 'dryrun': | |
| 273 dry_run = True | |
| 255 | 274 |
| 256 print 'Building file list...' | 275 print 'Building file list...' |
| 257 files = BuildFileList() | 276 files = BuildFileList() |
| 258 | 277 |
| 259 AddEnvSetup(files) | 278 AddEnvSetup(files) |
| 260 | 279 |
| 261 if False: | 280 if False: |
| 262 for f in files: | 281 for f in files: |
| 263 print f[0], '->', f[1] | 282 print f[0], '->', f[1] |
| 264 return 0 | 283 return 0 |
| 265 | 284 |
| 266 output = 'out.zip' | 285 output = 'out.zip' |
| 267 if os.path.exists(output): | 286 if os.path.exists(output): |
| 268 os.unlink(output) | 287 os.unlink(output) |
| 269 count = 0 | 288 count = 0 |
| 289 version_match_count = 0 | |
| 290 total_size = 0 | |
| 291 missing_files = False | |
| 270 with zipfile.ZipFile(output, 'w', zipfile.ZIP_DEFLATED, True) as zf: | 292 with zipfile.ZipFile(output, 'w', zipfile.ZIP_DEFLATED, True) as zf: |
| 271 for disk_name, archive_name in files: | 293 for disk_name, archive_name in files: |
| 272 sys.stdout.write('\r%d/%d ...%s' % (count, len(files), disk_name[-40:])) | 294 sys.stdout.write('\r%d/%d ...%s' % (count, len(files), disk_name[-40:])) |
| 273 sys.stdout.flush() | 295 sys.stdout.flush() |
| 274 count += 1 | 296 count += 1 |
| 275 zf.write(disk_name, archive_name) | 297 if disk_name.count(WIN_VERSION) > 0: |
| 298 version_match_count += 1 | |
| 299 if os.path.exists(disk_name): | |
| 300 if dry_run: | |
| 301 total_size += os.path.getsize(disk_name) | |
| 302 else: | |
| 303 zf.write(disk_name, archive_name) | |
| 304 else: | |
| 305 missing_files = True | |
| 306 sys.stdout.write('\r%s does not exist.\n\n' % disk_name) | |
| 307 sys.stdout.flush() | |
| 308 if dry_run: | |
| 309 sys.stdout.write('\r%1.3f GB of data in %d files, %d files for %s.%s\n' % | |
| 310 (total_size / 1e9, count, version_match_count, WIN_VERSION, ' '*50)) | |
| 311 sys.stdout.flush() | |
|
scottmg
2015/12/07 20:58:04
No need to .flush() here, that's just because of t
brucedawson
2015/12/08 01:13:49
Done.
| |
| 312 return 0 | |
| 313 if missing_files: | |
| 314 raise "One or more files were missing - aborting" | |
| 315 if version_match_count == 0: | |
| 316 raise "No files found that match the specified winversion" | |
| 276 sys.stdout.write('\rWrote to %s.%s\n' % (output, ' '*50)) | 317 sys.stdout.write('\rWrote to %s.%s\n' % (output, ' '*50)) |
| 277 sys.stdout.flush() | 318 sys.stdout.flush() |
| 278 | 319 |
| 279 RenameToSha1(output) | 320 RenameToSha1(output) |
| 280 | 321 |
| 281 return 0 | 322 return 0 |
| 282 | 323 |
| 283 | 324 |
| 284 if __name__ == '__main__': | 325 if __name__ == '__main__': |
| 285 sys.exit(main()) | 326 sys.exit(main()) |
| OLD | NEW |