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 """ |
| 6 From a system-installed copy of the toolchain, packages all the required bits |
| 7 into a .zip file. |
| 8 |
| 9 It assumes default install locations for tools, in particular: |
| 10 - C:\Program Files (x86)\Microsoft Visual Studio 12.0\... |
| 11 - C:\Program Files (x86)\Windows Kits\8.0\... |
| 12 |
| 13 1. Start from a fresh Win7 VM image. |
| 14 2. Install VS Pro. Deselect everything except MFC. |
| 15 3. Install Windows 8 SDK. Select only the Windows SDK and Debugging Tools for |
| 16 Windows. |
| 17 4. Run this script, which will build a <sha1>.zip. |
| 18 |
| 19 Express is not yet supported by this script, but patches welcome (it's not too |
| 20 useful as the resulting zip can't be redistributed, and most will presumably |
| 21 have a Pro license anyway). |
| 22 """ |
| 23 |
| 24 import os |
| 25 import shutil |
| 26 import sys |
| 27 import tempfile |
| 28 import zipfile |
| 29 |
| 30 import get_toolchain_if_necessary |
| 31 import toolchain2013 # pylint: disable=F0401 |
| 32 |
| 33 |
| 34 def BuildFileList(): |
| 35 result = [] |
| 36 |
| 37 # Subset of VS corresponding roughly to VC. |
| 38 vs_path = r'C:\Program Files (x86)\Microsoft Visual Studio 12.0' |
| 39 for path in [ |
| 40 'DIA SDK/bin', |
| 41 'DIA SDK/idl', |
| 42 'DIA SDK/include', |
| 43 'DIA SDK/lib', |
| 44 'VC/atlmfc', |
| 45 'VC/bin', |
| 46 'VC/crt', |
| 47 'VC/include', |
| 48 'VC/lib', |
| 49 'VC/redist', |
| 50 ('VC/redist/x86/Microsoft.VC120.CRT', 'sys32'), |
| 51 ('VC/redist/x86/Microsoft.VC120.MFC', 'sys32'), |
| 52 ('VC/redist/Debug_NonRedist/x86/Microsoft.VC120.DebugCRT', 'sys32'), |
| 53 ('VC/redist/Debug_NonRedist/x86/Microsoft.VC120.DebugMFC', 'sys32'), |
| 54 ('VC/redist/x64/Microsoft.VC120.CRT', 'sys64'), |
| 55 ('VC/redist/x64/Microsoft.VC120.MFC', 'sys64'), |
| 56 ('VC/redist/Debug_NonRedist/x64/Microsoft.VC120.DebugCRT', 'sys64'), |
| 57 ('VC/redist/Debug_NonRedist/x64/Microsoft.VC120.DebugMFC', 'sys64'), |
| 58 ]: |
| 59 src = path[0] if isinstance(path, tuple) else path |
| 60 combined = os.path.join(vs_path, src) |
| 61 assert os.path.exists(combined) and os.path.isdir(combined) |
| 62 for root, _, files in os.walk(combined): |
| 63 for f in files: |
| 64 final_from = os.path.normpath(os.path.join(root, f)) |
| 65 if isinstance(path, tuple): |
| 66 result.append( |
| 67 (final_from, os.path.normpath(os.path.join(path[1], f)))) |
| 68 else: |
| 69 assert final_from.startswith(vs_path) |
| 70 dest = final_from[len(vs_path) + 1:] |
| 71 if dest.lower().endswith('\\xtree'): |
| 72 # Patch for C4702 in xtree. http://crbug.com/346399. |
| 73 (handle, patched) = tempfile.mkstemp() |
| 74 with open(final_from, 'rb') as unpatched_f: |
| 75 unpatched_contents = unpatched_f.read() |
| 76 os.write(handle, |
| 77 unpatched_contents.replace('warning(disable: 4127)', |
| 78 'warning(disable: 4127 4702)')) |
| 79 result.append((patched, dest)) |
| 80 else: |
| 81 result.append((final_from, dest)) |
| 82 |
| 83 # Just copy the whole SDK. |
| 84 sdk_path = r'C:\Program Files (x86)\Windows Kits\8.0' |
| 85 for root, _, files in os.walk(sdk_path): |
| 86 for f in files: |
| 87 combined = os.path.normpath(os.path.join(root, f)) |
| 88 to = os.path.join('win8sdk', combined[len(sdk_path) + 1:]) |
| 89 result.append((combined, to)) |
| 90 |
| 91 # Generically drop all arm stuff that we don't need. |
| 92 return [(f, t) for f, t in result if 'arm\\' not in f.lower()] |
| 93 |
| 94 |
| 95 def AddEnvSetup(files): |
| 96 """We need to generate this file in the same way that the "from pieces" |
| 97 script does, so pull that in here.""" |
| 98 tempdir = tempfile.mkdtemp() |
| 99 os.makedirs(os.path.join(tempdir, 'win8sdk', 'bin')) |
| 100 toolchain2013.GenerateSetEnvCmd(tempdir, True) |
| 101 files.append((os.path.join(tempdir, 'win8sdk', 'bin', 'SetEnv.cmd'), |
| 102 'win8sdk\\bin\\SetEnv.cmd')) |
| 103 |
| 104 |
| 105 def RenameToSha1(output): |
| 106 """Determine the hash in the same way that the unzipper does to rename the |
| 107 # .zip file.""" |
| 108 print 'Extracting to determine hash...' |
| 109 tempdir = tempfile.mkdtemp() |
| 110 old_dir = os.getcwd() |
| 111 os.chdir(tempdir) |
| 112 rel_dir = 'vs2013_files' |
| 113 with zipfile.ZipFile( |
| 114 os.path.join(old_dir, output), 'r', zipfile.ZIP_DEFLATED, True) as zf: |
| 115 zf.extractall(rel_dir) |
| 116 print 'Hashing...' |
| 117 sha1 = get_toolchain_if_necessary.CalculateHash(rel_dir) |
| 118 os.chdir(old_dir) |
| 119 shutil.rmtree(tempdir) |
| 120 final_name = sha1 + '.zip' |
| 121 os.rename(output, final_name) |
| 122 print 'Renamed %s to %s.' % (output, final_name) |
| 123 |
| 124 |
| 125 def main(): |
| 126 print 'Building file list...' |
| 127 files = BuildFileList() |
| 128 |
| 129 AddEnvSetup(files) |
| 130 |
| 131 if False: |
| 132 for f in files: |
| 133 print f[0], '->', f[1] |
| 134 return 0 |
| 135 |
| 136 output = 'out.zip' |
| 137 if os.path.exists(output): |
| 138 os.unlink(output) |
| 139 count = 0 |
| 140 with zipfile.ZipFile(output, 'w', zipfile.ZIP_DEFLATED, True) as zf: |
| 141 for disk_name, archive_name in files: |
| 142 sys.stdout.write('\r%d/%d ...%s' % (count, len(files), disk_name[-40:])) |
| 143 sys.stdout.flush() |
| 144 count += 1 |
| 145 zf.write(disk_name, archive_name) |
| 146 sys.stdout.write('\rWrote to %s.%s\n' % (output, ' '*50)) |
| 147 sys.stdout.flush() |
| 148 |
| 149 RenameToSha1(output) |
| 150 |
| 151 return 0 |
| 152 |
| 153 |
| 154 if __name__ == '__main__': |
| 155 sys.exit(main()) |
OLD | NEW |