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 varsA-cross-compilingArea: using --target flag for other platformsA-environment-variablesArea: environment variablesC-bugCategory: bugS-needs-designStatus: Needs someone to work further on the design for the feature or fix. NOT YET accepted.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions