# 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 <oss@mateuszmikula.dev>
258 lines
5.8 KiB
Bash
Executable File
258 lines
5.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -xeuo pipefail
|
|
|
|
# if root or if sudo/unavailable, define an empty variable
|
|
if [ "$(id -u)" -eq 0 ]
|
|
then maysudo=''
|
|
else maysudo="$(command -v sudo || command -v doas || true)"
|
|
fi
|
|
|
|
function finalize {
|
|
# after packages install (curl, etc), get the rust toolchain
|
|
which rustup > /dev/null 2>&1 || curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
|
cat <<EOF
|
|
Note: It's recommended to install and configure Wild or Mold for faster builds.
|
|
Run script/install-wild or script/install-mold.
|
|
Then add these lines to your ~/.cargo/config.toml:
|
|
|
|
[target.x86_64-unknown-linux-gnu]
|
|
linker = "clang"
|
|
rustflags = ["-C", "link-arg=--ld-path=wild"]
|
|
|
|
[target.aarch64-unknown-linux-gnu]
|
|
linker = "clang"
|
|
rustflags = ["-C", "link-arg=--ld-path=wild"]
|
|
|
|
|
|
|
|
Finished installing Linux dependencies with script/linux
|
|
EOF
|
|
}
|
|
|
|
# Ubuntu, Debian, Mint, Kali, Pop!_OS, Raspbian, etc.
|
|
apt=$(command -v apt-get || true)
|
|
if [[ -n $apt ]]; then
|
|
deps=(
|
|
gcc
|
|
g++
|
|
libasound2-dev
|
|
libfontconfig-dev
|
|
libwayland-dev
|
|
libx11-xcb-dev
|
|
libxkbcommon-x11-dev
|
|
libssl-dev
|
|
libzstd-dev
|
|
libvulkan1
|
|
libgit2-dev
|
|
make
|
|
cmake
|
|
clang
|
|
jq
|
|
git
|
|
curl
|
|
gettext-base
|
|
elfutils
|
|
libsqlite3-dev
|
|
musl-tools
|
|
musl-dev
|
|
build-essential
|
|
)
|
|
if (grep -qP 'PRETTY_NAME="(Debian|Raspbian).+13' /etc/os-release); then
|
|
# libstdc++-14-dev is in build-essential
|
|
deps+=( mold )
|
|
elif (grep -qP 'PRETTY_NAME="(Linux Mint 22|.+24\.(04|10))' /etc/os-release); then
|
|
deps+=( mold libstdc++-14-dev )
|
|
elif (grep -qP 'PRETTY_NAME="((Debian|Raspbian).+12|Linux Mint 21|.+22\.04)' /etc/os-release); then
|
|
deps+=( mold libstdc++-12-dev )
|
|
elif (grep -qP 'PRETTY_NAME="((Debian|Raspbian).+11|Linux Mint 20|.+20\.04)' /etc/os-release); then
|
|
deps+=( libstdc++-10-dev )
|
|
fi
|
|
|
|
$maysudo "$apt" update
|
|
$maysudo "$apt" install -y "${deps[@]}"
|
|
finalize
|
|
exit 0
|
|
fi
|
|
|
|
# Fedora, CentOS, RHEL, Alma, Amazon 2023, Oracle, etc.
|
|
dnf=$(command -v dnf || true)
|
|
# Old Redhat (yum only): Amazon Linux 2, Oracle Linux 7, etc.
|
|
yum=$(command -v yum || true)
|
|
|
|
if [[ -n $dnf ]] || [[ -n $yum ]]; then
|
|
pkg_cmd="${dnf:-${yum}}"
|
|
deps=(
|
|
musl-gcc
|
|
gcc
|
|
clang
|
|
cmake
|
|
alsa-lib-devel
|
|
fontconfig-devel
|
|
wayland-devel
|
|
libxcb-devel
|
|
libxkbcommon-x11-devel
|
|
openssl-devel
|
|
libzstd-devel
|
|
vulkan-loader
|
|
sqlite-devel
|
|
jq
|
|
git
|
|
tar
|
|
)
|
|
# perl used for building openssl-sys crate. See: https://docs.rs/openssl/latest/openssl/
|
|
if grep -qP '^ID="?(fedora)' /etc/os-release; then
|
|
deps+=(
|
|
perl-FindBin
|
|
perl-IPC-Cmd
|
|
perl-File-Compare
|
|
perl-File-Copy
|
|
mold
|
|
)
|
|
elif grep -qP '^ID="?(rhel|rocky|alma|centos|ol)' /etc/os-release; then
|
|
deps+=( perl-interpreter )
|
|
fi
|
|
|
|
# gcc-c++ is g++ on RHEL8 and 8.x clones
|
|
if grep -qP '^ID="?(rhel|rocky|alma|centos|ol)' /etc/os-release \
|
|
&& grep -qP '^VERSION_ID="?(8)' /etc/os-release; then
|
|
deps+=( gcc-c++ )
|
|
else
|
|
deps+=( g++ )
|
|
fi
|
|
|
|
# libxkbcommon-x11-devel is in a non-default repo on RHEL 8.x/9.x (except on AmazonLinux)
|
|
if grep -qP '^VERSION_ID="?(8|9)' /etc/os-release && grep -qP '^ID="?(rhel|rocky|centos|alma|ol)' /etc/os-release; then
|
|
$maysudo dnf install -y 'dnf-command(config-manager)'
|
|
if grep -qP '^PRETTY_NAME="(AlmaLinux 8|Rocky Linux 8)' /etc/os-release; then
|
|
$maysudo dnf config-manager --set-enabled powertools
|
|
elif grep -qP '^PRETTY_NAME="((AlmaLinux|Rocky|CentOS Stream) 9|Red Hat.+(8|9))' /etc/os-release; then
|
|
$maysudo dnf config-manager --set-enabled crb
|
|
elif grep -qP '^PRETTY_NAME="Oracle Linux Server 8' /etc/os-release; then
|
|
$maysudo dnf config-manager --set-enabled ol8_codeready_builder
|
|
elif grep -qP '^PRETTY_NAME="Oracle Linux Server 9' /etc/os-release; then
|
|
$maysudo dnf config-manager --set-enabled ol9_codeready_builder
|
|
else
|
|
echo "Unexpected distro" && grep 'PRETTY_NAME' /etc/os-release && exit 1
|
|
fi
|
|
fi
|
|
|
|
$maysudo "$pkg_cmd" install -y "${deps[@]}"
|
|
finalize
|
|
exit 0
|
|
fi
|
|
|
|
# openSUSE
|
|
# https://software.opensuse.org/
|
|
zyp=$(command -v zypper || true)
|
|
if [[ -n $zyp ]]; then
|
|
deps=(
|
|
alsa-devel
|
|
clang
|
|
cmake
|
|
fontconfig-devel
|
|
gcc
|
|
gcc-c++
|
|
git
|
|
gzip
|
|
jq
|
|
libvulkan1
|
|
libx11-devel
|
|
libxcb-devel
|
|
libxkbcommon-devel
|
|
libxkbcommon-x11-devel
|
|
libzstd-devel
|
|
make
|
|
mold
|
|
openssl-devel
|
|
sqlite3-devel
|
|
tar
|
|
wayland-devel
|
|
xcb-util-devel
|
|
)
|
|
$maysudo "$zyp" install -y "${deps[@]}"
|
|
finalize
|
|
exit 0
|
|
fi
|
|
|
|
# Arch, Manjaro, etc.
|
|
# https://archlinux.org/packages
|
|
pacman=$(command -v pacman || true)
|
|
if [[ -n $pacman ]]; then
|
|
deps=(
|
|
gcc
|
|
clang
|
|
musl
|
|
cmake
|
|
alsa-lib
|
|
fontconfig
|
|
wayland
|
|
libgit2
|
|
libxcb
|
|
libxkbcommon-x11
|
|
openssl
|
|
zstd
|
|
pkgconf
|
|
mold
|
|
sqlite
|
|
jq
|
|
git
|
|
)
|
|
$maysudo "$pacman" -Syu --needed --noconfirm "${deps[@]}"
|
|
finalize
|
|
exit 0
|
|
fi
|
|
|
|
# Void
|
|
# https://voidlinux.org/packages/
|
|
xbps=$(command -v xbps-install || true)
|
|
if [[ -n $xbps ]]; then
|
|
deps=(
|
|
gettext-devel
|
|
clang
|
|
cmake
|
|
jq
|
|
elfutils-devel
|
|
gcc
|
|
alsa-lib-devel
|
|
fontconfig-devel
|
|
libxcb-devel
|
|
libxkbcommon-devel
|
|
libzstd-devel
|
|
openssl-devel
|
|
wayland-devel
|
|
vulkan-loader
|
|
mold
|
|
sqlite-devel
|
|
)
|
|
$maysudo "$xbps" -Syu "${deps[@]}"
|
|
finalize
|
|
exit 0
|
|
fi
|
|
|
|
# Gentoo
|
|
# https://packages.gentoo.org/
|
|
emerge=$(command -v emerge || true)
|
|
if [[ -n $emerge ]]; then
|
|
deps=(
|
|
app-arch/zstd
|
|
app-misc/jq
|
|
dev-libs/openssl
|
|
dev-libs/wayland
|
|
dev-util/cmake
|
|
media-libs/alsa-lib
|
|
media-libs/fontconfig
|
|
media-libs/vulkan-loader
|
|
x11-libs/libxcb
|
|
x11-libs/libxkbcommon
|
|
sys-devel/mold
|
|
dev-db/sqlite
|
|
)
|
|
$maysudo "$emerge" -u "${deps[@]}"
|
|
finalize
|
|
exit 0
|
|
fi
|
|
|
|
echo "Unsupported Linux distribution in script/linux"
|
|
exit 1
|