Skip to content

Config keys for and targets with dots in its name. #15901

@tanshihaj

Description

@tanshihaj

Problem

I'm trying to compile rust program for the "thumbv8m.main-none-eabi" target and apparently cannot understand how to specify various configs for this target in .cargo/config.toml file in [target."thumbv8m.main-none-eabi"] table.

Lets say I want to test new fancy /usr/bin/false linker with my program. So I'm creating .cargo/config.toml in the root of the project with following content:

[target."thumbv8m.main-none-eabi"]
"linker" = "/usr/bin/false"

and running compilation for the thumbv8m.main-none-eabi target:

$ cargo build -v --target thumbv8m.main-none-eabi
   Compiling cortex-m33 v0.0.1 (/home/kamil/code/test/cortex-m33)
     Running `rustc --crate-name cortex_m33 --edition=2021 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=380 --crate-type bin --emit=dep-info,link -C panic=abort -C embed-bitcode=no -C debuginfo=2 --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values())' -C metadata=58ca4f7134653c7f -C extra-filename=-3b13f08da6609273 --out-dir /home/kamil/code/test/cortex-m33/target/thumbv8m.main-none-eabi/debug/deps --target thumbv8m.main-none-eabi -C incremental=/home/kamil/code/test/cortex-m33/target/thumbv8m.main-none-eabi/debug/incremental -L dependency=/home/kamil/code/test/cortex-m33/target/thumbv8m.main-none-eabi/debug/deps -L dependency=/home/kamil/code/test/cortex-m33/target/debug/deps`
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.68s

For some reason cargo does not pass the /usr/bin/false linker to the rustc.

At the same time if I'm specifying the same config for the thumbv7m-none-eabi target:

[target."thumbv7m-none-eabi"]
"linker" = "/usr/bin/false"

cargo uses correct linker:

$ cargo build -v --target thumbv7m-none-eabi
   Compiling cortex-m3 v0.1.0 (/home/kamil/code/test/cortex-m3)
     Running `rustc --crate-name cortex_m3 --edition=2021 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=380 --crate-type bin --emit=dep-info,link -C panic=abort -C embed-bitcode=no -C debuginfo=2 --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values())' -C metadata=400f54e48fcd3f1f -C extra-filename=-e46df0b3d5d7b4af --out-dir /home/kamil/code/test/cortex-m3/target/thumbv7m-none-eabi/debug/deps --target thumbv7m-none-eabi -C linker=/usr/bin/false -C incremental=/home/kamil/code/test/cortex-m3/target/thumbv7m-none-eabi/debug/incremental -L dependency=/home/kamil/code/test/cortex-m3/target/thumbv7m-none-eabi/debug/deps -L dependency=/home/kamil/code/test/cortex-m3/target/debug/deps`
error: linker `/usr/bin/false` not found
  |
  = note: No such file or directory (os error 2)

error: could not compile `cortex-m3` (bin "cortex-m3") due to 1 previous error

Caused by:
  process didn't exit successfully: `rustc --crate-name cortex_m3 --edition=2021 src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=380 --crate-type bin --emit=dep-info,link -C panic=abort -C embed-bitcode=no -C debuginfo=2 --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values())' -C metadata=400f54e48fcd3f1f -C extra-filename=-e46df0b3d5d7b4af --out-dir /home/kamil/code/test/cortex-m3/target/thumbv7m-none-eabi/debug/deps --target thumbv7m-none-eabi -C linker=/usr/bin/false -C incremental=/home/kamil/code/test/cortex-m3/target/thumbv7m-none-eabi/debug/incremental -L dependency=/home/kamil/code/test/cortex-m3/target/thumbv7m-none-eabi/debug/deps -L dependency=/home/kamil/code/test/cortex-m3/target/debug/deps` (exit status: 1)

Probably the issue is the way cargo encodes the configuration option keys to retrieve the configuration value:

let runner: OptValue<PathAndArgs> = gctx.get(&format!("{prefix}.runner"))?;
let rustflags: OptValue<StringList> = gctx.get(&format!("{prefix}.rustflags"))?;
let rustdocflags: OptValue<StringList> = gctx.get(&format!("{prefix}.rustdocflags"))?;
let linker: OptValue<ConfigRelativePath> = gctx.get(&format!("{prefix}.linker"))?;

It first create target.thumbv8m.main-none-eabi.linker string and then split it by . char which obviously create wrong table in config file.

Steps

  1. Create simple embedded rust program.

    • main.rs

        #![no_std]
        #![no_main]
      
        use cortex_m_rt::entry;
        use panic_halt as _;
      
        #[entry]
        fn main() -> ! {
            loop {}
        }
      
    • Cargo.toml

        [package]
        name = "cortex-m33"
        version = "0.1.0"
        edition = "2021"
      
        [dependencies]
        cortex-m-rt = "0.7"
        panic-halt = "0.2"
      
    • .cargo/config.toml

        [build]
        target = "thumbv8m.main-none-eabi"
      
        [target."thumbv8m.main-none-eabi"]
        "linker" = "/usr/bin/false"
      
  2. Prepare rustc for the cross-compilation for thumbv8m.main-none-eabi target: rustup target add thumbv8m.main-none-eabi.

  3. Run build with cargo build -v and see that cargo do not pass -C linker=/usr/bin/false to the rustc.

Possible Solution(s)

Probably crate code should not pass path to the config option as a string but as a parsed ConfigKey when querying config values.

Notes

No response

Version

$ cargo version --verbose
cargo 1.88.0 (873a06493 2025-05-10)
release: 1.88.0
commit-hash: 873a0649350c486caf67be772828a4f36bb4734c
commit-date: 2025-05-10
host: x86_64-unknown-linux-gnu
libgit2: 1.9.0 (sys:0.20.0 vendored)
libcurl: 8.14.1 (sys:0.4.80+curl-8.12.1 system ssl:OpenSSL/3.5.1)
os: NixOS 25.5.0 [64-bit]

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-configurationArea: cargo config files and env varsC-bugCategory: bugS-triageStatus: This issue is waiting on initial triage.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions