Rust
Linker
Learn linker selection and LTO settings.
The linker
The compiler turns each crate into separate object files; the linker combines them and the libraries into a single binary. Link time becomes significant in large projects; faster linkers (lld, mold) can be used. Settings in the release profile decide the scope of optimization:
[profile.release]
lto = "fat" # cross-crate inlining and dead-code removal
codegen-units = 1 # a single unit: better optimization, slower build
panic = "abort" # no unwind tables: smaller binary
strip = true # strip symbols
lto = "thin" gives most of the gain of full LTO in much less time.
Choose settings by measuring
Every setting is a trade-off: speed, size and build time. For size use opt-level = "z", for speed opt-level = 3; different profiles should be tried and measured before shipping. Custom profiles can be defined:
[profile.dagitim]
inherits = "release"
lto = "fat"
codegen-units = 1
$ cargo build --profile dagitim
The profile file is a simple key = value format; tools can read it and produce suggestions.
Exercise Read a profile
Read the text "lto = \"fat\"\ncodegen-units = 1\nopt-level = 3" line by line, split each line with split_once('='), trim keys and values, strip the quotes and put them in a BTreeMap. Print the number of settings and the value of lto separated by a space.
Show example solution
use std::collections::BTreeMap;
fn main() {
let metin = "lto = \"fat\"\ncodegen-units = 1\nopt-level = 3";
let mut ayarlar = BTreeMap::new();
for s in metin.lines() {
if let Some((a, d)) = s.split_once('=') {
ayarlar.insert(a.trim().to_string(), d.trim().trim_matches('"').to_string());
}
}
println!("{} {}", ayarlar.len(), ayarlar["lto"]);
}
Test yourself
-
What does LTO (link-time optimization) make possible?
- Optimizing functions in different crates together (inlining, dead-code removal)
- Faster builds
- Debugging
- Cross compilation
Show answer
Optimizing functions in different crates together (inlining, dead-code removal) — Without LTO each crate is optimized separately; small functions in dependencies may not be inlined.
-
Cross-crate optimization
[profile.release]
____ = "fat"
Show answer
[profile.release]
lto = "fat"
-
Setting and effect
- lto = "fat"
- Full LTO
- codegen-units = 1
- Single optimization unit
- panic = "abort"
- Smaller binary
- opt-level = "z"
- Size-focused
Next lesson: Profiling