diff options
author | kuchhal@chromium.org <kuchhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-03 17:43:59 +0000 |
---|---|---|
committer | kuchhal@chromium.org <kuchhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-03 17:43:59 +0000 |
commit | 28937b29b58e9aa1989349335ef83995e008098e (patch) | |
tree | 5cac7de39ea0a329d71bf13303fefd6b5b12af1d /chrome/tools | |
parent | 2c41ad7b7986fdec304ffa3d42ab4bc162bb89e0 (diff) | |
download | chromium_src-28937b29b58e9aa1989349335ef83995e008098e.zip chromium_src-28937b29b58e9aa1989349335ef83995e008098e.tar.gz chromium_src-28937b29b58e9aa1989349335ef83995e008098e.tar.bz2 |
Modify script that creates differntial installer to support 3stage update installer.
BUG=12832
TEST=While building mini_installer try various values of DiffAlgorithm and SetupExeFormat property and make sure generated installer works.
Review URL: http://codereview.chromium.org/114073
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17493 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/tools')
-rwxr-xr-x | chrome/tools/build/win/create_installer_archive.py | 270 | ||||
-rw-r--r-- | chrome/tools/build/win/release.rules | 24 |
2 files changed, 173 insertions, 121 deletions
diff --git a/chrome/tools/build/win/create_installer_archive.py b/chrome/tools/build/win/create_installer_archive.py index cf6d846..88bdb4d 100755 --- a/chrome/tools/build/win/create_installer_archive.py +++ b/chrome/tools/build/win/create_installer_archive.py @@ -1,5 +1,5 @@ #!/usr/bin/python -# Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +# Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -22,26 +22,30 @@ import sys ARCHIVE_DIR = "installer_archive" -FULL_ARCHIVE_FILE = "chrome.7z" # uncompresed full archive file -C_FULL_ARCHIVE_FILE = "chrome.packed.7z" # compressed full archive file -PATCH_FILE_NAME = "patch" # patch archive file name -PATCH_FILE_EXT = ".packed.7z" # extension of patch archive file +ARCHIVE_FILE = "chrome.7z" # uncompresed full archive file +BSDIFF_EXEC = "bsdiff.exe" CHROME_DIR = "Chrome-bin" +CHROME_PATCH_FILE_PREFIX = "chrome_patch" +COMPRESSED_ARCHIVE_FILE = "chrome.packed.7z" # compressed full archive file +COMPRESSED_FILE_EXT = ".packed.7z" # extension of patch archive file +COURGETTE_EXEC = "courgette.exe" MINI_INSTALLER_INPUT_FILE = "packed_files.txt" -SETUP_EXEC = "setup.exe" -BSDIFF_EXEC = "bsdiff.exe" -VERSION_FILE = "VERSION" PACKED_FILE_COMMENTS = """ // This file is automatically generated by create_installer_archive.py. // It contains the resource entries that are going to be linked inside // mini_installer.exe. For each file to be linked there should be two // lines: // - The first line contains the output filename (without path) and the -// type of the resource ('BN' means the file is not compressed and -// 'BL' means the file is compressed. +// type of the resource ('BN' - not compressed , 'BL' - LZ compressed, +// 'B7' - LZMA compressed) // - The second line contains the path to the input file. Uses '/' to // separate path components. """ +PATCH_FILE_EXT = '.diff' +SETUP_EXEC = "setup.exe" +SETUP_PATCH_FILE_PREFIX = "setup_patch" +TEMP_ARCHIVE_DIR = "temp_installer_archive" +VERSION_FILE = "VERSION" def BuildVersion(output_dir): """Returns the full build version string constructed from information in @@ -51,7 +55,6 @@ def BuildVersion(output_dir): minor = 0 build = 0 patch = 0 - # TODO(rahulk): find a better way to locate VERSION file for line in open(os.path.join(output_dir, "..", VERSION_FILE), 'r'): line = line.rstrip() if line.startswith('MAJOR='): @@ -64,29 +67,12 @@ def BuildVersion(output_dir): patch = line[6:] return '%s.%s.%s.%s' % (major, minor, build, patch) - -def Readconfig(output_dir, input_file, current_version): - """Reads config information from input file after setting default value of - global variabes. - """ - variables = {} - variables['ChromeDir'] = CHROME_DIR - variables['VersionDir'] = os.path.join(variables['ChromeDir'], - current_version) - config = ConfigParser.SafeConfigParser(variables) - config.read(input_file) - return config - - -def MakeStagingDirectory(output_dir): - """Creates a staging path for installer archive. If directory exists already, - deletes the existing directory. - """ - file_path = os.path.join(output_dir, ARCHIVE_DIR) - if os.path.exists(file_path): - shutil.rmtree(file_path) - os.makedirs(file_path) - return file_path +def CompressUsingLZMA(output_dir, compressed_file, input_file): + lzma_exec = GetLZMAExec(output_dir) + cmd = '%s a -t7z "%s" "%s" -mx9' % (lzma_exec, compressed_file, input_file) + if os.path.exists(compressed_file): + os.remove(compressed_file) + RunSystemCommand(cmd) def CopyAllFilesToStagingDir(config, distribution, staging_dir, output_dir): """Copies the files required for installer archive. @@ -100,7 +86,6 @@ def CopyAllFilesToStagingDir(config, distribution, staging_dir, output_dir): CopySectionFilesToStagingDir(config, distribution.upper(), staging_dir, output_dir) - def CopySectionFilesToStagingDir(config, section, staging_dir, output_dir): """Copies installer archive files specified in section to staging dir. This method copies reads section from config file and copies all the files @@ -116,104 +101,150 @@ def CopySectionFilesToStagingDir(config, section, staging_dir, output_dir): for file in glob.glob(os.path.join(output_dir, option)): shutil.copy(file, dst) +def GenerateDiffPatch(options, orig_file, new_file, patch_file): + if (options.diff_algorithm == "COURGETTE"): + exe_file = os.path.join(options.last_chrome_installer, COURGETTE_EXEC) + cmd = '%s -gen "%s" "%s" "%s"' % (exe_file, orig_file, new_file, patch_file) + else: + exe_file = os.path.join(options.output_dir, BSDIFF_EXEC) + cmd = '%s "%s" "%s" "%s"' % (exe_file, orig_file, new_file, patch_file) + RunSystemCommand(cmd) + +def GetLZMAExec(output_dir): + lzma_exec = os.path.join(output_dir, "..", "..", "third_party", + "lzma_sdk", "Executable", "7za.exe") + return lzma_exec + +def GetPrevVersion(output_dir, temp_dir, last_chrome_installer): + if not last_chrome_installer: + return '' + + lzma_exec = GetLZMAExec(options.output_dir) + prev_archive_file = os.path.join(options.last_chrome_installer, + ARCHIVE_FILE) + cmd = '%s x -o"%s" "%s" Chrome-bin/*/gears.dll' % (lzma_exec, temp_dir, + prev_archive_file) + RunSystemCommand(cmd) + dll_path = glob.glob(os.path.join(temp_dir, 'Chrome-bin', '*', 'gears.dll')) + return os.path.split(os.path.split(dll_path[0])[0])[1] + +def MakeStagingDirectories(output_dir): + """Creates a staging path for installer archive. If directory exists already, + deletes the existing directory. + """ + file_path = os.path.join(output_dir, ARCHIVE_DIR) + if os.path.exists(file_path): + shutil.rmtree(file_path) + os.makedirs(file_path) + + temp_file_path = os.path.join(output_dir, TEMP_ARCHIVE_DIR) + if os.path.exists(temp_file_path): + shutil.rmtree(temp_file_path) + os.makedirs(temp_file_path) + return (file_path, temp_file_path) + +def Readconfig(output_dir, input_file, current_version): + """Reads config information from input file after setting default value of + global variabes. + """ + variables = {} + variables['ChromeDir'] = CHROME_DIR + variables['VersionDir'] = os.path.join(variables['ChromeDir'], + current_version) + config = ConfigParser.SafeConfigParser(variables) + config.read(input_file) + return config def RunSystemCommand(cmd): + print 'Running [' + cmd + ']' if (os.system(cmd) != 0): raise "Error while running cmd: %s" % cmd - -def CreateArchiveFile(output_dir, staging_dir, current_version, - prev_version_dir, prev_version, skip_rebuild_archive): +def CreateArchiveFile(options, staging_dir, current_version, prev_version): """Creates a new installer archive file after deleting any existing old file. """ - # First create an uncompressed archive file for the current build - # TODO(rahulk): find a better way to locate 7za.exe - lzma_exec = os.path.join(output_dir, "..", "..", "third_party", - "lzma_sdk", "Executable", "7za.exe") - archive_file = os.path.join(output_dir, FULL_ARCHIVE_FILE) + # First create an uncompressed archive file for the current build (chrome.7z) + lzma_exec = GetLZMAExec(options.output_dir) + archive_file = os.path.join(options.output_dir, ARCHIVE_FILE) cmd = '%s a -t7z "%s" "%s" -mx0' % (lzma_exec, archive_file, os.path.join(staging_dir, CHROME_DIR)) # There doesnt seem to be any way in 7za.exe to override existing file so # we always delete before creating a new one. if not os.path.exists(archive_file): RunSystemCommand(cmd) - elif skip_rebuild_archive != "true": + elif options.skip_rebuild_archive != "true": os.remove(archive_file) RunSystemCommand(cmd) # If we are generating a patch, run bsdiff against previous build and # compress the resulting patch file. If this is not a patch just compress the # uncompressed archive file. - if (prev_version_dir): - prev_archive_file = os.path.join(prev_version_dir, FULL_ARCHIVE_FILE) - patch_file = os.path.join(output_dir, "patch.7z") - cmd = '%s "%s" "%s" "%s"' % (os.path.join(output_dir, BSDIFF_EXEC), - prev_archive_file, archive_file, patch_file) - RunSystemCommand(cmd) - - archive_file_name = PATCH_FILE_NAME + PATCH_FILE_EXT + if options.last_chrome_installer: + prev_archive_file = os.path.join(options.last_chrome_installer, + ARCHIVE_FILE) + patch_file = os.path.join(options.output_dir, CHROME_PATCH_FILE_PREFIX + + PATCH_FILE_EXT) + GenerateDiffPatch(options, prev_archive_file, archive_file, patch_file) + compressed_archive_file = CHROME_PATCH_FILE_PREFIX + '_' + \ + current_version + '_from_' + prev_version + \ + COMPRESSED_FILE_EXT orig_file = patch_file else: - archive_file_name = C_FULL_ARCHIVE_FILE + compressed_archive_file = COMPRESSED_ARCHIVE_FILE orig_file = archive_file - compressed_archive_file_path = os.path.join(output_dir, archive_file_name) - cmd = '%s a -t7z "%s" "%s" -mx9' % (lzma_exec, compressed_archive_file_path, - orig_file) - if os.path.exists(compressed_archive_file_path): - os.remove(compressed_archive_file_path) - RunSystemCommand(cmd) - - return archive_file_name - - -def CompressSetupExec(output_dir): - """Compresses setup.exe to reduce size.""" - cmd = 'makecab.exe /V1 /L "%s" "%s"' % (output_dir, - os.path.join(output_dir, SETUP_EXEC)) - RunSystemCommand(cmd) - - -def GetFileMD5Hash(file): - f = open(file, 'rb') - hash = md5.new(f.read()).hexdigest() - f.close() - return hash + compressed_archive_file_path = os.path.join(options.output_dir, + compressed_archive_file) + CompressUsingLZMA(options.output_dir, compressed_archive_file_path, orig_file) + + return compressed_archive_file + + +def PrepareSetupExec(options, staging_dir, current_version, prev_version): + """Prepares setup.exe for bundling in mini_installer based on options.""" + if options.setup_exe_format == "FULL": + setup_file = SETUP_EXEC + elif options.setup_exe_format == "DIFF": + if not options.last_chrome_installer: + raise "To use DIFF for setup.exe, --last_chrome_installer is needed." + prev_setup_file = os.path.join(options.last_chrome_installer, SETUP_EXEC) + new_setup_file = os.path.join(options.output_dir, SETUP_EXEC) + patch_file = os.path.join(options.output_dir, SETUP_PATCH_FILE_PREFIX + + PATCH_FILE_EXT) + GenerateDiffPatch(options, prev_setup_file, new_setup_file, patch_file) + setup_file = SETUP_PATCH_FILE_PREFIX + '_' + current_version + \ + '_from_' + prev_version + COMPRESSED_FILE_EXT + setup_file_path = os.path.join(options.output_dir, setup_file) + CompressUsingLZMA(options.output_dir, setup_file_path, patch_file) + else: + cmd = 'makecab.exe /V1 /L "%s" "%s"' % (options.output_dir, + os.path.join(options.output_dir, SETUP_EXEC)) + RunSystemCommand(cmd) + setup_file = SETUP_EXEC[:len(SETUP_EXEC) - 1] + "_" + return setup_file -def CreateResourceInputFile(output_dir, - prev_version_dir, archive_file_name): +def CreateResourceInputFile(output_dir, setup_format, archive_file, setup_file): """Creates resource input file (packed_files.txt) for mini_installer project. - This method checks if we are generating a patch instead of full installer. In - case of patch it also checks if setup.exe has changed by comparing its - MD5 hash with the MD5 hash of previous setup.exe. If hash values are same - setup.exe is not included in packed_files.txt. - - In case of patch we include patch.7z and in case of full - installer we include chrome.7z in packed_files.txt. + This method checks the format of setup.exe being used and according sets + its resource type. """ - setup_exe_needed = 1 - if (prev_version_dir): - current_hash = GetFileMD5Hash(os.path.join(output_dir, SETUP_EXEC)) - prev_hash = GetFileMD5Hash(os.path.join(prev_version_dir, SETUP_EXEC)) - if (current_hash == prev_hash): - setup_exe_needed = 0 - - if (setup_exe_needed): - CompressSetupExec(output_dir) - c_setup_file = SETUP_EXEC[:len(SETUP_EXEC) - 1] + "_" - setup_file_entry = "%s\t\tBL\n\"%s\"" % (c_setup_file, - os.path.join(output_dir, c_setup_file).replace("\\","/")) - - archive_file_entry = "\n%s\t\tB7\n\"%s\"" % (archive_file_name, - os.path.join(output_dir, archive_file_name).replace("\\","/")) + setup_resource_type = "BL" + if (options.setup_exe_format == "FULL"): + setup_resource_type = "BN" + elif (options.setup_exe_format == "DIFF"): + setup_resource_type = "B7" + setup_file_entry = "%s\t\t%s\n\"%s\"" % (setup_file, setup_resource_type, + os.path.join(output_dir, setup_file).replace("\\","/")) + + archive_file_entry = "\n%s\t\tB7\n\"%s\"\n" % (archive_file, + os.path.join(output_dir, archive_file).replace("\\","/")) output_file = os.path.join(output_dir, MINI_INSTALLER_INPUT_FILE) f = open(output_file, 'w') try: f.write(PACKED_FILE_COMMENTS) - if (setup_exe_needed): - f.write(setup_file_entry) + f.write(setup_file_entry) f.write(archive_file_entry) finally: f.close() @@ -227,19 +258,31 @@ def main(options): config = Readconfig(options.output_dir, options.input_file, current_version) - staging_dir = MakeStagingDirectory(options.output_dir) + (staging_dir, temp_dir) = MakeStagingDirectories(options.output_dir) + + prev_version = GetPrevVersion(options.output_dir, temp_dir, + options.last_chrome_installer) CopyAllFilesToStagingDir(config, options.distribution, staging_dir, options.output_dir) + version_numbers = current_version.split('.') + current_build_number = version_numbers[2] + '.' + version_numbers[3] + prev_build_number = '' + if prev_version: + version_numbers = prev_version.split('.') + prev_build_number = version_numbers[2] + '.' + version_numbers[3] + # Name of the archive file built (for example - chrome.7z or # patch-<old_version>-<new_version>.7z or patch-<new_version>.7z - archive_file_name = CreateArchiveFile(options.output_dir, staging_dir, - current_version, options.last_chrome_installer, - options.last_chrome_version, options.skip_rebuild_archive) + archive_file = CreateArchiveFile(options, staging_dir, + current_build_number, prev_build_number) - CreateResourceInputFile(options.output_dir, options.last_chrome_installer, - archive_file_name) + setup_file = PrepareSetupExec(options, staging_dir, + current_build_number, prev_build_number) + + CreateResourceInputFile(options.output_dir, options.setup_exe_format, + archive_file, setup_file) if '__main__' == __name__: @@ -253,11 +296,14 @@ if '__main__' == __name__: option_parser.add_option('-l', '--last_chrome_installer', help='Generate differential installer. The value of this parameter ' + 'specifies the directory that contains base versions of ' + - 'setup.exe & chrome.7z.') - option_parser.add_option('-v', '--last_chrome_version', - help='Version of the previous installer. ' + - 'Used only for the purpose of naming archive file. Optional.') + 'setup.exe, courgette.exe (if --diff_algorithm is COURGETTE) ' + + '& chrome.7z.') + option_parser.add_option('-f', '--setup_exe_format', default='COMPRESSED', + help='How setup.exe should be included {COMPRESSED|DIFF|FULL}.') + option_parser.add_option('-a', '--diff_algorithm', default='BSDIFF', + help='Diff algorithm to use when generating differential patches ' + + '{BSDIFF|COURGETTE}.') options, args = option_parser.parse_args() + print sys.argv sys.exit(main(options)) - diff --git a/chrome/tools/build/win/release.rules b/chrome/tools/build/win/release.rules index 4bcf1c5..21cdf14 100644 --- a/chrome/tools/build/win/release.rules +++ b/chrome/tools/build/win/release.rules @@ -5,9 +5,9 @@ > <Rules> <CustomBuildRule - Name="create installer archive" - DisplayName="create installer archive" - CommandLine="$(SolutionDir)..\third_party\python_24\python.exe $(SolutionDir)tools\build\win\create_installer_archive.py --output_dir="$(OutDir)" --input_file="$(InputPath)" --distribution=$(CHROMIUM_BUILD) [LastChromeInstaller] [LastChromeVersion] [SkipRebuildArchive]" + Name="Create Installer Archive" + DisplayName="Create Installer Archive" + CommandLine="$(SolutionDir)..\third_party\python_24\python.exe $(SolutionDir)tools\build\win\create_installer_archive.py --output_dir="$(OutDir)" --input_file="$(InputPath)" --distribution=$(CHROMIUM_BUILD) [LastChromeInstaller] [SkipRebuildArchive] [SetupExeFormat] [DiffAlgorithm]" Outputs="$(OutDir)/$(InputName).7z;$(OutDir)/$(InputName).packed.7z;$(OutDir)/setup.ex_;$(OutDir)/packed_files.txt;" AdditionalDependencies="$(SolutionDir)\tools\build\win\create_installer_archive.py;$(OutDir)\chrome.exe;$(OutDir)\crash_reporter.exe;$(OutDir)\chrome.dll;$(OutDir)\locales\en-US.dll;$(OutDir)\icudt38.dll" FileExtensions="*.release" @@ -21,17 +21,23 @@ Switch="--last_chrome_installer="[value]"" /> <StringProperty - Name="LastChromeVersion" - DisplayName="Last Chrome Version" - Description="Last released version of Chrome (used to name the patch file)" - Switch="--last_chrome_version="[value]"" - /> - <StringProperty Name="SkipRebuildArchive" DisplayName="Skip Rebuilding Archive" Description="Skips rebuilding chrome.7z archive if it already exists" Switch="--skip_rebuild_archive="[value]"" /> + <StringProperty + Name="SetupExeFormat" + DisplayName="Setup.exe format" + Description="The format that should be used to bundle setup.exe. Possible values - {COMPRESSED|DIFF|FULL}." + Switch="--setup_exe_format="[value]"" + /> + <StringProperty + Name="DiffAlgorithm" + DisplayName="Differential Algorithm" + Description="Differential algorithm to use when generating differential patch. Possible values - {BSDIFF|COURGETTE}." + Switch="--diff_algorithm="[value]"" + /> </Properties> </CustomBuildRule> </Rules> |