Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
build: reduce linux release binary size by 87%
Our Linux release binary was hilariously large, weighing in at nearly 800MB (!). Nearly all of the bloat was from DWARF debug info: $ bloaty materialized -n 10 FILE SIZE VM SIZE -------------- -------------- 24.5% 194Mi 0.0% 0 .debug_info 24.1% 191Mi 0.0% 0 .debug_loc 13.8% 109Mi 0.0% 0 .debug_pubtypes 10.1% 79.9Mi 0.0% 0 .debug_pubnames 8.8% 70.0Mi 0.0% 0 .debug_str 8.3% 66.3Mi 0.0% 0 .debug_ranges 4.4% 35.3Mi 0.0% 0 .debug_line 3.1% 24.8Mi 66.3% 24.8Mi .text 1.8% 14.4Mi 25.1% 9.39Mi [41 Others] 0.6% 4.79Mi 0.0% 0 .strtab 0.4% 3.22Mi 8.6% 3.22Mi .eh_frame 100.0% 793Mi 100.0% 37.4Mi TOTAL This patch gets a handle on this by attacking the problem from several angles: 1. We instruct the linker to compress debug info sections. Most of the debug info is redundant and compresses exceptionally well. Part of the reason we didn't notice the issue is because our Docker images and gzipped tarballs were relatively small (~150MB). 2. We strip out the unnecessary `.debug_pubnames` and `.debug_pubtypes` from the binary. This works around a known Rust bug (rust-lang/rust#46034). 3. We ask Rust to generate less debug info for release builds, limiting it to line info. This is enough information to symbolicate a backtrace, but not enough information to run an interactive debugger. This is usually the right tradeoff for a release build. $ bloaty materialized -n 10 VM SIZE FILE SIZE -------------- -------------- 0.0% 0 .debug_info 31.9Mi 33.8% 70.5% 25.0Mi .text 25.0Mi 26.5% 0.0% 0 .debug_str 7.54Mi 8.0% 0.0% 0 .debug_line 6.36Mi 6.7% 9.4% 3.33Mi [38 Others] 5.36Mi 5.7% 0.0% 0 .strtab 4.71Mi 5.0% 0.0% 0 .debug_ranges 3.55Mi 3.8% 8.8% 3.11Mi .eh_frame 3.11Mi 3.3% 0.0% 0 .symtab 2.87Mi 3.0% 6.0% 2.12Mi .rodata 2.12Mi 2.2% 5.4% 1.92Mi .gcc_except_table 1.92Mi 2.0% 100.0% 35.5Mi TOTAL 94.4Mi 100.0% One issue remains unsolved, which is that Rust/LLVM cannot currently garbage collect DWARF that refers to unused symbols/types. The actual symbols get cut from the binary, but their debug info remains. Follow rust-lang/rust#56068 and LLVM D74169 [0] if curious. I tested with the aforementioned lld patch (and none of the other changes) and it cut the binary down to 300MB. With the other changes, the savings are less substantial, but probably another 10MB to be had. [0]: https://reviews.llvm.org/D74169
- Loading branch information