-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #40018 - japaric:ld, r=alexcrichton
-Z linker-flavor (Please read the commit message first) This PR is an alternative to #36120 (internal lld linker). The main goal of this PR is to make it *possible* to use LLD as a linker to allow out of tree experimentation. Now that LLD is going to be shipped with LLVM 4.0, it should become easier to get a hold of LLD (hopefully, it will be packaged by Linux distros soon). Since LLD is a multiarch linker, it has the potential to make cross compilation easier (less tools need to be installed). Supposedly, LLD is also faster than the gold linker so LLD may improve build times where link times are significant (e.g. 100% incremental compilation reuse). The place where LLD shines is at linking Rust programs that don't depend on system libraries. For example, here's how you would link a bare metal ARM Cortex-M program: ``` $ xargo rustc --target thumbv7m-none-eabi -- -Z linker-flavor=ld -C linker=ld.lld -Z print-link-args "ld.lld" \ "-L" \ "$XARGO_HOME/lib/rustlib/thumbv7m-none-eabi/lib" \ "$PWD/target/thumbv7m-none-eabi/debug/deps/app-de1f86df314ad68c.0.o" \ "-o" \ "$PWD/target/thumbv7m-none-eabi/debug/deps/app-de1f86df314ad68c" \ "--gc-sections" \ "-L" \ "$PWD/target/thumbv7m-none-eabi/debug/deps" \ "-L" \ "$PWD/target/debug/deps" \ "-L" \ "$XARGO_HOME/lib/rustlib/thumbv7m-none-eabi/lib" \ "-Bstatic" \ "-Bdynamic" \ "$XARGO_HOME/lib/rustlib/thumbv7m-none-eabi/lib/libcore-11670d2bd4951fa7.rlib" $ file target/thumbv7m-none-eabi/debug/app app: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped, with debug_info ``` This doesn't require installing the `arm-none-eabi-gcc` toolchain. Even cooler (but I'm biased) is that you can link Rust programs that use [`steed`] (`steed` is a `std` re-implementation free of C dependencies for Linux systems) instead of `std` for a bunch of different architectures without having to install a single cross toolchain. [`steed`]: https://github.com/japaric/steed ``` $ xargo rustc --target aarch64-unknown-linux-steed --example hello --release -- -Z print-link-args "ld.lld" \ "-L" \ "$XARGO_HOME/lib/rustlib/aarch64-unknown-linux-steed/lib" \ "$PWD/target/aarch64-unknown-linux-steed/release/examples/hello-80c130ad884c0f8f.0.o" \ "-o" \ "$PWD/target/aarch64-unknown-linux-steed/release/examples/hello-80c130ad884c0f8f" \ "--gc-sections" \ "-L" \ "$PWD/target/aarch64-unknown-linux-steed/release/deps" \ "-L" \ "$PWD/target/release/deps" \ "-L" \ "$XARGO_HOME/lib/rustlib/aarch64-unknown-linux-steed/lib" \ "-Bstatic" \ "-Bdynamic" \ "/tmp/rustc.lAybk9Ltx93Q/libcompiler_builtins-589aede02de78434.rlib" $ file target/aarch64-unknown-linux-steed/release/examples/hello hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, not stripped, with debug_info ``` All these targets (architectures) worked with LLD: - [aarch64-unknown-linux-steed](https://github.com/japaric/steed/blob/lld/docker/aarch64-unknown-linux-steed.json) - [arm-unknown-linux-steedeabi](https://github.com/japaric/steed/blob/lld/docker/arm-unknown-linux-steedeabi.json) - [arm-unknown-linux-steedeabihf](https://github.com/japaric/steed/blob/lld/docker/arm-unknown-linux-steedeabihf.json) - [armv7-unknown-linux-steedeabihf](https://github.com/japaric/steed/blob/lld/docker/armv7-unknown-linux-steedeabihf.json) - [i686-unknown-linux-steed](https://github.com/japaric/steed/blob/lld/docker/i686-unknown-linux-steed.json) - [mips-unknown-linux-steed](https://github.com/japaric/steed/blob/lld/docker/mips-unknown-linux-steed.json) - [mipsel-unknown-linux-steed](https://github.com/japaric/steed/blob/lld/docker/mipsel-unknown-linux-steed.json) - [powerpc-unknown-linux-steed](https://github.com/japaric/steed/blob/lld/docker/powerpc-unknown-linux-steed.json) - [powerpc64-unknown-linux-steed](https://github.com/japaric/steed/blob/lld/docker/powerpc64-unknown-linux-steed.json) - [x86_64-unknown-linux-steed](https://github.com/japaric/steed/blob/lld/docker/x86_64-unknown-linux-steed.json) --- The case where lld is unergonomic is linking binaries that depend on system libraries. Like "Hello, world" for `x86_64-unknown-linux-gnu`. Because you have to pass as linker arguments: the path to the startup objects, the path to the dynamic linker and the library search paths. And all those are system specific so they can't be encoded in the target itself. ``` $ cargo \ rustc \ --release \ -- \ -C \ linker=ld.lld \ -Z \ linker-flavor=ld \ -C \ link-args='-dynamic-linker /lib64/ld-linux-x86-64.so.2 -L/usr/lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.1 /usr/lib/Scrt1.o /usr/lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/6.3.1/crtbeginS.o /usr/lib/gcc/x86_64-pc-linux-gnu/6.3.1/crtendS.o /usr/lib/crtn.o' ``` --- Another case where `-Z linker-flavor` may come in handy is directly calling Solaris' linker which is also a multiarch linker (or so I have heard). cc @binarycrusader cc @alexcrichton Heads up: [breaking-change] due to changes in the target specification format.
- Loading branch information
Showing
92 changed files
with
682 additions
and
240 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# `linker-flavor` | ||
|
||
The tracking issue for this feature is: None | ||
|
||
------------------------ | ||
|
||
Every `rustc` target defaults to some linker. For example, Linux targets default | ||
to gcc. In some cases, you may want to override the default; you can do that | ||
with the unstable CLI argument: `-Z linker-flavor`. | ||
|
||
Here how you would use this flag to link a Rust binary for the | ||
`thumbv7m-none-eabi` using LLD instead of GCC. | ||
|
||
``` text | ||
$ xargo rustc --target thumbv7m-none-eabi -- \ | ||
-C linker=ld.lld \ | ||
-Z linker-flavor=ld \ | ||
-Z print-link-args | tr ' ' '\n' | ||
"ld.lld" | ||
"-L" | ||
"$SYSROOT/lib/rustlib/thumbv7m-none-eabi/lib" | ||
"$PWD/target/thumbv7m-none-eabi/debug/deps/app-512e9dbf385f233c.0.o" | ||
"-o" | ||
"$PWD/target/thumbv7m-none-eabi/debug/deps/app-512e9dbf385f233c" | ||
"--gc-sections" | ||
"-L" | ||
"$PWD/target/thumbv7m-none-eabi/debug/deps" | ||
"-L" | ||
"$PWD/target/debug/deps" | ||
"-L" | ||
"$SYSROOT/lib/rustlib/thumbv7m-none-eabi/lib" | ||
"-Bstatic" | ||
"$SYSROOT/lib/rustlib/thumbv7m-none-eabi/lib/libcore-e1ccb7dfb1cb9ebb.rlib" | ||
"-Bdynamic" | ||
``` | ||
|
||
Whereas the default is: | ||
|
||
``` text | ||
$ xargo rustc --target thumbv7m-none-eabi -- \ | ||
-C link-arg=-nostartfiles \ | ||
-Z print-link-args | tr ' ' '\n' | ||
"arm-none-eabi-gcc" | ||
"-L" | ||
"$SYSROOT/lib/rustlib/thumbv7m-none-eabi/lib" | ||
"$PWD/target/thumbv7m-none-eabi/debug/deps/app-961e39416baa38d9.0.o" | ||
"-o" | ||
"$PWD/target/thumbv7m-none-eabi/debug/deps/app-961e39416baa38d9" | ||
"-Wl,--gc-sections" | ||
"-nodefaultlibs" | ||
"-L" | ||
"$PWD/target/thumbv7m-none-eabi/debug/deps" | ||
"-L" | ||
"$PWD/target/debug/deps" | ||
"-L" | ||
"$SYSROOT/lib/rustlib/thumbv7m-none-eabi/lib" | ||
"-Wl,-Bstatic" | ||
"$SYSROOT/lib/rustlib/thumbv7m-none-eabi/lib/libcore-e1ccb7dfb1cb9ebb.rlib" | ||
"-nostartfiles" | ||
"-Wl,-Bdynamic" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.