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

Side by Side Diff: chrome/tools/build/win/create_installer_archive.py

Issue 63153013: Have the component build use the same manifest tricks for the installer archive that are now used b… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: remove print Created 7 years, 1 month 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
« no previous file with comments | « chrome/installer/setup/install_worker.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 manifest_file = open(os.path.join(build_dir, manifest_name), 'r') 328 with open(os.path.join(build_dir, manifest_name), 'r') as manifest_file:
329 manifest_lines = manifest_file.readlines() 329 manifest_lines = manifest_file.readlines()
330 manifest_file.close()
331 330
332 insert_line = -1 331 insert_line = -1
333 insert_pos = -1 332 insert_pos = -1
334 for i in xrange(len(manifest_lines)): 333 for i in xrange(len(manifest_lines)):
335 insert_pos = manifest_lines[i].find(insert_before) 334 insert_pos = manifest_lines[i].find(insert_before)
336 if insert_pos != -1: 335 if insert_pos != -1:
337 insert_line = i 336 insert_line = i
338 break 337 break
339 if insert_line == -1: 338 if insert_line == -1:
340 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(
341 insert_before, ''.join(manifest_lines))) 340 insert_before, ''.join(manifest_lines)))
342 old = manifest_lines[insert_line] 341 old = manifest_lines[insert_line]
343 manifest_lines[insert_line] = (old[:insert_pos] + inserted_string + 342 manifest_lines[insert_line] = (old[:insert_pos] + '\n' + inserted_string +
344 old[insert_pos:]) 343 '\n' + old[insert_pos:])
345 344
346 modified_manifest_file = open( 345 with open(os.path.join(output_dir, manifest_name),
347 os.path.join(output_dir, manifest_name), 'w') 346 'w') as modified_manifest_file :
grt (UTC plus 2) 2013/11/15 17:26:24 minor nit: i think it's okay to use "f" or "file"
gab 2013/11/15 21:18:52 Done.
348 modified_manifest_file.write(''.join(manifest_lines)) 347 modified_manifest_file.write(''.join(manifest_lines))
349 modified_manifest_file.close()
350 348
351 349
352 def CopyIfChanged(src, target_dir): 350 def CopyIfChanged(src, target_dir):
353 """Copy specified |src| file to |target_dir|, but only write to target if 351 """Copy specified |src| file to |target_dir|, but only write to target if
354 the file has changed. This avoids a problem during packaging where parts of 352 the file has changed. This avoids a problem during packaging where parts of
355 the build have not completed and have the runtime DLL locked when we try to 353 the build have not completed and have the runtime DLL locked when we try to
356 copy over it. See http://crbug.com/305877 for details.""" 354 copy over it. See http://crbug.com/305877 for details."""
357 assert os.path.isdir(target_dir) 355 assert os.path.isdir(target_dir)
358 dest = os.path.join(target_dir, os.path.basename(src)) 356 dest = os.path.join(target_dir, os.path.basename(src))
359 if os.path.exists(dest): 357 if os.path.exists(dest):
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 # |installer_dir| is technically only created post-install, but we need it 436 # |installer_dir| is technically only created post-install, but we need it
439 # now to add setup.exe's config and manifest to the archive. 437 # now to add setup.exe's config and manifest to the archive.
440 if not os.path.exists(installer_dir): 438 if not os.path.exists(installer_dir):
441 os.mkdir(installer_dir) 439 os.mkdir(installer_dir)
442 440
443 # Copy the VS CRT DLLs to |build_dir|. This must be done before the general 441 # Copy the VS CRT DLLs to |build_dir|. This must be done before the general
444 # copy step below to ensure the CRT DLLs are added to the archive and marked 442 # copy step below to ensure the CRT DLLs are added to the archive and marked
445 # as a dependency in the exe manifests generated below. 443 # as a dependency in the exe manifests generated below.
446 CopyVisualStudioRuntimeDLLs(build_dir, target_arch) 444 CopyVisualStudioRuntimeDLLs(build_dir, target_arch)
447 445
448 # Copy all the DLLs in |build_dir| to the version directory. Simultaneously 446 # Stage all the component DLLs found in |build_dir|. These are all the DLLs
449 # build a list of their names to mark them as dependencies of chrome.exe and 447 # which have not already been added to the staged |version_dir| by virtue of
450 # setup.exe later. 448 # chrome.release.
451 dlls = glob.glob(os.path.join(build_dir, '*.dll')) 449 build_dlls = glob.glob(os.path.join(build_dir, '*.dll'))
452 dll_names = [] 450 staged_dll_basenames = [os.path.basename(staged_dll) for staged_dll in \
453 for dll in dlls: 451 glob.glob(os.path.join(version_dir, '*.dll'))]
Mathieu 2013/11/18 19:10:06 nit: you can de-indent by 4
gab 2013/11/18 20:37:16 Done.
452 component_dll_filenames = []
453 for component_dll in [dll for dll in build_dlls if \
454 os.path.basename(dll) not in staged_dll_basenames]:
Mathieu 2013/11/18 19:10:06 nit: same here
gab 2013/11/18 20:37:16 Done.
454 # remoting_*.dll's don't belong in the archive (it doesn't depend on them 455 # remoting_*.dll's don't belong in the archive (it doesn't depend on them
455 # in gyp). Trying to copy them causes a build race when creating the 456 # in gyp). Trying to copy them causes a build race when creating the
456 # installer archive in component mode. See: crbug.com/180996 457 # installer archive in component mode. See: crbug.com/180996
457 if os.path.basename(dll).startswith('remoting_'): 458 if os.path.basename(component_dll).startswith('remoting_'):
458 continue 459 continue
459 shutil.copy(dll, version_dir) 460 # Copy them to the version_dir (for the version assembly to be able to refer
460 dll_names.append(os.path.splitext(os.path.basename(dll))[0]) 461 # to them below and thus for chrome.exe to be able to load them at runtime).
462 shutil.copy(component_dll, version_dir)
463 # 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
465 # DLLs).
466 # TODO(gab): This makes the archive ~278MB instead of ~185MB; consider
467 # copying the DLLs over from the installer.
468 shutil.copy(component_dll, installer_dir)
469 component_dll_filenames.append(os.path.basename(component_dll))
461 470
462 exe_config = ( 471 # Copy chrome.exe.manifest as-is. It is required, among other things, to
463 "<configuration>\n" 472 # declare a dependency on the version dir assembly.
464 " <windows>\n" 473 shutil.copy(os.path.join(build_dir, 'chrome.exe.manifest'), chrome_dir)
465 " <assemblyBinding xmlns='urn:schemas-microsoft-com:asm.v1'>\n"
466 " <probing privatePath='{rel_path}'/>\n"
467 " </assemblyBinding>\n"
468 " </windows>\n"
469 "</configuration>")
470 474
471 # Write chrome.exe.config to point to the version directory. 475 # Also copy setup.exe.manifest as-is. It is required, among other things, to
472 chrome_exe_config_file = open( 476 # let setup.exe UAC when it wants to, by specifying that it handles elevation
473 os.path.join(chrome_dir, 'chrome.exe.config'), 'w') 477 # "asInvoker", rather than have Windows auto-elevate it when launched.
474 chrome_exe_config_file.write(exe_config.format(rel_path=current_version)) 478 shutil.copy(os.path.join(build_dir, 'setup.exe.manifest'), installer_dir)
475 chrome_exe_config_file.close()
476 479
477 # Write setup.exe.config to point to the version directory (which is one 480 # Augment {version}.manifest to include all component DLLs as part of the
478 # level up from setup.exe post-install). 481 # assembly it constitutes which will allow dependents of this assembly to
Sigurður Ásgeirsson 2013/11/15 18:31:12 nit: constitutes, which
gab 2013/11/15 21:18:52 Done.
479 setup_exe_config_file = open( 482 # find these DLLs.
480 os.path.join(installer_dir, 'setup.exe.config'), 'w') 483 version_assembly_dll_additions = []
481 setup_exe_config_file.write(exe_config.format(rel_path='..')) 484 for dll_filename in component_dll_filenames:
482 setup_exe_config_file.close() 485 version_assembly_dll_additions.append(
483 486 " <file name='{dll_filename}'/>".format(dll_filename=dll_filename))
Sigurður Ásgeirsson 2013/11/15 18:31:12 nit: this is a fairly long-winded way to say " <
gab 2013/11/15 21:18:52 Done.
484 # Add a dependency for each DLL in |dlls| to the existing manifests for 487 CopyAndAugmentManifest(build_dir, version_dir,
485 # chrome.exe and setup.exe. Some of these DLLs are not actually used by 488 '{version}.manifest'.format(version=current_version),
486 # either process, but listing them all as dependencies doesn't hurt as it 489 '\n'.join(version_assembly_dll_additions),
487 # only makes them visible to the exes, just like they already are in the 490 '</assembly>')
488 # build output directory.
489 exe_manifest_dependencies_list = []
490 for name in dll_names:
491 exe_manifest_dependencies_list.append(
492 "<dependency>"
493 "<dependentAssembly>"
494 "<assemblyIdentity type='win32' name='chrome.{dll_name}' "
495 "version='0.0.0.0' language='*'/>"
496 "</dependentAssembly>"
497 "</dependency>".format(dll_name=name))
498
499 exe_manifest_dependencies = ''.join(exe_manifest_dependencies_list)
500
501 # Write a modified chrome.exe.manifest beside chrome.exe.
502 CopyAndAugmentManifest(build_dir, chrome_dir, 'chrome.exe.manifest',
503 exe_manifest_dependencies, '</assembly>')
504
505 # Write a modified setup.exe.manifest beside setup.exe in
506 # |version_dir|/Installer.
507 CopyAndAugmentManifest(build_dir, installer_dir, 'setup.exe.manifest',
508 exe_manifest_dependencies, '</assembly>')
509
510 # Generate assembly manifests for each DLL in |dlls|. These do not interfere
511 # with the private manifests potentially embedded in each DLL. They simply
512 # allow chrome.exe and setup.exe to see those DLLs although they are in a
513 # separate directory post-install.
514 for name in dll_names:
515 dll_manifest = (
516 "<assembly\n"
517 " xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>\n"
518 " <assemblyIdentity name='chrome.{dll_name}' version='0.0.0.0'\n"
519 " type='win32'/>\n"
520 " <file name='{dll_name}.dll'/>\n"
521 "</assembly>".format(dll_name=name))
522
523 dll_manifest_file = open(os.path.join(
524 version_dir, "chrome.{dll_name}.manifest".format(dll_name=name)), 'w')
525 dll_manifest_file.write(dll_manifest)
526 dll_manifest_file.close()
527 491
528 492
529 def main(options): 493 def main(options):
530 """Main method that reads input file, creates archive file and write 494 """Main method that reads input file, creates archive file and write
531 resource input file. 495 resource input file.
532 """ 496 """
533 current_version = BuildVersion(options.build_dir) 497 current_version = BuildVersion(options.build_dir)
534 498
535 config = Readconfig(options.input_file, current_version) 499 config = Readconfig(options.input_file, current_version)
536 500
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 if not options.resource_file_path: 603 if not options.resource_file_path:
640 options.resource_file_path = os.path.join(options.build_dir, 604 options.resource_file_path = os.path.join(options.build_dir,
641 MINI_INSTALLER_INPUT_FILE) 605 MINI_INSTALLER_INPUT_FILE)
642 606
643 return options 607 return options
644 608
645 609
646 if '__main__' == __name__: 610 if '__main__' == __name__:
647 print sys.argv 611 print sys.argv
648 sys.exit(main(_ParseOptions())) 612 sys.exit(main(_ParseOptions()))
OLDNEW
« no previous file with comments | « chrome/installer/setup/install_worker.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698