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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 59 major = line[6:] | 59 major = line[6:] |
| 60 elif line.startswith('MINOR='): | 60 elif line.startswith('MINOR='): |
| 61 minor = line[6:] | 61 minor = line[6:] |
| 62 elif line.startswith('BUILD='): | 62 elif line.startswith('BUILD='): |
| 63 build = line[6:] | 63 build = line[6:] |
| 64 elif line.startswith('PATCH='): | 64 elif line.startswith('PATCH='): |
| 65 patch = line[6:] | 65 patch = line[6:] |
| 66 return '%s.%s.%s.%s' % (major, minor, build, patch) | 66 return '%s.%s.%s.%s' % (major, minor, build, patch) |
| 67 | 67 |
| 68 | 68 |
| 69 def CompressUsingLZMA(build_dir, compressed_file, input_file): | 69 def CompressUsingLZMA(build_dir, compressed_file, input_file, verbose): |
| 70 lzma_exec = GetLZMAExec(build_dir) | 70 lzma_exec = GetLZMAExec(build_dir) |
| 71 cmd = [lzma_exec, | 71 cmd = [lzma_exec, |
| 72 'a', '-t7z', | 72 'a', '-t7z', |
| 73 # Flags equivalent to -mx9 (ultra) but with the bcj2 turned on (exe | 73 # Flags equivalent to -mx9 (ultra) but with the bcj2 turned on (exe |
| 74 # pre-filter). This results in a ~2.3MB decrease in installer size on | 74 # pre-filter). This results in a ~2.3MB decrease in installer size on |
| 75 # a 24MB installer. | 75 # a 24MB installer. |
| 76 # Additionally, these settings reflect a 7zip 4.42 and up change in | 76 # Additionally, these settings reflect a 7zip 4.42 and up change in |
| 77 # the definition of -mx9, increasting the dicionary size moving to | 77 # the definition of -mx9, increasting the dicionary size moving to |
| 78 # 26bit = 64MB. This results in an additional ~3.5MB decrease. | 78 # 26bit = 64MB. This results in an additional ~3.5MB decrease. |
| 79 # Older 7zip versions can support these settings, as these changes | 79 # Older 7zip versions can support these settings, as these changes |
| 80 # rely on existing functionality in the lzma format. | 80 # rely on existing functionality in the lzma format. |
| 81 '-m0=BCJ2', | 81 '-m0=BCJ2', |
| 82 '-m1=LZMA:d27:fb128', | 82 '-m1=LZMA:d27:fb128', |
| 83 '-m2=LZMA:d22:fb128:mf=bt2', | 83 '-m2=LZMA:d22:fb128:mf=bt2', |
| 84 '-m3=LZMA:d22:fb128:mf=bt2', | 84 '-m3=LZMA:d22:fb128:mf=bt2', |
| 85 '-mb0:1', | 85 '-mb0:1', |
| 86 '-mb0s1:2', | 86 '-mb0s1:2', |
| 87 '-mb0s2:3', | 87 '-mb0s2:3', |
| 88 compressed_file, | 88 compressed_file, |
| 89 input_file,] | 89 input_file,] |
| 90 if os.path.exists(compressed_file): | 90 if os.path.exists(compressed_file): |
| 91 os.remove(compressed_file) | 91 os.remove(compressed_file) |
| 92 RunSystemCommand(cmd) | 92 RunSystemCommand(cmd, verbose) |
| 93 | 93 |
| 94 | 94 |
| 95 def CopyAllFilesToStagingDir(config, distribution, staging_dir, build_dir, | 95 def CopyAllFilesToStagingDir(config, distribution, staging_dir, build_dir, |
| 96 enable_hidpi): | 96 enable_hidpi): |
| 97 """Copies the files required for installer archive. | 97 """Copies the files required for installer archive. |
| 98 Copies all common files required for various distributions of Chromium and | 98 Copies all common files required for various distributions of Chromium and |
| 99 also files for the specific Chromium build specified by distribution. | 99 also files for the specific Chromium build specified by distribution. |
| 100 """ | 100 """ |
| 101 CopySectionFilesToStagingDir(config, 'GENERAL', staging_dir, build_dir) | 101 CopySectionFilesToStagingDir(config, 'GENERAL', staging_dir, build_dir) |
| 102 if distribution: | 102 if distribution: |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 127 g_archive_inputs.append(src_path) | 127 g_archive_inputs.append(src_path) |
| 128 shutil.copy(src_path, dst_dir) | 128 shutil.copy(src_path, dst_dir) |
| 129 | 129 |
| 130 def GenerateDiffPatch(options, orig_file, new_file, patch_file): | 130 def GenerateDiffPatch(options, orig_file, new_file, patch_file): |
| 131 if (options.diff_algorithm == "COURGETTE"): | 131 if (options.diff_algorithm == "COURGETTE"): |
| 132 exe_file = os.path.join(options.last_chrome_installer, COURGETTE_EXEC) | 132 exe_file = os.path.join(options.last_chrome_installer, COURGETTE_EXEC) |
| 133 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) |
| 134 else: | 134 else: |
| 135 exe_file = os.path.join(options.build_dir, BSDIFF_EXEC) | 135 exe_file = os.path.join(options.build_dir, BSDIFF_EXEC) |
| 136 cmd = [exe_file, orig_file, new_file, patch_file,] | 136 cmd = [exe_file, orig_file, new_file, patch_file,] |
| 137 RunSystemCommand(cmd) | 137 RunSystemCommand(cmd, options.verbose) |
| 138 | 138 |
| 139 def GetLZMAExec(build_dir): | 139 def GetLZMAExec(build_dir): |
| 140 lzma_exec = os.path.join(build_dir, "..", "..", "third_party", | 140 lzma_exec = os.path.join(build_dir, "..", "..", "third_party", |
| 141 "lzma_sdk", "Executable", "7za.exe") | 141 "lzma_sdk", "Executable", "7za.exe") |
| 142 return lzma_exec | 142 return lzma_exec |
| 143 | 143 |
| 144 def GetPrevVersion(build_dir, temp_dir, last_chrome_installer, output_name): | 144 def GetPrevVersion(build_dir, temp_dir, last_chrome_installer, output_name): |
| 145 if not last_chrome_installer: | 145 if not last_chrome_installer: |
| 146 return '' | 146 return '' |
| 147 | 147 |
| 148 lzma_exec = GetLZMAExec(build_dir) | 148 lzma_exec = GetLZMAExec(build_dir) |
| 149 prev_archive_file = os.path.join(last_chrome_installer, | 149 prev_archive_file = os.path.join(last_chrome_installer, |
| 150 output_name + ARCHIVE_SUFFIX) | 150 output_name + ARCHIVE_SUFFIX) |
| 151 cmd = [lzma_exec, | 151 cmd = [lzma_exec, |
| 152 'x', | 152 'x', |
| 153 '-o"%s"' % temp_dir, | 153 '-o"%s"' % temp_dir, |
| 154 prev_archive_file, | 154 prev_archive_file, |
| 155 'Chrome-bin/*/chrome.dll',] | 155 'Chrome-bin/*/chrome.dll',] |
| 156 RunSystemCommand(cmd) | 156 RunSystemCommand(cmd, options.verbose) |
| 157 dll_path = glob.glob(os.path.join(temp_dir, 'Chrome-bin', '*', 'chrome.dll')) | 157 dll_path = glob.glob(os.path.join(temp_dir, 'Chrome-bin', '*', 'chrome.dll')) |
| 158 return os.path.split(os.path.split(dll_path[0])[0])[1] | 158 return os.path.split(os.path.split(dll_path[0])[0])[1] |
| 159 | 159 |
| 160 def MakeStagingDirectories(staging_dir): | 160 def MakeStagingDirectories(staging_dir): |
| 161 """Creates a staging path for installer archive. If directory exists already, | 161 """Creates a staging path for installer archive. If directory exists already, |
| 162 deletes the existing directory. | 162 deletes the existing directory. |
| 163 """ | 163 """ |
| 164 file_path = os.path.join(staging_dir, TEMP_ARCHIVE_DIR) | 164 file_path = os.path.join(staging_dir, TEMP_ARCHIVE_DIR) |
| 165 if os.path.exists(file_path): | 165 if os.path.exists(file_path): |
| 166 shutil.rmtree(file_path) | 166 shutil.rmtree(file_path) |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 177 global variabes. | 177 global variabes. |
| 178 """ | 178 """ |
| 179 variables = {} | 179 variables = {} |
| 180 variables['ChromeDir'] = CHROME_DIR | 180 variables['ChromeDir'] = CHROME_DIR |
| 181 variables['VersionDir'] = os.path.join(variables['ChromeDir'], | 181 variables['VersionDir'] = os.path.join(variables['ChromeDir'], |
| 182 current_version) | 182 current_version) |
| 183 config = ConfigParser.SafeConfigParser(variables) | 183 config = ConfigParser.SafeConfigParser(variables) |
| 184 config.read(input_file) | 184 config.read(input_file) |
| 185 return config | 185 return config |
| 186 | 186 |
| 187 def RunSystemCommand(cmd, **kw): | 187 def RunSystemCommand(cmd, verbose, **kw): |
| 188 print 'Running', cmd | 188 """Runs |cmd|, printing verbose output if |verbose| and redirecting its output |
| 189 to os.devnull otherwise. | |
| 190 """ | |
| 191 if verbose: | |
| 192 print 'Running', cmd | |
| 193 else: | |
| 194 kw['stdout'] = open(os.devnull, "w") | |
| 189 exit_code = subprocess.call(cmd, **kw) | 195 exit_code = subprocess.call(cmd, **kw) |
| 190 if (exit_code != 0): | 196 if (exit_code != 0): |
| 191 raise Exception("Error while running cmd: %s, exit_code: %s" % | 197 raise Exception("Error while running cmd: %s, exit_code: %s" % |
|
grt (UTC plus 2)
2015/09/30 18:25:08
is it possible to capture the command's stdout in
gab
2015/10/01 14:21:18
Improved the way stdout/stderr capture is done by
grt (UTC plus 2)
2015/10/01 14:31:56
awesome!
| |
| 192 (cmd, exit_code)) | 198 (cmd, exit_code)) |
| 193 | 199 |
| 194 def CreateArchiveFile(options, staging_dir, current_version, prev_version): | 200 def CreateArchiveFile(options, staging_dir, current_version, prev_version): |
| 195 """Creates a new installer archive file after deleting any existing old file. | 201 """Creates a new installer archive file after deleting any existing old file. |
| 196 """ | 202 """ |
| 197 # First create an uncompressed archive file for the current build (chrome.7z) | 203 # First create an uncompressed archive file for the current build (chrome.7z) |
| 198 lzma_exec = GetLZMAExec(options.build_dir) | 204 lzma_exec = GetLZMAExec(options.build_dir) |
| 199 archive_file = os.path.join(options.output_dir, | 205 archive_file = os.path.join(options.output_dir, |
| 200 options.output_name + ARCHIVE_SUFFIX) | 206 options.output_name + ARCHIVE_SUFFIX) |
| 201 if options.depfile: | 207 if options.depfile: |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 238 | 244 |
| 239 cmd = [lzma_exec, | 245 cmd = [lzma_exec, |
| 240 'a', | 246 'a', |
| 241 '-t7z', | 247 '-t7z', |
| 242 archive_file, | 248 archive_file, |
| 243 os.path.join(staging_dir, CHROME_DIR), | 249 os.path.join(staging_dir, CHROME_DIR), |
| 244 '-mx0',] | 250 '-mx0',] |
| 245 # There doesnt seem to be any way in 7za.exe to override existing file so | 251 # There doesnt seem to be any way in 7za.exe to override existing file so |
| 246 # we always delete before creating a new one. | 252 # we always delete before creating a new one. |
| 247 if not os.path.exists(archive_file): | 253 if not os.path.exists(archive_file): |
| 248 RunSystemCommand(cmd) | 254 RunSystemCommand(cmd, options.verbose) |
| 249 elif options.skip_rebuild_archive != "true": | 255 elif options.skip_rebuild_archive != "true": |
| 250 os.remove(archive_file) | 256 os.remove(archive_file) |
| 251 RunSystemCommand(cmd) | 257 RunSystemCommand(cmd, options.verbose) |
| 252 | 258 |
| 253 # Do not compress the archive in developer (component) builds. | 259 # Do not compress the archive in developer (component) builds. |
| 254 if options.component_build == '1': | 260 if options.component_build == '1': |
| 255 compressed_file = os.path.join( | 261 compressed_file = os.path.join( |
| 256 options.output_dir, options.output_name + COMPRESSED_ARCHIVE_SUFFIX) | 262 options.output_dir, options.output_name + COMPRESSED_ARCHIVE_SUFFIX) |
| 257 if os.path.exists(compressed_file): | 263 if os.path.exists(compressed_file): |
| 258 os.remove(compressed_file) | 264 os.remove(compressed_file) |
| 259 return os.path.basename(archive_file) | 265 return os.path.basename(archive_file) |
| 260 | 266 |
| 261 # If we are generating a patch, run bsdiff against previous build and | 267 # If we are generating a patch, run bsdiff against previous build and |
| 262 # compress the resulting patch file. If this is not a patch just compress the | 268 # compress the resulting patch file. If this is not a patch just compress the |
| 263 # uncompressed archive file. | 269 # uncompressed archive file. |
| 264 patch_name_prefix = options.output_name + CHROME_PATCH_FILE_SUFFIX | 270 patch_name_prefix = options.output_name + CHROME_PATCH_FILE_SUFFIX |
| 265 if options.last_chrome_installer: | 271 if options.last_chrome_installer: |
| 266 prev_archive_file = os.path.join(options.last_chrome_installer, | 272 prev_archive_file = os.path.join(options.last_chrome_installer, |
| 267 options.output_name + ARCHIVE_SUFFIX) | 273 options.output_name + ARCHIVE_SUFFIX) |
| 268 patch_file = os.path.join(options.build_dir, patch_name_prefix + | 274 patch_file = os.path.join(options.build_dir, patch_name_prefix + |
| 269 PATCH_FILE_EXT) | 275 PATCH_FILE_EXT) |
| 270 GenerateDiffPatch(options, prev_archive_file, archive_file, patch_file) | 276 GenerateDiffPatch(options, prev_archive_file, archive_file, patch_file) |
| 271 compressed_archive_file = patch_name_prefix + '_' + \ | 277 compressed_archive_file = patch_name_prefix + '_' + \ |
| 272 current_version + '_from_' + prev_version + \ | 278 current_version + '_from_' + prev_version + \ |
| 273 COMPRESSED_FILE_EXT | 279 COMPRESSED_FILE_EXT |
| 274 orig_file = patch_file | 280 orig_file = patch_file |
| 275 else: | 281 else: |
| 276 compressed_archive_file = options.output_name + COMPRESSED_ARCHIVE_SUFFIX | 282 compressed_archive_file = options.output_name + COMPRESSED_ARCHIVE_SUFFIX |
| 277 orig_file = archive_file | 283 orig_file = archive_file |
| 278 | 284 |
| 279 compressed_archive_file_path = os.path.join(options.output_dir, | 285 compressed_archive_file_path = os.path.join(options.output_dir, |
| 280 compressed_archive_file) | 286 compressed_archive_file) |
| 281 CompressUsingLZMA(options.build_dir, compressed_archive_file_path, orig_file) | 287 CompressUsingLZMA(options.build_dir, compressed_archive_file_path, orig_file, |
| 288 options.verbose) | |
| 282 | 289 |
| 283 return compressed_archive_file | 290 return compressed_archive_file |
| 284 | 291 |
| 285 | 292 |
| 286 def PrepareSetupExec(options, current_version, prev_version): | 293 def PrepareSetupExec(options, current_version, prev_version): |
| 287 """Prepares setup.exe for bundling in mini_installer based on options.""" | 294 """Prepares setup.exe for bundling in mini_installer based on options.""" |
| 288 if options.setup_exe_format == "FULL": | 295 if options.setup_exe_format == "FULL": |
| 289 setup_file = SETUP_EXEC | 296 setup_file = SETUP_EXEC |
| 290 elif options.setup_exe_format == "DIFF": | 297 elif options.setup_exe_format == "DIFF": |
| 291 if not options.last_chrome_installer: | 298 if not options.last_chrome_installer: |
| 292 raise Exception( | 299 raise Exception( |
| 293 "To use DIFF for setup.exe, --last_chrome_installer is needed.") | 300 "To use DIFF for setup.exe, --last_chrome_installer is needed.") |
| 294 prev_setup_file = os.path.join(options.last_chrome_installer, SETUP_EXEC) | 301 prev_setup_file = os.path.join(options.last_chrome_installer, SETUP_EXEC) |
| 295 new_setup_file = os.path.join(options.build_dir, SETUP_EXEC) | 302 new_setup_file = os.path.join(options.build_dir, SETUP_EXEC) |
| 296 patch_file = os.path.join(options.build_dir, SETUP_PATCH_FILE_PREFIX + | 303 patch_file = os.path.join(options.build_dir, SETUP_PATCH_FILE_PREFIX + |
| 297 PATCH_FILE_EXT) | 304 PATCH_FILE_EXT) |
| 298 GenerateDiffPatch(options, prev_setup_file, new_setup_file, patch_file) | 305 GenerateDiffPatch(options, prev_setup_file, new_setup_file, patch_file) |
| 299 setup_file = SETUP_PATCH_FILE_PREFIX + '_' + current_version + \ | 306 setup_file = SETUP_PATCH_FILE_PREFIX + '_' + current_version + \ |
| 300 '_from_' + prev_version + COMPRESSED_FILE_EXT | 307 '_from_' + prev_version + COMPRESSED_FILE_EXT |
| 301 setup_file_path = os.path.join(options.build_dir, setup_file) | 308 setup_file_path = os.path.join(options.build_dir, setup_file) |
| 302 CompressUsingLZMA(options.build_dir, setup_file_path, patch_file) | 309 CompressUsingLZMA(options.build_dir, setup_file_path, patch_file, |
| 310 options.verbose) | |
| 303 else: | 311 else: |
| 304 cmd = ['makecab.exe', | 312 cmd = ['makecab.exe', |
| 305 '/D', 'CompressionType=LZX', | 313 '/D', 'CompressionType=LZX', |
| 306 '/V1', | 314 '/V1', |
| 307 '/L', options.output_dir, | 315 '/L', options.output_dir, |
| 308 os.path.join(options.build_dir, SETUP_EXEC),] | 316 os.path.join(options.build_dir, SETUP_EXEC),] |
| 309 # Send useless makecab progress on stdout to the bitbucket. | 317 # Send useless makecab progress on stdout to the bitbucket. |
| 310 RunSystemCommand(cmd, stdout=open(os.devnull, "w")) | 318 RunSystemCommand(cmd, options.verbose, stdout=open(os.devnull, "w")) |
|
csharp
2015/09/29 17:38:00
What about removing the stdout setting here and ju
gab
2015/09/29 17:44:02
Feels knowing the actual command could be useful.
gab
2015/10/01 14:21:19
Revised this as it made things more complicated fo
| |
| 311 setup_file = SETUP_EXEC[:-1] + "_" | 319 setup_file = SETUP_EXEC[:-1] + "_" |
| 312 return setup_file | 320 return setup_file |
| 313 | 321 |
| 314 | 322 |
| 315 _RESOURCE_FILE_HEADER = """\ | 323 _RESOURCE_FILE_HEADER = """\ |
| 316 // This file is automatically generated by create_installer_archive.py. | 324 // This file is automatically generated by create_installer_archive.py. |
| 317 // It contains the resource entries that are going to be linked inside | 325 // It contains the resource entries that are going to be linked inside |
| 318 // mini_installer.exe. For each file to be linked there should be two | 326 // mini_installer.exe. For each file to be linked there should be two |
| 319 // lines: | 327 // lines: |
| 320 // - The first line contains the output filename (without path) and the | 328 // - The first line contains the output filename (without path) and the |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 619 help='Whether this archive is packaging a component build. This will ' | 627 help='Whether this archive is packaging a component build. This will ' |
| 620 'also turn off compression of chrome.7z into chrome.packed.7z and ' | 628 'also turn off compression of chrome.7z into chrome.packed.7z and ' |
| 621 'helpfully delete any old chrome.packed.7z in |output_dir|.') | 629 'helpfully delete any old chrome.packed.7z in |output_dir|.') |
| 622 parser.add_option('--depfile', | 630 parser.add_option('--depfile', |
| 623 help='Generate a depfile with the given name listing the implicit inputs ' | 631 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.') | 632 'to the archive process that can be used with a build system.') |
| 625 parser.add_option('--target_arch', default='x86', | 633 parser.add_option('--target_arch', default='x86', |
| 626 help='Specify the target architecture for installer - this is used ' | 634 help='Specify the target architecture for installer - this is used ' |
| 627 'to determine which CRT runtime files to pull and package ' | 635 'to determine which CRT runtime files to pull and package ' |
| 628 'with the installer archive {x86|x64}.') | 636 'with the installer archive {x86|x64}.') |
| 637 parser.add_option('-v', '--verbose', action='store_true', dest='verbose', | |
| 638 default=False) | |
| 629 | 639 |
| 630 options, _ = parser.parse_args() | 640 options, _ = parser.parse_args() |
| 631 if not options.build_dir: | 641 if not options.build_dir: |
| 632 parser.error('You must provide a build dir.') | 642 parser.error('You must provide a build dir.') |
| 633 | 643 |
| 634 options.build_dir = os.path.normpath(options.build_dir) | 644 options.build_dir = os.path.normpath(options.build_dir) |
| 635 | 645 |
| 636 if not options.staging_dir: | 646 if not options.staging_dir: |
| 637 parser.error('You must provide a staging dir.') | 647 parser.error('You must provide a staging dir.') |
| 638 | 648 |
| 639 if not options.input_file: | 649 if not options.input_file: |
| 640 parser.error('You must provide an input file') | 650 parser.error('You must provide an input file') |
| 641 | 651 |
| 642 if not options.output_dir: | 652 if not options.output_dir: |
| 643 options.output_dir = options.build_dir | 653 options.output_dir = options.build_dir |
| 644 | 654 |
| 645 if not options.resource_file_path: | 655 if not options.resource_file_path: |
| 646 options.resource_file_path = os.path.join(options.build_dir, | 656 options.resource_file_path = os.path.join(options.build_dir, |
| 647 MINI_INSTALLER_INPUT_FILE) | 657 MINI_INSTALLER_INPUT_FILE) |
| 648 | 658 |
| 649 return options | 659 return options |
| 650 | 660 |
| 651 | 661 |
| 652 if '__main__' == __name__: | 662 if '__main__' == __name__: |
| 653 print sys.argv | 663 options = _ParseOptions() |
| 654 sys.exit(main(_ParseOptions())) | 664 if options.verbose: |
| 665 print sys.argv | |
| 666 sys.exit(main(options)) | |
| OLD | NEW |