Rollup merge of #113631 - lqd:fix-113597, r=petrochenkov
make MCP510 behavior opt-in to avoid conflicts between the CLI and target flavors Fixes #113597, which contains more details on how this happens through the code, and showcases an unexpected `Gnu(Cc::Yes, Lld::Yes)` flavor. #112910 added support to use `lld` when the flavor requests it, but didn't explicitly do so only when using `-Clink-self-contained=+linker` or one of the unstable `-Clinker-flavor`s. The problem: some targets have a `lld` linker and flavor, e.g. `thumbv6m-none-eabi` from that issue. Users can override the linker but there are no linker flavors precise enough to describe the linker opting out of lld: when using `-Clinker=arm-none-eabi-gcc`, we infer this is a `Cc::Yes` linker flavor, but the `lld` component is unknown and therefore defaulted to the target's linker flavor, `Lld::Yes`. <details> <summary>Walkthrough of how this happens</summary> The linker flavor used is a mix between what can be inferred from the CLI (`-C linker`) and the target's default linker flavor: - there is no linker flavor on the CLI (and that also offers another workaround on nightly: `-C linker-flavor=gnu-cc -Zunstable-options`), so it will have to be inferred [from here](5dac6b320b/compiler/rustc_codegen_ssa/src/back/link.rs (L1334-L1336)
) to [here](5dac6b320b/compiler/rustc_codegen_ssa/src/back/link.rs (L1321-L1327)
). - in [`infer_linker_hints`](5dac6b320b/compiler/rustc_target/src/spec/mod.rs (L320-L352)
) `-C linker=arm-none-eabi-gcc` infers a `Some(Cc::Yes)` cc hint, and no hint about lld. - the target's `linker_flavor` is combined in `with_cli_hints` with these hints. We have our `Cc::Yes`, but there is no hint about lld, [so the target's flavor `lld` component is used](5dac6b320b/compiler/rustc_target/src/spec/mod.rs (L356-L358)
). It's [`Gnu(Cc::No, Lld::Yes)`](993deaa0bf/compiler/rustc_target/src/spec/thumb_base.rs (L35)
). - so we now have our `Gnu(Cc::Yes, Lld::Yes)` flavor </details> This results in a `Gnu(Cc::Yes, Lld::Yes)` flavor on a non-lld linker, causing an additional unexpected `-fuse-ld=lld` argument to be passed. I don't know if this target defaulting to `rust-lld` is expected, but until MCP510's new linker flavor are stable, when people will be able to describe their linker/flavor accurately, this PR keeps the stable behavior of not doing anything when the linker/flavor on the CLI unexpectedly conflict with the target's. I've tested this on a `no_std` `-C linker=arm-none-eabi-gcc -C link-arg=-nostartfiles --target thumbv6m-none-eabi` example, trying to simulate one of `cortex-m`'s test mentioned in issue #113597 (I don't know how to build a local complete `thumbv6m-none-eabi` toolchain to run the exact test), and checked that `-fuse-lld` was indeed gone and the error disappeared. r? `````@petrochenkov`````
This commit is contained in:
commit
fc1cb0459d
1 changed files with 17 additions and 2 deletions
|
@ -2970,10 +2970,25 @@ fn add_lld_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
|
|||
return;
|
||||
}
|
||||
|
||||
let self_contained_linker = sess.opts.cg.link_self_contained.linker();
|
||||
|
||||
// FIXME: some targets default to using `lld`, but users can only override the linker on the CLI
|
||||
// and cannot yet select the precise linker flavor to opt out of that. See for example issue
|
||||
// #113597 for the `thumbv6m-none-eabi` target: a driver is used, and its default linker
|
||||
// conflicts with the target's flavor, causing unexpected arguments being passed.
|
||||
//
|
||||
// Until the new `LinkerFlavor`-like CLI options are stabilized, we only adopt MCP510's behavior
|
||||
// if its dedicated unstable CLI flags are used, to keep the current sub-optimal stable
|
||||
// behavior.
|
||||
let using_mcp510 =
|
||||
self_contained_linker || sess.opts.cg.linker_flavor.is_some_and(|f| f.is_unstable());
|
||||
if !using_mcp510 && !unstable_use_lld {
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. Implement the "self-contained" part of this feature by adding rustc distribution
|
||||
// directories to the tool's search path.
|
||||
let self_contained_linker = sess.opts.cg.link_self_contained.linker() || unstable_use_lld;
|
||||
if self_contained_linker {
|
||||
if self_contained_linker || unstable_use_lld {
|
||||
for path in sess.get_tools_search_paths(false) {
|
||||
cmd.arg({
|
||||
let mut arg = OsString::from("-B");
|
||||
|
|
Loading…
Add table
Reference in a new issue