Skip to content

[RFC] [breaking-change] change the default linker of the thumbv*m-none-eabi* targets #160

Closed
rust-lang/rust
#53648
@japaric

Description

@japaric

Summary

Change the default linker of the Thumb targets from arm-none-eabi-gcc to rustc's LLD (rust-lld).
The following targets would be affected:

  • thumbv6m-none-eabi
  • thumbv7m-none-eabi
  • thumbv7em-none-eabi
  • thumbv7em-none-eabihf

Background

The Thumb targets were added to the compiler well over a year ago. Back then we didn't know if we
were going to ship LLD with rustc so arm-none-eabi-gcc was selected as the default linker.

Fast forward to today LLD ships with rustc on tier 1 platforms (x86_64 Linux, macOS and Windows),
and rustc supports GCC-style, LLD-style and LD-style ELF linkers (the linker can be chosen using -C linker and -Z linker-flavor).

Motivation

We want to simplify the development setup for embedded developers that will be using the stable
channel. Right now the linker can't be changed on stable because the -Z linker-flavor flag is
unstable. Thus the default of GCC forces ARM Cortex-M developers to install arm-none-eabi-gcc
before they can build even the smallest embedded Rust program.

With the change proposed in this RFC those developers would be able to build and link embedded Rust
programs without having to install a C toolchain.

Detailed design

On the compiler side the change is simple so this section will focus on how end users will have to
deal with the breaking change.

Dealing with breakage

This change will be breaking for all users that are customizing the linking process with any of
these flags: -C link-arg, -C link-args, -Z pre-link-arg and -Z pre-link-args --
unfortunately this is the majority of users.

The user has two ways to fix their code:

They can switch back to GCC. Pass the flags -C linker=arm-none-eabi-gcc -Z linker-flavor=gcc to
the compiler and you'll be using GCC again. Note that once rust-lang/rust#52101 the unstable -Z linker-flavor flag won't be required.

They can change their custom linker flags to make them compatible with LLD. rust-lld will be using
the LD linker flavor which is incompatible with the current default linker flavor of GCC. The
changes will mostly consist of removing the -Wl, prefix that GCC uses. For example, -C link-arg=-Wl,-Tlink.x would become -C link-arg=-Tlink.x.

Rust stability promise

"This is a breaking change. Isn't this against Rust stability principle of "code never breaks when
moving to a newer stable release"?"

This is technically a breaking change but it will only affect nightly users because the linker is
only used to build binary crates, cdylibs crates and the like; all those types of crate require the
still unstable #[panic_implementation] feature. As long as this change is done before or at the
same time #[panic_implementation] is stabilized it won't break Rust stability promise.

Alternatives

We can leave things as they are. It won't be possible to use rust-lld on stable until either -Z linker-flavor is stabilized (-C linker=rust-lld -Z linker-flavor=ld.lld), or rust-lang/rust#52101
lands and the proposed idea of a ld_flavor field for target specifications (see
rust-lang/rust#52101 (comment)) is implemented.

Instead of changing the default linker we could stabilize -Z linker-flavor then it would be
possible to switch to rust-lld on stable using these flags: -C linker=rust-lld -C linker-flavor=ld.lld.

Disadvantages

The disadvantage of using LLD as the default linker is that it doesn't have a default library search
path. If you need to link to a system library like newlib compiled for ARM Cortex-M you would need
to supply the path to that library using the -L flag. This is not a problem if you are linking to
C code compiled using a build script.

GCC is a better linker in that case because it already knows where the system libraries are so it's
not necessary to pass a library search path that depends on a particular installation. However, it's
possible to switch the linker to GCC to make this scenario simpler (-C linker=arm-none-eabi-gcc
once rust-lang/rust#52101 lands).


We need the approval of the Cortex-M community to land this change in rustc. Do you think the change
is worth it?

cc @rust-embedded/all
cc @alevy (Tock OS)

Metadata

Metadata

Assignees

No one assigned

    Labels

    RFCdecision-acceptedWe voted on this proposal and accepted it

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions