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

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: 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
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 # Gather the list of files in the staging dir that will be zipped up. We
210 # only gather this list to make sure that g_archive_inputs is complete (i.e.
211 # that there's not file copies that got missed).
212 staging_contents = []
213 for root, dirs, files in os.walk(os.path.join(staging_dir, CHROME_DIR)):
214 for filename in files:
215 staging_contents.append(
216 os.path.relpath(os.path.join(root, filename), options.build_dir)
217 .replace('\\', '/'))
218
219 # Make sure there's an archive_input for each staging dir file.
220 for staging_file in staging_contents:
221 for archive_input in g_archive_inputs:
222 archive_rel = (os.path.relpath(archive_input, options.build_dir)
223 .replace('\\', '/'))
224 if staging_file.lower().endswith('/' + archive_rel.lower()):
225 break
226 else:
227 raise Exception('Did not find an archive input file for "%s"' %
228 staging_file)
229
230 # Finally, write the depfile referencing the inputs.
231 with open(options.depfile, 'wb') as f:
232 f.write(os.path.relpath(archive_file, options.build_dir)
233 .replace('\\', '/') + ': \\\n')
234 f.write(' ' +
235 ' \\\n '.join(x.replace('\\', '/') for x in g_archive_inputs))
236
197 cmd = [lzma_exec, 237 cmd = [lzma_exec,
198 'a', 238 'a',
199 '-t7z', 239 '-t7z',
200 archive_file, 240 archive_file,
201 os.path.join(staging_dir, CHROME_DIR), 241 os.path.join(staging_dir, CHROME_DIR),
202 '-mx0',] 242 '-mx0',]
203 # There doesnt seem to be any way in 7za.exe to override existing file so 243 # There doesnt seem to be any way in 7za.exe to override existing file so
204 # we always delete before creating a new one. 244 # we always delete before creating a new one.
205 if not os.path.exists(archive_file): 245 if not os.path.exists(archive_file):
206 RunSystemCommand(cmd) 246 RunSystemCommand(cmd)
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 f.write(''.join(manifest_lines)) 383 f.write(''.join(manifest_lines))
344 384
345 385
346 def CopyIfChanged(src, target_dir): 386 def CopyIfChanged(src, target_dir):
347 """Copy specified |src| file to |target_dir|, but only write to target if 387 """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 388 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 389 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.""" 390 copy over it. See http://crbug.com/305877 for details."""
351 assert os.path.isdir(target_dir) 391 assert os.path.isdir(target_dir)
352 dest = os.path.join(target_dir, os.path.basename(src)) 392 dest = os.path.join(target_dir, os.path.basename(src))
393 g_archive_inputs.append(src)
353 if os.path.exists(dest): 394 if os.path.exists(dest):
354 # We assume the files are OK to buffer fully into memory since we know 395 # We assume the files are OK to buffer fully into memory since we know
355 # they're only 1-2M. 396 # they're only 1-2M.
356 with open(src, 'rb') as fsrc: 397 with open(src, 'rb') as fsrc:
357 src_data = fsrc.read() 398 src_data = fsrc.read()
358 with open(dest, 'rb') as fdest: 399 with open(dest, 'rb') as fdest:
359 dest_data = fdest.read() 400 dest_data = fdest.read()
360 if src_data != dest_data: 401 if src_data != dest_data:
361 # This may still raise if we get here, but this really should almost 402 # 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 403 # 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', 485 setup_component_dll_globs = [ 'base.dll',
445 'boringssl.dll', 486 'boringssl.dll',
446 'crcrypto.dll', 487 'crcrypto.dll',
447 'icui18n.dll', 488 'icui18n.dll',
448 'icuuc.dll', 489 'icuuc.dll',
449 'msvc*.dll' ] 490 'msvc*.dll' ]
450 for setup_component_dll_glob in setup_component_dll_globs: 491 for setup_component_dll_glob in setup_component_dll_globs:
451 setup_component_dlls = glob.glob(os.path.join(build_dir, 492 setup_component_dlls = glob.glob(os.path.join(build_dir,
452 setup_component_dll_glob)) 493 setup_component_dll_glob))
453 for setup_component_dll in setup_component_dlls: 494 for setup_component_dll in setup_component_dlls:
495 g_archive_inputs.append(setup_component_dlls)
454 shutil.copy(setup_component_dll, installer_dir) 496 shutil.copy(setup_component_dll, installer_dir)
455 497
456 # Stage all the component DLLs found in |build_dir| to the |version_dir| (for 498 # 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 499 # 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 500 # 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 501 # be all the DLLs which have not already been added to the |version_dir| by
460 # virtue of chrome.release. 502 # virtue of chrome.release.
461 build_dlls = glob.glob(os.path.join(build_dir, '*.dll')) 503 build_dlls = glob.glob(os.path.join(build_dir, '*.dll'))
462 staged_dll_basenames = [os.path.basename(staged_dll) for staged_dll in \ 504 staged_dll_basenames = [os.path.basename(staged_dll) for staged_dll in \
463 glob.glob(os.path.join(version_dir, '*.dll'))] 505 glob.glob(os.path.join(version_dir, '*.dll'))]
464 component_dll_filenames = [] 506 component_dll_filenames = []
465 for component_dll in [dll for dll in build_dlls if \ 507 for component_dll in [dll for dll in build_dlls if \
466 os.path.basename(dll) not in staged_dll_basenames]: 508 os.path.basename(dll) not in staged_dll_basenames]:
467 component_dll_name = os.path.basename(component_dll) 509 component_dll_name = os.path.basename(component_dll)
468 # remoting_*.dll's don't belong in the archive (it doesn't depend on them 510 # 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 511 # in gyp). Trying to copy them causes a build race when creating the
470 # installer archive in component mode. See: crbug.com/180996 512 # installer archive in component mode. See: crbug.com/180996
471 if component_dll_name.startswith('remoting_'): 513 if component_dll_name.startswith('remoting_'):
472 continue 514 continue
473 component_dll_filenames.append(component_dll_name) 515 component_dll_filenames.append(component_dll_name)
516 g_archive_inputs.append(component_dll)
474 shutil.copy(component_dll, version_dir) 517 shutil.copy(component_dll, version_dir)
475 518
476 # Augment {version}.manifest to include all component DLLs as part of the 519 # Augment {version}.manifest to include all component DLLs as part of the
477 # assembly it constitutes, which will allow dependents of this assembly to 520 # assembly it constitutes, which will allow dependents of this assembly to
478 # find these DLLs. 521 # find these DLLs.
479 version_assembly_dll_additions = [] 522 version_assembly_dll_additions = []
480 for dll_filename in component_dll_filenames: 523 for dll_filename in component_dll_filenames:
481 version_assembly_dll_additions.append(" <file name='%s'/>" % dll_filename) 524 version_assembly_dll_additions.append(" <file name='%s'/>" % dll_filename)
482 CopyAndAugmentManifest(build_dir, version_dir, 525 CopyAndAugmentManifest(build_dir, version_dir,
483 '%s.manifest' % current_version, 526 '%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 ' 610 help='Diff algorithm to use when generating differential patches '
568 '{BSDIFF|COURGETTE}.') 611 '{BSDIFF|COURGETTE}.')
569 parser.add_option('-n', '--output_name', default='chrome', 612 parser.add_option('-n', '--output_name', default='chrome',
570 help='Name used to prefix names of generated archives.') 613 help='Name used to prefix names of generated archives.')
571 parser.add_option('--enable_hidpi', default='0', 614 parser.add_option('--enable_hidpi', default='0',
572 help='Whether to include HiDPI resource files.') 615 help='Whether to include HiDPI resource files.')
573 parser.add_option('--component_build', default='0', 616 parser.add_option('--component_build', default='0',
574 help='Whether this archive is packaging a component build. This will ' 617 help='Whether this archive is packaging a component build. This will '
575 'also turn off compression of chrome.7z into chrome.packed.7z and ' 618 'also turn off compression of chrome.7z into chrome.packed.7z and '
576 'helpfully delete any old chrome.packed.7z in |output_dir|.') 619 'helpfully delete any old chrome.packed.7z in |output_dir|.')
620 parser.add_option('--depfile',
621 help='Generate a depfile with the given name listing the implicit inputs '
622 'to the archive process that can be used with a build system.')
577 parser.add_option('--target_arch', default='x86', 623 parser.add_option('--target_arch', default='x86',
578 help='Specify the target architecture for installer - this is used ' 624 help='Specify the target architecture for installer - this is used '
579 'to determine which CRT runtime files to pull and package ' 625 'to determine which CRT runtime files to pull and package '
580 'with the installer archive {x86|x64}.') 626 'with the installer archive {x86|x64}.')
581 627
582 options, _ = parser.parse_args() 628 options, _ = parser.parse_args()
583 if not options.build_dir: 629 if not options.build_dir:
584 parser.error('You must provide a build dir.') 630 parser.error('You must provide a build dir.')
585 631
586 options.build_dir = os.path.normpath(options.build_dir) 632 options.build_dir = os.path.normpath(options.build_dir)
(...skipping 10 matching lines...) Expand all
597 if not options.resource_file_path: 643 if not options.resource_file_path:
598 options.resource_file_path = os.path.join(options.build_dir, 644 options.resource_file_path = os.path.join(options.build_dir,
599 MINI_INSTALLER_INPUT_FILE) 645 MINI_INSTALLER_INPUT_FILE)
600 646
601 return options 647 return options
602 648
603 649
604 if '__main__' == __name__: 650 if '__main__' == __name__:
605 print sys.argv 651 print sys.argv
606 sys.exit(main(_ParseOptions())) 652 sys.exit(main(_ParseOptions()))
OLDNEW
« chrome/installer/mini_installer.gyp ('K') | « chrome/installer/mini_installer.gyp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698