Skip to content

Commit

Permalink
Use fast compression instead of none
Browse files Browse the repository at this point in the history
Historically Chrome's mini_installer has disabled compression for
developer builds in order to improve turnaround times. However the
mini_installer has grown enough to about 2 GB in debug builds which
has caused the executable to be corrupt (for some unknown reason).

It turns out that using fast compression rather than no compression is
just as fast, while removing some code paths, and the reduced size makes
the mini_installer easier to transfer between machines.

Since compression is always enabled the enable_archive_compression
config and its derivatives were deleted.

This change shrinks the debug installer from about 2 GB to about 500 MB.
A release non-official install shrinks from about 340 MB to 125 MB. For
context, a fully compressed release build would be about 94 MB. The
official build mini_installer is unaffected.

The mb_config.pyl changes required running mb.py which required fixing
it so that it generated correct line endings on Windows.

Bug: 1408213
Change-Id: Ib669488f0d2554b09a852f19dfada2b43de9bbc4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4175292
Reviewed-by: Greg Thompson <grt@chromium.org>
Commit-Queue: Bruce Dawson <brucedawson@chromium.org>
Reviewed-by: Sorin Jianu <sorin@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1097544}
  • Loading branch information
randomascii authored and Chromium LUCI CQ committed Jan 26, 2023
1 parent c0658a1 commit acc7c7d
Show file tree
Hide file tree
Showing 14 changed files with 90 additions and 147 deletions.
23 changes: 9 additions & 14 deletions chrome/installer/mini_installer/BUILD.gn
Expand Up @@ -15,11 +15,12 @@ import("//ui/base/ui_features.gni")
import("//v8/gni/v8.gni")

declare_args() {
# The Chrome archive is compressed in official builds to reduce the size of
# the installer. By default: non-official or component builds, a build mode
# targeting developers, do not compress so as to provide quicker build-test
# cycles.
skip_archive_compression = !is_official_build || is_component_build
# The Chrome archive is maximally compressed in official builds to reduce the
# size of the installer. By default: non-official or component builds, build
# modes targeting developers, use maximum-speed instead of maximum-compression
# settings so as to provide quicker build-test cycles. Uncompressed archives
# are not supported due to size constraints.
fast_archive_compression = !is_official_build || is_component_build
}

