Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: win_toolchain/toolchain2013.py

Issue 148453008: Support VS2013 Express for automatic toolchain too (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: .gitignore Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
11 import os 11 import os
12 import shutil 12 import shutil
13 import subprocess 13 import subprocess
14 import sys 14 import sys
15 import tempfile 15 import tempfile
16 import urllib2 16 import urllib2
17 17
18 18
19 BASEDIR = os.path.dirname(os.path.abspath(__file__)) 19 BASEDIR = os.path.dirname(os.path.abspath(__file__))
20 WDK_ISO_URL = (
21 'http://download.microsoft.com/download/'
22 '4/A/2/4A25C7D5-EFBE-4182-B6A9-AE6850409A78/GRMWDK_EN_7600_1.ISO')
20 g_temp_dirs = [] 23 g_temp_dirs = []
21 24
22 25
23 sys.path.append(os.path.join(BASEDIR, '..')) 26 sys.path.append(os.path.join(BASEDIR, '..'))
24 import download_from_google_storage 27 import download_from_google_storage
25 28
26 29
27 def GetLongPathName(path): 30 def GetLongPathName(path):
28 """Converts any 8dot3 names in the path to the full name.""" 31 """Converts any 8dot3 names in the path to the full name."""
29 buf = ctypes.create_unicode_buffer(260) 32 buf = ctypes.create_unicode_buffer(260)
(...skipping 20 matching lines...) Expand all
50 """Removes all temporary directories created by |TempDir()|.""" 53 """Removes all temporary directories created by |TempDir()|."""
51 global g_temp_dirs 54 global g_temp_dirs
52 if g_temp_dirs: 55 if g_temp_dirs:
53 sys.stdout.write('Cleaning up temporaries...\n') 56 sys.stdout.write('Cleaning up temporaries...\n')
54 for temp in g_temp_dirs: 57 for temp in g_temp_dirs:
55 # shutil.rmtree errors out on read only attributes. 58 # shutil.rmtree errors out on read only attributes.
56 RunOrDie('rmdir /s/q "%s"' % temp) 59 RunOrDie('rmdir /s/q "%s"' % temp)
57 g_temp_dirs = [] 60 g_temp_dirs = []
58 61
59 62
60 def GetIsoUrl(pro): 63 def GetMainIsoUrl(pro):
61 """Gets the .iso URL. 64 """Gets the main .iso URL.
62 65
63 If |pro| is False, downloads the Express edition. If |CHROME_HEADLESS| is 66 If |pro| is False, downloads the Express edition. If |CHROME_HEADLESS| is
64 set in the environment, then we assume we're on an internal bot, and download 67 set in the environment, then we assume we're on an internal bot, and download
65 from internal google storage instead. 68 from internal google storage instead.
66 """ 69 """
67 prefix = 'http://download.microsoft.com/download/' 70 prefix = 'http://download.microsoft.com/download/'
68 if pro: 71 if pro:
69 return (prefix + 72 return (prefix +
70 'A/F/1/AF128362-A6A8-4DB3-A39A-C348086472CC/VS2013_RTM_PRO_ENU.iso') 73 'A/F/1/AF128362-A6A8-4DB3-A39A-C348086472CC/VS2013_RTM_PRO_ENU.iso')
71 else: 74 else:
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 Download( 147 Download(
145 ('http://download.microsoft.com/download/' 148 ('http://download.microsoft.com/download/'
146 'F/1/3/F1300C9C-A120-4341-90DF-8A52509B23AC/standalonesdk/sdksetup.exe'), 149 'F/1/3/F1300C9C-A120-4341-90DF-8A52509B23AC/standalonesdk/sdksetup.exe'),
147 target_path) 150 target_path)
148 sys.stdout.write( 151 sys.stdout.write(
149 'Running sdksetup.exe to download Win8 SDK (may request elevation)...\n') 152 'Running sdksetup.exe to download Win8 SDK (may request elevation)...\n')
150 count = 0 153 count = 0
151 while count < 5: 154 while count < 5:
152 rc = os.system(target_path + ' /quiet ' 155 rc = os.system(target_path + ' /quiet '
153 '/features OptionId.WindowsDesktopDebuggers ' 156 '/features OptionId.WindowsDesktopDebuggers '
157 'OptionId.WindowsDesktopSoftwareDevelopmentKit '
154 '/layout ' + standalone_path) 158 '/layout ' + standalone_path)
155 if rc == 0: 159 if rc == 0:
156 return standalone_path 160 return standalone_path
157 count += 1 161 count += 1
158 sys.stdout.write('Windows 8 SDK failed to download, retrying.\n') 162 sys.stdout.write('Windows 8 SDK failed to download, retrying.\n')
159 sys.exit('After multiple retries, couldn\'t download Win8 SDK') 163 sys.exit('After multiple retries, couldn\'t download Win8 SDK')
160 164
161 165
166 def DownloadWDKIso():
167 wdk_temp_dir = TempDir()
168 target_path = os.path.join(wdk_temp_dir, 'GRMWDK_EN_7600_1.ISO')
169 Download(WDK_ISO_URL, target_path)
170 return target_path
171
172
162 def DownloadUsingGsutil(filename): 173 def DownloadUsingGsutil(filename):
163 """Downloads the given file from Google Storage chrome-wintoolchain bucket.""" 174 """Downloads the given file from Google Storage chrome-wintoolchain bucket."""
164 temp_dir = TempDir() 175 temp_dir = TempDir()
165 assert os.path.basename(filename) == filename 176 assert os.path.basename(filename) == filename
166 target_path = os.path.join(temp_dir, filename) 177 target_path = os.path.join(temp_dir, filename)
167 gsutil = download_from_google_storage.Gsutil( 178 gsutil = download_from_google_storage.Gsutil(
168 download_from_google_storage.GSUTIL_DEFAULT_PATH, boto_path=None) 179 download_from_google_storage.GSUTIL_DEFAULT_PATH, boto_path=None)
169 code = gsutil.call('cp', 'gs://chrome-wintoolchain/' + filename, target_path) 180 code = gsutil.call('cp', 'gs://chrome-wintoolchain/' + filename, target_path)
170 if code != 0: 181 if code != 0:
171 sys.exit('gsutil failed') 182 sys.exit('gsutil failed')
172 return target_path 183 return target_path
173 184
174 185
175 def GetVSInternal(): 186 def GetVSInternal():
176 """Uses gsutil to pull the toolchain from internal Google Storage bucket.""" 187 """Uses gsutil to pull the toolchain from internal Google Storage bucket."""
177 return DownloadUsingGsutil('VS2013_RTM_PRO_ENU.iso') 188 return DownloadUsingGsutil('VS2013_RTM_PRO_ENU.iso')
178 189
179 190
180 def GetSDKInternal(): 191 def GetSDKInternal():
181 """Downloads a zipped copy of the SDK from internal Google Storage bucket, 192 """Downloads a zipped copy of the SDK from internal Google Storage bucket,
182 and extracts it.""" 193 and extracts it."""
183 zip_file = DownloadUsingGsutil('Standalone.zip') 194 zip_file = DownloadUsingGsutil('Standalone.zip')
184 return ExtractIso(zip_file) 195 return ExtractIso(zip_file)
185 196
186 197
187 class SourceImages(object): 198 class SourceImages(object):
188 def __init__(self, vs_path, sdk8_path): 199 """Local paths for components. |wdk_path| may be None if it's unnecessary for
200 the given configuration."""
201 def __init__(self, vs_path, sdk8_path, wdk_path):
189 self.vs_path = vs_path 202 self.vs_path = vs_path
190 self.sdk8_path = sdk8_path 203 self.sdk8_path = sdk8_path
204 self.wdk_path = wdk_path
191 205
192 206
193 def GetSourceImages(local_dir, pro): 207 def GetSourceImages(local_dir, pro):
194 url = GetIsoUrl(pro) 208 """Downloads the various sources that we need.
209
210 Of note: Because Express does not include ATL, there's an additional download
211 of the 7.1 WDK which is the latest publically accessible source for ATL. When
212 |pro| this is not necessary (and CHROME_HEADLESS always implies Pro).
213 """
214 url = GetMainIsoUrl(pro)
195 if os.environ.get('CHROME_HEADLESS'): 215 if os.environ.get('CHROME_HEADLESS'):
M-A Ruel 2014/02/03 23:10:52 I'd prefer an option --bot-mode with default=bool(
scottmg 2014/02/03 23:22:12 Done.
196 return SourceImages(GetVSInternal(), GetSDKInternal()) 216 return SourceImages(GetVSInternal(), GetSDKInternal(), wdk_path=None)
197 elif local_dir: 217 elif local_dir:
218 wdk_path = (os.path.join(local_dir, os.path.basename(WDK_ISO_URL))
219 if not pro else None)
198 return SourceImages(os.path.join(local_dir, os.path.basename(url)), 220 return SourceImages(os.path.join(local_dir, os.path.basename(url)),
199 os.path.join(local_dir, 'Standalone')) 221 os.path.join(local_dir, 'Standalone'),
222 wdk_path=wdk_path)
200 else: 223 else:
201 # Note that we do the SDK first, as it might cause an elevation prompt. 224 # Note that we do the SDK first, as it might cause an elevation prompt.
202 sdk8_path = DownloadSDK8() 225 sdk8_path = DownloadSDK8()
203 vs_path = DownloadMainIso(url) 226 vs_path = DownloadMainIso(url)
204 return SourceImages(vs_path, sdk8_path) 227 wdk_path = DownloadWDKIso() if not pro else None
228 return SourceImages(vs_path, sdk8_path, wdk_path=wdk_path)
205 229
206 230
207 def ExtractMsiList(root_dir, packages): 231 def ExtractMsiList(root_dir, packages):
208 """Extracts the contents of a list of .msi files from an already extracted 232 """Extracts the contents of a list of .msi files from an already extracted
209 .iso file. 233 .iso file.
210 234
211 |packages| is a list of pairs (msi, required). If required is not True, the 235 |packages| is a list of pairs (msi, required). If required is not True, the
212 msi is optional (this is set for packages that are in Pro but not Express). 236 msi is optional (this is set for packages that are in Pro but not Express).
213 """ 237 """
214 results = [] 238 results = []
(...skipping 16 matching lines...) Expand all
231 (r'vc_compilerCore86\vc_compilerCore86.msi', True), 255 (r'vc_compilerCore86\vc_compilerCore86.msi', True),
232 (r'vc_compilerCore86res\vc_compilerCore86res.msi', True), 256 (r'vc_compilerCore86res\vc_compilerCore86res.msi', True),
233 (r'vc_compilerx64nat\vc_compilerx64nat.msi', False), 257 (r'vc_compilerx64nat\vc_compilerx64nat.msi', False),
234 (r'vc_compilerx64natres\vc_compilerx64natres.msi', False), 258 (r'vc_compilerx64natres\vc_compilerx64natres.msi', False),
235 (r'vc_compilerx64x86\vc_compilerx64x86.msi', False), 259 (r'vc_compilerx64x86\vc_compilerx64x86.msi', False),
236 (r'vc_compilerx64x86res\vc_compilerx64x86res.msi', False), 260 (r'vc_compilerx64x86res\vc_compilerx64x86res.msi', False),
237 (r'vc_librarycore86\vc_librarycore86.msi', True), 261 (r'vc_librarycore86\vc_librarycore86.msi', True),
238 (r'vc_libraryDesktop\x64\vc_LibraryDesktopX64.msi', True), 262 (r'vc_libraryDesktop\x64\vc_LibraryDesktopX64.msi', True),
239 (r'vc_libraryDesktop\x86\vc_LibraryDesktopX86.msi', True), 263 (r'vc_libraryDesktop\x86\vc_LibraryDesktopX86.msi', True),
240 (r'vc_libraryextended\vc_libraryextended.msi', False), 264 (r'vc_libraryextended\vc_libraryextended.msi', False),
241 (r'Windows_SDK\Windows Software Development Kit-x86_en-us.msi', True),
242 ('Windows_SDK\\'
243 r'Windows Software Development Kit for Metro style Apps-x86_en-us.msi',
244 True),
245 ] 265 ]
246 extracted_iso = ExtractIso(image.vs_path) 266 extracted_iso = ExtractIso(image.vs_path)
247 result = ExtractMsiList(os.path.join(extracted_iso, 'packages'), vs_packages) 267 result = ExtractMsiList(os.path.join(extracted_iso, 'packages'), vs_packages)
248 268
249 sdk_packages = [ 269 sdk_packages = [
250 (r'X86 Debuggers And Tools-x86_en-us.msi', True), 270 (r'X86 Debuggers And Tools-x86_en-us.msi', True),
251 (r'X64 Debuggers And Tools-x64_en-us.msi', True), 271 (r'X64 Debuggers And Tools-x64_en-us.msi', True),
252 (r'SDK Debuggers-x86_en-us.msi', True), 272 (r'SDK Debuggers-x86_en-us.msi', True),
273 (r'Windows Software Development Kit-x86_en-us.msi', True),
274 (r'Windows Software Development Kit for Metro style Apps-x86_en-us.msi',
275 True),
253 ] 276 ]
254 result.extend(ExtractMsiList(os.path.join(image.sdk8_path, 'Installers'), 277 result.extend(ExtractMsiList(os.path.join(image.sdk8_path, 'Installers'),
255 sdk_packages)) 278 sdk_packages))
256 279
280 if image.wdk_path:
281 # This image will only be set when using Express, when we need the WDK
282 # headers and libs to supplement Express with ATL.
283 wdk_packages = [
284 (r'headers.msi', True),
285 (r'libs_x86fre.msi', True),
286 (r'libs_x64fre.msi', True),
287 ]
288 extracted_iso = ExtractIso(image.wdk_path)
289 result.extend(ExtractMsiList(os.path.join(extracted_iso, 'WDK'),
290 wdk_packages))
291
257 return result 292 return result
258 293
259 294
260 def CopyToFinalLocation(extracted_dirs, target_dir): 295 def CopyToFinalLocation(extracted_dirs, target_dir):
261 sys.stdout.write('Copying to final location...\n') 296 sys.stdout.write('Copying to final location...\n')
262 mappings = { 297 mappings = {
263 'Program Files\\Microsoft Visual Studio 12.0\\': '.\\', 298 'Program Files\\Microsoft Visual Studio 12.0\\': '.\\',
264 'System64\\': 'sys64\\', 299 'System64\\': 'sys64\\',
265 'System\\': 'sys32\\', 300 'System\\': 'sys32\\',
266 'Windows Kits\\8.0\\': 'win8sdk\\', 301 'Windows Kits\\8.0\\': 'win8sdk\\',
302 'WinDDK\\7600.16385.win7_wdk.100208-1538\\': 'wdk\\',
267 } 303 }
268 matches = [] 304 matches = []
269 for extracted_dir in extracted_dirs: 305 for extracted_dir in extracted_dirs:
270 for root, _, filenames in os.walk(extracted_dir): 306 for root, _, filenames in os.walk(extracted_dir):
271 for filename in filenames: 307 for filename in filenames:
272 matches.append((extracted_dir, os.path.join(root, filename))) 308 matches.append((extracted_dir, os.path.join(root, filename)))
273 309
274 copies = [] 310 copies = []
275 for prefix, full_path in matches: 311 for prefix, full_path in matches:
276 # +1 for trailing \. 312 # +1 for trailing \.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 '%~dp0..\\..\\VC\\atlmfc\\lib\n' 356 '%~dp0..\\..\\VC\\atlmfc\\lib\n'
321 'goto :EOF\n') 357 'goto :EOF\n')
322 358
323 # Express does not include a native 64 bit compiler, so we have to use 359 # Express does not include a native 64 bit compiler, so we have to use
324 # the x86->x64 cross. 360 # the x86->x64 cross.
325 if not pro: 361 if not pro:
326 # x86->x64 cross. 362 # x86->x64 cross.
327 f.write(':x64\n' 363 f.write(':x64\n'
328 'set PATH=%~dp0..\\..\\win8sdk\\bin\\x64;' 364 'set PATH=%~dp0..\\..\\win8sdk\\bin\\x64;'
329 '%~dp0..\\..\\VC\\bin\\x86_amd64;' 365 '%~dp0..\\..\\VC\\bin\\x86_amd64;'
366 # Needed for mspdb120.dll. Must be after above though, so
367 # that cl.exe is the x86_amd64 one.
368 '%~dp0..\\..\\VC\\bin;'
330 '%PATH%\n') 369 '%PATH%\n')
331 else: 370 else:
332 # x64 native. 371 # x64 native.
333 f.write(':x64\n' 372 f.write(':x64\n'
334 'set PATH=%~dp0..\\..\\win8sdk\\bin\\x64;' 373 'set PATH=%~dp0..\\..\\win8sdk\\bin\\x64;'
335 '%~dp0..\\..\\VC\\bin\\amd64;' 374 '%~dp0..\\..\\VC\\bin\\amd64;'
336 '%PATH%\n') 375 '%PATH%\n')
337 f.write('set LIB=%~dp0..\\..\\VC\\lib\\amd64;' 376 f.write('set LIB=%~dp0..\\..\\VC\\lib\\amd64;'
338 '%~dp0..\\..\\win8sdk\\Lib\\win8\\um\\x64;' 377 '%~dp0..\\..\\win8sdk\\Lib\\win8\\um\\x64;'
339 '%~dp0..\\..\\VC\\atlmfc\\lib\\amd64\n') 378 '%~dp0..\\..\\VC\\atlmfc\\lib\\amd64\n')
(...skipping 20 matching lines...) Expand all
360 target_dir) 399 target_dir)
361 # Set the working directory to 7z subdirectory. 7-zip doesn't find its 400 # Set the working directory to 7z subdirectory. 7-zip doesn't find its
362 # codec dll very well, so this is the simplest way to make sure it runs 401 # codec dll very well, so this is the simplest way to make sure it runs
363 # correctly, as we don't otherwise care about working directory. 402 # correctly, as we don't otherwise care about working directory.
364 os.chdir(os.path.join(BASEDIR, '7z')) 403 os.chdir(os.path.join(BASEDIR, '7z'))
365 images = GetSourceImages(options.local, not options.express) 404 images = GetSourceImages(options.local, not options.express)
366 extracted = ExtractComponents(images) 405 extracted = ExtractComponents(images)
367 CopyToFinalLocation(extracted, target_dir) 406 CopyToFinalLocation(extracted, target_dir)
368 407
369 GenerateSetEnvCmd(target_dir, not options.express) 408 GenerateSetEnvCmd(target_dir, not options.express)
409 with open(os.path.join(target_dir, '.version'), 'w') as f:
410 f.write('express' if options.express else 'pro')
370 finally: 411 finally:
371 if options.clean: 412 if options.clean:
372 DeleteAllTempDirs() 413 DeleteAllTempDirs()
373 414
374 415
375 if __name__ == '__main__': 416 if __name__ == '__main__':
376 sys.exit(main()) 417 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698