diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 0000000000000..e4c0c93aa37b4 --- /dev/null +++ b/.cargo/config @@ -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"] diff --git a/.gitignore b/.gitignore index 3e219c873a51b..d19e3bed16e89 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,6 @@ target miri-target -/.cargo .mtrlz.log **/*.rs.bk .netlify diff --git a/Cargo.toml b/Cargo.toml index a5fa23dd36ccf..eff750733e27a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 symbolicate a backtrace, but not enough to use a debugger interactively. +# 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: diff --git a/bin/lint b/bin/lint index 1aa020cdb2cad..8da770d9679ac 100755 --- a/bin/lint +++ b/bin/lint @@ -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$' \ diff --git a/misc/python/mzbuild.py b/misc/python/mzbuild.py index a9d4339391572..1b66e2f30a63e 100644 --- a/misc/python/mzbuild.py +++ b/misc/python/mzbuild.py @@ -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]: @@ -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" ) @@ -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( @@ -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" )