Chromium Code Reviews| 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 setup_file = SETUP_PATCH_FILE_PREFIX + '_' + current_version + \ | 318 setup_file = SETUP_PATCH_FILE_PREFIX + '_' + current_version + \ |
| 319 '_from_' + prev_version + COMPRESSED_FILE_EXT | 319 '_from_' + prev_version + COMPRESSED_FILE_EXT |
| 320 setup_file_path = os.path.join(options.build_dir, setup_file) | 320 setup_file_path = os.path.join(options.build_dir, setup_file) |
| 321 CompressUsingLZMA(options.build_dir, setup_file_path, patch_file, | 321 CompressUsingLZMA(options.build_dir, setup_file_path, patch_file, |
| 322 options.verbose) | 322 options.verbose) |
| 323 else: | 323 else: |
| 324 cmd = ['makecab.exe', | 324 cmd = ['makecab.exe', |
| 325 '/D', 'CompressionType=LZX', | 325 '/D', 'CompressionType=LZX', |
| 326 '/V1', | 326 '/V1', |
| 327 '/L', options.output_dir, | 327 '/L', options.output_dir, |
| 328 os.path.join(options.build_dir, SETUP_EXEC),] | 328 os.path.join(options.output_dir, SETUP_EXEC),] |
| 329 RunSystemCommand(cmd, options.verbose) | 329 RunSystemCommand(cmd, options.verbose) |
| 330 setup_file = SETUP_EXEC[:-1] + "_" | 330 setup_file = SETUP_EXEC[:-1] + "_" |
| 331 return setup_file | 331 return setup_file |
| 332 | 332 |
| 333 | 333 |
| 334 _RESOURCE_FILE_HEADER = """\ | 334 _RESOURCE_FILE_HEADER = """\ |
| 335 // This file is automatically generated by create_installer_archive.py. | 335 // This file is automatically generated by create_installer_archive.py. |
| 336 // It contains the resource entries that are going to be linked inside | 336 // It contains the resource entries that are going to be linked inside |
| 337 // mini_installer.exe. For each file to be linked there should be two | 337 // mini_installer.exe. For each file to be linked there should be two |
| 338 // lines: | 338 // lines: |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 359 setup_resource_type = "B7" | 359 setup_resource_type = "B7" |
| 360 | 360 |
| 361 # An array of (file, type, path) tuples of the files to be included. | 361 # An array of (file, type, path) tuples of the files to be included. |
| 362 resources = [] | 362 resources = [] |
| 363 resources.append((setup_file, setup_resource_type, | 363 resources.append((setup_file, setup_resource_type, |
| 364 os.path.join(output_dir, setup_file))) | 364 os.path.join(output_dir, setup_file))) |
| 365 resources.append((archive_file, 'B7', | 365 resources.append((archive_file, 'B7', |
| 366 os.path.join(output_dir, archive_file))) | 366 os.path.join(output_dir, archive_file))) |
| 367 # Include all files needed to run setup.exe (these are copied into the | 367 # Include all files needed to run setup.exe (these are copied into the |
| 368 # 'Installer' dir by DoComponentBuildTasks). | 368 # 'Installer' dir by DoComponentBuildTasks). |
| 369 if component_build: | 369 installer_dir = os.path.join(staging_dir, CHROME_DIR, current_version, |
| 370 installer_dir = os.path.join(staging_dir, CHROME_DIR, current_version, | 370 'Installer') |
| 371 'Installer') | 371 for file in os.listdir(installer_dir): |
| 372 for file in os.listdir(installer_dir): | 372 resources.append((file, 'BN', os.path.join(installer_dir, file))) |
| 373 resources.append((file, 'BN', os.path.join(installer_dir, file))) | |
|
grt (UTC plus 2)
2016/12/09 08:30:54
this puts the component DLLs in as uncompressed bl
Sébastien Marchand
2017/03/06 21:52:26
Sure, if you think that all the dll dependencies s
grt (UTC plus 2)
2017/03/10 09:08:10
Yeah, I think it's worth doing the compression. Do
| |
| 374 | 373 |
| 375 with open(resource_file_path, 'w') as f: | 374 with open(resource_file_path, 'w') as f: |
| 376 f.write(_RESOURCE_FILE_HEADER) | 375 f.write(_RESOURCE_FILE_HEADER) |
| 377 for (file, type, path) in resources: | 376 for (file, type, path) in resources: |
| 378 f.write('\n%s %s\n "%s"\n' % (file, type, path.replace("\\","/"))) | 377 f.write('\n%s %s\n "%s"\n' % (file, type, path.replace("\\","/"))) |
| 379 | 378 |
| 380 | 379 |
| 381 # Reads |manifest_name| from |build_dir| and writes |manifest_name| to | 380 # Reads |manifest_name| from |build_dir| and writes |manifest_name| to |
| 382 # |output_dir| with the same content plus |inserted_string| added just before | 381 # |output_dir| with the same content plus |inserted_string| added just before |
| 383 # |insert_before|. | 382 # |insert_before|. |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 461 def ParseDLLsFromDeps(build_dir, runtime_deps_file): | 460 def ParseDLLsFromDeps(build_dir, runtime_deps_file): |
| 462 """Parses the runtime_deps file and returns the set of DLLs in it, relative | 461 """Parses the runtime_deps file and returns the set of DLLs in it, relative |
| 463 to build_dir.""" | 462 to build_dir.""" |
| 464 build_dlls = set() | 463 build_dlls = set() |
| 465 args = open(runtime_deps_file).read() | 464 args = open(runtime_deps_file).read() |
| 466 for l in args.splitlines(): | 465 for l in args.splitlines(): |
| 467 if os.path.splitext(l)[1] == ".dll": | 466 if os.path.splitext(l)[1] == ".dll": |
| 468 build_dlls.add(os.path.join(build_dir, l)) | 467 build_dlls.add(os.path.join(build_dir, l)) |
| 469 return build_dlls | 468 return build_dlls |
| 470 | 469 |
| 470 | |
| 471 def CopySetupRuntimeDeps(build_dir, setup_runtime_deps, version_dir): | |
| 472 installer_dir = os.path.join(version_dir, 'Installer') | |
| 473 # |installer_dir| is technically only created post-install, but we need it | |
| 474 # now to add setup.exe's config and manifest to the archive. | |
| 475 if not os.path.exists(installer_dir): | |
| 476 os.mkdir(installer_dir) | |
| 477 | |
| 478 setup_component_dlls = ParseDLLsFromDeps(build_dir, setup_runtime_deps) | |
| 479 for setup_component_dll in setup_component_dlls: | |
| 480 g_archive_inputs.append(setup_component_dll) | |
| 481 shutil.copy(setup_component_dll, installer_dir) | |
| 482 | |
|
grt (UTC plus 2)
2016/12/09 08:30:54
nit: extra blank line
Sébastien Marchand
2017/03/06 21:52:26
Done.
| |
| 471 # Copies component build DLLs and generates required config files and manifests | 483 # Copies component build DLLs and generates required config files and manifests |
| 472 # in order for chrome.exe and setup.exe to be able to find those DLLs at | 484 # in order for chrome.exe and setup.exe to be able to find those DLLs at |
| 473 # run-time. | 485 # run-time. |
| 474 # This is meant for developer builds only and should never be used to package | 486 # This is meant for developer builds only and should never be used to package |
| 475 # an official build. | 487 # an official build. |
| 476 def DoComponentBuildTasks(staging_dir, build_dir, target_arch, | 488 def DoComponentBuildTasks(staging_dir, build_dir, target_arch, |
| 477 setup_runtime_deps, chrome_runtime_deps, | 489 setup_runtime_deps, chrome_runtime_deps, |
| 478 current_version): | 490 current_version): |
| 479 # Get the required directories for the upcoming operations. | 491 # Get the required directories for the upcoming operations. |
| 480 chrome_dir = os.path.join(staging_dir, CHROME_DIR) | 492 chrome_dir = os.path.join(staging_dir, CHROME_DIR) |
| 481 version_dir = os.path.join(chrome_dir, current_version) | 493 version_dir = os.path.join(chrome_dir, current_version) |
| 482 installer_dir = os.path.join(version_dir, 'Installer') | |
| 483 # |installer_dir| is technically only created post-install, but we need it | |
| 484 # now to add setup.exe's config and manifest to the archive. | |
| 485 if not os.path.exists(installer_dir): | |
| 486 os.mkdir(installer_dir) | |
| 487 | 494 |
| 488 if setup_runtime_deps: | 495 CopySetupRuntimeDeps(build_dir, setup_runtime_deps, version_dir) |
| 489 setup_component_dlls = ParseDLLsFromDeps(build_dir, setup_runtime_deps) | |
| 490 else: | |
| 491 # Explicitly list the component DLLs setup.exe depends on (this list may | |
| 492 # contain wildcards). These will be copied to |installer_dir| in the | |
| 493 # archive. | |
| 494 # TODO(jbauman): Remove when GYP is deprecated on Windows. | |
|
grt (UTC plus 2)
2016/12/09 08:30:54
w00t!
gab
2016/12/09 19:23:24
@grt: re. does setup.exe use the version manifest
| |
| 495 setup_component_dll_globs = [ 'api-ms-win-*.dll', | |
| 496 'base.dll', | |
| 497 'boringssl.dll', | |
| 498 'crcrypto.dll', | |
| 499 'icui18n.dll', | |
| 500 'icuuc.dll', | |
| 501 'msvc*.dll', | |
| 502 'ucrtbase*.dll', | |
| 503 'vcruntime*.dll', ] | |
| 504 setup_component_dlls = set() | |
| 505 for setup_component_dll_glob in setup_component_dll_globs: | |
| 506 setup_component_partial_dlls = glob.glob( | |
| 507 os.path.join(build_dir, setup_component_dll_glob)) | |
| 508 if len(setup_component_partial_dlls) == 0: | |
| 509 raise Exception('Error: missing expected DLL for component build ' | |
| 510 'mini_installer: "%s"' % setup_component_dll_glob) | |
| 511 setup_component_dlls.update(setup_component_partial_dlls) | |
| 512 for setup_component_dll in setup_component_dlls: | |
| 513 g_archive_inputs.append(setup_component_dll) | |
| 514 shutil.copy(setup_component_dll, installer_dir) | |
| 515 | 496 |
| 516 # Stage all the component DLLs to the |version_dir| (for | 497 # Stage all the component DLLs to the |version_dir| (for |
| 517 # the version assembly to be able to refer to them below and make sure | 498 # the version assembly to be able to refer to them below and make sure |
| 518 # chrome.exe can find them at runtime), except the ones that are already | 499 # chrome.exe can find them at runtime), except the ones that are already |
| 519 # staged (i.e. non-component DLLs). | 500 # staged (i.e. non-component DLLs). |
| 520 if chrome_runtime_deps: | 501 if chrome_runtime_deps: |
| 521 build_dlls = ParseDLLsFromDeps(build_dir, chrome_runtime_deps) | 502 build_dlls = ParseDLLsFromDeps(build_dir, chrome_runtime_deps) |
| 522 else: | 503 else: |
| 523 # If no chrome_runtime_deps was specified, every DLL in build_dir is | 504 # If no chrome_runtime_deps was specified, every DLL in build_dir is |
| 524 # considered to be a component DLL. | 505 # considered to be a component DLL. |
| 525 # TODO(jbauman): Remove when GYP is deprecated on Windows. | 506 # TODO(jbauman): Remove when GYP is deprecated on Windows. |
|
gab
2016/12/09 19:23:24
While you're here, also resolve this? :)
gab
2016/12/09 19:24:46
Actually, cleaning up the post GYP era is slightly
gab
2016/12/12 16:20:00
FYI, jbauman took care of this in https://coderevi
grt (UTC plus 2)
2016/12/12 20:12:32
Thanks, Gab!
| |
| 526 build_dlls = glob.glob(os.path.join(build_dir, '*.dll')) | 507 build_dlls = glob.glob(os.path.join(build_dir, '*.dll')) |
| 527 staged_dll_basenames = [os.path.basename(staged_dll) for staged_dll in \ | 508 staged_dll_basenames = [os.path.basename(staged_dll) for staged_dll in \ |
| 528 glob.glob(os.path.join(version_dir, '*.dll'))] | 509 glob.glob(os.path.join(version_dir, '*.dll'))] |
| 529 component_dll_filenames = [] | 510 component_dll_filenames = [] |
| 530 for component_dll in [dll for dll in build_dlls if \ | 511 for component_dll in [dll for dll in build_dlls if \ |
| 531 os.path.basename(dll) not in staged_dll_basenames]: | 512 os.path.basename(dll) not in staged_dll_basenames]: |
| 532 component_dll_name = os.path.basename(component_dll) | 513 component_dll_name = os.path.basename(component_dll) |
| 533 # These remoting_*.dll's don't belong in the archive (it doesn't depend | 514 # These remoting_*.dll's don't belong in the archive (it doesn't depend |
| 534 # on them in gyp). Trying to copy them causes a build race when creating the | 515 # on them in gyp). Trying to copy them causes a build race when creating the |
| 535 # installer archive in component mode. See: crbug.com/180996 and | 516 # installer archive in component mode. See: crbug.com/180996 and |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 577 | 558 |
| 578 # Now copy the remainder of the files from the build dir. | 559 # Now copy the remainder of the files from the build dir. |
| 579 CopyAllFilesToStagingDir(config, options.distribution, | 560 CopyAllFilesToStagingDir(config, options.distribution, |
| 580 staging_dir, options.build_dir, | 561 staging_dir, options.build_dir, |
| 581 options.enable_hidpi) | 562 options.enable_hidpi) |
| 582 | 563 |
| 583 if options.component_build == '1': | 564 if options.component_build == '1': |
| 584 DoComponentBuildTasks(staging_dir, options.build_dir, | 565 DoComponentBuildTasks(staging_dir, options.build_dir, |
| 585 options.target_arch, options.setup_runtime_deps, | 566 options.target_arch, options.setup_runtime_deps, |
| 586 options.chrome_runtime_deps, current_version) | 567 options.chrome_runtime_deps, current_version) |
| 568 elif options.setup_runtime_deps: | |
| 569 CopySetupRuntimeDeps(options.build_dir, options.setup_runtime_deps, | |
| 570 os.path.join(staging_dir, CHROME_DIR, current_version)) | |
| 587 | 571 |
| 588 version_numbers = current_version.split('.') | 572 version_numbers = current_version.split('.') |
| 589 current_build_number = version_numbers[2] + '.' + version_numbers[3] | 573 current_build_number = version_numbers[2] + '.' + version_numbers[3] |
| 590 prev_build_number = '' | 574 prev_build_number = '' |
| 591 if prev_version: | 575 if prev_version: |
| 592 version_numbers = prev_version.split('.') | 576 version_numbers = prev_version.split('.') |
| 593 prev_build_number = version_numbers[2] + '.' + version_numbers[3] | 577 prev_build_number = version_numbers[2] + '.' + version_numbers[3] |
| 594 | 578 |
| 595 # Name of the archive file built (for example - chrome.7z or | 579 # Name of the archive file built (for example - chrome.7z or |
| 596 # patch-<old_version>-<new_version>.7z or patch-<new_version>.7z | 580 # patch-<old_version>-<new_version>.7z or patch-<new_version>.7z |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 682 MINI_INSTALLER_INPUT_FILE) | 666 MINI_INSTALLER_INPUT_FILE) |
| 683 | 667 |
| 684 return options | 668 return options |
| 685 | 669 |
| 686 | 670 |
| 687 if '__main__' == __name__: | 671 if '__main__' == __name__: |
| 688 options = _ParseOptions() | 672 options = _ParseOptions() |
| 689 if options.verbose: | 673 if options.verbose: |
| 690 print sys.argv | 674 print sys.argv |
| 691 sys.exit(main(options)) | 675 sys.exit(main(options)) |
| OLD | NEW |