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 json | 10 import json |
(...skipping 30 matching lines...) Expand all Loading... |
41 # List of reources to be downloaded and installed. These are tuples with the | 41 # List of reources to be downloaded and installed. These are tuples with the |
42 # following format: | 42 # following format: |
43 # (basename, logging name, relative installation path, extraction filter) | 43 # (basename, logging name, relative installation path, extraction filter) |
44 _RESOURCES = [ | 44 _RESOURCES = [ |
45 ('benchmark.zip', 'benchmark', '', None), | 45 ('benchmark.zip', 'benchmark', '', None), |
46 ('binaries.zip', 'binaries', 'exe', None), | 46 ('binaries.zip', 'binaries', 'exe', None), |
47 ('symbols.zip', 'symbols', 'exe', | 47 ('symbols.zip', 'symbols', 'exe', |
48 lambda x: x.filename.endswith('.dll.pdb'))] | 48 lambda x: x.filename.endswith('.dll.pdb'))] |
49 | 49 |
50 | 50 |
51 # Name of the MS DIA dll that we need to copy to the binaries directory. | |
52 _DIA_DLL_NAME = "msdia140.dll" | |
53 | |
54 | |
55 def _LoadState(output_dir): | 51 def _LoadState(output_dir): |
56 """Loads the contents of the state file for a given |output_dir|, returning | 52 """Loads the contents of the state file for a given |output_dir|, returning |
57 None if it doesn't exist. | 53 None if it doesn't exist. |
58 """ | 54 """ |
59 path = os.path.join(output_dir, _STATE) | 55 path = os.path.join(output_dir, _STATE) |
60 if not os.path.exists(path): | 56 if not os.path.exists(path): |
61 _LOGGER.debug('No state file found.') | 57 _LOGGER.debug('No state file found.') |
62 return None | 58 return None |
63 with open(path, 'rb') as f: | 59 with open(path, 'rb') as f: |
64 _LOGGER.debug('Reading state file: %s', path) | 60 _LOGGER.debug('Reading state file: %s', path) |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 | 275 |
280 def _Download(resource): | 276 def _Download(resource): |
281 """Downloads the given GS resource to a temporary file, returning its path.""" | 277 """Downloads the given GS resource to a temporary file, returning its path.""" |
282 tmp = tempfile.mkstemp(suffix='syzygy_archive') | 278 tmp = tempfile.mkstemp(suffix='syzygy_archive') |
283 os.close(tmp[0]) | 279 os.close(tmp[0]) |
284 url = 'gs://syzygy-archive' + resource | 280 url = 'gs://syzygy-archive' + resource |
285 _GsUtil('cp', url, tmp[1]) | 281 _GsUtil('cp', url, tmp[1]) |
286 return tmp[1] | 282 return tmp[1] |
287 | 283 |
288 | 284 |
289 def _CopyDIABinaries(options, contents): | |
290 """Copy the DIA DLL to the binaries exe directory.""" | |
291 toolchain_data_file = os.path.join(os.path.dirname(__file__), | |
292 'win_toolchain.json') | |
293 if not os.path.exists(toolchain_data_file): | |
294 raise Exception('Toolchain JSON data file doesn\'t exist.') | |
295 | |
296 with open(toolchain_data_file) as temp_f: | |
297 toolchain_data = json.load(temp_f) | |
298 if not os.path.isdir(toolchain_data['path']): | |
299 raise Exception('The toolchain JSON file is invalid.') | |
300 dia_sdk_binaries_dir = os.path.join(toolchain_data['path'], 'DIA SDK', 'bin') | |
301 dia_dll = os.path.join(dia_sdk_binaries_dir, _DIA_DLL_NAME) | |
302 if not os.path.exists(dia_dll): | |
303 raise Exception('%s is missing.') | |
304 dia_dll_dest = os.path.join(options.output_dir, 'exe', _DIA_DLL_NAME) | |
305 _LOGGER.debug('Copying %s to %s.' % (dia_dll, dia_dll_dest)) | |
306 if not options.dry_run: | |
307 shutil.copy(dia_dll, dia_dll_dest) | |
308 contents[os.path.relpath(dia_dll_dest, options.output_dir)] = ( | |
309 _Md5(dia_dll_dest)) | |
310 | |
311 | |
312 def _InstallBinaries(options, deleted={}): | 285 def _InstallBinaries(options, deleted={}): |
313 """Installs Syzygy binaries. This assumes that the output directory has | 286 """Installs Syzygy binaries. This assumes that the output directory has |
314 already been cleaned, as it will refuse to overwrite existing files.""" | 287 already been cleaned, as it will refuse to overwrite existing files.""" |
315 contents = {} | 288 contents = {} |
316 state = { 'revision': options.revision, 'contents': contents } | 289 state = { 'revision': options.revision, 'contents': contents } |
317 archive_path = _SYZYGY_ARCHIVE_PATH % { 'revision': options.revision } | 290 archive_path = _SYZYGY_ARCHIVE_PATH % { 'revision': options.revision } |
318 if options.resources: | 291 if options.resources: |
319 resources = [(resource, resource, '', None) | 292 resources = [(resource, resource, '', None) |
320 for resource in options.resources] | 293 for resource in options.resources] |
321 else: | 294 else: |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 if not options.dry_run: | 329 if not options.dry_run: |
357 archive.extract(entry.filename, fulldir) | 330 archive.extract(entry.filename, fulldir) |
358 md5 = _Md5(fullpath) | 331 md5 = _Md5(fullpath) |
359 contents[relpath] = md5 | 332 contents[relpath] = md5 |
360 if sys.platform == 'cygwin': | 333 if sys.platform == 'cygwin': |
361 os.chmod(fullpath, os.stat(fullpath).st_mode | stat.S_IXUSR) | 334 os.chmod(fullpath, os.stat(fullpath).st_mode | stat.S_IXUSR) |
362 | 335 |
363 _LOGGER.debug('Removing temporary file "%s".', path) | 336 _LOGGER.debug('Removing temporary file "%s".', path) |
364 os.remove(path) | 337 os.remove(path) |
365 | 338 |
366 if options.copy_dia_binaries: | |
367 # Copy the DIA binaries to the binaries directory. | |
368 _CopyDIABinaries(options, contents) | |
369 | |
370 return state | 339 return state |
371 | 340 |
372 | 341 |
373 def _ParseCommandLine(): | 342 def _ParseCommandLine(): |
374 """Parses the command-line and returns an options structure.""" | 343 """Parses the command-line and returns an options structure.""" |
375 option_parser = optparse.OptionParser() | 344 option_parser = optparse.OptionParser() |
376 option_parser.add_option('--dry-run', action='store_true', default=False, | 345 option_parser.add_option('--dry-run', action='store_true', default=False, |
377 help='If true then will simply list actions that would be performed.') | 346 help='If true then will simply list actions that would be performed.') |
378 option_parser.add_option('--force', action='store_true', default=False, | 347 option_parser.add_option('--force', action='store_true', default=False, |
379 help='Force an installation even if the binaries are up to date.') | 348 help='Force an installation even if the binaries are up to date.') |
(...skipping 11 matching lines...) Expand all Loading... |
391 option_parser.add_option('--revision-file', type='string', | 360 option_parser.add_option('--revision-file', type='string', |
392 help='A text file containing an SVN revision or GIT hash.') | 361 help='A text file containing an SVN revision or GIT hash.') |
393 option_parser.add_option('--resource', type='string', action='append', | 362 option_parser.add_option('--resource', type='string', action='append', |
394 dest='resources', help='A resource to be downloaded.') | 363 dest='resources', help='A resource to be downloaded.') |
395 option_parser.add_option('--verbose', dest='log_level', action='store_const', | 364 option_parser.add_option('--verbose', dest='log_level', action='store_const', |
396 default=logging.INFO, const=logging.DEBUG, | 365 default=logging.INFO, const=logging.DEBUG, |
397 help='Enables verbose logging.') | 366 help='Enables verbose logging.') |
398 option_parser.add_option('--quiet', dest='log_level', action='store_const', | 367 option_parser.add_option('--quiet', dest='log_level', action='store_const', |
399 default=logging.INFO, const=logging.ERROR, | 368 default=logging.INFO, const=logging.ERROR, |
400 help='Disables all output except for errors.') | 369 help='Disables all output except for errors.') |
401 option_parser.add_option('--copy-dia-binaries', action='store_true', | |
402 default=False, help='If true then the DIA dll will get copied into the ' | |
403 'binaries directory.') | |
404 options, args = option_parser.parse_args() | 370 options, args = option_parser.parse_args() |
405 if args: | 371 if args: |
406 option_parser.error('Unexpected arguments: %s' % args) | 372 option_parser.error('Unexpected arguments: %s' % args) |
407 if not options.output_dir: | 373 if not options.output_dir: |
408 option_parser.error('Must specify --output-dir.') | 374 option_parser.error('Must specify --output-dir.') |
409 if not options.revision and not options.revision_file: | 375 if not options.revision and not options.revision_file: |
410 option_parser.error('Must specify one of --revision or --revision-file.') | 376 option_parser.error('Must specify one of --revision or --revision-file.') |
411 if options.revision and options.revision_file: | 377 if options.revision and options.revision_file: |
412 option_parser.error('Must not specify both --revision and --revision-file.') | 378 option_parser.error('Must not specify both --revision and --revision-file.') |
413 | 379 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 # Install the new binaries. In a dry-run this will actually download the | 478 # Install the new binaries. In a dry-run this will actually download the |
513 # archives, but it won't write anything to disk. | 479 # archives, but it won't write anything to disk. |
514 state = _InstallBinaries(options, deleted) | 480 state = _InstallBinaries(options, deleted) |
515 | 481 |
516 # Build and save the state for the directory. | 482 # Build and save the state for the directory. |
517 _SaveState(options.output_dir, state, options.dry_run) | 483 _SaveState(options.output_dir, state, options.dry_run) |
518 | 484 |
519 | 485 |
520 if __name__ == '__main__': | 486 if __name__ == '__main__': |
521 main() | 487 main() |
OLD | NEW |