config("mini_installer_compiler_flags") {
Expand Down Expand Up @@ -59,10 +60,6 @@ source_set("lib") {
"//chrome/browser/chrome_for_testing:buildflags",
]

if (skip_archive_compression) {
defines = [ "SKIP_ARCHIVE_COMPRESSION" ]
}

# Initialization may insert unexpected memset calls.
configs -= [ "//build/config/compiler:default_init_stack_vars" ]
configs += [ ":mini_installer_compiler_flags" ]
Expand Down Expand Up @@ -131,8 +128,8 @@ action("mini_installer_archive") {
]

outputs = [
# See also chrome.packed.7z conditionally added below.
"$root_out_dir/chrome.7z",
"$root_out_dir/chrome.packed.7z",
"$root_out_dir/setup.ex_",
packed_files_rc_file,
]
Expand Down Expand Up @@ -186,10 +183,8 @@ action("mini_installer_archive") {
args += [ "--component_ffmpeg_build=1" ]
}

if (skip_archive_compression) {
args += [ "--skip_archive_compression" ]
} else {
outputs += [ "$root_out_dir/chrome.packed.7z" ]
if (fast_archive_compression) {
args += [ "--fast_archive_compression" ]
}

if (enable_nacl) {
Expand Down
7 changes: 1 addition & 6 deletions chrome/installer/mini_installer/mini_installer.cc
Expand Up @@ -567,12 +567,7 @@ ProcessExitResult RunSetup(const Configuration& configuration,
}

// Append the command line param for chrome archive file.
if (!cmd_line.append(L" --") ||
#if defined(SKIP_ARCHIVE_COMPRESSION)
!cmd_line.append(kCmdUncompressedArchive) ||
#else
!cmd_line.append(kCmdInstallArchive) ||
#endif
if (!cmd_line.append(L" --") || !cmd_line.append(kCmdInstallArchive) ||
!cmd_line.append(L"=\"") || !cmd_line.append(archive_path) ||
!cmd_line.append(L"\"")) {
return ProcessExitResult(COMMAND_STRING_OVERFLOW);
Expand Down
4 changes: 0 additions & 4 deletions chrome/installer/mini_installer/mini_installer_constants.cc
Expand Up @@ -18,11 +18,7 @@ const wchar_t kChromeArchivePrefix[] = L"chrome";
const wchar_t kSetupPrefix[] = L"setup";

// Command line switch names for setup.exe.
#if defined(SKIP_ARCHIVE_COMPRESSION)
const wchar_t kCmdUncompressedArchive[] = L"uncompressed-archive";
#else
const wchar_t kCmdInstallArchive[] = L"install-archive";
#endif
const wchar_t kCmdUpdateSetupExe[] = L"update-setup-exe";
const wchar_t kCmdNewSetupExe[] = L"new-setup-exe";
const wchar_t kCmdPreviousVersion[] = L"previous-version";
Expand Down
4 changes: 0 additions & 4 deletions chrome/installer/mini_installer/mini_installer_constants.h
Expand Up @@ -13,11 +13,7 @@ extern const wchar_t kChromeArchivePrefix[];
extern const wchar_t kSetupPrefix[];

// Unprefixed command line switch names for setup.exe.
#if defined(SKIP_ARCHIVE_COMPRESSION)
extern const wchar_t kCmdUncompressedArchive[];
#else
extern const wchar_t kCmdInstallArchive[];
#endif
extern const wchar_t kCmdUpdateSetupExe[];
extern const wchar_t kCmdNewSetupExe[];
extern const wchar_t kCmdPreviousVersion[];
Expand Down
50 changes: 23 additions & 27 deletions chrome/installer/setup/setup_main.cc
Expand Up @@ -1278,36 +1278,32 @@ InstallStatus InstallProductsHelper(InstallationState& original_state,
return TEMP_DIR_FAILED;
}

// Uncompress and optionally patch the archive if an uncompressed archive was
// not specified on the command line and a compressed archive is found.
// Uncompress and optionally patch the archive if a compressed archive is
// found.
*archive_type = UNKNOWN_ARCHIVE_TYPE;
base::FilePath uncompressed_archive(
cmd_line.GetSwitchValuePath(switches::kUncompressedArchive));
if (uncompressed_archive.empty()) {
base::Version previous_version;
if (cmd_line.HasSwitch(installer::switches::kPreviousVersion)) {
previous_version = base::Version(
cmd_line.GetSwitchValueASCII(installer::switches::kPreviousVersion));
}
base::Version previous_version;
if (cmd_line.HasSwitch(installer::switches::kPreviousVersion)) {
previous_version = base::Version(
cmd_line.GetSwitchValueASCII(installer::switches::kPreviousVersion));
}

std::unique_ptr<ArchivePatchHelper> archive_helper(
CreateChromeArchiveHelper(
setup_exe, cmd_line, installer_state, unpack_path,
(previous_version.IsValid()
? UnPackConsumer::CHROME_ARCHIVE_PATCH
: UnPackConsumer::COMPRESSED_CHROME_ARCHIVE)));
if (archive_helper) {
VLOG(1) << "Installing Chrome from compressed archive "
<< archive_helper->compressed_archive().value();
if (!UncompressAndPatchChromeArchive(original_state, installer_state,
archive_helper.get(), archive_type,
&install_status, previous_version)) {
DCHECK_NE(install_status, UNKNOWN_STATUS);
return install_status;
}
uncompressed_archive = archive_helper->target();
DCHECK(!uncompressed_archive.empty());
std::unique_ptr<ArchivePatchHelper> archive_helper(CreateChromeArchiveHelper(
setup_exe, cmd_line, installer_state, unpack_path,
(previous_version.IsValid()
? UnPackConsumer::CHROME_ARCHIVE_PATCH
: UnPackConsumer::COMPRESSED_CHROME_ARCHIVE)));
base::FilePath uncompressed_archive;
if (archive_helper) {
VLOG(1) << "Installing Chrome from compressed archive "
<< archive_helper->compressed_archive().value();
if (!UncompressAndPatchChromeArchive(original_state, installer_state,
archive_helper.get(), archive_type,
&install_status, previous_version)) {
DCHECK_NE(install_status, UNKNOWN_STATUS);
return install_status;
}
uncompressed_archive = archive_helper->target();
DCHECK(!uncompressed_archive.empty());
}

// Check for an uncompressed archive alongside the current executable if one
Expand Down
26 changes: 9 additions & 17 deletions chrome/installer/test/alternate_version_generator.cc
Expand Up @@ -64,7 +64,6 @@ const wchar_t kB7[] = L"B7";
const wchar_t kBl[] = L"BL";
const wchar_t kChromeBin[] = L"Chrome-bin";
const wchar_t kChromePacked7z[] = L"CHROME.PACKED.7Z";
const wchar_t kChrome7z[] = L"CHROME.7Z";
const wchar_t kExe[] = L"exe";
const wchar_t kExpandExe[] = L"expand.exe";
const wchar_t kExtDll[] = L".dll";
Expand Down Expand Up @@ -577,7 +576,6 @@ bool GenerateAlternateVersion(const base::FilePath& original_installer_path,

base::FilePath setup_ex_ = work_dir.directory().Append(&kSetupEx_[0]);
base::FilePath chrome_packed_7z; // Empty for component builds.
base::FilePath chrome_7z;
const wchar_t* archive_resource_name = nullptr;
base::FilePath* archive_file = nullptr;
// Load the original file and extract setup.ex_ and chrome.packed.7z
Expand All @@ -599,20 +597,16 @@ bool GenerateAlternateVersion(const base::FilePath& original_installer_path,
return false;
}

// Write out chrome.packed.7z (static build) or chrome.7z (component build)
// Write out chrome.packed.7z
if (resource_loader.Load(&kChromePacked7z[0], &kB7[0], &resource_data)) {
archive_resource_name = &kChromePacked7z[0];
chrome_packed_7z = work_dir.directory().Append(archive_resource_name);
archive_file = &chrome_packed_7z;
} else if (resource_loader.Load(&kChrome7z[0], &kB7[0], &resource_data)) {
archive_resource_name = &kChrome7z[0];
chrome_7z = work_dir.directory().Append(archive_resource_name);
archive_file = &chrome_7z;
} else {
return false;
}
DCHECK(archive_resource_name);
DCHECK(!chrome_packed_7z.empty() || !chrome_7z.empty());
DCHECK(!chrome_packed_7z.empty());
DCHECK(archive_file);
written = base::WriteFile(
*archive_file, reinterpret_cast<const char*>(resource_data.first),
Expand Down Expand Up @@ -641,13 +635,12 @@ bool GenerateAlternateVersion(const base::FilePath& original_installer_path,
return false;
}

// Unpack chrome.packed.7z (static build only).
if (!chrome_packed_7z.empty()) {
if (UnPackArchive(chrome_packed_7z, work_dir.directory(), &chrome_7z) !=
UNPACK_NO_ERROR) {
LOG(DFATAL) << "Failed unpacking \"" << chrome_packed_7z.value() << "\"";
return false;
}
// Unpack chrome.packed.7z.
base::FilePath chrome_7z;
if (UnPackArchive(chrome_packed_7z, work_dir.directory(), &chrome_7z) !=
UNPACK_NO_ERROR) {
LOG(DFATAL) << "Failed unpacking \"" << chrome_packed_7z.value() << "\"";
return false;
}
DCHECK(!chrome_7z.empty());

Expand All @@ -659,8 +652,7 @@ bool GenerateAlternateVersion(const base::FilePath& original_installer_path,
}

// Get rid of intermediate files
if (!base::DeleteFile(chrome_7z) ||
(!chrome_packed_7z.empty() && !base::DeleteFile(chrome_packed_7z)) ||
if (!base::DeleteFile(chrome_7z) || (!base::DeleteFile(chrome_packed_7z)) ||
!base::DeleteFile(setup_ex_)) {
LOG(DFATAL) << "Failed deleting intermediate files";
return false;
Expand Down
7 changes: 1 addition & 6 deletions chrome/installer/util/util_constants.cc
Expand Up @@ -81,8 +81,7 @@ const char kInputFile[] = "input-file";

// Specify the path to the compressed Chrome archive for install. If not
// specified, chrome.packed.7z or chrome.7z in the same directory as setup.exe
// is used (the packed file is preferred; see kUncompressedArchive to force use
// of an uncompressed archive).
// is used.
const char kInstallArchive[] = "install-archive";

// Specify the file path of Chrome initial preference file.
Expand Down Expand Up @@ -180,10 +179,6 @@ const char kSystemLevel[] = "system-level";
// Signals to setup.exe that it should trigger the active setup command.
const char kTriggerActiveSetup[] = "trigger-active-setup";

// Use the given uncompressed chrome.7z archive as the source of files to
// install.
const char kUncompressedArchive[] = "uncompressed-archive";

// If present, setup will uninstall chrome.
const char kUninstall[] = "uninstall";

Expand Down
1 change: 0 additions & 1 deletion chrome/installer/util/util_constants.h
Expand Up @@ -209,7 +209,6 @@ extern const char kShowEula[];
extern const char kStoreDMToken[];
extern const char kSystemLevel[];
extern const char kTriggerActiveSetup[];
extern const char kUncompressedArchive[];
extern const char kUninstall[];
extern const char kUpdateSetupExe[];
extern const char kVerboseLogging[];
Expand Down
35 changes: 19 additions & 16 deletions chrome/tools/build/win/create_installer_archive.py
Expand Up @@ -70,10 +70,16 @@ def BuildVersion():
return '%s.%s.%s.%s' % (major, minor, build, patch)


def CompressUsingLZMA(build_dir, compressed_file, input_file, verbose):
def CompressUsingLZMA(build_dir, compressed_file, input_file, verbose, fast):
lzma_exec = GetLZMAExec(build_dir)
cmd = [lzma_exec,
'a', '-t7z',
]
if fast:
cmd.append('-mx1')
else:
cmd.extend(
[
# Flags equivalent to -mx9 (ultra) but with the bcj2 turned on (exe
# pre-filter). This results in a ~2.3MB decrease in installer size on
# a 24MB installer.
Expand All @@ -89,8 +95,13 @@ def CompressUsingLZMA(build_dir, compressed_file, input_file, verbose):
'-mb0:1',
'-mb0s1:2',
'-mb0s2:3',
os.path.abspath(compressed_file),
os.path.abspath(input_file),]
])
cmd.extend(
[
os.path.abspath(compressed_file),
os.path.abspath(input_file),
]
)
if os.path.exists(compressed_file):
os.remove(compressed_file)
RunSystemCommand(cmd, verbose)
Expand Down Expand Up @@ -300,14 +311,6 @@ def path_fixup(path):
os.remove(archive_file)
RunSystemCommand(cmd, options.verbose)

# Do not compress the archive when skip_archive_compression is specified.
if options.skip_archive_compression:
compressed_file = os.path.join(
options.output_dir, options.output_name + COMPRESSED_ARCHIVE_SUFFIX)
if os.path.exists(compressed_file):
os.remove(compressed_file)
return os.path.basename(archive_file)

# 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.
Expand All @@ -329,7 +332,7 @@ def path_fixup(path):
compressed_archive_file_path = os.path.join(options.output_dir,
compressed_archive_file)
CompressUsingLZMA(options.build_dir, compressed_archive_file_path, orig_file,
options.verbose)
options.verbose, options.fast_archive_compression)

return compressed_archive_file

Expand All @@ -351,7 +354,7 @@ def PrepareSetupExec(options, current_version, prev_version):
'_from_' + prev_version + COMPRESSED_FILE_EXT
setup_file_path = os.path.join(options.build_dir, setup_file)
CompressUsingLZMA(options.build_dir, setup_file_path, patch_file,
options.verbose)
options.verbose, options.fast_archive_compression)
else:
# Use makecab.py instead of makecab.exe so that this works when building
# on non-Windows hosts too.
Expand Down Expand Up @@ -616,10 +619,10 @@ def _ParseOptions():
help='Whether this archive is packaging a component build.')
parser.add_option('--component_ffmpeg_build', default='0',
help='Whether this archive is packaging with ffmpeg component build.')
parser.add_option('--skip_archive_compression',
parser.add_option('--fast_archive_compression',
action='store_true', default=False,
help='This will turn off compression of chrome.7z into chrome.packed.7z '
'and helpfully delete any old chrome.packed.7z in |output_dir|.')
help='This will enable fast compression of chrome.7z into '
'chrome.packed.7z.')
parser.add_option('--depfile',
help='Generate a depfile with the given name listing the implicit inputs '
'to the archive process that can be used with a build system.')
Expand Down

0 comments on commit acc7c7d

Please sign in to comment.