What is the smallest unit for static linking?

There are several post about executable size in this forum already. Also there are several cases that has shown that Rust scales down to small executable if you want. Logicoma - Engage (Final version) - YouTube this is made with Rust. The executable is 64k in size including all music, graphics, etc and static linking.

Sure you will need to do some effort to get to something like this but as shown this is doable.

2 Likes

There's some confusion here.

A crate is Rust's unit of compilation in the sense that rustc will always be invoked on an entire crate. At least historically speaking, that meant it would always recompile the whole thing from scratch, which was a real pitfall for compilation speed, but incremental compilation is starting to change that.

That does not mean that rustc will always bundle all of a crate's code into a final executable. In some cases rustc can eliminate dead code itself, but anything that makes it to the linking stage will be eliminated by the linker. On GNU targets, rustc passes the equivalent of -ffunction-sections as an LLVM option, and passes --gc-sections to the linker: each function goes in its own section, and the linker is told to 'garbage collect' unreferenced sections. On macOS, the linker is able to garbage collect symbols without needing separate sections, and rustc passes -dead_strip to tell it to do so. I'm not sure what happens on Windows, but it's probably similar.

Rust does tend to have issues with binary bloat – for various reasons which hopefully someone else can explain, since I'm too tired right now to try – but those reasons are entirely unrelated to crates being the unit of compilation.

LTO can help with binary size, but not because it uses a smaller unit of compilation; on the contrary, by deferring all native code generation and optimization until link time, it essentially makes the "unit of compilation" the entire program!

10 Likes

pc-windows-msvc is by far the best in this regard because link.exe not only will strip unreferenced sections (each individual function and static is a separate section), but it will even perform identical code folding resulting in size reductions to the point where LTO has no effect on binary size. Also the fact that pc-windows-msvc doesn't statically link in any C libraries like jemalloc or libbacktrace helps significantly with binary size.

6 Likes