⚡️
GSoC Final Report: Improving the Fast Linker for Faster Rust Builds
#rust
#gsoc
2025-09-09
Nobody enjoys waiting endlessly for their code to compile. At the same time, correctness is non-negotiable when it comes to compilers and linkers.
Wild is a new Linux linker project that aims to be faster than even mold, currently considered the fastest ELF linker around (see benchmarks). On top of that, Wild has a unique long-term goal: incremental linking. Neither ld
, lld
, nor even mold
support this, but incremental linking could be a game-changer for Rust—where compile times are an ongoing pain point.
During GSoC 2025, I worked on Wild with the goal of improving its correctness and expanding its feature set under the Rust Foundation.
My work can be divided into two broad categories:
- Core work – leveraging existing linker test suites to improve Wild’s reliability
- Extended work – adding missing features, fixing bugs, and making Wild a more practical replacement for existing linkers
In this article, I will explain the specific work I conducted on each of the following topics.
The core work of the project is borrowing test suites from other linkers to improve Wild’s reliability.
Correctness is particularly hard to guarantee for linkers. They expose a huge number of options, many of which interact in subtle ways. Since the ultimate output is an ELF executable, even a small mishandling can produce invalid binaries. While Wild already had integration tests, it was unclear how much coverage they actually gave us.
Luckily, one characteristic of ELF linkers works in our favor: most of the major Unix linkers share a common set of options with the same names and semantics. With this in mind, I set out to make it easy to run other linker test suites against Wild, starting with mold’s.
The main steps were:
- Extending Wild’s test framework so it could execute mold’s test suite
- Automatically skipping tests irrelevant to Wild’s supported architectures
- Categorizing failing tests and configuring CI to detect regressions without being noisy
- Gradually fixing Wild until those skipped tests could pass
Some of the key PRs I worked on include:
- Allow running the mold test suite #903
- Filter mold tests by architecture #936
- Allow skipping of mold tests #980
- Run external tests in CI #1005
At the time of writing, the list of skipped tests lives in mold_skip_tests.toml
. Some are skipped for legitimate reasons (and won’t need fixing), but the goal is to eventually eliminate as many as possible. A significant portion of my remaining time in GSoC went into tackling these failing tests directly.
While Wild's CI currently performs regression testing against the mold test suite, you can execute it in your own environment by checking out the mold submodule and running cargo test --features mold_tests
. Additionally, by setting the environment variable WILD_IGNORE_SKIP=mold
, you can run tests that would normally be skipped according to mold_skip_tests.toml
.
Even though Wild is already usable, it still lacked several important options—and like any young project, it had its share of bugs. With the borrowed test suite in place, it became much easier to spot and address these gaps.
Over the summer, I implemented or fixed several features to bring Wild closer to a drop-in replacement for existing ELF linkers. Some of the highlights include:
- Support
-Bsymbolic-functions
#770 - Support
-Bsymbolic
,-Bsymbolic-non-weak
,-Bsymbolic-non-weak-functions
and-Bno-symbolic
#782 - add alias for
-shared
to-Bshareable
#805 - Add flag to write symbols for PLT / GOT entries #827
- Add alternative syntax for some options #946
- Add
--unresolved-symbols=
and--{warn, error}-unresolved-symbols
options support #993 - Implement
--allow-multiple-definition
and-z muldefs
#1015 - Prevent link failure when there are multiple alias definitions pointing to the same symbol #1021
- version scripts: Allow parsing of extern blocks without a trailing ";" after the last symbol #1022
- Add
-z interpose
#1048 - Support escaping in version scripts #1053
One particularly interesting task was redesigning Wild’s argument parser (PR #1029). The Wild argument parser was implemented using simple if-else logic, with options not being managed uniformly and lacking a --help
option.
Linker command-line arguments come in many irregular forms, and existing parser libraries introduced unwanted complexity and overhead. I built a domain-specific declarative parser instead, striking a balance between flexibility, performance, and ease of defining new options.
In total, I had 48
PRs merged during GSoC 2025 (full list here), ranging from bug fixes and feature additions to infrastructure improvements.
Wild is making steady progress toward becoming not just the fastest ELF linker, but also one of the most practical, feature-complete alternatives available. The foundation laid this summer—borrowing test suites, expanding option coverage, and strengthening CI—should make it easier for contributors to continue improving Wild.
For me, working on Wild through GSoC wasn’t just about writing linker code; it was about building confidence in correctness without sacrificing speed. I’m excited to see how far Wild can go in reshaping the Linux linking ecosystem. Furthermore, I'm eager to continue contributing to the project even after the GSoC period ends.
My remaining tasks include making modifications to pass tests for mold failures and adding support for other architectures.
I'd like to express my gratitude to my mentor, @davidlattimore and the people who actively reviewed my code and gave me feedback, @marxin and @mati865. I'm very grateful because I've really learned a lot through this project.