Skip to content

Commit 10b99c6

Browse files
sourcefrogmati865
andauthored
RFC: Recommend and enable using Wild rather than Mold on Linux for local builds (#37717)
# Summary Today, Zed uses Mold on Linux, but Wild can be significantly faster. On my machine, Wild is 14% faster at a whole-tree clean build, 20% faster on an incremental build with a minimal change, and makes no measurable effect on runtime performance of tests. However, Wild's page says it's not yet ready for production, so it seems to early to switch for production and CI builds. This PR keeps using Mold in CI and lets developers choose in their own config what linker to use. (The downside of this is that after landing this change, developers will have to do some local config or it will fall back to the default linker which may be slower.) [Wild 0.6 is out, and their announcement has some benchmarks](https://davidlattimore.github.io/posts/2025/09/23/wild-update-0.6.0.html). cc @davidlattimore from Wild, just fyi # Tasks - [x] Measure Wild build, incremental build, and runtime performance in different scenarios - [x] Remove the Linux linker config from `.cargo/config.toml` in the tree - [x] Test rope benchmarks etc - [x] Set the linker to Mold in CI - [x] Add instructions to use Wild or Mold into `linux.md` - [x] Add a script to download Wild - [x] Measure binary size - [x] Recommend Wild from `scripts/linux` # Benchmarks | | wild 0.6 (rust 1.89) | mold 2.37.1 (1.89) | lld (rust 1.90) | wild advantage | | -- | -- | -- | -- | -- | | clean workspace build | 176s | 184s | 182s | 5% faster than mold | | nextest run workspace after build | 137s | 142s | 137s | in the noise? | | incremental rebuild | 3.9s | 5.0s | 6.6s | 22% faster than mold | I didn't observe any apparent significant change in runtime performance or binary size, or in the in-tree microbenchmarks. Release Notes: - N/A --------- Co-authored-by: Mateusz Mikuła <[email protected]>
1 parent 17dea24 commit 10b99c6

File tree

5 files changed

+85
-14
lines changed

5 files changed

+85
-14
lines changed

.cargo/ci-config.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,15 @@
1010
# Here, we opted to use `[target.'cfg(all())']` instead of `[build]` because `[target.'**']` is guaranteed to be cumulative.
1111
[target.'cfg(all())']
1212
rustflags = ["-D", "warnings"]
13+
14+
# Use Mold on Linux, because it's faster than GNU ld and LLD.
15+
#
16+
# We no longer set this in the default `config.toml` so that developers can opt in to Wild, which
17+
# is faster than Mold, in their own ~/.cargo/config.toml.
18+
[target.x86_64-unknown-linux-gnu]
19+
linker = "clang"
20+
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
21+
22+
[target.aarch64-unknown-linux-gnu]
23+
linker = "clang"
24+
rustflags = ["-C", "link-arg=-fuse-ld=mold"]

.cargo/config.toml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,6 @@ xtask = "run --package xtask --"
77
perf-test = ["test", "--profile", "release-fast", "--lib", "--bins", "--tests", "--all-features", "--config", "target.'cfg(true)'.runner='cargo run -p perf --release'", "--config", "target.'cfg(true)'.rustflags=[\"--cfg\", \"perf_enabled\"]"]
88
perf-compare = ["run", "--release", "-p", "perf", "--", "compare"]
99

10-
[target.x86_64-unknown-linux-gnu]
11-
linker = "clang"
12-
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
13-
14-
[target.aarch64-unknown-linux-gnu]
15-
linker = "clang"
16-
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
17-
1810
[target.'cfg(target_os = "windows")']
1911
rustflags = [
2012
"--cfg",

docs/src/development/linux.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,33 @@ Clone down the [Zed repository](https://github.com/zed-industries/zed).
2020

2121
If you are looking to develop Zed collaboration features using a local collaboration server, please see: [Local Collaboration](./local-collaboration.md) docs.
2222

23+
### Linkers {#linker}
24+
25+
On Linux, Rust's default linker is [LLVM's `lld`](https://blog.rust-lang.org/2025/09/18/Rust-1.90.0/). Alternative linkers, especially [Wild](https://github.com/davidlattimore/wild) and [Mold](https://github.com/rui314/mold) can significantly improve clean and incremental build time.
26+
27+
At present Zed uses Mold in CI because it's more mature. For local development Wild is recommended because it's 5-20% faster than Mold.
28+
29+
These linkers can be installed with `script/install-mold` and `script/install-wild`.
30+
31+
To use Wild as your default, add these lines to your `~/.cargo/config.toml`:
32+
33+
```toml
34+
[target.x86_64-unknown-linux-gnu]
35+
linker = "clang"
36+
rustflags = ["-C", "link-arg=--ld-path=wild"]
37+
38+
[target.aarch64-unknown-linux-gnu]
39+
linker = "clang"
40+
rustflags = ["-C", "link-arg=--ld-path=wild"]
41+
```
42+
43+
To use Mold as your default:
44+
45+
```toml
46+
[target.'cfg(target_os = "linux")']
47+
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
48+
```
49+
2350
## Building from source
2451

2552
Once the dependencies are installed, you can build Zed using [Cargo](https://doc.rust-lang.org/cargo/).

script/install-wild

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/env bash
2+
3+
# Install wild-linker official binaries from GitHub Releases.
4+
5+
set -euo pipefail
6+
7+
WILD_VERSION="${WILD_VERSION:-${1:-0.6.0}}"
8+
if [ "$(uname -s)" != "Linux" ]; then
9+
echo "Error: This script is intended for Linux systems only."
10+
exit 1
11+
elif [ -z "$WILD_VERSION" ]; then
12+
echo "Usage: $0 [version]"
13+
exit 1
14+
elif which -s wild && wild --version | grep -Fq "$WILD_VERSION" ; then
15+
echo "Warning: existing wild $WILD_VERSION found at $(which wild). Skipping installation."
16+
exit 0
17+
fi
18+
19+
if [ "$(whoami)" = root ]; then SUDO=; else SUDO="$(command -v sudo || command -v doas || true)"; fi
20+
21+
ARCH="$(uname -m)"
22+
WILD_REPO="${WILD_REPO:-https://github.com/davidlattimore/wild}"
23+
WILD_PACKAGE="wild-linker-${ARCH}-unknown-linux-gnu"
24+
WILD_URL="${WILD_URL:-$WILD_REPO}/releases/download/$WILD_VERSION/${WILD_PACKAGE}.tar.gz"
25+
26+
echo "Downloading from $WILD_URL"
27+
curl -fsSL --output - "$WILD_URL" \
28+
| $SUDO tar -C /usr/local/bin --strip-components=1 --no-overwrite-dir -xJf - \
29+
"wild-linker-${ARCH}-unknown-linux-gnu/wild"

script/linux

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,23 @@ fi
1111
function finalize {
1212
# after packages install (curl, etc), get the rust toolchain
1313
which rustup > /dev/null 2>&1 || curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
14-
# verify the mold situation
15-
if ! command -v mold >/dev/null 2>&1; then
16-
echo "Warning: Mold binaries are unavailable on your system." >&2
17-
echo " Builds will be slower without mold. Try: script/install-mold" >&2
18-
fi
19-
echo "Finished installing Linux dependencies with script/linux"
14+
cat <<EOF
15+
Note: It's recommended to install and configure Wild or Mold for faster builds.
16+
Run script/install-wild or script/install-mold.
17+
Then add these lines to your ~/.cargo/config.toml:
18+
19+
[target.x86_64-unknown-linux-gnu]
20+
linker = "clang"
21+
rustflags = ["-C", "link-arg=--ld-path=wild"]
22+
23+
[target.aarch64-unknown-linux-gnu]
24+
linker = "clang"
25+
rustflags = ["-C", "link-arg=--ld-path=wild"]
26+
27+
28+
29+
Finished installing Linux dependencies with script/linux
30+
EOF
2031
}
2132

2233
# Ubuntu, Debian, Mint, Kali, Pop!_OS, Raspbian, etc.

0 commit comments

Comments
 (0)