Linking with LLD
LLVM 4.0 is shipping with LLD enabled, though AFAIK it is not yet production-ready on all platforms. I believe we've got an LLVM upgrade planned soon to resolve AVR/emscripten problems anyway, so now's the time to start determining what we might need to do to support it, how it impacts compiler performance/binary size/runtime performance compared to our usual linkers, and what platforms on which we might want to enable it by default.
Current status (2020-04-24) summarized at https://github.com/rust-lang/rust/issues/39915#issuecomment-618726211
LLVM 4.0 is shipping with LLD enabled, though AFAIK it is not yet production-ready on all platforms. I believe we've got an LLVM upgrade planned soon to resolve AVR/emscripten problems anyway, so now's the time to start determining what we might need to do to support it, how it impacts compiler performance/binary size/runtime performance compared to our usual linkers, and what platforms on which we might want to enable it by default.
Current status (2020-04-24) summarized at https://github.com/rust-lang/rust/issues/39915#issuecomment-618726211
Possible problems:
- LLD has internal parallelism, and is not documented to have jobserver support, which can lead to poor contention resolution in practice
Mark Rousskov at 2021-02-14 02:56:14
See also a PoC in #36120.
bstrie at 2017-02-17 19:52:24
LLD may be a very good candidate for MinGW targets, because we currently bundle a linker with them anyway and MinGW's linker has a variety of issues ranging from a lack of ASLR to no bigobj support. If we can somehow also bring along the necessary mingw libraries when cross compiling and not just native targeting (which rustup's mingw package is currently limited to), then that would enable rust cross compilation from linux out of the box, which would be a huge improvement over the existing situation where people get MinGW from their distro and then run into issues because distros almost always use an incompatible MinGW.
LLD is not a good candidate for natively targeting MSVC targets, due to several reasons, the primary reason being the lack of debuginfo support. Cross compiling to MSVC targets requires libraries that can't be redistributed so we can't support that out of the box anyway.
Peter Atashian at 2017-02-18 00:42:21
The tracking issue for upgrading to LLVM 4.0 is https://github.com/rust-lang/rust/issues/37609 .
bstrie at 2017-02-19 16:14:36
For the record lld is definitely not ready for Solaris targets. But on Solaris, there's no reason that I'm aware of to use lld instead of the native ld instead. We've already been looking at what it would take to have rust use Solaris ld on Solaris instead of using gcc for linking.
Shawn Walker-Salas at 2017-02-20 00:06:09
@binarycrusader One reason to use lld is when building for Solaris, not on Solaris.
Catherine at 2017-02-20 02:42:14
PR rust-lang/rust#40018 adds a
-Z linker-flavorflag to rustc to make it possible to use LLD as a linker. That PR doesn't embed LLD in rustc but allows out of tree experimentation with it.@binarycrusader ^ that may help with your experiment of directly using Solaris' ld instead of gcc.
Jorge Aparicio at 2017-02-21 22:19:20
We now appear to be running on LLVM 4.0. @japaric , does this mean that the linker-flavor flag can now be easily used to compare and contrast LLD with the system linker?
bstrie at 2017-04-25 02:23:00
@bstrie #40018 landed a few weeks ago. Since that landed one has been able to use
-Z linker-flavor=ld -C linker=ld.lldto use an external LLD binary as a linker. Note that, unlike gcc, LLD doesn't know where the system libraries are so you'll have to pass the library search path to the linker using-C link-args='-L ...'if you are linking to any system library.What LLVM 4.0 helps with is merging LLD into rustc. With that change we wouldn't require an external linker in some scenarios like linking MUSL binaries or bare metal programs. I say some scenarios because most targets require linking to system libraries where you will run into the library search path problem I mentioned above. For those targets, LLD won't work out of the box. It's not clear how and where to solve that problem and without a solution for that we can't switch to LLD for the most important (tier 1) targets, which the reduces the appeal of embedding LLD into rustc in the first place.
Jorge Aparicio at 2017-04-29 04:11:31
@japaric What are the arguments against embedding (sysroot-relative library) search paths, as well as things like
-lc -lpthread crt0.o, directly into rustc? After all, some component of the toolchain has to embed them as we don't have any standard for the platforms to follow, and binutils is not a good golden source of this knowledge.The only drawback I can think of is the situation where the same triple would have different search paths on different flavors of systems (which will likely be exclusive to Linux/glibc triples, and especially bad on platforms with multilib). In that case, I believe clang snoops the OS name and hardcodes OS-specific conventions, which seems bad but probably unavoidable if one wants to distribute a single binary that runs on any Linux (and doesn't need the system linker).
Catherine at 2017-04-29 04:22:29
@retep998 I had a brief look at lld a few months ago. I wasn't able to cross compile (cross link?) an .exe from Linux. It seemed like lld only supports platform native formats.
Hopefully I'm mistaken.
Iain Nicol at 2017-06-16 12:41:06
Tagging this as a performance bug, since according to LLD's benchmarks it seems to outperform GNU ld by a factor of ten, and linking performance is a large component of compiler speed currently.
bstrie at 2017-09-08 13:39:03
Er, forgot to link the benchmarks: https://lld.llvm.org/#performance
(Relevant today since LLVM 5.0 has just been released.)
bstrie at 2017-09-08 13:39:43
Linking with LLD is much faster than bfd or gold, but I doubt that using it will significantly improve overall performance. Still I think this issue is important and should be a priority.
Dima Pulkinen at 2017-09-09 11:23:06
@tpimh I'm actually not entirely sure whether the I-slow tag is supposed to represent runtime performance bugs or compiletime performance bugs, I was intending it as the latter. And IME when I look at time-passes output linking is usually in the top three longest phases, significantly longer than most, so even cutting linking time in half would probably be a huge win (especially for big things like Servo and rustc).
bstrie at 2017-09-09 17:33:34
@bstrie I-slow is for bad runtime performance, I-compiletime is for compiler perf last time I checked
Jonas Schievink at 2017-09-09 18:44:25
Good news for anybody interested in the obscure topic of cross linking from Linux to Windows. I said earlier it wasn't possible with lld, but that's only true for lld's ld flavor. It's possible for lld's link.exe flavour (lld-link).
Specifically for Rust we can do this today with a couple code changes.
-
We need to compile a very small subset of mingw-w64's CRT into .o object files. Namely some thread local storage init. We also need chkstk.
-
lld does not like MinGW's usual import libraries. Instead we need to build the .def files into .lib files ourselves, using lld-link or llvm-dlltool
-
Modify lld to treat IMPORT_NAME_NOPREFIX like IMPORT_NAME_UNDECORATE, because even with step 2 the .libs aren't perfect
-
Modify Rust's seh.rs to replace TYPE_INFO_VTABLE with ptr::null(). Required because the symbol
??_7type_info@@6B@isn't defined in MinGW. Then build and install Rust. -
Use .cargo/config to specify a custom wrapper script as the linker.
-
Our wrapper linker script should invoke lld-link mostly using the parameters it is passed. However we must make a few tweaks:
a) Fix filename casing e.g. change AdvAPI32.Lib to advapi32.lib
b) Modify the .def file Rust generates to prefix symbols with an extra underscore
c) Override the entry point (/entry). Required probably due to a name mangling issue.
d) Append the mingw-crt object files you compiled in step 1
-
Build your Rust project using xargo --target=i686-pc-windows-msvc
Doing the above steps allows me to cross compile Rust code. I can even panic and catch panics using Rust's SEH-based unwinding.
Iain Nicol at 2017-09-17 15:58:19
-
@iainnicol You're mixing the msvc target with MinGW bits, which is why you have to do all those weird modifications. If you just copy over the libraries from an existing VC++ installation then you can use lld-link normally without all those modifications or any MinGW bits.
Peter Atashian at 2017-09-17 16:22:08
But I don't want to use an existing VC++ installation. There isn't even any way to get one without spending something like eight hours downloading and installing junk, much less to redistribute.
Catherine at 2017-09-17 16:25:41
The standalone build tools are much lighter-weight, unless that's already what you're referring to, in which case perhaps we ought to put some work into improving or recreating what MinGW did so it's actually compatible with MSVC.
Russell Johnston at 2017-09-17 16:32:54
The standalone build tools are much lighter-weight
I haven't realized Microsoft distributes those. Could you link to them? Is there any reasonable way to extract the installation archive without actually running it i.e. is it an msi or something similar?
Catherine at 2017-09-17 16:38:52
Here they are: http://landinghub.visualstudio.com/visual-cpp-build-tools
Both the 2015 and 2017 versions are exes, but you may be able to convince the 2017 exe to give you what you want via this: https://docs.microsoft.com/en-us/visualstudio/install/install-vs-inconsistent-quality-network
Russell Johnston at 2017-09-17 16:45:26
If we really want to do this right for Windows, we'd first of all need https://github.com/rust-lang/rust/issues/30027 to eliminate the need for the Windows SDK or MinGW's import libraries. Then all we'd have left is to replace the CRT bits with our own pure Rust versions (math/memory functions, entry point, a few other runtime bits Rust needs) and we'd have a fully self-contained Rust toolchain that can create Windows binaries! The downside of this is that you wouldn't be able to statically link C/C++ code because that relies very heavily on linking in the appropriate CRT from either MinGW or VC++. Of course the whole point of Rust is to rewrite everything in Rust, so this isn't really much of an issue.
Peter Atashian at 2017-09-17 16:53:46
Good news for anybody interested in the obscure topic of cross linking from Linux to Windows. I said earlier it wasn't possible with lld, but that's only true for lld's ld flavor. It's possible for lld's link.exe flavour (lld-link).
Looks like it should now be possible with the ld flavor as well: https://reviews.llvm.org/rL312926
Russell Johnston at 2017-09-19 19:04:17
The new lld's MinGW-compatible driver is a wrapper to the lld-link linker. It internally translates Unix-ish options to Windows-ish options and then call lld-link's entry point. I'm not sure if you guys want to use it because (except that the wrapper driver incomplete and not ready for use) it doesn't seem to make things easier unless you already have Makefiles for MinGW.
I have a (probably silly) question for you guys about cross-compilation. On Windows, all dllimport'ed symbols have DLL names from which they are imported. If you don't have any MSVC library files, how do you know which files dllimport'ed symbols are imported from?
Rui Ueyama at 2017-09-20 00:11:58
I have a (probably silly) question for you guys about cross-compilation. On Windows, all dllimport'ed symbols have DLL names from which they are imported. If you don't have any MSVC library files, how do you know which files dllimport'ed symbols are imported from?
If you don't have any import libraries, then you have to either create import libraries or implement https://github.com/rust-lang/rust/issues/30027 so that
winapican do all the hard work of specifying which DLL each symbol comes from along with zaniness like ordinals. Something has to specify the mapping of symbols at link time to symbols/ordinals in DLLs, whether it be import libraries or annotations in your code.Peter Atashian at 2017-09-20 02:34:38
After pulling in https://reviews.llvm.org/rL311734 I am almost able to bootstrap rustc using lld on macOS. There appears to be an issue with dylib metadata, which I still need to investigate.
I have a branch that resurrects https://github.com/rust-lang/rust/pull/36120; since we need that (very recent) lld fix, this is blocked on https://github.com/rust-lang/rust/issues/43370.
Tamir Duberstein at 2017-11-25 19:18:04
@tamird: #43370 has been closed.
Sander Maijers at 2018-02-26 21:49:48
LLD has been added in https://github.com/rust-lang/rust/pull/48125 and is now shipping with tier 1 platforms (mac, linux, windows). You can test it out with
-Z linker-flavorfor each platform, although it's unlikely to work for most platforms by default. It does work, however, by default on MSVC. For example:$ RUSTFLAGS='-Z linker-flavor=lld-link' cargo buildreduced Cargo's own link time from 2.5s to 1.5s, a nice improvement!
Alex Crichton at 2018-03-06 17:05:12
@alexcrichton, what are the next steps? Ideally we'd have LLD working by default on all platforms (I have no conception of how much work this will take), and then I'd like to run compiletime/runtime benchmarks to see whether it makes sense to make LLD the default on any platforms. Especially with incremental compilation, linking performance is going to be more important than ever.
bstrie at 2018-03-08 01:22:43
Especially with incremental compilation, linking performance is going to be more important than ever.
It's a shame linking performance still isn't important enough for us to do things like enabling incremental linking on platforms that support it. https://github.com/rust-lang/rust/issues/37543
Peter Atashian at 2018-03-08 03:10:13
@bstrie I suppose those are the next steps, getting it working on other platforms :)
As to what that entails I'm not sure, but it already works on MSVC, I think it's far from working on MinGW/Linux, and we're pretty close on OSX. As for the cross-architecture support, I'm not sure as well. I don't expect we'll "stabilize" it for anything other than the wasm platform in the near future.
Alex Crichton at 2018-03-08 04:34:16
@alexcrichton May I ask how you would specify "stabilizing"? Why wouldn't it be possible to "stablize" the linking with lld for the other major platforms rust supports? (eg. cross-compiling an executable from linux for macOS).
Right now, it's such a pain to cross-compile, for example the work needed to cross-compile an executable for macOS (x86_64-apple-darwin) from linux requires non-trivial steps like acquiring the xcode sdk and building the whole toolchain.
cynecx at 2018-03-11 03:04:18
@cynecx a good question! One I haven't thought much about. I think, however, we do not want to defacto-stabilize LLD just because we added it for another platform, it'll require time and work to get it right and expose it well.
Alex Crichton at 2018-03-11 18:07:43
for example the work needed to cross-compile an executable for macOS (x86_64-apple-darwin) from linux requires non-trivial steps like acquiring the xcode sdk and building the whole toolchain.
LLD wouldn't really help here, you still need the Xcode SDK because it has headers you can't redistribute (and depending on what you're building, you'll need other SDK tools as well).
Catherine at 2018-03-11 18:25:10
What's really nice about LLD now being built-in on nightly is that you can easily cross-compile pure Rust projects from Windows to Linux with
RUSTFLAGS='-Z linker-flavor=ld.lld' cargo build --target x86_64-unknown-linux-musl. Great for writing small tools for Linux machines you can't simply install Rust on.Rolf Karp at 2018-03-15 21:39:18
I don't expect we'll "stabilize" it for anything other than the wasm platform in the near future.
Like @rkarp said, a very common use case is targeting x86_64-unknown-linux-musl (and eventually steed) for supporting containerized Linux workloads. This is one of those things that Go does really well and where we seem to be very close to Rust being able to do likewise. In terms of actual usage, I bet LLD for x86_64-unknown-linux-musl would actually get used much more broadly than wasm.
More generally, when it comes to cross-building, I don't think a "it must work for all hosts and/or all targets" approach makes sense. I think it makes sense to stabilize this on a target-by-target basis as targets start working.
In particular, I would love to help with the effort to get LLD for the x86_64-unknown-linux-musl target stabilized ASAP.
Brian Smith at 2018-03-17 21:36:16
My project has 37 crates, and the build links about 70 binaries (lots of tests). Unscientifically (eyeballing
top) at least half of the build time we are only running ld. I expect using lld would speed up our builds a lot. We're on stable Rust and I haven't managed to get lld 6.0 to work yet.Robert O'Callahan at 2018-03-19 21:56:45
@briansmith have you tested out LLD for musl and your use case? In theory all you'd need to do to test it is to pass
-Z linker-flavor=ld.lld, and if that works seems plausible we could switch the defaults!@rocallahan just to confirm, y'all are using the gold linker currently, right? (as afaik it's faster than the standard binutils linker). If
-Z linker-flavor=ld.lldworks (and is faster) then we could look to stabilize it perhaps! What platform was that on?Alex Crichton at 2018-03-19 22:55:46
Unscientifically (eyeballing top) at least half of the build time we are only running ld.
That's for a debug build BTW.
y'all are using the gold linker currently, right? (as afaik it's faster than the standard binutils linker)
No, that's the Fedora system linker, the standard GNU linker.
What platform was that on?
Fedora 27, quad-core Skylake laptop with SSD. I will get some performance numbers.
Robert O'Callahan at 2018-03-19 22:59:44
Ah ok good to know! Debug builds will probably get the most benefit in link time from split dwarf (https://github.com/rust-lang/rust/issues/34651) rather than linker improvements.
For timing information, though, @rocallahan if you get a chance mind testing with
ld.goldandld.lld?Alex Crichton at 2018-03-19 23:03:56
Sure. I should also remind that issue #48762 is very low-hanging-fruit for speeding up Linux debug link times. (We're already using a hacked linker script that drops
.debug_pubnames/.debug_pubtypesfrom the executable.)Split DWARF might be good but it might also cause problems for users. I'll comment in that issue.
Robert O'Callahan at 2018-03-19 23:12:29
@briansmith have you tested out LLD for musl and your use case? In theory all you'd need to do to test it is to pass -Z linker-flavor=ld.lld, and if that works seems plausible we could switch the defaults!
OK, I will test things. Perhaps initially there should be a middle ground between "default" and "only on nightly," some way of opting into using LLD like we can with
-Z, but without using-Zso that it works in stable builds.Brian Smith at 2018-03-20 00:22:49
but without using -Z so that it works in stable builds.
You can try
RUSTC_BOOTSTRAP=1 RUSTFLAGS="-Z linker-flavor=foo" cargo buildMatthias Krüger at 2018-03-20 04:25:35
Please let’s not recommend the bootstrap flag? I worry that if enough projects rely on it things will become de-facto stable, defeating the point of the entire stability mechanism.
Simon Sapin at 2018-03-20 08:22:15
Sorry =/
Matthias Krüger at 2018-03-20 12:42:38
As a data point, linking the
rustc_transcrate in the Rust repo itself plummeted from a 78s link time to 1s link time on my local machine.Alex Crichton at 2018-03-20 15:58:49
My performance results from making a whitespace change to a crate near the bottom of our crate hierarchy. Quad core Skylake laptop, 16GB RAM, rustc 1.24.0, LLD 7.0.0, GNU ld 2.29-13. We use a custom linker script that discards
.debug_pubnamesand.debug_pubtypes; LLD uses quite different code paths when a linker script is present, so that might affect things.GNU ld:
real 2m39.138s user 8m18.992s sys 1m37.513sLLD:
real 2m19.164s user 6m4.477s sys 0m56.858sGold didn't work, it barfed on our linker script. The results are fairly stable. LLD doesn't affect the end-to-end time that much but it does reduce CPU usage significantly; I guess that means our build doesn't spend much time waiting for lds to finish, but it does spend a lot of CPU time running them.
Robert O'Callahan at 2018-03-20 23:03:51
See #50584 for a real world example where switching from GNU ld to lld makes a common "minor change and rebuild" workload execute more than 2.5x faster.
Nicholas Nethercote at 2018-06-21 06:29:37
Er https://github.com/rust-lang/rust/issues/50584#issuecomment-400918647 is more appropriate here:
The next step for stabilizing LLD would be to get a flag, like -Z linker-flavor=lld, working for all targets (Windows + Mac + Linux). It'd do whatever it needs to do to work across the various platforms.
Once that's done we can advertise it to the community, asking for feedback. Here we can gain both timing information as well as bug reports to send to LLD. If everything goes smoothly (which is sort of doubtful with a whole brand new linker, but hey you never know!) we can turn it on by default, otherwise we can work to stabilize the selection of LLD and then add an option to Cargo.toml so projects can at least opt-in to it.
Alex Crichton at 2018-06-28 05:52:48
We have switched to lld for some targets: https://rust-embedded.github.io/blog/2018-08-2x-psa-cortex-m-breakage/
I believe for wasm as well?
Steve Klabnik at 2018-11-13 17:54:56
Does this issue cover both linking with an external lld binary and linking with internal lld support built into rustc itself? Or only the former?
Josh Triplett at 2019-02-05 16:29:10
Does this issue cover both linking with an external lld binary and linking with internal lld support built into rustc itself? Or only the former?
Just the external lld binary, IIUC.
Nicholas Nethercote at 2019-02-05 21:57:00
@nnethercote Is there another issue for tracking the use of an internal linker, or should I file a separate issue for that?
Josh Triplett at 2019-02-06 08:53:02
I haven't heard of the internal linker idea before. I'm not aware of a PR for it.
Nicholas Nethercote at 2019-02-06 09:25:39
https://github.com/rust-lang/rust/pull/57514 prepared ground for using LLD to link LLVM.
Mateusz Mikuła at 2019-02-06 09:42:45
Perhaps initially there should be a middle ground between "default" and "only on nightly," some way of opting into using LLD like we can with -Z, but without using -Z so that it works in stable builds.
https://github.com/rust-lang/rust/pull/56351 added
-C linker-flavor.It's not clear what this issue is intended to track. It seems like it would be better to close this in favor of having specific issues, e.g. "Link with LLD for -msvc targets when Microsoft's toolchain isn't available".
Brian Smith at 2019-03-26 01:08:13
To me, this issue is about enabling LLD as the default linker for all targets. I would like that because LLD is extremely fast, and linking time is often a significant component of compile time, and compile speed is a perennial problem.
Nicholas Nethercote at 2019-03-26 01:35:34
FWIW I filed a bug for supporting LLD on macOS over in BMO. Apparently that's WONTFIX. From the comments there it seems that it's not as simple as "LLD is extremely fast", since the LLDs on different platforms are different programs, and the one on macOS is broken with stalled development.
Jonathan Watt at 2019-03-26 08:49:22
Agreed with @briansmith that it would be good to have dedicated issues to track the status of this for different targets, though rather than closing this we could then turn this into a metabug. If there's anyone who knows more about what targets are worth opening issues for, please feel free, since I'm very out of the loop on the LLD support status.
bstrie at 2019-04-03 20:36:46
Is linking with LLD documented anywhere? I have (on Linux)
rustc -C linker-flavor=ld.lld hello.rs, but I'm not having luck. I thought that LLD was distributed with our copy of LLVM, am I wrong? I've also tried installing LLD via apt, but rustc is still mystified. What are the steps that must be taken to try out LLD with Rust code today?bstrie at 2019-05-17 19:26:33
@bstrie You have to additionally pass the
-C linker=rust-lldargument.Philipp Oppermann at 2019-05-18 11:36:51
Is it supposed to work with cargo ? I currently get the following errors when trying to build a blank project on the latest nightly build of rust and cargo.
$ RUSTFLAGS='-C linker=rust-lld' cargo build Compiling rust3 v0.1.0 (/home/carado/tmp/rust3) error: linking with `rust-lld` failed: exit code: 1 | = note: "rust-lld" "-flavor" "gnu" "-L" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.2ualxzb8lqn4ho3y.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.32vfyq64cfbzv618.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.4rbt3m5y8o8cl09t.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.ben0932xzwyt64v.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.fzsdnygvstiwzxo.rcgu.o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.x0rq6ifodcf11zi.rcgu.o" "-o" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55" "/home/carado/tmp/rust3/target/debug/deps/rust3-c4f8c40972021c55.1m259ox4uzrzk583.rcgu.o" "--gc-sections" "-pie" "-zrelro" "-znow" "-L" "/home/carado/tmp/rust3/target/debug/deps" "-L" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--start-group" "-Bstatic" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-44988553032616b2.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-607feef6be9150b2.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace-a8dbf6d92401e34a.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace_sys-9a4716f5e8a3e722.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-988a64d96b043c6d.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-cadd6177b8c6d586.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-8f1d8efc92b45369.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-1e76014677816767.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-cc28bce38cb195d9.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-4123e9e89add689a.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-4d259c17788c1fb5.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-9495dbda85bb8f16.rlib" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-793d0026c575805f.rlib" "--end-group" "/home/carado/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-33c3162edae6574e.rlib" "-Bdynamic" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-lutil" = note: rust-lld: error: unable to find library -ldl rust-lld: error: unable to find library -lrt rust-lld: error: unable to find library -lpthread rust-lld: error: unable to find library -lgcc_s rust-lld: error: unable to find library -lc rust-lld: error: unable to find library -lm rust-lld: error: unable to find library -lrt rust-lld: error: unable to find library -lpthread rust-lld: error: unable to find library -lutil rust-lld: error: unable to find library -lutil error: aborting due to previous error error: Could not compile `rust3`. To learn more, run the command again with --verbose.carado at 2019-05-28 15:24:44
I'm getting same errors as carado. Managed to "shoehorn" -L /usr/lib into the linker invokation but that just shortens the list of missed libs to
-lgccwhich does not exist anywhere in the system aslibgcc(there's alibgcc_s.a) I suspect this is a result of some gnu-ism but can't figure out how to fix it.Aleš Katona at 2019-07-17 23:14:12
@almindor try
RUSTFLAGS='-C linker=rust-lld -L /usr/lib -L /usr/lib/gcc/x86_64-pc-linux-gnu/9.1.0'or something similar. The path will depend on your distro and compiler version.Laurențiu Nicola at 2019-07-24 13:04:38
Is my comment above the right way to use LLD? I can't get it to work, as every program crashes with
SIGSEGV:Reading symbols from target/debug/hello... (gdb) show directories Source directories searched: ~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/etc:$cdir:$cwd (gdb) r Starting program: target/debug/hello Program received signal SIGSEGV, Segmentation fault. core::ops::function::FnOnce::call_once{{vtable-shim}} () at /rustc/a7f28678bbf4e16893bb6a718e427504167a9494/src/libcore/ops/function.rs:231 (gdb) l 226 #[stable(feature = "fn_once_output", since = "1.12.0")] 227 type Output; 228 229 /// Performs the call operation. 230 #[unstable(feature = "fn_traits", issue = "29625")] 231 extern "rust-call" fn call_once(self, args: Args) -> Self::Output; 232 } 233 234 mod impls { 235 #[stable(feature = "rust1", since = "1.0.0")] (gdb) info reg rax 0x0 0 rbx 0x0 0 rcx 0x0 0 rdx 0x0 0 rsi 0x0 0 rdi 0x0 0 rbp 0x0 0x0 rsp 0x7fffffffddb0 0x7fffffffddb0 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0x0 0 r12 0x0 0 r13 0x0 0 r14 0x0 0 r15 0x0 0 rip 0x7ffff7ffc000 0x7ffff7ffc000 <core::ops::function::FnOnce::call_once{{vtable-shim}}> eflags 0x10202 [ IF RF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 (gdb) disassemble Dump of assembler code for function core::ops::function::FnOnce::call_once{{vtable-shim}}: => 0x00007ffff7ffc000 <+0>: mov (%rdi),%rax 0x00007ffff7ffc003 <+3>: mov (%rax),%rdi 0x00007ffff7ffc006 <+6>: jmpq *0x11d4(%rip) # 0x7ffff7ffd1e0 End of assembler dump.Laurențiu Nicola at 2019-07-24 18:27:12
For anyone ending up here, the magic incantation is
RUSTFLAGS="-C link-arg=-fuse-ld=lld" cargo buildif you have GCC 9 or Clang as your compiler. Alternatively,-C linker=clangshould work regardless of the GCC version, so it might be preferred.To make that permanent, you can add it to
~/.cargo/configor.cargo/configin a specific project:[build] rustflags = ["-C", "linker=clang"] # rustflags = ["-C", "link-arg=-fuse-ld=lld"]Laurențiu Nicola at 2019-10-03 17:40:04
@lnicola note it works only when using GCC 9 or Clang as CC.
Mateusz Mikuła at 2019-10-03 17:44:34
@bstrie do you know what the current status of this is? What are the blockers to moving forward with it?
Jon Gjengset at 2019-10-22 11:40:45
@mati865 do you happen to know an alternative invocation for people with an older GCC?
Laurențiu Nicola at 2019-10-22 11:46:44
@lnicola all my platforms have Clang + GCC 9 and I haven't investigated how to use it with incompatible compilers.
Mateusz Mikuła at 2019-10-22 14:23:08
@jonhoo I'm not abreast of any of the work in this area, I suppose you'd want to ask the compiler team.
bstrie at 2019-10-22 19:52:29
I don't think I can tag teams, and I don't want to cause undue noise for them either. What's the best avenue to get someone from there to take a quick look you think?
Jon Gjengset at 2019-10-23 12:26:16
Triage; @rust-lang/compiler does anyone know what is the current status of this issue?
XAMPPRocky at 2019-10-23 13:31:03
For anyone here who manages to get LLD working with Rust, can you additionally include the details about your platform and the specific versions of all compilers being used? I'm still seeing people in the wild having trouble with getting it to work, even with the advice listed here.
bstrie at 2019-10-25 20:41:59
The command I posted above works on Linux with GCC 9.2.0 and LLD 9.0.0. I think it sometimes also works on Windows, but I've seen someone with a GCC 9 for Windows that did not support -fuse=lld. On MacOS it's not worth trying, according to some links posted here.
Laurențiu Nicola at 2019-10-25 20:47:52
For anyone here who manages to get LLD working with Rust, can you additionally include the details about your platform and the specific versions of all compilers being used? I'm still seeing people in the wild having trouble with getting it to work, even with the advice listed here.
cat /etc/system-release Fedora release 30 (Thirty)
cc --version cc (GCC) 9.2.1 20190827 (Red Hat 9.2.1-1)
ld.lld --version LLD 8.0.0 (compatible with GNU linkers)
Hopefully this helps
Aleš Musil at 2019-10-30 11:58:23
but I've seen someone with a GCC 9 for Windows that did not support -fuse=lld
@lnicola Windows GCC 9 builds support
-fuse-ld=lld(unless they are patched to not support it but why would somebody do it?). I supposerust-mingwcomponent was installed and linker was not overridden in.cargo/config. That way rustc picked GCC 6 it ships instead of the system one.Another issue on Windows is hardcoded linker flag
--enable-long-section-nameswhich LLD 9 and older do not support (there are plans to support it in the future). To get around this you can:- create wrapper which strips this flag
- patch LLD to accept this flag as no-op
- use local patched Rust builds that don't use this flag
Mateusz Mikuła at 2019-10-30 13:34:55
Another issue on Windows is hardcoded linker flag --enable-long-section-names which LLD 9 and older do not support (there are plans to support it in the future).
This part is fixed by: https://github.com/rust-lang/rust/pull/66257 Windows-gnu users still have to do manual work to use C compiler which supports
-fuse-ld=lldthough.Mateusz Mikuła at 2019-11-13 20:15:16
@bstrie: This works with Stable and Nightly on Windows-MSVC, details in the first post of this gamedev-wg issue: https://github.com/rust-gamedev/wg/issues/50
Lokathor at 2019-11-16 06:30:36
Another data point: using
RUSTFLAGS="-C link-arg=-fuse-ld=lld"when buildingrustcitself, linking time drops from 93s to 41s on my fast 14-core Linux box.Nicholas Nethercote at 2020-03-06 01:34:09
@nnethercote: Is that different from setting
linker=lldin (for example) the[target.x86_64-unknown-linux-gnu]section of theconfig.toml?Aaron Hill at 2020-03-06 01:56:08
@Aaron1011: My guess would be the two approaches have the same effect, but I haven't checked this myself.
Nicholas Nethercote at 2020-03-06 03:37:08
@Aaron1011 it should be clang, see https://github.com/rust-lang/rust/issues/39915#issuecomment-538049306.
Laurențiu Nicola at 2020-03-06 07:08:31
@mati865 Have you tried to build
rustconx86_64-pc-windows-gnuwith LLD as a linker?I tried it today and LLD either hangs in the middle of the build and stops doing any work, or complains about
unknown argument: --version-script=.... The hang also happens if LLD is used for linking LLVM only, with[llvm] use-linker = "lld"Tool versions:
$ ld.lld --version LLD 9.0.1 (https://github.com/msys2/MINGW-packages.git 5e3b8820ed9f04221affee4197e458aca2612e87) (compatible with GNU linkers) $ gcc --version gcc.exe (Rev2, Built by MSYS2 project) 9.2.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.Vadim Petrochenkov at 2020-03-06 23:34:05
@petrochenkov yes I could build it with some hacks:
- LLD COFF backend doesn't support linker scripts but both LD and LLD are fine with MSVC style
.deffiles; easy to solve - LLD expects libraries to start with
lib(it's a standard in UNIX world) but somehow Rust ended up not doing it for allwindows-*targets: https://github.com/rust-lang/rust/blob/9ebf47851a357faa4cd97f4b1dc7835f6376e639/src/libstd/sys/windows/env.rs#L4 LD doesn't mind either way and I don't know whether to push on LLD or Rust side to fix it.
Mateusz Mikuła at 2020-03-06 23:59:13
- LLD COFF backend doesn't support linker scripts but both LD and LLD are fine with MSVC style
I'm writing down some future possibilities here. While some implementation efforts are needed, i think these will help solving some longstanding pain points in Rust development:
- Instead of using external provided lld, build and use it as static libraries within rustc. This allows tighter integration to rustc itself, improves the out-of-box experience, and unlocks future possibilities.
- Instead of passing a lot of path names to lld as a linker command, use a virtual file system, and pass those data from memory-to-memory instead of using disk IO whenever there's enough memory space to do. For larger projects this might save hundreds or even thousands megabytes of disk IO, and thus improves compilation time.
Charles Lew at 2020-03-07 11:11:52
Instead of passing a lot of path names to lld as a linker command, use a virtual file system, and pass those data from memory-to-memory instead of using disk IO whenever there's enough memory space to do. For larger projects this might save hundreds or even thousands megabytes of disk IO, and thus improves compilation time.
It's not just a matter of IO bandwidth. On platforms like Windows, especially when Windows Defender is enabled, each file you want to work with adds a fairly significant time penalty, and Rust's codegen unit model means crates are split into hundreds of tiny object files that can quickly rack up a lot of compilation time.
Peter Atashian at 2020-03-07 11:46:41
This bug is a bit of a mess, so here's my best shot at a quick summary of the current situation, for folks who want to move this forward.
What is lld
A linker that's part of the llvm project, which is desirable for two reasons:
- it's very friendly to cross compilation (hence its emphasis for embedded targets)
- it's very fast (often runs in half the time as Gold -- linking can take several minutes for big projects (rustc, servo, etc.) and linking can be a huge % of the compile with incremental builds, so halving this runtime is a Big Deal.)
Things Rust does with lld today
- Rust currently ships its own copy of lld on most platforms as a binary it calls rust-lld
- rust-lld is used by default on many bare-metal targets
- rust-lld is used by default for wasm
- (?) you can explicitly request rust-lld be used by using "-C linker-flavor" (fuzzy on what exactly this does on non-bare-metal platforms, see below)
Problems for using rust-lld in more places (i.e. desktop linux/mac/windows)
- The macOS (Mach-O) backend for lld is broken and abandoned
- a rewrite from scratch has begun, but it's early days
- On linux/unix platforms, you aren't supposed to directly invoke ld/lld. You're supposed to invoke the linker through your system c compiler (i.e. gcc), whose responsibility it is to discover system symbols like crt1.o and provide them to ld. This means we can't "just" use rust-lld; we must feed it into gcc/clang/whatever. (we don't want to implement this system symbol logic ourselves)
- In general, you can't provide the linker as a path, you must inject it into the C compiler's search path as "ld"
- Alternatively, you can do the same thing but inject it as "ld.lld", and pass "-fuse-ld=lld"
- This may be important, apparently lld does clang-style binary name detection of if it's being executed as "ld" or "ld.lld" (needs investigation)
- Unfortunately -fuse-ld=lld is only part of GCC 9, so we may require feature/version detection to use it (clang has had it for a long time)
- windows-msvc is apparently in good shape, and seems to have some limited support for using rust-lld in the backend, but I'm unclear on what needs to be done here.
- windows-mingw seems to be in roughly the same place as linux/unix, except you're liable to get an ancient GCC, and things are a bit wonky because pseudo-windows-linux isn't exactly a well-tested configuration?
Also just in general, lld is newer, it's not the default for most OSes, random compat bugs are almost certainly going to come up if we start using this in more places.
I have filed two metabugs for focused efforts on using (rust-)lld by default on two platforms:
- #71515 - x64 Ubuntu 20.04 LTS (and more broadly all the x64 ELF platforms)
- #71520 - x64 msvc windows
Aria Desires at 2020-04-23 23:43:30
windows-msvc is apparently in good shape, and seems to have some limited support for using rust-lld in the backend, but I'm unclear on what needs to be done here.
LLD +
windows-msvcis in pretty good state, I'm currently using this setup forrustcdevelopment.All the necessary support for
lld-linkis in place inrustcbackend, but there are bugs like https://github.com/rust-lang/rust/issues/68647.Vadim Petrochenkov at 2020-04-24 07:50:07
- This may be important, apparently lld does clang-style binary name detection of if it's being executed as "ld" or "ld.lld" (needs investigation)
it does, but ld and ld.lld are the same mode: https://github.com/rust-lang/llvm-project/blob/rustc/10.0-2020-02-05/lld/tools/lld/lld.cpp (same since 8.0-2019-01-16)
- Unfortunately -fuse-ld=lld is only part of GCC 9, so we may require feature/version detection to use it (clang has had it for a long time)
since ld.lld is the same as ld, and according to https://patches-gcc.linaro.org/patch/11148/ the only change with -fuse-ld=lld is to run ld.lld instead of ld, if we use PATH injection, it should be fine. I think locking this out to gcc 9+ isn't good though: debian stable only has 8.3, and bullseye probably won't be released until 2021.
- windows-mingw seems to be in roughly the same place as linux/unix, except you're liable to get an ancient GCC, and things are a bit wonky because pseudo-windows-linux isn't exactly a well-tested configuration?
mingw-w64 6.0.0, released 2018-09-16, has gcc 8.3.0, which doesn't have -fuse-ld=lld, but is still reasonably new. mingw-w64 7.0.0, released 2019-11-11, has gcc 9.3.0, which does have -fuse-ld=lld. Debian buster (stable) has 6.0.0, bullseye (testing) has 7.0.0. Debian stretch (oldstable) only has 5.0.1 with gcc 6.3.0, but I think it would be reasonable to require latest debian stable for lld support if there are significant issues with gcc 6.3.
Alex Xu at 2020-04-24 15:56:52
I have filed two metabugs for focused efforts on using (rust-)lld by default on two platforms:
- #71515 - x64 Ubuntu 20.04 LTS (and more broadly all the x64 ELF platforms)
- #71520 - x64 msvc windows
Aria Desires at 2020-04-24 18:05:34
About the macOS (Mach-O) port of lld: it seems to work, or at the very least, be in significantly better shape since https://github.com/rust-lang/rust/issues/39915#issuecomment-618726211 was written!
Using this LLVM commit, I built
lldand set it as a project-specific linker for tokio-rs/tracing. I then built tracing againstnightly-x86_64-apple-darwinand ran all tests successfully. I'm especially happy about about the (debug) build times:- With
ld, a cleancargo buildtook 35 seconds. - With
lld, a cleancargo buildtook 20 seconds.
Note that:
- these performance numbers came from a recent MacBook Pro with 32GB of RAM and an 8-Core i9, and
- there are a few outstanding issues for lld and Mach-O.
David Barsky at 2020-10-06 22:54:27
- With
@davidbarsky Cool! Out of curiosity, how does that performance compare with
zld? ( https://github.com/michaeleisel/zld )Also, did you account for thermals? MBPs go into thermal throttling very quickly, especially with the default fan speed profile. Just waiting until the bottom of the machine near the hinge is cool to the touch before doing a run should help consistency.
trevyn at 2020-10-07 02:24:41
I just such a bug, on Ubuntu 16 i686
Yan Titarenko at 2020-11-10 03:24:35
Potential problem for using rust-lld on Arm64 / aarch64 / Apple Silicon macOS
All executables are required to be code-signed on the new Arm64 macOS machines. By default, the system linker does that for you:
% cargo new hello-world Created binary (application) `hello-world` package % cd hello-world % cargo build Compiling hello-world v0.1.0 (/private/tmp/hello-world) Finished dev [unoptimized + debuginfo] target(s) in 5.03s % codesign -dvvv target/debug/hello-world Executable=/private/tmp/hello-world/target/debug/hello-world Identifier=hello_world Format=Mach-O thin (arm64) CodeDirectory v=20400 size=3140 flags=0x20002(adhoc,linker-signed) hashes=95+0 location=embedded Hash type=sha256 size=32 CandidateCDHash sha256=2fd59b9215be8cfaa04c619323546803bd8ee109 CandidateCDHashFull sha256=2fd59b9215be8cfaa04c619323546803bd8ee1091eab723ddedc127abacd9e6b Hash choices=sha256 CMSDigest=2fd59b9215be8cfaa04c619323546803bd8ee1091eab723ddedc127abacd9e6b CMSDigestType=2 CDHash=2fd59b9215be8cfaa04c619323546803bd8ee109 Signature=adhoc Info.plist=not bound TeamIdentifier=not set Sealed Resources=none Internal requirements=noneIf someone tries to get
lldworking on macOS, we should verify that the code signing still happens for free.Jake Goulding at 2020-11-20 19:29:21
[lld-macho] add code signature for native arm64 macOS https://reviews.llvm.org/D96164
Thorsten Schütt at 2021-02-18 21:13:52
Since a lot of people are invested in this, I should note that enabling LLD by default on Linux (https://github.com/rust-lang/rust/issues/71515) and Windows (https://github.com/rust-lang/rust/issues/71520) both seem relatively close to completion, but they each need a champion willing to put in the last bit of work to push them over the finish line.
bstrie at 2021-05-22 23:11:38
so was wondering if it was possible to cross link for macos using lld and the macos sdk. I get this error:
error: linking with `rust-lld` failed: exit status: 1 | = note: "rust-lld" "-flavor" "darwin" "/home/dvc/cloudpeer/cross-hw/target/x86_64-apple-darwin/debug/deps/cross_hw-70d0fd826bb4c755.1k1r2peqlms382uw.rcgu.o" "/home/dvc/cloudpeer/cross-hw/target/x86_64-apple-darwin/debug/deps/cross_hw-70d0fd826bb4c755.1suwbij9vuhemtp7.rcgu.o" "/home/dvc/cloudpeer/cross-hw/target/x86_64-apple-darwin/debug/deps/cross_hw-70d0fd826bb4c755.28of16y6dy4ftj2l.rcgu.o" "/home/dvc/cloudpeer/cross-hw/target/x86_64-apple-darwin/debug/deps/cross_hw-70d0fd826bb4c755.2cqhpy3ctqkp1udg.rcgu.o" "/home/dvc/cloudpeer/cross-hw/target/x86_64-apple-darwin/debug/deps/cross_hw-70d0fd826bb4c755.2mgjts3992b5y0bz.rcgu.o" "/home/dvc/cloudpeer/cross-hw/target/x86_64-apple-darwin/debug/deps/cross_hw-70d0fd826bb4c755.4438dslzay5e4h5g.rcgu.o" "/home/dvc/cloudpeer/cross-hw/target/x86_64-apple-darwin/debug/deps/cross_hw-70d0fd826bb4c755.49lwkudf6wetod32.rcgu.o" "/home/dvc/cloudpeer/cross-hw/target/x86_64-apple-darwin/debug/deps/cross_hw-70d0fd826bb4c755.4o3qjqrb84o9o4w5.rcgu.o" "/home/dvc/cloudpeer/cross-hw/target/x86_64-apple-darwin/debug/deps/cross_hw-70d0fd826bb4c755.4o5cczgq0rwzc52s.rcgu.o" "/home/dvc/cloudpeer/cross-hw/target/x86_64-apple-darwin/debug/deps/cross_hw-70d0fd826bb4c755.4kvw9qe301n2oclv.rcgu.o" "-L" "/home/dvc/cloudpeer/cross-hw/target/x86_64-apple-darwin/debug/deps" "-L" "/home/dvc/cloudpeer/cross-hw/target/debug/deps" "-L" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib" "/home/dvc/cloudpeer/cross-hw/target/x86_64-apple-darwin/debug/deps/libcross_hw-69c8e78ff0eca6e4.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/libstd-dd8a82589e0cba34.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/libpanic_unwind-8c04c8bd0d1a8900.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/libobject-c6a4ae86ed2c40d0.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/libmemchr-f9ab4d1b2e38b05e.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/libaddr2line-002c7b677ad6c512.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/libgimli-a3f3d9f86c37973f.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/libstd_detect-8b14bcf2354140fd.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/librustc_demangle-d6f2fd91ec8bbbcc.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/libhashbrown-24c80e37fb5b15c5.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/librustc_std_workspace_alloc-edb9b11fa36b4795.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/libunwind-769780536fb7ef9b.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/libcfg_if-d37c37a3a3ac2b0c.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/liblibc-c1bdc4c1f89760ef.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/liballoc-750380e9c94de9ce.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/librustc_std_workspace_core-1108e622f5a15c3d.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/libcore-43af7053e70b1eed.rlib" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib/libcompiler_builtins-3a81ebf6a3abbdee.rlib" "-lSystem" "-lresolv" "-lc" "-lm" "-liconv" "-L" "/home/dvc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-apple-darwin/lib" "-o" "/home/dvc/cloudpeer/cross-hw/target/x86_64-apple-darwin/debug/deps/cross_hw-70d0fd826bb4c755" "-dead_strip" = note: rust-lld: error: must specify -archmy
~/.cargo/configlooks like this:[target.x86_64-pc-windows-msvc] rustflags = [ "-C", "target-feature=+crt-static", "-Lnative=/home/dvc/xwin/crt/lib/x86_64", "-Lnative=/home/dvc/xwin/sdk/lib/um/x86_64", "-Lnative=/home/dvc/xwin/sdk/lib/ucrt/x86_64", ] linker = "rust-lld" [target.x86_64-apple-darwin] linker = "rust-lld"David Craven at 2021-12-21 13:11:37
Directly using
-Clinker=rust-lldonly works for wasm and windows. On all unix platforms you need gcc or clang to invoke the linker for you as they pass a lot of arguments to the linker necessary for a successful compilation like the path to system libraries or in this case the system architecture to link for. The way to make gcc and clang invoke lld would be to use-fuse-ld=lldas argument (-Clink-arg=-fuse-ld=lldwhen using rustc) if lld is in your path. To use the lld version shipped with rustc you can use-Zgcc-ld=lld.bjorn3 at 2021-12-21 13:41:36
building with
-Zgcc-ld=llddoesn't seem to work either:= note: cc: error: unrecognized command-line option '-arch' cc: error: unrecognized command-line option '-fuse-ld=/home/dvc/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin/gcc-ld/ld64'got a bit further with the previous approach:
[target.x86_64-apple-darwin] rustflags = [ "-C", "link-arg=-arch", "-C", "link-arg=x86_64", "-C", "link-arg=-platform_version", "-C", "link-arg=macos", "-C", "link-arg=10.10", "-C", "link-arg=10.10", "-L/home/dvc/MacOSX10.10.sdk/usr/lib", ] linker = "rust-lld"but now I get errors like this:
rust-lld: error: unable to locate re-export with install name /usr/lib/system/libcache.dylibDavid Craven at 2021-12-21 14:36:05
so got it to compile like this:
[target.x86_64-apple-darwin] rustflags = [ "-C", "link-arg=-target", "-C", "link-arg=x86_64-apple-darwin", "-C", "link-arg=-fuse-ld=lld", "-C", "link-arg=-mmacosx-version-min=10.10", "-C", "link-arg=-v", "-C", "link-arg=-isystem", "-C", "link-arg=/home/dvc/MacOSX10.10.sdk", "-L", "/home/dvc/MacOSX10.10.sdk/usr/lib", "-L", "/home/dvc/MacOSX10.10.sdk/usr/lib/system", "-C", "link-arg=-F", "-C", "link-arg=/home/dvc/MacOSX10.10.sdk/System/Library/Frameworks", ] linker = "clang"~get some warnings though:~ nope was due to some env variables set during experimenting
and I have no idea if the binary actually works as I don't have a mac to test it on yet.
David Craven at 2021-12-22 13:15:20
I compiled a relatively large project with ~450 dependencies that's a GRPC service that does raytracing, so a bunch of different kinds of dependencies. I have an M1 Mac so my config was:
[target.aarch64-apple-darwin] rustflags = [ "-C", "link-arg=-target", "-C", "link-arg=aarch64-apple-darwin", "-C", "link-arg=-fuse-ld=lld", "-C", "link-arg=-mmacosx-version-min=12.1", "-C", "link-arg=-v", "-C", "link-arg=-isystem", "-C", "link-arg=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk", "-L", "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib", "-L", "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/system", "-C", "link-arg=-F", "-C", "link-arg=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks", ] linker = "clang"For this to work I used Xcode.app and LLVM installed with Homebrew (
brew install llvm).The binaries worked just fine, the test suite passed. Looking at the file sizes, they were comparable if a tiny bit larger with lld.
-rwxr-xr-x 1 redacted staff 18324905 Dec 24 11:04 ./std/debug/test -rwxr-xr-x 1 redacted staff 17645152 Dec 24 11:01 ./lld/debug/test -rwxr-xr-x 1 redacted staff 2852265 Dec 24 11:05 ./std/release/test -rwxr-xr-x 1 redacted staff 2872608 Dec 24 11:03 ./lld/release/testCompile times were also comparable if a tiny bit faster with lld.
std: cargo build 165.67s user 14.97s system 542% cpu 33.287 total lld: cargo build 160.69s user 15.24s system 535% cpu 32.852 total std: cargo build --release 279.84s user 15.70s system 440% cpu 1:07.08 total lld: cargo build --release 276.73s user 16.06s system 439% cpu 1:06.59 totalNebojsa Sabovic at 2021-12-24 10:20:03
Working on a cross compile toolchain for all platforms using distro supplied clang/lld. Copies the relevant parts from a GitHub runner and publishes a release. Still tweaking the .cargo/config for the example app to build.
- [0] https://github.com/cloudpeers/xcross
David Craven at 2021-12-24 10:41:24
I will like to know if the goal of using lld as the default linker has been achieved ?
peter Abeshi at 2023-03-19 15:10:20
It isn't the default yet.
bjorn3 at 2023-03-19 15:20:53
I believe LLD on macOS is now in a much better state (and specifically that whereas previously the macOS version of lld was a completely separate codebase from the windows/linux versions, macOS lld is now based on the same codebase as windows/linux lld). Certainly, linking with homebrew installed LLD seems to work well with stable Rust.
Would it make sense to create an issue for making LLD the default linker on macOS?
Nico Burns at 2023-03-28 12:16:45
There are issues open for Linux and Windows already and none for Mac. So having one might be reasonable for parity, but I don't think it will make any difference one way or the other about when this will happen. AIUI there are still various things blocking shipping on any platform, e.g. this. @lqd and @petrochenkov will know more.
Nicholas Nethercote at 2023-03-29 02:34:59
I would like to know the current status of the
lldsupport as the default linker, so could anyone of you please let me know about the current status?neon_arch at 2024-02-07 12:23:09
I would like to know the current status of the
lldsupport as the default linker, so could anyone of you please let me know about the current status?Here's a summary by ChatGPT 3.5, hope it's of help:
Overall, while there is interest in using LLD due to its speed advantages, concerns about platform support and unresolved issues appear to be delaying its adoption as the default linker in Rust.
<details><summary>Details</summary> <p>-
Initial Discussion (March 26, 2019): There's a debate about enabling LLD as the default linker for all targets due to its speed benefits. However, concerns are raised about LLD support on different platforms, particularly macOS. Documentation and Usage (May 17, 2019): Questions arise about the documentation and usage of LLD with Rust code, particularly regarding the linker flags required.
-
Error Reports and Workarounds (May 28, 2019 - October 3, 2019): Users report errors and difficulties when attempting to use LLD with Cargo builds, including missing libraries and segmentation faults. Various workarounds and suggestions are provided, such as adjusting RUSTFLAGS and linker arguments.
-
Continued Inquiry (October 22, 2019): Users inquire about the current status and blockers for moving forward with using LLD as the default linker.
-
Status Check (March 19, 2023): A user seeks an update on whether LLD has become the default linker yet. The response indicates that it has not.
-
Discussion on macOS Support (March 28, 2023): There's a discussion about the improved state of LLD on macOS and the possibility of creating an issue to make LLD the default linker on macOS.
Andrew Zhurov at 2024-03-17 14:40:44
-
Here's a summary by ChatGPT 3.5, hope it's of help:
It is actively unhelpful.
Catherine at 2024-03-17 16:32:22
I would like to know the current status of the lld support as the default linker, so could anyone of you please let me know about the current status?
It's mostly prepared, implementation-wise, but we're still deciding on how should the CLI flags work. See https://github.com/rust-lang/rust/pull/119906 for the most recent discussion.
Jakub Beránek at 2024-03-17 18:36:58
status update: as of #124129, rustup-distributed rustc (not distros') on
x86_64-unknown-linux-gnuuses the self-contained lld linker by default, (rust-lld, itself also distributed with rustup), on nightly only for now and starting from tomorrow's nightly.Rémy Rakic at 2024-05-17 07:58:00