OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 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 """A utility script for downloading versioned Syzygy binaries.""" | 6 """A utility script for downloading versioned Syzygy binaries.""" |
7 | 7 |
8 import hashlib | 8 import hashlib |
9 import errno | 9 import errno |
10 import fnmatch | |
10 import json | 11 import json |
11 import logging | 12 import logging |
12 import optparse | 13 import optparse |
13 import os | 14 import os |
14 import re | 15 import re |
15 import shutil | 16 import shutil |
16 import stat | 17 import stat |
17 import sys | 18 import sys |
18 import subprocess | 19 import subprocess |
19 import tempfile | 20 import tempfile |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
275 | 276 |
276 def _Download(resource): | 277 def _Download(resource): |
277 """Downloads the given GS resource to a temporary file, returning its path.""" | 278 """Downloads the given GS resource to a temporary file, returning its path.""" |
278 tmp = tempfile.mkstemp(suffix='syzygy_archive') | 279 tmp = tempfile.mkstemp(suffix='syzygy_archive') |
279 os.close(tmp[0]) | 280 os.close(tmp[0]) |
280 url = 'gs://syzygy-archive' + resource | 281 url = 'gs://syzygy-archive' + resource |
281 _GsUtil('cp', url, tmp[1]) | 282 _GsUtil('cp', url, tmp[1]) |
282 return tmp[1] | 283 return tmp[1] |
283 | 284 |
284 | 285 |
286 def _MaybeCopyDIABinaries(options, contents): | |
287 """Try to copy the DIA DLL to the binaries exe directory. | |
288 | |
289 This doesn't check if the toolchain version of this DLL is the same as the | |
290 one used by the Syzygy binaries, so this will only be useful if Chrome and | |
291 Syzygy are using the same revision of the toolchain. | |
292 """ | |
293 toolchain_data_file = os.path.join(os.path.dirname(__file__), | |
294 'win_toolchain.json') | |
295 if not os.path.exists(toolchain_data_file): | |
296 _LOGGER.debug('Toolchain JSON data file doesn\'t exist.') | |
297 return | |
298 _LOGGER.debug('%s exists' % toolchain_data_file) | |
299 with open(toolchain_data_file) as temp_f: | |
300 toolchain_data = json.load(temp_f) | |
301 if not os.path.isdir(toolchain_data['path']): | |
302 _LOGGER.error('The toolchain JSON file is invalid.') | |
303 return | |
304 dia_sdk_binaries_dir = os.path.join(toolchain_data['path'], 'DIA SDK', 'bin') | |
305 for binary in os.listdir(dia_sdk_binaries_dir): | |
scottmg
2016/10/03 20:20:55
If you're only copying msdia140.dll, why not just
Sébastien Marchand
2016/10/03 20:23:42
Chris had the same question :), I just wanted this
| |
306 if fnmatch.fnmatch(binary, 'msdia[0-9][0-9][0-9].dll'): | |
307 if binary != 'msdia140.dll': | |
chrisha
2016/09/29 15:26:58
Lift this to a definition at the top of the file?
| |
308 raise Exception('Invalid version, expecting msdia140.dll but got %s' % | |
309 binary) | |
310 dia_dll = os.path.join(dia_sdk_binaries_dir, binary) | |
311 dia_dll_dest = os.path.join(options.output_dir, 'exe', binary) | |
312 _LOGGER.debug('Copying %s to %s.' % (dia_dll, dia_dll_dest)) | |
313 if not options.dry_run: | |
314 shutil.copy(dia_dll, dia_dll_dest) | |
315 contents[os.path.relpath(dia_dll_dest, options.output_dir)] = ( | |
316 _Md5(dia_dll_dest)) | |
317 return | |
318 | |
319 raise Exception('Unable to find the DIA binaries.') | |
320 | |
321 | |
285 def _InstallBinaries(options, deleted={}): | 322 def _InstallBinaries(options, deleted={}): |
286 """Installs Syzygy binaries. This assumes that the output directory has | 323 """Installs Syzygy binaries. This assumes that the output directory has |
287 already been cleaned, as it will refuse to overwrite existing files.""" | 324 already been cleaned, as it will refuse to overwrite existing files.""" |
288 contents = {} | 325 contents = {} |
289 state = { 'revision': options.revision, 'contents': contents } | 326 state = { 'revision': options.revision, 'contents': contents } |
290 archive_path = _SYZYGY_ARCHIVE_PATH % { 'revision': options.revision } | 327 archive_path = _SYZYGY_ARCHIVE_PATH % { 'revision': options.revision } |
291 if options.resources: | 328 if options.resources: |
292 resources = [(resource, resource, '', None) | 329 resources = [(resource, resource, '', None) |
293 for resource in options.resources] | 330 for resource in options.resources] |
294 else: | 331 else: |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
329 if not options.dry_run: | 366 if not options.dry_run: |
330 archive.extract(entry.filename, fulldir) | 367 archive.extract(entry.filename, fulldir) |
331 md5 = _Md5(fullpath) | 368 md5 = _Md5(fullpath) |
332 contents[relpath] = md5 | 369 contents[relpath] = md5 |
333 if sys.platform == 'cygwin': | 370 if sys.platform == 'cygwin': |
334 os.chmod(fullpath, os.stat(fullpath).st_mode | stat.S_IXUSR) | 371 os.chmod(fullpath, os.stat(fullpath).st_mode | stat.S_IXUSR) |
335 | 372 |
336 _LOGGER.debug('Removing temporary file "%s".', path) | 373 _LOGGER.debug('Removing temporary file "%s".', path) |
337 os.remove(path) | 374 os.remove(path) |
338 | 375 |
376 if options.copy_dia_binaries: | |
377 # Try to copy the DIA binaries to the binaries directory. | |
378 _MaybeCopyDIABinaries(options, contents) | |
379 | |
339 return state | 380 return state |
340 | 381 |
341 | 382 |
342 def _ParseCommandLine(): | 383 def _ParseCommandLine(): |
343 """Parses the command-line and returns an options structure.""" | 384 """Parses the command-line and returns an options structure.""" |
344 option_parser = optparse.OptionParser() | 385 option_parser = optparse.OptionParser() |
345 option_parser.add_option('--dry-run', action='store_true', default=False, | 386 option_parser.add_option('--dry-run', action='store_true', default=False, |
346 help='If true then will simply list actions that would be performed.') | 387 help='If true then will simply list actions that would be performed.') |
347 option_parser.add_option('--force', action='store_true', default=False, | 388 option_parser.add_option('--force', action='store_true', default=False, |
348 help='Force an installation even if the binaries are up to date.') | 389 help='Force an installation even if the binaries are up to date.') |
(...skipping 11 matching lines...) Expand all Loading... | |
360 option_parser.add_option('--revision-file', type='string', | 401 option_parser.add_option('--revision-file', type='string', |
361 help='A text file containing an SVN revision or GIT hash.') | 402 help='A text file containing an SVN revision or GIT hash.') |
362 option_parser.add_option('--resource', type='string', action='append', | 403 option_parser.add_option('--resource', type='string', action='append', |
363 dest='resources', help='A resource to be downloaded.') | 404 dest='resources', help='A resource to be downloaded.') |
364 option_parser.add_option('--verbose', dest='log_level', action='store_const', | 405 option_parser.add_option('--verbose', dest='log_level', action='store_const', |
365 default=logging.INFO, const=logging.DEBUG, | 406 default=logging.INFO, const=logging.DEBUG, |
366 help='Enables verbose logging.') | 407 help='Enables verbose logging.') |
367 option_parser.add_option('--quiet', dest='log_level', action='store_const', | 408 option_parser.add_option('--quiet', dest='log_level', action='store_const', |
368 default=logging.INFO, const=logging.ERROR, | 409 default=logging.INFO, const=logging.ERROR, |
369 help='Disables all output except for errors.') | 410 help='Disables all output except for errors.') |
411 option_parser.add_option('--copy-dia-binaries', action='store_true', | |
412 default=False, help='If true then the DIA dll will get copied into the ' | |
413 'binaries directory if it\'s available.') | |
370 options, args = option_parser.parse_args() | 414 options, args = option_parser.parse_args() |
371 if args: | 415 if args: |
372 option_parser.error('Unexpected arguments: %s' % args) | 416 option_parser.error('Unexpected arguments: %s' % args) |
373 if not options.output_dir: | 417 if not options.output_dir: |
374 option_parser.error('Must specify --output-dir.') | 418 option_parser.error('Must specify --output-dir.') |
375 if not options.revision and not options.revision_file: | 419 if not options.revision and not options.revision_file: |
376 option_parser.error('Must specify one of --revision or --revision-file.') | 420 option_parser.error('Must specify one of --revision or --revision-file.') |
377 if options.revision and options.revision_file: | 421 if options.revision and options.revision_file: |
378 option_parser.error('Must not specify both --revision and --revision-file.') | 422 option_parser.error('Must not specify both --revision and --revision-file.') |
379 | 423 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
478 # Install the new binaries. In a dry-run this will actually download the | 522 # Install the new binaries. In a dry-run this will actually download the |
479 # archives, but it won't write anything to disk. | 523 # archives, but it won't write anything to disk. |
480 state = _InstallBinaries(options, deleted) | 524 state = _InstallBinaries(options, deleted) |
481 | 525 |
482 # Build and save the state for the directory. | 526 # Build and save the state for the directory. |
483 _SaveState(options.output_dir, state, options.dry_run) | 527 _SaveState(options.output_dir, state, options.dry_run) |
484 | 528 |
485 | 529 |
486 if __name__ == '__main__': | 530 if __name__ == '__main__': |
487 main() | 531 main() |
OLD | NEW |