Skip to content
chornous.dev

Type two or more letters. Esc closes.

Index of sheets
Theme

Sheet 03 · Writing

All notes

mold 3.0: the linker moved from C++ to Rust, and the build moved from CMake to Cargo

Rui Ueyama released mold 3.0.0 on October 5, 2026, the first version written in Rust. It keeps 2.42.1's options, targets and linking speed, replaces CMake with Cargo, needs Rust 1.95 to build, and panics on corrupted input instead of reading out of bounds.

Pl. 29 · pipeline drawing generated from the slug “mold-3-0-rust-rewrite”

Rui Ueyama released mold 3.0.0 on October 5, 2026. The release ports the high-speed linker from C++ to Rust, and 2.42.1 stays the last C++ release. The release notes call 3.0 "meant to be a drop-in replacement for 2.42.1." The release reached 234 points on Hacker News a day later.

If you call mold from a compiler flag and nothing more, little changes for you. If you package it, build it from source in CI or ship it inside a toolchain image, the build system changed under you.

Unchanged from 2.42.1

mold 3.0 accepts the same command-line options and supports the same target architectures as 2.42.1. It produces the same output, apart from the bug fixes in the notes. Ueyama reports linking speed on par with 2.42.1 and publishes no new benchmark numbers.

The team checked compatibility three ways. They ran the test suite on each supported target, compared linker output across real-world workloads and option combinations, and built all Gentoo packages. The notes report no regressions.

The rewrite targets the next step. Ueyama wants 3.x to close the remaining gaps with GNU ld, linker scripts above all, so Linux distributions can adopt mold as their default linker.

Corrupted input panics now

The C++ version could read past a buffer on a corrupted object file and die with a segmentation fault. mold 3.0 bounds-checks those reads and stops with a panic at the faulty access. You still get a failed link. You get it with a location, and without an out-of-bounds read in a tool that parses files from your dependency tree.

The build changed

Building mold from source, 2.42.1 versus 3.0
Item2.42.13.0
Build systemCMakeCargo, CMake options removed
ToolchainC++ compilerRust 1.95 or later, plus a C compiler
Target selectionMOLD_TARGETSCargo features
ThreadingoneTBBoneTBB dependency removed
Testsctestcargo test
Test dependenciesinstall-build-deps.shinstall-test-deps.sh

mold still links mimalloc 3.5.3 as a static library unless you build with --features system-allocator. It links the system zlib when one exists and bundles zstd and BLAKE3. Set ZSTD_SYS_USE_PKG_CONFIG=1 to link the system zstd.

A source build looks like this:

cargo build --release
./install-mold.sh   # honors PREFIX and DESTDIR

# if libraries don't live in $PREFIX/lib
MOLD_LIBDIR=/usr/lib64 cargo build --release
MOLD_LIBDIR=/usr/lib64 ./install-mold.sh

MOLD_LIBDIR matters for mold -run, which loads mold-wrapper.so. Set it at build time and at install time, or mold -run won't find the wrapper on distributions that use lib64.

Bug fixes worth a look

Several fixes change output, so check them against your builds:

  • --gc-sections no longer removes the functions you pass to --init and --fini.
  • Common symbols take the largest size and strictest alignment among their definitions.
  • mold parses single-dash options the way GNU ld does, so -entry=main no longer reads as -e ntry=main.
  • --strip-debug no longer crashes on DWARF type units, and several -r bugs are gone.

mold also stopped reserving 8 GiB of virtual address space at startup. If you run builds under ulimit -v, mold works there now. Static executables that use version scripts or --default-symver no longer crash the linker, and the notes list fixes for AArch64, RISC-V, LoongArch, PPC64 and other targets.

Some inputs that used to produce a broken binary or a crash now produce an error message. If an old build "worked" with a quiet bad output, 3.0 may fail it. Treat that as a find.

This week

  1. If you install mold from a distribution package or a release binary, upgrade and run your full test suite. The options didn't change, so your flags carry over.
  2. If you build mold from source, add Rust 1.95 to the builder image and replace CMake flags with Cargo features.
  3. Set MOLD_LIBDIR in packaging scripts that install to lib64, then run mold -run make once to confirm the wrapper loads.
  4. Grep your link lines for --gc-sections with --init or --fini, and single-dash long options. Compare the output binaries against 2.42.1.

If your CI image can't take a Rust toolchain this week, stay on 2.42.1. Ueyama has stopped C++ releases, so put the upgrade on next month's list instead of skipping it.

Volodymyr Chornous