How do I change the default rustc / Cargo linker?
Asked Answered
S

3

41

I would like to make rustc use lld as a linker instead of ld in a particular crate. So I create .cargo/config in my project directory with the following:

[target.x86_64-unknown-linux-gnu]                                                                   
linker = "ld.lld"

Which leads to linker errors:

$ cargo build
...
  = note: ld.lld: error: unable to find library -ldl
          ld.lld: error: unable to find library -lrt
          ld.lld: error: unable to find library -lpthread
          ld.lld: error: unable to find library -lgcc_s
          ld.lld: error: unable to find library -lc
          ld.lld: error: unable to find library -lm
          ld.lld: error: unable to find library -lrt
          ld.lld: error: unable to find library -lpthread
          ld.lld: error: unable to find library -lutil
          ld.lld: error: unable to find library -lutil

Same thing with rust-lld. If I set linker = "ld" (which should be the default, right?), I just get

  = note: ld: cannot find -lgcc_s

I tried to resolve all the missing libraries manually (with -C link-arg=--library-path=/usr/lib/x86_64-linux-gnu and the like), but it only lead to wrong linkage and a segfaulting binary.

Interestingly enough, if I replace /usr/bin/ld with a symlink to /usr/bin/ld.lld, it works great (no errors, and from the compiled binary I see that it was indeed linked with lld). However, I don't want to make lld my system-wide linker, I just want to use it in a particular Rust crate.

So what is the proper way to change the default rustc linker?

Sterne answered 5/9, 2019 at 20:59 Comment(1)
What happens if you put clang as the linker?Stabler
S
41

Thanks to @Jmb comment, I found a solution. Turns out that the default linker that rustc uses is actually cc (which makes sense - it supplies all the needed defaults to compile/link C code, which also work for Rust). We can pass an argument to cc to make it link with lld:

[target.x86_64-unknown-linux-gnu]
rustflags = [
    "-C", "link-arg=-fuse-ld=lld",
]

Now cargo build links with lld.

Sterne answered 6/9, 2019 at 7:51 Comment(0)
M
10

Adding this to .cargo/config.toml (in the project) forces using lld

[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "link-arg=-fuse-ld=lld"]

[target.x86_64-pc-windows-gnu]
rustflags = ["-C", "link-arg=-fuse-ld=lld"]

[target.x86_64-unknown-linux-gnu]
rustflags = ["-C", "linker=clang", "-C", "link-arg=-fuse-ld=lld"]

For more information see this: https://github.com/rust-lang/rust/issues/71515

You can remove "-C", "linker=clang" on Linux, if you have Gcc 9 or newer installed

Mydriasis answered 5/10, 2021 at 8:30 Comment(1)
I don't think this has any effect if it's placed in the Cargo.toml. It should go into the config file instead: doc.rust-lang.org/cargo/reference/config.htmlUnrivalled
D
5

This also works and is what I think @Jmb actually asked.

rustflags = [
  "-C", "linker=clang-12",  # change the version as needed
]
Disassembly answered 11/3, 2021 at 5:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.