OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 specified to staging dir. | 108 specified to staging dir. |
109 """ | 109 """ |
110 for option in config.options(section): | 110 for option in config.options(section): |
111 if option.endswith('dir'): | 111 if option.endswith('dir'): |
112 continue | 112 continue |
113 | 113 |
114 dst = os.path.join(staging_dir, config.get(section, option)) | 114 dst = os.path.join(staging_dir, config.get(section, option)) |
115 if not os.path.exists(dst): | 115 if not os.path.exists(dst): |
116 os.makedirs(dst) | 116 os.makedirs(dst) |
117 for file in glob.glob(os.path.join(build_dir, option)): | 117 for file in glob.glob(os.path.join(build_dir, option)): |
118 shutil.copy(file, dst) | 118 dst_file = os.path.join(dst, os.path.basename(file)) |
| 119 if not os.path.exists(dst_file): |
| 120 shutil.copy(file, dst) |
119 | 121 |
120 def GenerateDiffPatch(options, orig_file, new_file, patch_file): | 122 def GenerateDiffPatch(options, orig_file, new_file, patch_file): |
121 if (options.diff_algorithm == "COURGETTE"): | 123 if (options.diff_algorithm == "COURGETTE"): |
122 exe_file = os.path.join(options.last_chrome_installer, COURGETTE_EXEC) | 124 exe_file = os.path.join(options.last_chrome_installer, COURGETTE_EXEC) |
123 cmd = '%s -gen "%s" "%s" "%s"' % (exe_file, orig_file, new_file, patch_file) | 125 cmd = '%s -gen "%s" "%s" "%s"' % (exe_file, orig_file, new_file, patch_file) |
124 else: | 126 else: |
125 exe_file = os.path.join(options.build_dir, BSDIFF_EXEC) | 127 exe_file = os.path.join(options.build_dir, BSDIFF_EXEC) |
126 cmd = [exe_file, orig_file, new_file, patch_file,] | 128 cmd = [exe_file, orig_file, new_file, patch_file,] |
127 RunSystemCommand(cmd) | 129 RunSystemCommand(cmd) |
128 | 130 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 exit_code = subprocess.call(cmd) | 181 exit_code = subprocess.call(cmd) |
180 if (exit_code != 0): | 182 if (exit_code != 0): |
181 raise Exception("Error while running cmd: %s, exit_code: %s" % | 183 raise Exception("Error while running cmd: %s, exit_code: %s" % |
182 (cmd, exit_code)) | 184 (cmd, exit_code)) |
183 | 185 |
184 def CreateArchiveFile(options, staging_dir, current_version, prev_version): | 186 def CreateArchiveFile(options, staging_dir, current_version, prev_version): |
185 """Creates a new installer archive file after deleting any existing old file. | 187 """Creates a new installer archive file after deleting any existing old file. |
186 """ | 188 """ |
187 # First create an uncompressed archive file for the current build (chrome.7z) | 189 # First create an uncompressed archive file for the current build (chrome.7z) |
188 lzma_exec = GetLZMAExec(options.build_dir) | 190 lzma_exec = GetLZMAExec(options.build_dir) |
189 archive_file = os.path.join(options.build_dir, | 191 archive_file = os.path.join(options.output_dir, |
190 options.output_name + ARCHIVE_SUFFIX) | 192 options.output_name + ARCHIVE_SUFFIX) |
191 cmd = [lzma_exec, | 193 cmd = [lzma_exec, |
192 'a', | 194 'a', |
193 '-t7z', | 195 '-t7z', |
194 archive_file, | 196 archive_file, |
195 os.path.join(staging_dir, CHROME_DIR), | 197 os.path.join(staging_dir, CHROME_DIR), |
196 '-mx0',] | 198 '-mx0',] |
197 # There doesnt seem to be any way in 7za.exe to override existing file so | 199 # There doesnt seem to be any way in 7za.exe to override existing file so |
198 # we always delete before creating a new one. | 200 # we always delete before creating a new one. |
199 if not os.path.exists(archive_file): | 201 if not os.path.exists(archive_file): |
(...skipping 13 matching lines...) Expand all Loading... |
213 PATCH_FILE_EXT) | 215 PATCH_FILE_EXT) |
214 GenerateDiffPatch(options, prev_archive_file, archive_file, patch_file) | 216 GenerateDiffPatch(options, prev_archive_file, archive_file, patch_file) |
215 compressed_archive_file = patch_name_prefix + '_' + \ | 217 compressed_archive_file = patch_name_prefix + '_' + \ |
216 current_version + '_from_' + prev_version + \ | 218 current_version + '_from_' + prev_version + \ |
217 COMPRESSED_FILE_EXT | 219 COMPRESSED_FILE_EXT |
218 orig_file = patch_file | 220 orig_file = patch_file |
219 else: | 221 else: |
220 compressed_archive_file = options.output_name + COMPRESSED_ARCHIVE_SUFFIX | 222 compressed_archive_file = options.output_name + COMPRESSED_ARCHIVE_SUFFIX |
221 orig_file = archive_file | 223 orig_file = archive_file |
222 | 224 |
223 compressed_archive_file_path = os.path.join(options.build_dir, | 225 compressed_archive_file_path = os.path.join(options.output_dir, |
224 compressed_archive_file) | 226 compressed_archive_file) |
225 CompressUsingLZMA(options.build_dir, compressed_archive_file_path, orig_file) | 227 CompressUsingLZMA(options.build_dir, compressed_archive_file_path, orig_file) |
226 | 228 |
227 return compressed_archive_file | 229 return compressed_archive_file |
228 | 230 |
229 | 231 |
230 def PrepareSetupExec(options, staging_dir, current_version, prev_version): | 232 def PrepareSetupExec(options, staging_dir, current_version, prev_version): |
231 """Prepares setup.exe for bundling in mini_installer based on options.""" | 233 """Prepares setup.exe for bundling in mini_installer based on options.""" |
232 if options.setup_exe_format == "FULL": | 234 if options.setup_exe_format == "FULL": |
233 setup_file = SETUP_EXEC | 235 setup_file = SETUP_EXEC |
234 elif options.setup_exe_format == "DIFF": | 236 elif options.setup_exe_format == "DIFF": |
235 if not options.last_chrome_installer: | 237 if not options.last_chrome_installer: |
236 raise Exception( | 238 raise Exception( |
237 "To use DIFF for setup.exe, --last_chrome_installer is needed.") | 239 "To use DIFF for setup.exe, --last_chrome_installer is needed.") |
238 prev_setup_file = os.path.join(options.last_chrome_installer, SETUP_EXEC) | 240 prev_setup_file = os.path.join(options.last_chrome_installer, SETUP_EXEC) |
239 new_setup_file = os.path.join(options.build_dir, SETUP_EXEC) | 241 new_setup_file = os.path.join(options.build_dir, SETUP_EXEC) |
240 patch_file = os.path.join(options.build_dir, SETUP_PATCH_FILE_PREFIX + | 242 patch_file = os.path.join(options.build_dir, SETUP_PATCH_FILE_PREFIX + |
241 PATCH_FILE_EXT) | 243 PATCH_FILE_EXT) |
242 GenerateDiffPatch(options, prev_setup_file, new_setup_file, patch_file) | 244 GenerateDiffPatch(options, prev_setup_file, new_setup_file, patch_file) |
243 setup_file = SETUP_PATCH_FILE_PREFIX + '_' + current_version + \ | 245 setup_file = SETUP_PATCH_FILE_PREFIX + '_' + current_version + \ |
244 '_from_' + prev_version + COMPRESSED_FILE_EXT | 246 '_from_' + prev_version + COMPRESSED_FILE_EXT |
245 setup_file_path = os.path.join(options.build_dir, setup_file) | 247 setup_file_path = os.path.join(options.build_dir, setup_file) |
246 CompressUsingLZMA(options.build_dir, setup_file_path, patch_file) | 248 CompressUsingLZMA(options.build_dir, setup_file_path, patch_file) |
247 else: | 249 else: |
248 cmd = ['makecab.exe', | 250 cmd = ['makecab.exe', |
249 '/D', 'CompressionType=LZX', | 251 '/D', 'CompressionType=LZX', |
250 '/V1', | 252 '/V1', |
251 '/L', options.build_dir, | 253 '/L', options.output_dir, |
252 os.path.join(options.build_dir, SETUP_EXEC),] | 254 os.path.join(options.build_dir, SETUP_EXEC),] |
253 RunSystemCommand(cmd) | 255 RunSystemCommand(cmd) |
254 setup_file = SETUP_EXEC[:-1] + "_" | 256 setup_file = SETUP_EXEC[:-1] + "_" |
255 return setup_file | 257 return setup_file |
256 | 258 |
257 | 259 |
258 _RESOURCE_FILE_TEMPLATE = """\ | 260 _RESOURCE_FILE_TEMPLATE = """\ |
259 // This file is automatically generated by create_installer_archive.py. | 261 // This file is automatically generated by create_installer_archive.py. |
260 // It contains the resource entries that are going to be linked inside | 262 // It contains the resource entries that are going to be linked inside |
261 // mini_installer.exe. For each file to be linked there should be two | 263 // mini_installer.exe. For each file to be linked there should be two |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 """ | 311 """ |
310 current_version = BuildVersion(options.build_dir) | 312 current_version = BuildVersion(options.build_dir) |
311 | 313 |
312 config = Readconfig(options.build_dir, options.input_file, current_version) | 314 config = Readconfig(options.build_dir, options.input_file, current_version) |
313 | 315 |
314 (staging_dir, temp_dir) = MakeStagingDirectories(options.staging_dir) | 316 (staging_dir, temp_dir) = MakeStagingDirectories(options.staging_dir) |
315 | 317 |
316 prev_version = GetPrevVersion(options.build_dir, temp_dir, | 318 prev_version = GetPrevVersion(options.build_dir, temp_dir, |
317 options.last_chrome_installer) | 319 options.last_chrome_installer) |
318 | 320 |
| 321 # Preferentially copy the files we can find from the output_dir, as |
| 322 # this is where we'll find the Syzygy-optimized executables when |
| 323 # building the optimized mini_installer. |
| 324 if options.build_dir != options.output_dir: |
| 325 CopyAllFilesToStagingDir(config, options.distribution, |
| 326 staging_dir, options.output_dir) |
| 327 |
| 328 # Now copy the remainder of the files from the build dir. |
319 CopyAllFilesToStagingDir(config, options.distribution, | 329 CopyAllFilesToStagingDir(config, options.distribution, |
320 staging_dir, options.build_dir) | 330 staging_dir, options.build_dir) |
321 | 331 |
322 version_numbers = current_version.split('.') | 332 version_numbers = current_version.split('.') |
323 current_build_number = version_numbers[2] + '.' + version_numbers[3] | 333 current_build_number = version_numbers[2] + '.' + version_numbers[3] |
324 prev_build_number = '' | 334 prev_build_number = '' |
325 if prev_version: | 335 if prev_version: |
326 version_numbers = prev_version.split('.') | 336 version_numbers = prev_version.split('.') |
327 prev_build_number = version_numbers[2] + '.' + version_numbers[3] | 337 prev_build_number = version_numbers[2] + '.' + version_numbers[3] |
328 | 338 |
329 # Name of the archive file built (for example - chrome.7z or | 339 # Name of the archive file built (for example - chrome.7z or |
330 # patch-<old_version>-<new_version>.7z or patch-<new_version>.7z | 340 # patch-<old_version>-<new_version>.7z or patch-<new_version>.7z |
331 archive_file = CreateArchiveFile(options, staging_dir, | 341 archive_file = CreateArchiveFile(options, staging_dir, |
332 current_build_number, prev_build_number) | 342 current_build_number, prev_build_number) |
333 | 343 |
334 setup_file = PrepareSetupExec(options, staging_dir, | 344 setup_file = PrepareSetupExec(options, staging_dir, |
335 current_build_number, prev_build_number) | 345 current_build_number, prev_build_number) |
336 | 346 |
337 CreateResourceInputFile(options.build_dir, options.setup_exe_format, | 347 CreateResourceInputFile(options.build_dir, options.setup_exe_format, |
338 archive_file, setup_file, options.resource_file_path) | 348 archive_file, setup_file, options.resource_file_path) |
339 | 349 |
340 def _ParseOptions(): | 350 def _ParseOptions(): |
341 parser = optparse.OptionParser() | 351 parser = optparse.OptionParser() |
342 parser.add_option('-i', '--input_file', | 352 parser.add_option('-i', '--input_file', |
343 help='Input file describing which files to archive.') | 353 help='Input file describing which files to archive.') |
344 parser.add_option('-o', '--build_dir', | 354 parser.add_option('-b', '--build_dir', |
345 help='Build directory. The paths in input_file are relative to this.') | 355 help='Build directory. The paths in input_file are relative to this.') |
346 parser.add_option('--staging_dir', | 356 parser.add_option('--staging_dir', |
347 help='Staging directory where intermediate files and directories ' | 357 help='Staging directory where intermediate files and directories ' |
348 'will be created'), | 358 'will be created'), |
| 359 parser.add_option('-o', '--output_dir', |
| 360 help='The output directory where the archives will be written. ' |
| 361 'Defaults to the build_dir.') |
349 parser.add_option('--resource_file_path', | 362 parser.add_option('--resource_file_path', |
350 help='The path where the resource file will be output. ' | 363 help='The path where the resource file will be output. ' |
351 'Defaults to %s in the build directory.' % | 364 'Defaults to %s in the build directory.' % |
352 MINI_INSTALLER_INPUT_FILE), | 365 MINI_INSTALLER_INPUT_FILE), |
353 parser.add_option('-d', '--distribution', | 366 parser.add_option('-d', '--distribution', |
354 help='Name of Chromium Distribution. Optional.') | 367 help='Name of Chromium Distribution. Optional.') |
355 parser.add_option('-s', '--skip_rebuild_archive', | 368 parser.add_option('-s', '--skip_rebuild_archive', |
356 default="False", help='Skip re-building Chrome.7z archive if it exists.') | 369 default="False", help='Skip re-building Chrome.7z archive if it exists.') |
357 parser.add_option('-l', '--last_chrome_installer', | 370 parser.add_option('-l', '--last_chrome_installer', |
358 help='Generate differential installer. The value of this parameter ' | 371 help='Generate differential installer. The value of this parameter ' |
359 'specifies the directory that contains base versions of ' | 372 'specifies the directory that contains base versions of ' |
360 'setup.exe, courgette.exe (if --diff_algorithm is COURGETTE) ' | 373 'setup.exe, courgette.exe (if --diff_algorithm is COURGETTE) ' |
361 '& chrome.7z.') | 374 '& chrome.7z.') |
362 parser.add_option('-f', '--setup_exe_format', default='COMPRESSED', | 375 parser.add_option('-f', '--setup_exe_format', default='COMPRESSED', |
363 help='How setup.exe should be included {COMPRESSED|DIFF|FULL}.') | 376 help='How setup.exe should be included {COMPRESSED|DIFF|FULL}.') |
364 parser.add_option('-a', '--diff_algorithm', default='BSDIFF', | 377 parser.add_option('-a', '--diff_algorithm', default='BSDIFF', |
365 help='Diff algorithm to use when generating differential patches ' | 378 help='Diff algorithm to use when generating differential patches ' |
366 '{BSDIFF|COURGETTE}.') | 379 '{BSDIFF|COURGETTE}.') |
367 parser.add_option('-n', '--output_name', default='chrome', | 380 parser.add_option('-n', '--output_name', default='chrome', |
368 help='Name used to prefix names of generated archives.') | 381 help='Name used to prefix names of generated archives.') |
369 | 382 |
370 options, args = parser.parse_args() | 383 options, args = parser.parse_args() |
371 | |
372 if not options.build_dir: | 384 if not options.build_dir: |
373 parser.error('You must provide a build dir.') | 385 parser.error('You must provide a build dir.') |
374 | 386 |
375 if not options.staging_dir: | 387 if not options.staging_dir: |
376 parser.error('You must provide a staging dir.') | 388 parser.error('You must provide a staging dir.') |
377 | 389 |
| 390 if not options.output_dir: |
| 391 options.output_dir = options.build_dir |
| 392 |
378 if not options.resource_file_path: | 393 if not options.resource_file_path: |
379 options.options.resource_file_path = os.path.join(options.build_dir, | 394 options.options.resource_file_path = os.path.join(options.build_dir, |
380 MINI_INSTALLER_INPUT_FILE) | 395 MINI_INSTALLER_INPUT_FILE) |
381 | 396 |
382 print sys.argv | |
383 return options | 397 return options |
384 | 398 |
385 | 399 |
386 if '__main__' == __name__: | 400 if '__main__' == __name__: |
| 401 print sys.argv |
387 sys.exit(main(_ParseOptions())) | 402 sys.exit(main(_ParseOptions())) |
OLD | NEW |