Build Configuration - The Rust Performance Book
RUSTFLAGS="-C target-cpu=native" cargo build --release
works fine. But I am unable to set target-cpu=native globally in a configuration file. For example I tried a lot of variants like
$ cat ~/.cargo/config.toml
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=mold", "-C", "target-cpu=native"]
#[build]
#rustflags = ["-C", "target-cpu=native"]
#[build]
# Use a single absolute path for all build artifacts
#target-dir = "/home/stefan/.cargo/target_shared"
[profile.dev]
# One debuginfo file per dependency, to reduce file size of tests/examples.
# Note that this value is not supported on Windows.
# See https://doc.rust-lang.org/cargo/reference/profiles.html#split-debuginfo
#split-debuginfo="unpacked"
jonh
February 4, 2026, 11:22pm
2
What makes you think it has not been set?
kornel
February 5, 2026, 12:10am
3
Cargo has a bunch of rules for which of the many ways of setting RUSTFLAGS take precedence, and which are merged and which are replacing.
The global config will work if there are no per-target config sections. The per-target sections will work if there are no env vars replacing them. Various config files will merge settings when you use arrays, but won't when you set a single string.
1 Like
As we can learn from the performance book:
stefan@hx90 ~ $ rustc --print cfg
debug_assertions
panic="unwind"
target_abi=""
target_arch="x86_64"
target_endian="little"
target_env="gnu"
target_family="unix"
target_feature="fxsr"
target_feature="sse"
target_feature="sse2"
target_has_atomic="16"
target_has_atomic="32"
target_has_atomic="64"
target_has_atomic="8"
target_has_atomic="ptr"
target_os="linux"
target_pointer_width="64"
target_vendor="unknown"
unix
stefan@hx90 ~ $ rustc --print cfg -C target-cpu=native
debug_assertions
panic="unwind"
target_abi=""
target_arch="x86_64"
target_endian="little"
target_env="gnu"
target_family="unix"
target_feature="adx"
target_feature="aes"
target_feature="avx"
target_feature="avx2"
target_feature="bmi1"
target_feature="bmi2"
target_feature="cmpxchg16b"
target_feature="f16c"
target_feature="fma"
target_feature="fxsr"
target_feature="lzcnt"
target_feature="movbe"
target_feature="pclmulqdq"
target_feature="popcnt"
target_feature="rdrand"
target_feature="rdseed"
target_feature="sha"
target_feature="sse"
target_feature="sse2"
target_feature="sse3"
target_feature="sse4.1"
target_feature="sse4.2"
target_feature="sse4a"
target_feature="ssse3"
target_feature="vaes"
target_feature="vpclmulqdq"
target_feature="xsave"
target_feature="xsavec"
target_feature="xsaveopt"
target_feature="xsaves"
target_has_atomic="16"
target_has_atomic="32"
target_has_atomic="64"
target_has_atomic="8"
target_has_atomic="ptr"
target_os="linux"
target_pointer_width="64"
target_vendor="unknown"
unix
stefan@hx90 ~ $
Alternative test:
stefan@hx90 ~ $ cd /tmp/
stefan@hx90 /tmp $ cargo new flags
Creating binary (application) `flags` package
note: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
stefan@hx90 /tmp $ cd flags/
stefan@hx90 /tmp/flags $ RUSTFLAGS="-C target-cpu=native" cargo build --release
Compiling flags v0.1.0 (/tmp/flags)
Finished `release` profile [optimized] target(s) in 0.28s
stefan@hx90 /tmp/flags $ ls -l target/release/flags
-rwxr-xr-x 2 stefan stefan 450640 Feb 5 09:55 target/release/flags
stefan@hx90 /tmp/flags $ cargo build --release
Compiling flags v0.1.0 (/tmp/flags)
Finished `release` profile [optimized] target(s) in 0.10s
stefan@hx90 /tmp/flags $ ls -l target/release/flags
-rwxr-xr-x 2 stefan stefan 484296 Feb 5 09:56 target/release/flags
stefan@hx90 /tmp/flags $
As you can see, target-cpu=native results in a smaller binary and I assume is some cases in faster code.
StefanSalewski:
rustc --print cfg
This will not use Cargo config. You might want cargo rustc --print cfg instead.
stefan@hx90 /tmp/flags $ cargo rustc --print cfg
error: the `print` flag is unstable, and only available on the nightly channel of Cargo, but this is the `stable` channel
See https://doc.rust-lang.org/book/appendix-07-nightly-rust.html for more information about Rust release channels.
See https://github.com/rust-lang/cargo/issues/9357 for more information about the `print` flag.
But my test with cargo build --release comparing the executable sizes confirms that the native flag is not picked up.
Schard
February 5, 2026, 10:57am
7
Are you positive, that you un-commented the #[build] section as well?
jonh
February 5, 2026, 11:14am
8
Are you sure that (file size) is not from mold? (env replaces rather than supplements the config.)
Can use sudo forkstat -e exec to watch what processes get started.
Oh, that is a good hint.
In any case, it would be good if some experts could update the section Build Configuration - The Rust Performance Book as the note
If you are unsure whether -C target-cpu=native is working optimally, compare the output of rustc --print cfg and rustc --print cfg -C target-cpu=native to see if the CPU features are being detected correctly in the latter case.
might be incorrect as noted by Cerber-Ursi .
And the note
If not, you can use -C target-feature to target specific features.
is not very concrete, I have no idea how to do that.
I was even not sure if in ~/.cargo/config.toml
is should be
rustflags = ["-C", "link-arg=-fuse-ld=mold", "-C", "target-cpu=native"]
#or
rustflags = ["-C", "link-arg=-fuse-ld=mold", "target-cpu=native"]
#or
rustflags = ["-C", "link-arg=-fuse-ld=mold", "-C target-cpu=native"]
But I tested different combinations, and will continue testing soon.
The different file sizes resulted indeed from use of mold linker.
But I have still no idea if target-cpu=native is active or not. The --verboseflag does not really help.
cargo build --verbose --release
Dirty flags v0.1.0 (/tmp/flags): the file `src/main.rs` has changed (1770293433.791905572s, 2m 27s after last build at 1770293286.520223102s)
Compiling flags v0.1.0 (/tmp/flags)
Running `rustc --crate-name flags --edition=2024 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=230 --crate-type bin --emit=dep-info,link -C opt-level=3 -C embed-bitcode=no --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values())' -C metadata=b7d8b7787fd4e866 -C extra-filename=-c794e5da97ae3940 --out-dir /tmp/flags/target/release/deps -C strip=debuginfo -L dependency=/tmp/flags/target/release/deps`
Finished `release` profile [optimized] target(s) in 0.07s
OK, I finally got a working solution:
$ cat ~/.cargo/config.toml
[build]
rustflags = ["-C", "target-cpu=native"]
$ cargo build --release -v
Dirty flags v0.1.0 (/tmp/flags): the file `src/main.rs` has changed (1770294539.084949853s, 23m 31s after last build at 1770293128.856573350s)
Compiling flags v0.1.0 (/tmp/flags)
Running `rustc --crate-name flags --edition=2024 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=230 --crate-type bin --emit=dep-info,link -C opt-level=3 -C embed-bitcode=no --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values())' -C metadata=b7d8b7787fd4e866 -C extra-filename=-8e851e1211211a49 --out-dir /tmp/flags/target/release/deps -C strip=debuginfo -L dependency=/tmp/flags/target/release/deps
-C target-cpu=native`
confirming that target-cpu=native is actually enabled.
And now it work with the mold linker as well:
cat ~/.cargo/config.toml
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = [
"-C", "link-arg=-fuse-ld=mold",
"-C", "target-cpu=native"
]
$ cargo build --release -v
... -C link-arg=-fuse-ld=mold -C target-cpu=native`
The main reason for my confusion was that in Rust performance book
If you are unsure whether -C target-cpu=native is working optimally, compare the output of rustc --print cfg and
is not correct and helpful, as noted by Cerber-Ursi