Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2013 The Chromium Authors. All rights reserved. | 2 # Copyright 2013 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Extracts a Windows VS2013 toolchain from various downloadable pieces.""" | 6 """Extracts a Windows VS2013 toolchain from various downloadable pieces.""" |
| 7 | 7 |
| 8 | 8 |
| 9 import ctypes | 9 import ctypes |
| 10 import optparse | 10 import optparse |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 33 size = ctypes.windll.kernel32.GetLongPathNameW(unicode(path), buf, 260) | 33 size = ctypes.windll.kernel32.GetLongPathNameW(unicode(path), buf, 260) |
| 34 if (size > 260): | 34 if (size > 260): |
| 35 sys.exit('Long form of path longer than 260 chars: %s' % path) | 35 sys.exit('Long form of path longer than 260 chars: %s' % path) |
| 36 return buf.value | 36 return buf.value |
| 37 | 37 |
| 38 | 38 |
| 39 def RunOrDie(command): | 39 def RunOrDie(command): |
| 40 subprocess.check_call(command, shell=True) | 40 subprocess.check_call(command, shell=True) |
| 41 | 41 |
| 42 | 42 |
| 43 class ScopedSubstTempDir(object): | |
| 44 """Creates a |TempDir()| and subst's a drive to the path. This is done to | |
|
M-A Ruel
2014/02/13 02:49:38
Single line summary.
Description.
scottmg
2014/02/13 17:58:27
Done.
| |
| 45 avoid exceedingly long names in some .msi packages which fail to extract | |
| 46 because they exceed _MAX_PATH. Only the "subst" part of this is scoped, not | |
|
M-A Ruel
2014/02/13 02:49:38
Oh God I Hate Windows.
scottmg
2014/02/13 17:58:27
Great, isn't it! Should have been a 3 line CL... :
| |
| 47 the temp dir, which is left for use and cleanup by the caller. | |
| 48 """ | |
| 49 DefineDosDevice = ctypes.windll.kernel32.DefineDosDeviceW | |
| 50 DefineDosDevice.argtypes = [ctypes.c_int, ctypes.c_wchar_p, ctypes.c_wchar_p] | |
| 51 DDD_NO_BROADCAST_SYSTEM = 0x08 | |
| 52 DDD_REMOVE_DEFINITION = 0x02 | |
| 53 | |
| 54 def __init__(self): | |
| 55 self.real_path = TempDir() | |
| 56 self.subst_drive = None | |
| 57 | |
| 58 def __enter__(self): | |
| 59 """Tries to find a subst that we can use for the temporary directory, and | |
| 60 aborts on failure.""" | |
| 61 for drive in range(ord('Z'), ord('A') - 1, -1): | |
| 62 candidate = '%c:' % drive | |
| 63 if self.DefineDosDevice( | |
| 64 self.DDD_NO_BROADCAST_SYSTEM, candidate, self.real_path) != 0: | |
| 65 self.subst_drive = candidate | |
| 66 return self | |
| 67 raise RuntimeError("Unable to find a subst path") | |
|
M-A Ruel
2014/02/13 02:49:38
''
scottmg
2014/02/13 17:58:27
Done.
| |
| 68 | |
| 69 def __exit__(self, typ, value, traceback): | |
| 70 if self.subst_drive: | |
| 71 if self.DefineDosDevice(int(self.DDD_REMOVE_DEFINITION), | |
| 72 self.subst_drive, | |
| 73 self.real_path) == 0: | |
| 74 raise RuntimeError("Unable to remove subst") | |
| 75 | |
| 76 def ShortenedPath(self): | |
| 77 return self.subst_drive + '\\' | |
| 78 | |
| 79 def RealPath(self): | |
| 80 return self.real_path | |
| 81 | |
| 82 | |
| 43 def TempDir(): | 83 def TempDir(): |
| 44 """Generates a temporary directory (for downloading or extracting to) and keep | 84 """Generates a temporary directory (for downloading or extracting to) and keep |
| 45 track of the directory that's created for cleaning up later. | 85 track of the directory that's created for cleaning up later. |
| 46 """ | 86 """ |
| 47 temp = tempfile.mkdtemp() | 87 temp = tempfile.mkdtemp() |
| 48 g_temp_dirs.append(temp) | 88 g_temp_dirs.append(temp) |
| 49 return temp | 89 return temp |
| 50 | 90 |
| 51 | 91 |
| 52 def DeleteAllTempDirs(): | 92 def DeleteAllTempDirs(): |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 109 # TODO(scottmg): Do this (and exe) manually with python code. | 149 # TODO(scottmg): Do this (and exe) manually with python code. |
| 110 # Note that at the beginning of main() we set the working directory to 7z's | 150 # Note that at the beginning of main() we set the working directory to 7z's |
| 111 # location so that 7z can find its codec dll. | 151 # location so that 7z can find its codec dll. |
| 112 RunOrDie('7z x "%s" -y "-o%s" >nul' % (iso_path, target_path)) | 152 RunOrDie('7z x "%s" -y "-o%s" >nul' % (iso_path, target_path)) |
| 113 return target_path | 153 return target_path |
| 114 | 154 |
| 115 | 155 |
| 116 def ExtractMsi(msi_path): | 156 def ExtractMsi(msi_path): |
| 117 """Uses msiexec to extract the contents of the given .msi file.""" | 157 """Uses msiexec to extract the contents of the given .msi file.""" |
| 118 sys.stdout.write('Extracting %s...\n' % msi_path) | 158 sys.stdout.write('Extracting %s...\n' % msi_path) |
| 119 target_path = TempDir() | 159 with ScopedSubstTempDir() as temp_dir: |
| 120 RunOrDie('msiexec /a "%s" /qn TARGETDIR="%s"' % (msi_path, target_path)) | 160 RunOrDie('msiexec /a "%s" /qn TARGETDIR="%s"' % ( |
| 121 return target_path | 161 msi_path, temp_dir.ShortenedPath())) |
| 162 return temp_dir.RealPath() | |
| 122 | 163 |
| 123 | 164 |
| 124 def DownloadMainIso(url): | 165 def DownloadMainIso(url): |
| 125 temp_dir = TempDir() | 166 temp_dir = TempDir() |
| 126 target_path = os.path.join(temp_dir, os.path.basename(url)) | 167 target_path = os.path.join(temp_dir, os.path.basename(url)) |
| 127 Download(url, target_path) | 168 Download(url, target_path) |
| 128 return target_path | 169 return target_path |
| 129 | 170 |
| 130 | 171 |
| 131 def DownloadSDK8(): | 172 def DownloadSDK8(): |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 255 (r'vc_compilerCore86\vc_compilerCore86.msi', True), | 296 (r'vc_compilerCore86\vc_compilerCore86.msi', True), |
| 256 (r'vc_compilerCore86res\vc_compilerCore86res.msi', True), | 297 (r'vc_compilerCore86res\vc_compilerCore86res.msi', True), |
| 257 (r'vc_compilerx64nat\vc_compilerx64nat.msi', False), | 298 (r'vc_compilerx64nat\vc_compilerx64nat.msi', False), |
| 258 (r'vc_compilerx64natres\vc_compilerx64natres.msi', False), | 299 (r'vc_compilerx64natres\vc_compilerx64natres.msi', False), |
| 259 (r'vc_compilerx64x86\vc_compilerx64x86.msi', False), | 300 (r'vc_compilerx64x86\vc_compilerx64x86.msi', False), |
| 260 (r'vc_compilerx64x86res\vc_compilerx64x86res.msi', False), | 301 (r'vc_compilerx64x86res\vc_compilerx64x86res.msi', False), |
| 261 (r'vc_librarycore86\vc_librarycore86.msi', True), | 302 (r'vc_librarycore86\vc_librarycore86.msi', True), |
| 262 (r'vc_libraryDesktop\x64\vc_LibraryDesktopX64.msi', True), | 303 (r'vc_libraryDesktop\x64\vc_LibraryDesktopX64.msi', True), |
| 263 (r'vc_libraryDesktop\x86\vc_LibraryDesktopX86.msi', True), | 304 (r'vc_libraryDesktop\x86\vc_LibraryDesktopX86.msi', True), |
| 264 (r'vc_libraryextended\vc_libraryextended.msi', False), | 305 (r'vc_libraryextended\vc_libraryextended.msi', False), |
| 306 (r'professionalcore\Setup\vs_professionalcore.msi', False), | |
| 265 ] | 307 ] |
| 266 extracted_iso = ExtractIso(image.vs_path) | 308 extracted_iso = ExtractIso(image.vs_path) |
| 267 result = ExtractMsiList(os.path.join(extracted_iso, 'packages'), vs_packages) | 309 result = ExtractMsiList(os.path.join(extracted_iso, 'packages'), vs_packages) |
| 268 | 310 |
| 269 sdk_packages = [ | 311 sdk_packages = [ |
| 270 (r'X86 Debuggers And Tools-x86_en-us.msi', True), | 312 (r'X86 Debuggers And Tools-x86_en-us.msi', True), |
| 271 (r'X64 Debuggers And Tools-x64_en-us.msi', True), | 313 (r'X64 Debuggers And Tools-x64_en-us.msi', True), |
| 272 (r'SDK Debuggers-x86_en-us.msi', True), | 314 (r'SDK Debuggers-x86_en-us.msi', True), |
| 273 (r'Windows Software Development Kit-x86_en-us.msi', True), | 315 (r'Windows Software Development Kit-x86_en-us.msi', True), |
| 274 (r'Windows Software Development Kit for Metro style Apps-x86_en-us.msi', | 316 (r'Windows Software Development Kit for Metro style Apps-x86_en-us.msi', |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 288 extracted_iso = ExtractIso(image.wdk_path) | 330 extracted_iso = ExtractIso(image.wdk_path) |
| 289 result.extend(ExtractMsiList(os.path.join(extracted_iso, 'WDK'), | 331 result.extend(ExtractMsiList(os.path.join(extracted_iso, 'WDK'), |
| 290 wdk_packages)) | 332 wdk_packages)) |
| 291 | 333 |
| 292 return result | 334 return result |
| 293 | 335 |
| 294 | 336 |
| 295 def CopyToFinalLocation(extracted_dirs, target_dir): | 337 def CopyToFinalLocation(extracted_dirs, target_dir): |
| 296 sys.stdout.write('Copying to final location...\n') | 338 sys.stdout.write('Copying to final location...\n') |
| 297 mappings = { | 339 mappings = { |
| 298 'Program Files\\Microsoft Visual Studio 12.0\\': '.\\', | 340 'Program Files\\Microsoft Visual Studio 12.0\\VC\\': 'VC\\', |
| 341 'Program Files\\Microsoft Visual Studio 12.0\\DIA SDK\\': 'DIA SDK\\', | |
| 299 'System64\\': 'sys64\\', | 342 'System64\\': 'sys64\\', |
| 300 'System\\': 'sys32\\', | 343 'System\\': 'sys32\\', |
| 301 'Windows Kits\\8.0\\': 'win8sdk\\', | 344 'Windows Kits\\8.0\\': 'win8sdk\\', |
| 302 'WinDDK\\7600.16385.win7_wdk.100208-1538\\': 'wdk\\', | 345 'WinDDK\\7600.16385.win7_wdk.100208-1538\\': 'wdk\\', |
| 303 } | 346 } |
| 304 matches = [] | 347 matches = [] |
| 305 for extracted_dir in extracted_dirs: | 348 for extracted_dir in extracted_dirs: |
| 306 for root, _, filenames in os.walk(extracted_dir): | 349 for root, _, filenames in os.walk(extracted_dir): |
| 307 for filename in filenames: | 350 for filename in filenames: |
| 308 matches.append((extracted_dir, os.path.join(root, filename))) | 351 matches.append((extracted_dir, os.path.join(root, filename))) |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 413 GenerateSetEnvCmd(target_dir, not options.express) | 456 GenerateSetEnvCmd(target_dir, not options.express) |
| 414 with open(os.path.join(target_dir, '.version'), 'w') as f: | 457 with open(os.path.join(target_dir, '.version'), 'w') as f: |
| 415 f.write('express' if options.express else 'pro') | 458 f.write('express' if options.express else 'pro') |
| 416 finally: | 459 finally: |
| 417 if options.clean: | 460 if options.clean: |
| 418 DeleteAllTempDirs() | 461 DeleteAllTempDirs() |
| 419 | 462 |
| 420 | 463 |
| 421 if __name__ == '__main__': | 464 if __name__ == '__main__': |
| 422 sys.exit(main()) | 465 sys.exit(main()) |
| OLD | NEW |