Open

Description
The original issue title was "Implement cross-language ThinLTO," #49879 but when it was stabilized, the PR title became "Stabilize linker-plugin based LTO (aka cross-language LTO)," #58057 which seems to imply that fullLTO is available. The Rustc book states, "In both cases the Rust code has to be compiled with -C linker-plugin-lto and the C/C++ code with -flto or -flto=thin so that object files are emitted as LLVM bitcode," https://doc.rust-lang.org/rustc/linker-plugin-lto.html which also seems to confirm this. However, the documentation does not provide an example of fullLTO, and simply replacing "-flto=thin" with "-flto" does not work. Therefore, this should be considered a bug.
// with clang -flto=thin
// works
000000000005e054 <c_func_in_rust>:
5e054: 52800540 mov w0, #0x2a // #42
5e058: d65f03c0 ret
// with clang -flto
// doesn't work
000000000005e09c <c_func_in_rust>:
5e09c: 17ffffd9 b 5e000 <c_func_in_c>
000000000005e000 <c_func_in_c>:
5e000: 52800540 mov w0, #0x2a // #42
5e004: d65f03c0 ret
$ rustc --version --verbose
rustc 1.85.1 (4eb161250 2025-03-15)
binary: rustc
commit-hash: 4eb161250e340c8f48f66e2b929ef4a5bed7c181
commit-date: 2025-03-15
host: aarch64-unknown-linux-gnu
release: 1.85.1
LLVM version: 19.1.7
# build.sh
# copied from https://doc.rust-lang.org/rustc/linker-plugin-lto.html
clang ./clib.c -flto=thin -c -o ./clib.o -O2
# ^^^^^ remove this and it will not work
ar crus ./libxyz.a ./clib.o
RUSTFLAGS="-Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld" cargo build --release
objdump -d target/release/x > dump
// main.rs
use std::ffi::c_int;
fn main() {
println!("{}", c_func_in_rust());
}
#[inline(never)]
#[unsafe(no_mangle)]
pub extern "C" fn c_func_in_rust() -> c_int {
unsafe { c_func_in_c() }
}
unsafe extern "C" {
fn c_func_in_c() -> c_int;
}
// build.rs
fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rustc-link-search=.");
println!("cargo:rustc-link-lib=xyz")
}
// clib.c
int c_func_in_c() {
return 42;
}
# Cargo.toml
[package]
name = "x"
version = "0.1.0"
edition = "2024"
x
├── build.rs
├── build.sh
├── Cargo.toml
├── clib.c
└── src
└── main.rs