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

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

Issue 887673003: Add support for create_installer_archive.py to generate a depfile (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixes for component mode Created 5 years, 10 months 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
« no previous file with comments | « chrome/installer/mini_installer.gyp ('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 24 matching lines...) Expand all
35 COMPRESSED_FILE_EXT = ".packed.7z" # extension of patch archive file 35 COMPRESSED_FILE_EXT = ".packed.7z" # extension of patch archive file
36 COURGETTE_EXEC = "courgette.exe" 36 COURGETTE_EXEC = "courgette.exe"
37 MINI_INSTALLER_INPUT_FILE = "packed_files.txt" 37 MINI_INSTALLER_INPUT_FILE = "packed_files.txt"
38 PATCH_FILE_EXT = '.diff' 38 PATCH_FILE_EXT = '.diff'
39 SETUP_EXEC = "setup.exe" 39 SETUP_EXEC = "setup.exe"
40 SETUP_PATCH_FILE_PREFIX = "setup_patch" 40 SETUP_PATCH_FILE_PREFIX = "setup_patch"
41 TEMP_ARCHIVE_DIR = "temp_installer_archive" 41 TEMP_ARCHIVE_DIR = "temp_installer_archive"
42 VERSION_FILE = "VERSION" 42 VERSION_FILE = "VERSION"
43 43
44 44
45 g_archive_inputs = []
46
47
45 def BuildVersion(build_dir): 48 def BuildVersion(build_dir):
46 """Returns the full build version string constructed from information in 49 """Returns the full build version string constructed from information in
47 VERSION_FILE. Any segment not found in that file will default to '0'. 50 VERSION_FILE. Any segment not found in that file will default to '0'.
48 """ 51 """
49 major = 0 52 major = 0
50 minor = 0 53 minor = 0
51 build = 0 54 build = 0
52 patch = 0 55 patch = 0
53 for line in open(os.path.join(build_dir, '../../chrome', VERSION_FILE), 'r'): 56 for line in open(os.path.join(build_dir, '../../chrome', VERSION_FILE), 'r'):
54 line = line.rstrip() 57 line = line.rstrip()
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 if option.endswith('dir'): 117 if option.endswith('dir'):
115 continue 118 continue
116 119
117 dst_dir = os.path.join(staging_dir, config.get(section, option)) 120 dst_dir = os.path.join(staging_dir, config.get(section, option))
118 src_paths = glob.glob(os.path.join(src_dir, option)) 121 src_paths = glob.glob(os.path.join(src_dir, option))
119 if src_paths and not os.path.exists(dst_dir): 122 if src_paths and not os.path.exists(dst_dir):
120 os.makedirs(dst_dir) 123 os.makedirs(dst_dir)
121 for src_path in src_paths: 124 for src_path in src_paths:
122 dst_path = os.path.join(dst_dir, os.path.basename(src_path)) 125 dst_path = os.path.join(dst_dir, os.path.basename(src_path))
123 if not os.path.exists(dst_path): 126 if not os.path.exists(dst_path):
127 g_archive_inputs.append(src_path)
124 shutil.copy(src_path, dst_dir) 128 shutil.copy(src_path, dst_dir)
125 129
126 def GenerateDiffPatch(options, orig_file, new_file, patch_file): 130 def GenerateDiffPatch(options, orig_file, new_file, patch_file):
127 if (options.diff_algorithm == "COURGETTE"): 131 if (options.diff_algorithm == "COURGETTE"):
128 exe_file = os.path.join(options.last_chrome_installer, COURGETTE_EXEC) 132 exe_file = os.path.join(options.last_chrome_installer, COURGETTE_EXEC)
129 cmd = '%s -gen "%s" "%s" "%s"' % (exe_file, orig_file, new_file, patch_file) 133 cmd = '%s -gen "%s" "%s" "%s"' % (exe_file, orig_file, new_file, patch_file)
130 else: 134 else:
131 exe_file = os.path.join(options.build_dir, BSDIFF_EXEC) 135 exe_file = os.path.join(options.build_dir, BSDIFF_EXEC)
132 cmd = [exe_file, orig_file, new_file, patch_file,] 136 cmd = [exe_file, orig_file, new_file, patch_file,]
133 RunSystemCommand(cmd) 137 RunSystemCommand(cmd)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 raise Exception("Error while running cmd: %s, exit_code: %s" % 191 raise Exception("Error while running cmd: %s, exit_code: %s" %
188 (cmd, exit_code)) 192 (cmd, exit_code))
189 193
190 def CreateArchiveFile(options, staging_dir, current_version, prev_version): 194 def CreateArchiveFile(options, staging_dir, current_version, prev_version):
191 """Creates a new installer archive file after deleting any existing old file. 195 """Creates a new installer archive file after deleting any existing old file.
192 """ 196 """
193 # First create an uncompressed archive file for the current build (chrome.7z) 197 # First create an uncompressed archive file for the current build (chrome.7z)
194 lzma_exec = GetLZMAExec(options.build_dir) 198 lzma_exec = GetLZMAExec(options.build_dir)
195 archive_file = os.path.join(options.output_dir, 199 archive_file = os.path.join(options.output_dir,
196 options.output_name + ARCHIVE_SUFFIX) 200 options.output_name + ARCHIVE_SUFFIX)
201 if options.depfile:
202 # If a depfile was requested, do the glob of the staging dir and generate
203 # a list of dependencies in .d format. We list the files that were copied
204 # into the staging dir, not the files that are actually in the staging dir
205 # because the ones in the staging dir will never be edited, and we want
206 # to have the build be triggered when the thing-that-was-copied-there
207 # changes.
208
209 def path_fixup(path):
210 """Fixes path for depfile format: backslash to forward slash, and
211 backslash escaping for spaces."""
212 return path.replace('\\', '/').replace(' ', '\\ ')
213
214 # Gather the list of files in the staging dir that will be zipped up. We
215 # only gather this list to make sure that g_archive_inputs is complete (i.e.
216 # that there's not file copies that got missed).
217 staging_contents = []
218 for root, dirs, files in os.walk(os.path.join(staging_dir, CHROME_DIR)):
219 for filename in files:
220 staging_contents.append(path_fixup(os.path.join(root, filename)))
221
222 # Make sure there's an archive_input for each staging dir file.
223 for staging_file in staging_contents:
224 for archive_input in g_archive_inputs:
225 archive_rel = path_fixup(archive_input)
226 if (os.path.basename(staging_file).lower() ==
227 os.path.basename(archive_rel).lower()):
228 break
229 else:
230 raise Exception('Did not find an archive input file for "%s"' %
231 staging_file)
232
233 # Finally, write the depfile referencing the inputs.
234 with open(options.depfile, 'wb') as f:
235 f.write(path_fixup(os.path.relpath(archive_file, options.build_dir)) +
236 ': \\\n')
237 f.write(' ' + ' \\\n '.join(path_fixup(x) for x in g_archive_inputs))
238
197 cmd = [lzma_exec, 239 cmd = [lzma_exec,
198 'a', 240 'a',
199 '-t7z', 241 '-t7z',
200 archive_file, 242 archive_file,
201 os.path.join(staging_dir, CHROME_DIR), 243 os.path.join(staging_dir, CHROME_DIR),
202 '-mx0',] 244 '-mx0',]
203 # There doesnt seem to be any way in 7za.exe to override existing file so 245 # There doesnt seem to be any way in 7za.exe to override existing file so
204 # we always delete before creating a new one. 246 # we always delete before creating a new one.
205 if not os.path.exists(archive_file): 247 if not os.path.exists(archive_file):
206 RunSystemCommand(cmd) 248 RunSystemCommand(cmd)
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 f.write(''.join(manifest_lines)) 385 f.write(''.join(manifest_lines))
344 386
345 387
346 def CopyIfChanged(src, target_dir): 388 def CopyIfChanged(src, target_dir):
347 """Copy specified |src| file to |target_dir|, but only write to target if 389 """Copy specified |src| file to |target_dir|, but only write to target if
348 the file has changed. This avoids a problem during packaging where parts of 390 the file has changed. This avoids a problem during packaging where parts of
349 the build have not completed and have the runtime DLL locked when we try to 391 the build have not completed and have the runtime DLL locked when we try to
350 copy over it. See http://crbug.com/305877 for details.""" 392 copy over it. See http://crbug.com/305877 for details."""
351 assert os.path.isdir(target_dir) 393 assert os.path.isdir(target_dir)
352 dest = os.path.join(target_dir, os.path.basename(src)) 394 dest = os.path.join(target_dir, os.path.basename(src))
395 g_archive_inputs.append(src)
353 if os.path.exists(dest): 396 if os.path.exists(dest):
354 # We assume the files are OK to buffer fully into memory since we know 397 # We assume the files are OK to buffer fully into memory since we know
355 # they're only 1-2M. 398 # they're only 1-2M.
356 with open(src, 'rb') as fsrc: 399 with open(src, 'rb') as fsrc:
357 src_data = fsrc.read() 400 src_data = fsrc.read()
358 with open(dest, 'rb') as fdest: 401 with open(dest, 'rb') as fdest:
359 dest_data = fdest.read() 402 dest_data = fdest.read()
360 if src_data != dest_data: 403 if src_data != dest_data:
361 # This may still raise if we get here, but this really should almost 404 # This may still raise if we get here, but this really should almost
362 # never happen (it would mean that the contents of e.g. msvcr100d.dll 405 # never happen (it would mean that the contents of e.g. msvcr100d.dll
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 setup_component_dll_globs = [ 'base.dll', 487 setup_component_dll_globs = [ 'base.dll',
445 'boringssl.dll', 488 'boringssl.dll',
446 'crcrypto.dll', 489 'crcrypto.dll',
447 'icui18n.dll', 490 'icui18n.dll',
448 'icuuc.dll', 491 'icuuc.dll',
449 'msvc*.dll' ] 492 'msvc*.dll' ]
450 for setup_component_dll_glob in setup_component_dll_globs: 493 for setup_component_dll_glob in setup_component_dll_globs:
451 setup_component_dlls = glob.glob(os.path.join(build_dir, 494 setup_component_dlls = glob.glob(os.path.join(build_dir,
452 setup_component_dll_glob)) 495 setup_component_dll_glob))
453 for setup_component_dll in setup_component_dlls: 496 for setup_component_dll in setup_component_dlls:
497 g_archive_inputs.append(setup_component_dll)
454 shutil.copy(setup_component_dll, installer_dir) 498 shutil.copy(setup_component_dll, installer_dir)
455 499
456 # Stage all the component DLLs found in |build_dir| to the |version_dir| (for 500 # Stage all the component DLLs found in |build_dir| to the |version_dir| (for
457 # the version assembly to be able to refer to them below and make sure 501 # the version assembly to be able to refer to them below and make sure
458 # chrome.exe can find them at runtime). The component DLLs are considered to 502 # chrome.exe can find them at runtime). The component DLLs are considered to
459 # be all the DLLs which have not already been added to the |version_dir| by 503 # be all the DLLs which have not already been added to the |version_dir| by
460 # virtue of chrome.release. 504 # virtue of chrome.release.
461 build_dlls = glob.glob(os.path.join(build_dir, '*.dll')) 505 build_dlls = glob.glob(os.path.join(build_dir, '*.dll'))
462 staged_dll_basenames = [os.path.basename(staged_dll) for staged_dll in \ 506 staged_dll_basenames = [os.path.basename(staged_dll) for staged_dll in \
463 glob.glob(os.path.join(version_dir, '*.dll'))] 507 glob.glob(os.path.join(version_dir, '*.dll'))]
464 component_dll_filenames = [] 508 component_dll_filenames = []
465 for component_dll in [dll for dll in build_dlls if \ 509 for component_dll in [dll for dll in build_dlls if \
466 os.path.basename(dll) not in staged_dll_basenames]: 510 os.path.basename(dll) not in staged_dll_basenames]:
467 component_dll_name = os.path.basename(component_dll) 511 component_dll_name = os.path.basename(component_dll)
468 # remoting_*.dll's don't belong in the archive (it doesn't depend on them 512 # remoting_*.dll's don't belong in the archive (it doesn't depend on them
469 # in gyp). Trying to copy them causes a build race when creating the 513 # in gyp). Trying to copy them causes a build race when creating the
470 # installer archive in component mode. See: crbug.com/180996 514 # installer archive in component mode. See: crbug.com/180996
471 if component_dll_name.startswith('remoting_'): 515 if component_dll_name.startswith('remoting_'):
472 continue 516 continue
473 component_dll_filenames.append(component_dll_name) 517 component_dll_filenames.append(component_dll_name)
518 g_archive_inputs.append(component_dll)
474 shutil.copy(component_dll, version_dir) 519 shutil.copy(component_dll, version_dir)
475 520
476 # Augment {version}.manifest to include all component DLLs as part of the 521 # Augment {version}.manifest to include all component DLLs as part of the
477 # assembly it constitutes, which will allow dependents of this assembly to 522 # assembly it constitutes, which will allow dependents of this assembly to
478 # find these DLLs. 523 # find these DLLs.
479 version_assembly_dll_additions = [] 524 version_assembly_dll_additions = []
480 for dll_filename in component_dll_filenames: 525 for dll_filename in component_dll_filenames:
481 version_assembly_dll_additions.append(" <file name='%s'/>" % dll_filename) 526 version_assembly_dll_additions.append(" <file name='%s'/>" % dll_filename)
482 CopyAndAugmentManifest(build_dir, version_dir, 527 CopyAndAugmentManifest(build_dir, version_dir,
483 '%s.manifest' % current_version, 528 '%s.manifest' % current_version,
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 help='Diff algorithm to use when generating differential patches ' 612 help='Diff algorithm to use when generating differential patches '
568 '{BSDIFF|COURGETTE}.') 613 '{BSDIFF|COURGETTE}.')
569 parser.add_option('-n', '--output_name', default='chrome', 614 parser.add_option('-n', '--output_name', default='chrome',
570 help='Name used to prefix names of generated archives.') 615 help='Name used to prefix names of generated archives.')
571 parser.add_option('--enable_hidpi', default='0', 616 parser.add_option('--enable_hidpi', default='0',
572 help='Whether to include HiDPI resource files.') 617 help='Whether to include HiDPI resource files.')
573 parser.add_option('--component_build', default='0', 618 parser.add_option('--component_build', default='0',
574 help='Whether this archive is packaging a component build. This will ' 619 help='Whether this archive is packaging a component build. This will '
575 'also turn off compression of chrome.7z into chrome.packed.7z and ' 620 'also turn off compression of chrome.7z into chrome.packed.7z and '
576 'helpfully delete any old chrome.packed.7z in |output_dir|.') 621 'helpfully delete any old chrome.packed.7z in |output_dir|.')
622 parser.add_option('--depfile',
623 help='Generate a depfile with the given name listing the implicit inputs '
624 'to the archive process that can be used with a build system.')
577 parser.add_option('--target_arch', default='x86', 625 parser.add_option('--target_arch', default='x86',
578 help='Specify the target architecture for installer - this is used ' 626 help='Specify the target architecture for installer - this is used '
579 'to determine which CRT runtime files to pull and package ' 627 'to determine which CRT runtime files to pull and package '
580 'with the installer archive {x86|x64}.') 628 'with the installer archive {x86|x64}.')
581 629
582 options, _ = parser.parse_args() 630 options, _ = parser.parse_args()
583 if not options.build_dir: 631 if not options.build_dir:
584 parser.error('You must provide a build dir.') 632 parser.error('You must provide a build dir.')
585 633
586 options.build_dir = os.path.normpath(options.build_dir) 634 options.build_dir = os.path.normpath(options.build_dir)
(...skipping 10 matching lines...) Expand all
597 if not options.resource_file_path: 645 if not options.resource_file_path:
598 options.resource_file_path = os.path.join(options.build_dir, 646 options.resource_file_path = os.path.join(options.build_dir,
599 MINI_INSTALLER_INPUT_FILE) 647 MINI_INSTALLER_INPUT_FILE)
600 648
601 return options 649 return options
602 650
603 651
604 if '__main__' == __name__: 652 if '__main__' == __name__:
605 print sys.argv 653 print sys.argv
606 sys.exit(main(_ParseOptions())) 654 sys.exit(main(_ParseOptions()))
OLDNEW
« no previous file with comments | « chrome/installer/mini_installer.gyp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698