How to handle pre-built linkers?
ehuss opened this issue · 1 comments
Some pre-built standard library targets include a copy of rust-lld or gcc to assist with linking. We should probably figure out if these should be considered.
I'm not sure how this should be approached to supporting these targets. Some possible ideas:
- Ship
rust-lld
as a rustup component. - Force the user to install the appropriate linker themselves (other targets assume some kind of linker exists).
I'm actually not sure what is special about rust-lld
(does it deviate from stock lld
?). It may be easier for the user to install the real lld
, though there would need to be some way for cargo and rustc to know what to use, and provide good error messages if it is not installed.
There is some more detail in #30 (comment).
The most unusual target is x86_64-pc-windows-gnu
which ships gcc. I always find getting a working version of mingw a chore.
The following targets appear to want to use rust-lld
:
- aarch64-unknown-none
- armebv7r-none-eabi
- armebv7r-none-eabihf
- armv7r-none-eabi
- armv7r-none-eabihf
- fuchsia*
- i686-unknown-uefi
- riscv32i-unknown-none-elf
- riscv32imac-unknown-none-elf
- riscv32imc-unknown-none-elf
- riscv64gc-unknown-none-elf
- riscv64imac-unknown-none-elf
- thumb*
- wasm32*
- x86-64-unknown-uefi
I think the main question here is what to do with rust-lld
. For MinGW we ship a gcc.exe
but it's not required. We ship that largely so you don't have to install one yourself, but I frequently use the MinGW target without the bundled gcc.exe
. In that sense I think we can largely ignore gcc.exe
, and basically say that if we get MinGW working it just requires a gcc.exe
installed locally (like Linux does and such).
For rust-lld
I think it's actually quite important that we get it working transparently. It "accidentally" did when we didn't reconfigure --sysroot
, but now it doesn't unfortunately! Usage of rust-lld
(or LLD in general) is pretty important for all these embedded targets which is one of the primary reasons for -Zbuild-std
!
In any case, to answer your question about rust-lld
vs lld
. The rust-lld
binary is a stock LLD binary, without any substantial modifications (maybe some build system stuff but that's it). The main difference, however, is that rust-lld
is known to match the targets of the installed version of rustc
. Typically that doesn't matter too much but for wasm specifically LLD is changing enough in some regards that to get everything working we need to make sure rustc/lld are sync'd, which installing LLD from another source may not be easy to do so.
We also largely don't want a Rust-installed LLD to shadow or conflict with a system-installed LLD. Our intention is that it should be pretty easy (-Clinker=lld
etc) to switch to a system LLD from rust-lld
.
Note that also it's not always easiest to install LLD on all platforms, I'm not actually sure how to acquire it on OSX or Windows.
Finally, to clarify, rust-lld
is not in PATH
when rustc
starts. During rustc's execution it adds a path to PATH
specifically for invoking the linker, and that path is sourced from its own sysroot. (that's why it's broken when we switched --sysroot
)
Here's some spitballing for ideas we could solve this:
- We could promote
rust-lld.exe
to arustup.exe
-based executable. That means it'd always be inPATH
and everything would "just work". - Cargo could avoid using
--sysroot
but could use-L
instead. That means you couldn't-Zbuild-std
for a target you have in the main sysroot, though. - Cargo could take the
bin
dir out of the main sysroot for the host and move it into the sysroot it's generating. (via symlink, junction, etc) - We could change
rustc
to continue to search the default sysroot if--sysroot
is provided for executables, just not for libraries. - We could improve
rustc
's inference ofrust-lld
vs a natively installed executable, making everything "just work" if you have a preintalled LLD.