Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: reduce linux release binary size by 87% #2691

Merged
merged 2 commits into from
Apr 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[target."x86_64-unknown-linux-gnu"]
# Compressing debug information can yield hundreds of megabytes of savings.
# The Rust toolchain does not currently perform dead code elimination on
# debug info.
#
# See: https://github.com/rust-lang/rust/issues/56068
# See: https://reviews.llvm.org/D74169#1990180
rustflags = ["-C", "link-arg=-Wl,--compress-debug-sections=zlib-gabi"]
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

target
miri-target
/.cargo
.mtrlz.log
**/*.rs.bk
.netlify
Expand Down
8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@ members = [
]

[profile.release]
debug = true
# Emit only the line info tables, not full debug info, in release builds, to
# substantially reduce the size of the debug info. Line info tables are enough
# to correctly symbolicate a backtrace, but do not produce an ideal interactive
# debugger experience. This seems to be the right tradeoff for release builds:
# it's unlikely we're going to get interactive access to a debugger in
# production installations, but we still want useful crash reports.
debug = 1

[patch.crates-io]
# Waiting on a release with this commit:
Expand Down
1 change: 1 addition & 0 deletions bin/lint
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ copyright_files=$(grep -vE \
-e '(^|/)\.gitmodules$' \
-e '(^|/)go\.sum$' \
-e '(^|/)Cargo\.toml$' \
-e '^\.cargo/config$' \
-e '^Cargo\.lock$' \
-e '^deny\.toml$' \
-e '^netlify\.toml$' \
Expand Down
3 changes: 2 additions & 1 deletion bin/xcompile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

set -euo pipefail

root=$(dirname "$0")/..
root=$(cd "$(dirname "$0")/.." && pwd)

# shellcheck source=SCRIPTDIR/../misc/shlib/shlib.bash
. "$root/misc/shlib/shlib.bash"
Expand Down Expand Up @@ -61,6 +61,7 @@ do_cargo() {
export TARGET_CXX=$CXX
export TARGET_CFLAGS=$CFLAGS
export TARGET_CXXFLAGS=$CXXFLAGS
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=$CC

cargo "$subcommand" --target=x86_64-unknown-linux-gnu "$@"
}
Expand Down
37 changes: 30 additions & 7 deletions misc/python/mzbuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,15 @@ def xcargo_target_dir(root: Path) -> Path:
return root / "target" / "x86_64-unknown-linux-gnu"


def xstrip(root: Path) -> str:
def xbinutil(tool: str) -> str:
if sys.platform == "linux":
return "strip"
return tool
else:
return "x86_64-unknown-linux-gnu-strip"
return f"x86_64-unknown-linux-gnu-{tool}"


xobjcopy = xbinutil("objcopy")
xstrip = xbinutil("strip")


def docker_images() -> Set[str]:
Expand Down Expand Up @@ -157,13 +161,32 @@ def run(self, root: Path, path: Path) -> None:
# down CI, since we're packaging these binaries up into Docker
# images and shipping them around. A bit unfortunate, since it'd be
# nice to have useful backtraces if the binary crashes.
runv([xstrip(root), path / self.bin])
runv([xstrip, path / self.bin])
else:
# Even if we've been asked not to strip the binary, remove the
# `.debug_pubnames` and `.debug_pubtypes` sections. These are just
# indexes that speed up launching a debugger against the binary,
# and we're happy to have slower debugger start up in exchange for
# smaller binaries. Plus the sections have been obsoleted by a
# `.debug_names` section in DWARF 5, and so debugger support for
# `.debug_pubnames`/`.debug_pubtypes` is minimal anyway.
# See: https://github.com/rust-lang/rust/issues/46034
runv(
[
xobjcopy,
"-R",
".debug_pubnames",
"-R",
".debug_pubtypes",
path / self.bin,
]
)

def depends(self, root: Path, path: Path) -> List[bytes]:
# TODO(benesch): this should be much smarter about computing the Rust
# files that actually contribute to this binary target.
return super().depends(root, path) + git_ls_files(
root, "src/**", "Cargo.toml", "Cargo.lock"
root, "src/**", "Cargo.toml", "Cargo.lock", ".cargo"
)


Expand Down Expand Up @@ -216,7 +239,7 @@ def run(self, root: Path, path: Path) -> None:
with open(path / "tests" / "manifest", "w") as manifest:
for (executable, slug, crate_path) in tests:
shutil.copy(executable, path / "tests" / slug)
runv([xstrip(root), path / "tests" / slug])
runv([xstrip, path / "tests" / slug])
manifest.write(f"{slug} {crate_path}\n")
shutil.move(str(path / "testdrive"), path / "tests")
shutil.copy(
Expand All @@ -229,7 +252,7 @@ def depends(self, root: Path, path: Path) -> List[bytes]:
# TODO(benesch): this should be much smarter about computing the Rust
# files that actually contribute to this binary target.
return super().depends(root, path) + git_ls_files(
root, "src/**", "Cargo.toml", "Cargo.lock"
root, "src/**", "Cargo.toml", "Cargo.lock", ".cargo"
)


Expand Down