Change:
The CI tests building with all our supported linkers: Rust's provided , ARM GCC's , and ARM GCC's . It recently encountered an error when using in nightly builds since . The most likely culprit is that the failing version has started to the linker arguments, which was not present in previous working versions. I wonder if we're meant to be adding some other argument to disable adding ? The error occurs with the cortex-m-rt CI and can be reproduced like so: Or viewed in CI . The error is: nightly-2023-07-02 nightly-2023-07-03 bisected to from PR modify labels: +regression-from-stable-to-nightly -regression-untriaged
shows that the default for the target is rust-lld. i wonder if the new code uses the default instead of the linker in -C linker for some reason?
You were not meant to do anything, sorry about that. I'll fix it.
I can't build a toolchain locally, via , which would be complete enough for this test to build. There are issues about missing core/std. I tried on a example, and can also reproduce the issue and investigate more there, and that and work. The code I in is asked to add CLI arguments for a flavor: this asks to link using via a c/c++ compiler, and why is . I assume that flavor is incorrect when using ? (I don't know who the target maintainers are, so I'll also ping the other 2 people involved in : and still work because they result in a non- request, and we don't do anything there as expected. For my own understanding: does use by default maybe ? And if so, I'd expect that explicitly specifying the linker would also fix the issue, à la which seems to work for me ? I'll look into why this surprising flavor is used in this situation, as it seems to be the pre-existing issue here uncovered by the PR, and report back. It could be an issue in the flavor inference, or some information missing in the targets' definitions, and so on.
Technically, the target builds. As a tier 2 target, we would strongly prefer it to not require additional antics to build. There was but I have taken lqd's remarks that this may be just exposed preexisting problems as a reason to set it slightly lower.
The linker flavor used is a mix between what can be inferred from the CLI () and the target's default linker flavor: there is no linker flavor on the CLI (and that also offers another workaround on nightly: ), so it will have to be inferred to . in  infers a cc hint, and no hint about lld. the target's is combined in with these hints. We have our , but there is no hint about lld, . It's . so we now have our flavor is the linker people are expected to use on supposed to be some ? Is the default linker and flavor in correct ? In the meantime, I'll see to change this so that the lld flags are only when the unstable MCP510 options are used, to keep this stable and unfortunate behavior unchanged when the CLI and target conflict instead of compose.
Thanks for looking into this quickly! Most people building for will use the default linker today. It works fine for (I believe) all Rust-only projects. However, it's not uncommon to use , maybe to use specific GCC linker script directives, or just when hunting down linker-related bugs. For both of those use cases there's no problem with nightly, and I think the default in thumb_base is therefore fine. Some people do need to use when linking with pre-compiled C libraries - I understand that using gcc pulls in a target specific libc, and a lot of pre-compiled C libraries will be trying to link against symbols it exports which Rust doesn't. I believe does delegate to . Passing either or does work to get a build without errors, though I don't have a test case handy to check it's actually getting what people need out of . I'll try and dig around a bit more for the specific use cases where it's required over .
My main recollection is that gcc requires you to put in front of your linker arguments and using ld directly you don't But I think and friends are gcc options not ld options so maybe ld won't bring in libc and the C startup automatically. I'll test it out shortly.
main.c: Compile object code: Link with GCC: Link with ld: This does imply that for trivial invocations will include both the default start code (which provides ) and newlib (the C library), whilst will not.
See also , where I set the default target for bare-metal SPARC to be gcc, precisely because the default libraries it links in are so useful - they include not only the start-up code (no idea how that works, didn't need to find out) but also a C library for talking to the stdout of a popular SPARC CPU emulator. So, yeah, GCC is a really useful linker driver in some scenarios and we don't want to stop that from working.
Thanks for the information, it's very helpful. The good news is that using GCC as a linker is still working . In the future where we switch to lld, maybe rustc will also need an explicit linker flavor here, to make sure the flavor it guesses actually matches your expectations. But that's a topic for another day/stabilization: in the more immediate future, things will return to normal for the target and 's tests in a day or two.
Thank you! Just to come back to this point: I was under the impression that Arm Ltd were maintaining the targets. However, they don't appear to have the platform-support documentation that is required for more recently targets. Maybe that could be addressed.
This is now on beta, reopening to track backport.
Pursuant to your concern I have opened to summarize the issue that affects indeed all our tier 2 targets.
The backport of has landed on beta in We can close this issue as fixed.

Discussion:
return; } <ins> 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; } </ins> // 1. Implement the "self-contained" part of this feature by adding rustc distribution //    directories to the tool's search path. <del> let self_contained_linker = sess.opts.cg.link_self_contained.linker() || unstable_use_lld; if self_contained_linker { </del> <ins> if self_contained_linker || unstable_use_lld { </ins> for path in sess.get_tools_search_paths(false) { cmd.arg({ let mut arg = OsString::from("-B");