REPRO STEPS:
$ cat lib.rs
// Mimicking `std` behavior which uses the unstable `link_cfg` feature:
// https://github.com/rust-lang/rust/blob/f5eca4fcfa908d1e038afd19c6e746f075859130/library/std/src/lib.rs#L290
#![feature(link_cfg)]
#![allow(internal_features)]
// Mimicking part of `library/std/src/sys/pal/unix/mod.rs`:
// https://github.com/rust-lang/rust/blob/f5eca4fcfa908d1e038afd19c6e746f075859130/library/std/src/sys/pal/unix/mod.rs#L308-L315
//
// The expected behavior is that the whole `link` attribute is ignored when
// the `cfg` conditions are not met.
#[link(name = "dl", kind = "static", modifiers = "-bundle", cfg(FLAG_THAT_IS_NOT_SET))]
unsafe extern "C" {}
$ rustc --crate-type=dylib -ldl lib.rs
error: overriding linking modifiers from command line is not supported
--> lib.rs:12:1
|
12 | unsafe extern "C" {}
| ^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error
EXPECTED BEHAVIOR: The entire #[link...] attribute should be ignored because cfg conditions are not met
ACTUAL BEHAVIOR: The #[link...] was still processed, leading to the overriding linking modifiers from command line is not supported error.
Meta
$ rustc --version --verbose
rustc 1.96.0-nightly (900485642 2026-04-08)
binary: rustc
commit-hash: 900485642855f4729d926ecf24680a791f9293cf
commit-date: 2026-04-08
host: x86_64-unknown-linux-gnu
release: 1.96.0-nightly
LLVM version: 22.1.2
Discussion
The real repro is trying to compile std crate, and unexpectedly applying the top #[link...] even though the crt_static target_feature is disabled. In particular, I expect this piece of code to apply and check only the 2nd and 3rd #[link...] attributes when crt_static target_feature is disabled:
|
cfg_select! { |
|
target_os = "android" => { |
|
#[link(name = "dl", kind = "static", modifiers = "-bundle", |
|
cfg(target_feature = "crt-static"))] |
|
#[link(name = "dl", cfg(not(target_feature = "crt-static")))] |
|
#[link(name = "log", cfg(not(target_feature = "crt-static")))] |
|
unsafe extern "C" {} |
|
} |
I tested that the error I've observed when building std as dylib goes away after changing library/std/src/sys/pal/unix/mod.rs to check the crt_static target_feature via cfg_select! as follows:
cfg_select! {
all(target_os = "android", target_feature = "crt-static") => {
#[link(name = "dl", kind = "static", modifiers = "-bundle")]
unsafe extern "C" {}
}
all(target_os = "android", not(target_feature = "crt-static")) => {
#[link(name = "dl")]
#[link(name = "log")]
unsafe extern "C" {}
}
// ...
REPRO STEPS:
EXPECTED BEHAVIOR: The entire
#[link...]attribute should be ignored becausecfgconditions are not metACTUAL BEHAVIOR: The
#[link...]was still processed, leading to theoverriding linking modifiers from command line is not supportederror.Meta
Discussion
The real repro is trying to compile
stdcrate, and unexpectedly applying the top#[link...]even though thecrt_statictarget_featureis disabled. In particular, I expect this piece of code to apply and check only the 2nd and 3rd#[link...]attributes whencrt_statictarget_featureis disabled:rust/library/std/src/sys/pal/unix/mod.rs
Lines 308 to 315 in f5eca4f
I tested that the error I've observed when building
stdasdylibgoes away after changinglibrary/std/src/sys/pal/unix/mod.rsto check thecrt_statictarget_featureviacfg_select!as follows: