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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 return target_path | 112 return target_path |
113 | 113 |
114 | 114 |
115 def DownloadMainIso(url): | 115 def DownloadMainIso(url): |
116 temp_dir = TempDir() | 116 temp_dir = TempDir() |
117 target_path = os.path.join(temp_dir, os.path.basename(url)) | 117 target_path = os.path.join(temp_dir, os.path.basename(url)) |
118 Download(url, target_path) | 118 Download(url, target_path) |
119 return target_path | 119 return target_path |
120 | 120 |
121 | 121 |
122 def GetSourceImage(local_dir, pro): | 122 def DownloadSDK8(): |
| 123 """Downloads the Win8 SDK. |
| 124 |
| 125 This one is slightly different than the simpler direct downloads. There is |
| 126 no .ISO distribution for the Windows 8 SDK. Rather, a tool is provided that |
| 127 is a download manager. This is used to download the various .msi files to a |
| 128 target location. Unfortunately, this tool requires elevation for no obvious |
| 129 reason even when only downloading, so this function will trigger a UAC |
| 130 elevation if the script is not run from an elevated prompt. This is mostly |
| 131 grabbed for windbg and cdb (See http://crbug.com/321187) as most of the SDK |
| 132 is in VS2013, however we need a couple D3D related things from the SDK. |
| 133 """ |
| 134 # Use the long path name here because because 8dot3 names don't seem to work. |
| 135 sdk_temp_dir = GetLongPathName(TempDir()) |
| 136 target_path = os.path.join(sdk_temp_dir, 'sdksetup.exe') |
| 137 standalone_path = os.path.join(sdk_temp_dir, 'Standalone') |
| 138 Download( |
| 139 ('http://download.microsoft.com/download/' |
| 140 'F/1/3/F1300C9C-A120-4341-90DF-8A52509B23AC/standalonesdk/sdksetup.exe'), |
| 141 target_path) |
| 142 sys.stdout.write( |
| 143 'Running sdksetup.exe to download Win8 SDK (may request elevation)...\n') |
| 144 count = 0 |
| 145 while count < 5: |
| 146 rc = os.system(target_path + ' /quiet ' |
| 147 '/features OptionId.WindowsDesktopDebuggers ' |
| 148 '/layout ' + standalone_path) |
| 149 if rc == 0: |
| 150 return standalone_path |
| 151 count += 1 |
| 152 sys.stdout.write('Windows 8 SDK failed to download, retrying.\n') |
| 153 raise SystemExit("After multiple retries, couldn't download Win8 SDK") |
| 154 |
| 155 |
| 156 class SourceImages(object): |
| 157 def __init__(self, vs_path, sdk8_path): |
| 158 self.vs_path = vs_path |
| 159 self.sdk8_path = sdk8_path |
| 160 |
| 161 |
| 162 def GetSourceImages(local_dir, pro): |
123 url = GetIsoUrl(pro) | 163 url = GetIsoUrl(pro) |
124 if local_dir: | 164 if local_dir: |
125 return os.path.join(local_dir, os.path.basename(url)) | 165 return SourceImages(os.path.join(local_dir, os.path.basename(url)), |
| 166 os.path.join(local_dir, 'Standalone')) |
126 else: | 167 else: |
127 return DownloadMainIso(url) | 168 # Note that we do the SDK first, as it might cause an elevation prompt. |
| 169 sdk8_path = DownloadSDK8() |
| 170 vs_path = DownloadMainIso(url) |
| 171 return SourceImages(vs_path, sdk8_path) |
128 | 172 |
129 | 173 |
130 def ExtractMsiList(iso_dir, packages): | 174 def ExtractMsiList(root_dir, packages): |
131 """Extracts the contents of a list of .msi files from an already extracted | 175 """Extracts the contents of a list of .msi files from an already extracted |
132 .iso file. | 176 .iso file. |
133 | 177 |
134 |packages| is a list of pairs (msi, required). If required is not True, the | 178 |packages| is a list of pairs (msi, required). If required is not True, the |
135 msi is optional (this is set for packages that are in Pro but not Express). | 179 msi is optional (this is set for packages that are in Pro but not Express). |
136 """ | 180 """ |
137 results = [] | 181 results = [] |
138 for (package, required) in packages: | 182 for (package, required) in packages: |
139 path_to_package = os.path.join(iso_dir, 'packages', package) | 183 path_to_package = os.path.join(root_dir, package) |
140 if not os.path.exists(path_to_package) and not required: | 184 if not os.path.exists(path_to_package) and not required: |
141 continue | 185 continue |
142 results.append(ExtractMsi(path_to_package)) | 186 results.append(ExtractMsi(path_to_package)) |
143 return results | 187 return results |
144 | 188 |
145 | 189 |
146 def ExtractComponents(image): | 190 def ExtractComponents(image): |
147 packages = [ | 191 vs_packages = [ |
148 (r'vcRuntimeAdditional_amd64\vc_runtimeAdditional_x64.msi', True), | 192 (r'vcRuntimeAdditional_amd64\vc_runtimeAdditional_x64.msi', True), |
149 (r'vcRuntimeAdditional_x86\vc_runtimeAdditional_x86.msi', True), | 193 (r'vcRuntimeAdditional_x86\vc_runtimeAdditional_x86.msi', True), |
150 (r'vcRuntimeDebug_amd64\vc_runtimeDebug_x64.msi', True), | 194 (r'vcRuntimeDebug_amd64\vc_runtimeDebug_x64.msi', True), |
151 (r'vcRuntimeDebug_x86\vc_runtimeDebug_x86.msi', True), | 195 (r'vcRuntimeDebug_x86\vc_runtimeDebug_x86.msi', True), |
152 (r'vcRuntimeMinimum_amd64\vc_runtimeMinimum_x64.msi', True), | 196 (r'vcRuntimeMinimum_amd64\vc_runtimeMinimum_x64.msi', True), |
153 (r'vcRuntimeMinimum_x86\vc_runtimeMinimum_x86.msi', True), | 197 (r'vcRuntimeMinimum_x86\vc_runtimeMinimum_x86.msi', True), |
154 (r'vc_compilerCore86\vc_compilerCore86.msi', True), | 198 (r'vc_compilerCore86\vc_compilerCore86.msi', True), |
155 (r'vc_compilerCore86res\vc_compilerCore86res.msi', True), | 199 (r'vc_compilerCore86res\vc_compilerCore86res.msi', True), |
156 (r'vc_compilerx64nat\vc_compilerx64nat.msi', False), | 200 (r'vc_compilerx64nat\vc_compilerx64nat.msi', False), |
157 (r'vc_compilerx64natres\vc_compilerx64natres.msi', False), | 201 (r'vc_compilerx64natres\vc_compilerx64natres.msi', False), |
158 (r'vc_compilerx64x86\vc_compilerx64x86.msi', False), | 202 (r'vc_compilerx64x86\vc_compilerx64x86.msi', False), |
159 (r'vc_compilerx64x86res\vc_compilerx64x86res.msi', False), | 203 (r'vc_compilerx64x86res\vc_compilerx64x86res.msi', False), |
160 (r'vc_librarycore86\vc_librarycore86.msi', True), | 204 (r'vc_librarycore86\vc_librarycore86.msi', True), |
161 (r'vc_libraryDesktop\x64\vc_LibraryDesktopX64.msi', True), | 205 (r'vc_libraryDesktop\x64\vc_LibraryDesktopX64.msi', True), |
162 (r'vc_libraryDesktop\x86\vc_LibraryDesktopX86.msi', True), | 206 (r'vc_libraryDesktop\x86\vc_LibraryDesktopX86.msi', True), |
163 (r'vc_libraryextended\vc_libraryextended.msi', False), | 207 (r'vc_libraryextended\vc_libraryextended.msi', False), |
164 (r'Windows_SDK\Windows Software Development Kit-x86_en-us.msi', True), | 208 (r'Windows_SDK\Windows Software Development Kit-x86_en-us.msi', True), |
165 ('Windows_SDK\\' | 209 ('Windows_SDK\\' |
166 r'Windows Software Development Kit for Metro style Apps-x86_en-us.msi', | 210 r'Windows Software Development Kit for Metro style Apps-x86_en-us.msi', |
167 True), | 211 True), |
168 ] | 212 ] |
169 extracted_iso = ExtractIso(image) | 213 extracted_iso = ExtractIso(image.vs_path) |
170 return ExtractMsiList(extracted_iso, packages) | 214 result = ExtractMsiList(os.path.join(extracted_iso, 'packages'), vs_packages) |
| 215 |
| 216 sdk_packages = [ |
| 217 (r'X86 Debuggers And Tools-x86_en-us.msi', True), |
| 218 (r'X64 Debuggers And Tools-x64_en-us.msi', True), |
| 219 (r'SDK Debuggers-x86_en-us.msi', True), |
| 220 ] |
| 221 result.extend(ExtractMsiList(os.path.join(image.sdk8_path, 'Installers'), |
| 222 sdk_packages)) |
| 223 |
| 224 return result |
171 | 225 |
172 | 226 |
173 def CopyToFinalLocation(extracted_dirs, target_dir): | 227 def CopyToFinalLocation(extracted_dirs, target_dir): |
174 sys.stdout.write('Copying to final location...\n') | 228 sys.stdout.write('Copying to final location...\n') |
175 mappings = { | 229 mappings = { |
176 'Program Files\\Microsoft Visual Studio 12.0\\': '.\\', | 230 'Program Files\\Microsoft Visual Studio 12.0\\': '.\\', |
177 'System64\\': 'sys64\\', | 231 'System64\\': 'sys64\\', |
178 'System\\': 'sys32\\', | 232 'System\\': 'sys32\\', |
179 'Windows Kits\\8.0\\': 'win8sdk\\', | 233 'Windows Kits\\8.0\\': 'win8sdk\\', |
180 } | 234 } |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 try: | 322 try: |
269 target_dir = os.path.abspath(options.targetdir) | 323 target_dir = os.path.abspath(options.targetdir) |
270 if os.path.exists(target_dir): | 324 if os.path.exists(target_dir): |
271 parser.error('%s already exists. Please [re]move it or use ' | 325 parser.error('%s already exists. Please [re]move it or use ' |
272 '--targetdir to select a different target.\n' % | 326 '--targetdir to select a different target.\n' % |
273 target_dir) | 327 target_dir) |
274 # Set the working directory to 7z subdirectory. 7-zip doesn't find its | 328 # Set the working directory to 7z subdirectory. 7-zip doesn't find its |
275 # codec dll very well, so this is the simplest way to make sure it runs | 329 # codec dll very well, so this is the simplest way to make sure it runs |
276 # correctly, as we don't otherwise care about working directory. | 330 # correctly, as we don't otherwise care about working directory. |
277 os.chdir(os.path.join(BASEDIR, '7z')) | 331 os.chdir(os.path.join(BASEDIR, '7z')) |
278 image = GetSourceImage(options.local, not options.express) | 332 images = GetSourceImages(options.local, not options.express) |
279 extracted = ExtractComponents(image) | 333 extracted = ExtractComponents(images) |
280 CopyToFinalLocation(extracted, target_dir) | 334 CopyToFinalLocation(extracted, target_dir) |
281 | 335 |
282 GenerateSetEnvCmd(target_dir, not options.express) | 336 GenerateSetEnvCmd(target_dir, not options.express) |
283 finally: | 337 finally: |
284 if options.clean: | 338 if options.clean: |
285 DeleteAllTempDirs() | 339 DeleteAllTempDirs() |
286 | 340 |
287 | 341 |
288 if __name__ == '__main__': | 342 if __name__ == '__main__': |
289 sys.exit(main()) | 343 sys.exit(main()) |
OLD | NEW |