OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 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 """Script to create Chrome Installer archive. | 6 """Script to create Chrome Installer archive. |
7 | 7 |
8 This script is used to create an archive of all the files required for a | 8 This script is used to create an archive of all the files required for a |
9 Chrome install in appropriate directory structure. It reads chrome.release | 9 Chrome install in appropriate directory structure. It reads chrome.release |
10 file as input, creates chrome.7z archive, compresses setup.exe and | 10 file as input, creates chrome.7z archive, compresses setup.exe and |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 | 318 |
319 with open(resource_file_path, 'w') as f: | 319 with open(resource_file_path, 'w') as f: |
320 f.write(resource_file) | 320 f.write(resource_file) |
321 | 321 |
322 | 322 |
323 # Reads |manifest_name| from |build_dir| and writes |manifest_name| to | 323 # Reads |manifest_name| from |build_dir| and writes |manifest_name| to |
324 # |output_dir| with the same content plus |inserted_string| added just before | 324 # |output_dir| with the same content plus |inserted_string| added just before |
325 # |insert_before|. | 325 # |insert_before|. |
326 def CopyAndAugmentManifest(build_dir, output_dir, manifest_name, | 326 def CopyAndAugmentManifest(build_dir, output_dir, manifest_name, |
327 inserted_string, insert_before): | 327 inserted_string, insert_before): |
328 with open(os.path.join(build_dir, manifest_name), 'r') as manifest_file: | 328 with open(os.path.join(build_dir, manifest_name), 'r') as f: |
329 manifest_lines = manifest_file.readlines() | 329 manifest_lines = f.readlines() |
330 | 330 |
331 insert_line = -1 | 331 insert_line = -1 |
332 insert_pos = -1 | 332 insert_pos = -1 |
333 for i in xrange(len(manifest_lines)): | 333 for i in xrange(len(manifest_lines)): |
334 insert_pos = manifest_lines[i].find(insert_before) | 334 insert_pos = manifest_lines[i].find(insert_before) |
335 if insert_pos != -1: | 335 if insert_pos != -1: |
336 insert_line = i | 336 insert_line = i |
337 break | 337 break |
338 if insert_line == -1: | 338 if insert_line == -1: |
339 raise ValueError('Could not find {0} in the manifest:\n{1}'.format( | 339 raise ValueError('Could not find {0} in the manifest:\n{1}'.format( |
340 insert_before, ''.join(manifest_lines))) | 340 insert_before, ''.join(manifest_lines))) |
341 old = manifest_lines[insert_line] | 341 old = manifest_lines[insert_line] |
342 manifest_lines[insert_line] = (old[:insert_pos] + '\n' + inserted_string + | 342 manifest_lines[insert_line] = (old[:insert_pos] + '\n' + inserted_string + |
343 '\n' + old[insert_pos:]) | 343 '\n' + old[insert_pos:]) |
344 | 344 |
345 with open(os.path.join(output_dir, manifest_name), | 345 with open(os.path.join(output_dir, manifest_name), 'w') as f : |
346 'w') as modified_manifest_file : | 346 f.write(''.join(manifest_lines)) |
347 modified_manifest_file.write(''.join(manifest_lines)) | |
348 | 347 |
349 | 348 |
350 def CopyIfChanged(src, target_dir): | 349 def CopyIfChanged(src, target_dir): |
351 """Copy specified |src| file to |target_dir|, but only write to target if | 350 """Copy specified |src| file to |target_dir|, but only write to target if |
352 the file has changed. This avoids a problem during packaging where parts of | 351 the file has changed. This avoids a problem during packaging where parts of |
353 the build have not completed and have the runtime DLL locked when we try to | 352 the build have not completed and have the runtime DLL locked when we try to |
354 copy over it. See http://crbug.com/305877 for details.""" | 353 copy over it. See http://crbug.com/305877 for details.""" |
355 assert os.path.isdir(target_dir) | 354 assert os.path.isdir(target_dir) |
356 dest = os.path.join(target_dir, os.path.basename(src)) | 355 dest = os.path.join(target_dir, os.path.basename(src)) |
357 if os.path.exists(dest): | 356 if os.path.exists(dest): |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 # Copy the VS CRT DLLs to |build_dir|. This must be done before the general | 440 # Copy the VS CRT DLLs to |build_dir|. This must be done before the general |
442 # copy step below to ensure the CRT DLLs are added to the archive and marked | 441 # copy step below to ensure the CRT DLLs are added to the archive and marked |
443 # as a dependency in the exe manifests generated below. | 442 # as a dependency in the exe manifests generated below. |
444 CopyVisualStudioRuntimeDLLs(build_dir, target_arch) | 443 CopyVisualStudioRuntimeDLLs(build_dir, target_arch) |
445 | 444 |
446 # Stage all the component DLLs found in |build_dir|. These are all the DLLs | 445 # Stage all the component DLLs found in |build_dir|. These are all the DLLs |
447 # which have not already been added to the staged |version_dir| by virtue of | 446 # which have not already been added to the staged |version_dir| by virtue of |
448 # chrome.release. | 447 # chrome.release. |
449 build_dlls = glob.glob(os.path.join(build_dir, '*.dll')) | 448 build_dlls = glob.glob(os.path.join(build_dir, '*.dll')) |
450 staged_dll_basenames = [os.path.basename(staged_dll) for staged_dll in \ | 449 staged_dll_basenames = [os.path.basename(staged_dll) for staged_dll in \ |
451 glob.glob(os.path.join(version_dir, '*.dll'))] | 450 glob.glob(os.path.join(version_dir, '*.dll'))] |
452 component_dll_filenames = [] | 451 component_dll_filenames = [] |
453 for component_dll in [dll for dll in build_dlls if \ | 452 for component_dll in [dll for dll in build_dlls if \ |
454 os.path.basename(dll) not in staged_dll_basenames]: | 453 os.path.basename(dll) not in staged_dll_basenames]: |
455 # remoting_*.dll's don't belong in the archive (it doesn't depend on them | 454 # remoting_*.dll's don't belong in the archive (it doesn't depend on them |
456 # in gyp). Trying to copy them causes a build race when creating the | 455 # in gyp). Trying to copy them causes a build race when creating the |
457 # installer archive in component mode. See: crbug.com/180996 | 456 # installer archive in component mode. See: crbug.com/180996 |
458 if os.path.basename(component_dll).startswith('remoting_'): | 457 if os.path.basename(component_dll).startswith('remoting_'): |
459 continue | 458 continue |
460 # Copy them to the version_dir (for the version assembly to be able to refer | 459 # Copy them to the version_dir (for the version assembly to be able to refer |
461 # to them below and thus for chrome.exe to be able to load them at runtime). | 460 # to them below and make sure chrome.exe can find them at runtime). |
462 shutil.copy(component_dll, version_dir) | 461 shutil.copy(component_dll, version_dir) |
463 # Also copy them directly to the Installer directory for the installed | 462 # Also copy them directly to the Installer directory for the installed |
464 # setup.exe to be able to run (as it doesn't statically link in component | 463 # setup.exe to be able to run (as it doesn't statically link in component |
465 # DLLs). | 464 # DLLs). |
466 # TODO(gab): This makes the archive ~278MB instead of ~185MB; consider | 465 # This makes the archive ~1.5X bigger (Release ~185MB => ~278MB; |
467 # copying the DLLs over from the installer. | 466 # Debug ~520MB => ~875MB) this is however simpler than any other installer |
| 467 # change and doesn't make archive generation itself slower so it only |
| 468 # matters when copying the archive to other test machines. This approach |
| 469 # can be revised if this is a problem. |
468 shutil.copy(component_dll, installer_dir) | 470 shutil.copy(component_dll, installer_dir) |
469 component_dll_filenames.append(os.path.basename(component_dll)) | 471 component_dll_filenames.append(os.path.basename(component_dll)) |
470 | 472 |
471 # Copy chrome.exe.manifest as-is. It is required, among other things, to | 473 # Copy chrome.exe.manifest as-is. It is required, among other things, to |
472 # declare a dependency on the version dir assembly. | 474 # declare a dependency on the version dir assembly. |
473 shutil.copy(os.path.join(build_dir, 'chrome.exe.manifest'), chrome_dir) | 475 shutil.copy(os.path.join(build_dir, 'chrome.exe.manifest'), chrome_dir) |
474 | 476 |
475 # Also copy setup.exe.manifest as-is. It is required, among other things, to | 477 # Also copy setup.exe.manifest as-is. It is required, among other things, to |
476 # let setup.exe UAC when it wants to, by specifying that it handles elevation | 478 # let setup.exe UAC when it wants to, by specifying that it handles elevation |
477 # "asInvoker", rather than have Windows auto-elevate it when launched. | 479 # "asInvoker", rather than have Windows auto-elevate it when launched. |
478 shutil.copy(os.path.join(build_dir, 'setup.exe.manifest'), installer_dir) | 480 shutil.copy(os.path.join(build_dir, 'setup.exe.manifest'), installer_dir) |
479 | 481 |
480 # Augment {version}.manifest to include all component DLLs as part of the | 482 # Augment {version}.manifest to include all component DLLs as part of the |
481 # assembly it constitutes which will allow dependents of this assembly to | 483 # assembly it constitutes, which will allow dependents of this assembly to |
482 # find these DLLs. | 484 # find these DLLs. |
483 version_assembly_dll_additions = [] | 485 version_assembly_dll_additions = [] |
484 for dll_filename in component_dll_filenames: | 486 for dll_filename in component_dll_filenames: |
485 version_assembly_dll_additions.append( | 487 version_assembly_dll_additions.append(" <file name='%s'/>" % dll_filename) |
486 " <file name='{dll_filename}'/>".format(dll_filename=dll_filename)) | |
487 CopyAndAugmentManifest(build_dir, version_dir, | 488 CopyAndAugmentManifest(build_dir, version_dir, |
488 '{version}.manifest'.format(version=current_version), | 489 '%s.manifest' % current_version, |
489 '\n'.join(version_assembly_dll_additions), | 490 '\n'.join(version_assembly_dll_additions), |
490 '</assembly>') | 491 '</assembly>') |
491 | 492 |
492 | 493 |
493 def main(options): | 494 def main(options): |
494 """Main method that reads input file, creates archive file and write | 495 """Main method that reads input file, creates archive file and write |
495 resource input file. | 496 resource input file. |
496 """ | 497 """ |
497 current_version = BuildVersion(options.build_dir) | 498 current_version = BuildVersion(options.build_dir) |
498 | 499 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
603 if not options.resource_file_path: | 604 if not options.resource_file_path: |
604 options.resource_file_path = os.path.join(options.build_dir, | 605 options.resource_file_path = os.path.join(options.build_dir, |
605 MINI_INSTALLER_INPUT_FILE) | 606 MINI_INSTALLER_INPUT_FILE) |
606 | 607 |
607 return options | 608 return options |
608 | 609 |
609 | 610 |
610 if '__main__' == __name__: | 611 if '__main__' == __name__: |
611 print sys.argv | 612 print sys.argv |
612 sys.exit(main(_ParseOptions())) | 613 sys.exit(main(_ParseOptions())) |
OLD | NEW |