I assume you're already doing this since you're on a microcontroller, but have you set
[profile.release]
codegen-units = 1
lto = true [profile.release]
codegen-units = 1
lto = true [profile.release]
opt-level = "z"
lto = true
overflow-checks = false
codegen-units = 1
debug = false
Also invoking cargo with:
cargo build --release -Z build-std=core -Z build-std-features=panic_immediate_abortYou must then implement panic handling yourself:
pub mod std {
#[lang = "eh_personality"]
#[no_mangle]
pub unsafe extern "C" fn rust_eh_personality() -> () {}
// panic can be replaced by abort with the panic_immediate_abort feature.
// -Z build-std-features=panic_immediate_abort
// This saves space by getting rid of the unwinding.
#[panic_handler]
pub unsafe fn panic_impl(_info: &::core::panic::PanicInfo) -> ! {
loop {}
}
#[no_mangle]
pub unsafe extern "C" fn abort() {
// blink led
loop {}
}
}
If I still have some room in the flash, I will make some led blink with a noticable pattern on abort.You can also experiment with the inlining threshold:
export RUSTFLAGS+=-C inline-threshold=0The valid options are:
false: Performs “thin local LTO” which performs “thin” LTO on the local crate only across its codegen units. No LTO is performed if codegen units is 1 or opt-level is 0.
true or "fat": Performs “fat” LTO which attempts to perform optimizations across all crates within the dependency graph.
"thin": Performs “thin” LTO. This is similar to “fat”, but takes substantially less time to run while still achieving performance gains similar to “fat”.
"off": Disables LTO.
Basically, increases performance at cost of compile time. Great for release builds, not so much for debug builds (because most of the time that rustc spends is on linking anyways.)