15

I'm using lld as my linker currently for Rust, but recently encountered the mold project, which is faster than lld. I'd like to try it for Rust compilation, but I'm not sure how to pass it in as my linker. In my .cargo/config file I've got:

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

But I can't just change that lld to mold, or provide the path to the mold executable. Is there a way to get gcc to accept a path to a linker?

usr1234567
  • 21,601
  • 16
  • 108
  • 128
Marcus Buffett
  • 1,289
  • 1
  • 14
  • 32
  • 2
    [`-Clinker`](https://doc.rust-lang.org/rustc/codegen-options/index.html#linker) “controls which linker `rustc` invokes to link your code. It takes a path to the linker executable.” – eggyal May 12 '21 at 23:50
  • @eggyal looks like you could make an answer – mcarton May 13 '21 at 00:09
  • @mcarton: I don’t know anything about `mold`, and therefore other options may also need to be set (if indeed it’s compatible with rustc at all). – eggyal May 13 '21 at 01:44
  • 1
    You usually change the linker with these lines in `.cargo/config: `[target.x86_64-unknown-linux-gnu] linker = "/usr/bin/mold" `. But just like @eggyal, I don't know mold either to guess if it will work. – rodrigo May 13 '21 at 15:45

3 Answers3

30

Mold can now be used with Clang by simply adding this to ~/.cargo/config.toml

[target.x86_64-unknown-linux-gnu]
linker = "/usr/bin/clang"
rustflags = ["-C", "link-arg=--ld-path=/usr/bin/mold"]

Note: Mold may be installed at /usr/local/bin/mold if installed from source so the flags should be rustflags = ["-C", "link-arg=--ld-path=/usr/local/bin/mold"]. Run $ which mold to double check where it's installed

You can check it's worked by running readelf -p .comment target/<type>/<binary_name>

$ readelf -p .comment target/debug/my_binary

String dump of section '.comment':
  [     0]  GCC: (GNU) 11.1.0
  [    13]  mold 1.0.0 (compatible with GNU ld and GNU gold)
timlyo
  • 2,086
  • 1
  • 23
  • 35
  • 2
    Note, my installation of mold put the executable into `/usr/local/bin/mold` – aName Dec 23 '21 at 17:02
  • @aName which distro are you using? I'll add some detail to the answer. – timlyo Dec 30 '21 at 11:45
  • Following the instructions at https://github.com/rui314/mold#compile-mold gave me an executable at `/usr/local/bin/mold`. – Andy Balaam Jan 05 '22 at 01:35
  • 2
    The above did not work for me - I needed `rustflags = ["-C", "link-arg=-fuse-ld=/usr/local/bin/mold"]`, as specified at https://github.com/rui314/mold#how-to-use – Andy Balaam Jan 05 '22 at 01:35
  • Ahh I see, it looks like the difference between installing from a package manager and installing from the makefile. – timlyo Jan 05 '22 at 13:48
  • Setting `rustflags` does not affect native executables built while crosscompiling (for example, build scripts are built as executables for the build system while compiling for a different target). – Cody Schafer Feb 08 '23 at 16:03
16

gcc does not accept an arbitrary path as an argument for -fuse-ld, unfortunately. Instead of tweaking .cargo/config file, try running cargo build as path/to/mold -run cargo build. By doing this, cargo runs under an influence of mold, and all invocations of /usr/bin/ld, /usr/bin/ld.gold and /usr/bin/ld.lld are intercepted and replaced by mold.

Rui Ueyama
  • 321
  • 2
  • 4
1

First, create a symlink of mold to lld to trick rust into believing it's ld.lld.

sudo ln -s /usr/bin/ld.mold /usr/bin/ld.lld 

Then add this in your ~/.cargo/config file to specify ld.lld (which is now mold)

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

Now build without mold -run and read the comment (readelf -p .comment target/debug/program-name)

String dump of section '.comment':
  [     0]  GCC: (GNU) 11.1.0
  [    13]  mold 0.9.3 (compatible with GNU ld and GNU gold)

I'm not really sure how it is that I can set a symlink as ld.lld, I guess I don't have that file currently, but nonetheless this is very hacky and serves to fool any future compiler into using mold, while believing it's using lld (if it's set to use lld). I use this personally because I don't like typing mold -run every time, though.

Rustacean
  • 11
  • 1
  • There is also `-Clinker-flavor=ld` to control how it's invoked, which avoids messing with the file name. – poolie Oct 31 '22 at 14:19