Why are Rust executables so huge?
By default, the Rust compiler optimizes for execution speed, compilation speed, and ease of debugging (by including symbols, for example), rather than minimal binary size.
For an overview of all of the ways to reduce the size of a Rust binary, see the min-sized-rust
repository.
The current high level steps to reduce binary size are:
- Use Rust 1.32.0 or newer (which doesn't include
jemalloc
by default) - Add the following to
Cargo.toml
:
[profile.release]
opt-level = 'z' # Optimize for size.
lto = true # Enable Link Time Optimization
codegen-units = 1 # Reduce number of codegen units to increase optimizations.
panic = 'abort' # Abort on panic
strip = true # Strip symbols from binary*
*
strip = true
requires Rust 1.59+. On older Rust versions, runstrip
manually on the resulting binary.
- Build in release mode using
cargo build --release
There is more that can be done using nightly
Rust, but I'll leave that information in min-sized-rust
as it changes over time due to the use of unstable features.
You can also use #![no_std]
to remove Rust's libstd
. See min-sized-rust
for details.
Rust uses static linking to compile its programs, meaning that all libraries required by even the simplest Hello world!
program will be compiled into your executable. This also includes the Rust runtime.
To force Rust to dynamically link programs, use the command-line arguments -C prefer-dynamic
; this will result in a much smaller file size but will also require the Rust libraries (including its runtime) to be available to your program at runtime.
This essentially means you will need to provide them if the computer does not have them, taking up more space than your original statically linked program takes up.
For portability I'd recommend you statically link the Rust libraries and runtime in the way you have been doing if you were to ever distribute your programs to others.