Skip to content

#[link...] disabled via link_cfg feature still results in errors #155067

@anforowicz

Description

@anforowicz

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" {}                                                                                                                                                                                                                                                        
    }         
// ...

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions