As modern C, C++, and Rust codebases expand, developer iteration cycles often hit severe performance bottlenecks during the final linking phase. While modern multi-core processors compile individual translation units in parallel with extreme speed, legacy linkers like GNU ld and even LLVM’s lld can struggle to parallelise symbol resolution, relocation, and debug info deduplication. The result is sluggish build times where developers wait dozens of seconds—or even minutes—for a minor code change to link.
Enter mold, created by Rui Ueyama (the original author of LLVM’s lld). Mold is a high-performance modern linker designed specifically to exploit multi-core parallelism and fast NVMe storage, achieving linking speeds several times faster than lld and up to dozens of times faster than GNU gold or ld.bfd. This comprehensive tutorial details how to install mold on Linux, integrate it seamlessly into GCC, Clang, CMake, and Cargo (Rust) build pipelines, and troubleshoot common linking flags.
Why Linker Performance Matters
During a typical compilation workflow, source files (.c, .cpp, .rs) compile into individual object files (.o). The linker’s job is to stitch these disparate objects into a single executable or shared library: resolving external symbol addresses, merging sections, generating relocations, and writing debug information (DWARF). Because traditional linkers were architected when single-threaded disk I/O dominated, they serialise critical stages.
Mold re-engineers this pipeline from the ground up:
- Aggressive Parallelism: Operates across all available CPU threads during symbol parsing, string table generation, and section layout.
- Memory-Mapped I/O: Writes directly into output files using parallel memory mappings (
mmap), minimizing redundant memory copies. - Drop-In Compatibility: Designed as a direct drop-in replacement for GNU
ld, accepting standard flags and supporting ELF binaries onx86_64,aarch64,riscv64, and other architectures.
Step 1: Installing Mold on Linux
Mold is packaged in official repositories across modern Linux distributions and is also distributed as self-contained standalone binary tarballs.
Method A: On Ubuntu and Debian Systems
On Ubuntu 22.04 LTS, Debian 12 (Bookworm), or newer releases, mold is available directly via APT:
# Update package list and install mold
sudo apt update
sudo apt install -y mold
Method B: On Fedora, RHEL, and CentOS Stream
On Fedora 39/40 and enterprise systems with EPEL enabled:
# Install mold via DNF
sudo dnf install -y mold
Method C: On Arch Linux
sudo pacman -S mold
Method D: Official Precompiled Binary Tarball (Universal)
To run the latest upstream version with cutting-edge optimisations on any Linux distribution:
# Determine your system architecture
ARCH=$(uname -m)
# Fetch latest release tag from GitHub API
MOLD_VER=$(curl -s https://api.github.com/repos/rui314/mold/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
# Download prebuilt tarball
curl -LO "https://github.com/rui314/mold/releases/download/${MOLD_VER}/mold-${MOLD_VER#v}-${ARCH}-linux.tar.gz"
# Extract and install to /usr/local
sudo tar -C /usr/local --strip-components=1 -xzf "mold-${MOLD_VER#v}-${ARCH}-linux.tar.gz"
# Verify installation
mold --version
Step 2: Using Mold via the Wrapper Script (Fastest Method)
The simplest way to execute builds with mold without altering source Makefiles or build configurations is using the bundled wrapper command: mold -run.
The mold -run wrapper sets up an internal LD_PRELOAD or adjusts the PATH so that any compiler invocation transparently invokes mold whenever it attempts to call ld:
# Intercept standard make builds
mold -run make -j$(nproc)
# Intercept Cargo builds for Rust
mold -run cargo build
# Intercept CMake build steps
mold -run ninja
Step 3: Configuring GCC and Clang to Use Mold
For persistent toolchain configuration, pass linker flags directly to your compiler.
For Clang (version 12+)
Modern Clang natively accepts the --ld-path flag:
clang++ -fuse-ld=mold main.cpp -o myapp
For GCC (version 12.1+)
Recent versions of GCC support mold out of the box using the standard -fuse-ld switch:
g++ -fuse-ld=mold -O2 main.cpp -o myapp
For Older GCC Versions
If running an older GCC compiler that does not recognize -fuse-ld=mold, pass the direct path to the mold executable via the -B prefix:
g++ -B/usr/libexec/mold main.cpp -o myapp
Step 4: Integrating Mold into CMake Projects
To instruct CMake to build your entire C or C++ project with mold, add the following configuration block to your top-level CMakeLists.txt or pass it on the command line:
In CMakeLists.txt:
# Automatically enable mold if available on the host system
find_program(MOLD_PATH mold)
if(MOLD_PATH)
message(STATUS "Mold linker detected at ${MOLD_PATH}. Enabling fast linking.")
add_link_options("-fuse-ld=mold")
endif()
Via CMake Command Line:
Generate your build tree using the CMake link flags variable:
cmake -B build -G Ninja \
-DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" \
-DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold"
cmake --build build -j$(nproc)
Step 5: Accelerating Rust Cargo Builds with Mold
Rust developers frequently experience prolonged compile times due to massive monomorphised symbol tables. Mold provides extraordinary speedups for incremental Rust compilation.
Configure Cargo globally or per-project by updating .cargo/config.toml:
# Create or edit Cargo configuration
mkdir -p ~/.cargo
nano ~/.cargo/config.toml
Add the following target linker rules for x86_64 Linux:
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
If you prefer using GCC as the driver:
[target.x86_64-unknown-linux-gnu]
linker = "gcc"
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
Now, running cargo build or cargo test links incremental binaries nearly instantaneously.
Benchmarking Mold vs LLD vs GNU LD
The following performance overview summarizes typical benchmark timings linking large C++ codebases (such as Chromium, Clang, or Game Engines) with debug symbols enabled:
| Linker | Link Time (Large C++ Project) | Relative Speed | Multi-Core Efficiency |
|---|---|---|---|
GNU ld.bfd |
~52.4 seconds | 1.0x (Baseline) | Single-threaded; high latency |
GNU gold |
~24.1 seconds | ~2.2x faster | Coarse multi-threading |
LLVM lld |
~8.3 seconds | ~6.3x faster | Good multi-core scaling |
| Mold | ~1.8 seconds | ~29x faster | Near-linear multi-core saturation |
Troubleshooting Common Mold Linking Issues
| Issue | Underlying Cause | Recommended Resolution |
|---|---|---|
cannot find -lmold |
Incorrect flag syntax | Use -fuse-ld=mold, not -lmold (which instructs the compiler to link a library named libmold). |
GCC: invalid linker name in -fuse-ld=mold |
Legacy GCC version (< 12.1) | Upgrade GCC, or use mold -run <command>, or create a symlink in /usr/libexec/mold/ld -> /usr/bin/mold. |
| LTO (Link-Time Optimisation) slow | Compiler backend doing code generation | Mold only links; LTO optimization runs inside the compiler plugin (LLVM/GCC). For maximum iteration speed during development, disable LTO (-fno-lto). |