2020-10-21 08:55:50 +03:00
|
|
|
# mold: A Modern Linker
|
2020-10-21 06:52:11 +03:00
|
|
|
|
2022-11-19 07:03:50 +03:00
|
|
|
<i>This is a repo of a free, AGPL-licensed version of the linker.
|
|
|
|
If you are looking for a commercial, non-AGPL version of the same linker,
|
|
|
|
please visit the
|
|
|
|
[repo of the sold linker](https://github.com/bluewhalesystems/sold).</i>
|
|
|
|
|
2021-12-12 15:19:12 +03:00
|
|
|
mold is a faster drop-in replacement for existing Unix linkers.
|
2022-02-13 00:53:17 +03:00
|
|
|
It is several times faster than the LLVM lld linker, the second-fastest
|
2021-12-12 15:19:12 +03:00
|
|
|
open-source linker which I originally created a few years ago.
|
2022-02-13 00:53:17 +03:00
|
|
|
mold is designed to increase developer productivity by reducing
|
|
|
|
build time, especially in rapid debug-edit-rebuild cycles.
|
2020-10-21 06:52:11 +03:00
|
|
|
|
2021-08-06 02:55:25 +03:00
|
|
|
Here is a performance comparison of GNU gold, LLVM lld, and mold for
|
2021-12-12 15:19:12 +03:00
|
|
|
linking final debuginfo-enabled executables of major large programs
|
|
|
|
on a simulated 8-core 16-threads machine.
|
2021-03-21 07:51:34 +03:00
|
|
|
|
2021-12-12 15:19:12 +03:00
|
|
|
![Link speed comparison](docs/comparison.png)
|
2021-03-21 07:51:34 +03:00
|
|
|
|
2021-12-13 09:28:26 +03:00
|
|
|
| Program (linker output size) | GNU gold | LLVM lld | mold
|
|
|
|
|-------------------------------|----------|----------|--------
|
|
|
|
| Chrome 96 (1.89 GiB) | 53.86s | 11.74s | 2.21s
|
|
|
|
| Clang 13 (3.18 GiB) | 64.12s | 5.82s | 2.90s
|
|
|
|
| Firefox 89 libxul (1.64 GiB) | 32.95s | 6.80s | 1.42s
|
|
|
|
|
2021-12-12 15:19:12 +03:00
|
|
|
mold is so fast that it is only 2x _slower_ than `cp` on the same
|
2022-01-10 18:12:12 +03:00
|
|
|
machine. Feel free to [file a bug](https://github.com/rui314/mold/issues)
|
|
|
|
if you find mold is not faster than other linkers.
|
2021-03-21 07:51:34 +03:00
|
|
|
|
2022-10-01 06:22:24 +03:00
|
|
|
mold supports x86-64, i386, ARM64, ARM32, 64-bit/32-bit little/big-endian
|
2022-10-13 10:15:49 +03:00
|
|
|
RISC-V, 64-bit big-endian PowerPC ELFv1, 64-bit little-endian PowerPC ELFv2,
|
2022-10-30 06:52:39 +03:00
|
|
|
s390x, SPARC64 and m68k.
|
2021-12-15 04:44:10 +03:00
|
|
|
|
2021-12-12 15:19:12 +03:00
|
|
|
## Why does the speed of linking matter?
|
|
|
|
|
|
|
|
If you are using a compiled language such as C, C++ or Rust, a build
|
2022-04-20 05:14:42 +03:00
|
|
|
consists of two phases. In the first phase, a compiler compiles
|
|
|
|
source files into object files (`.o` files). In the second phase,
|
2021-12-12 15:19:12 +03:00
|
|
|
a linker takes all object files to combine them into a single executable
|
|
|
|
or a shared library file.
|
2021-04-18 15:41:36 +03:00
|
|
|
|
2021-12-12 15:19:12 +03:00
|
|
|
The second phase takes a long time if your build output is large.
|
|
|
|
mold can make it faster, saving your time and keeping you from being
|
|
|
|
distracted while waiting for a long build to finish. The difference is
|
|
|
|
most noticeable when you are in rapid debug-edit-rebuild cycles.
|
2021-04-19 16:25:13 +03:00
|
|
|
|
2021-12-22 13:59:39 +03:00
|
|
|
## Install
|
|
|
|
|
2022-04-28 15:23:55 +03:00
|
|
|
Binary packages for the following systems are currently available.
|
2021-12-22 13:59:39 +03:00
|
|
|
|
|
|
|
[![Packaging status](https://repology.org/badge/vertical-allrepos/mold.svg)](https://repology.org/project/mold/versions)
|
|
|
|
|
2021-03-16 19:35:32 +03:00
|
|
|
## How to build
|
|
|
|
|
2021-12-22 13:59:39 +03:00
|
|
|
mold is written in C++20, so if you build mold yourself, you need a
|
2022-01-12 07:46:44 +03:00
|
|
|
recent version of a C++ compiler and a C++ standard library. GCC 10.2
|
2022-04-20 05:14:42 +03:00
|
|
|
or Clang 12.0.0 (or later) as well as libstdc++ 10 or libc++ 7 (or
|
|
|
|
later) are recommended.
|
2021-03-16 19:35:32 +03:00
|
|
|
|
2021-10-27 20:22:38 +03:00
|
|
|
### Install dependencies
|
|
|
|
|
2022-04-23 13:22:53 +03:00
|
|
|
To install build dependencies, run `./install-build-deps.sh` in this
|
|
|
|
directory. It recognizes your Linux distribution and tries to install
|
|
|
|
necessary packages. You may want to run it as root.
|
2021-10-27 20:22:38 +03:00
|
|
|
|
|
|
|
### Compile mold
|
|
|
|
|
|
|
|
```shell
|
|
|
|
git clone https://github.com/rui314/mold.git
|
2022-09-27 06:53:08 +03:00
|
|
|
mkdir mold/build
|
|
|
|
cd mold/build
|
2022-11-19 13:27:50 +03:00
|
|
|
git checkout v1.7.1
|
2022-09-27 06:53:08 +03:00
|
|
|
../install-build-deps.sh
|
|
|
|
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=c++ ..
|
|
|
|
cmake --build . -j $(nproc)
|
|
|
|
sudo cmake --install .
|
2021-03-16 19:35:32 +03:00
|
|
|
```
|
|
|
|
|
2022-09-27 06:53:08 +03:00
|
|
|
You may need to pass a C++20 compiler command name to `cmake`.
|
|
|
|
In the above case, `c++` is passed. If it doesn't work for you,
|
2022-01-07 12:42:40 +03:00
|
|
|
try a specific version of a compiler such as `g++-10` or `clang++-12`.
|
|
|
|
|
2022-10-13 10:07:36 +03:00
|
|
|
By default, `mold` is installed to `/usr/local/bin`. You can change
|
|
|
|
that by passing `-DCMAKE_INSTALL_PREFIX=<directory>`. For other cmake
|
|
|
|
options, see the comments in `CMakeLists.txt`.
|
2021-03-24 12:38:08 +03:00
|
|
|
|
2022-02-19 05:56:20 +03:00
|
|
|
If you don't use a recent enough Linux distribution, or if for any reason
|
2022-09-27 06:53:08 +03:00
|
|
|
`cmake` in the above commands doesn't work for you, you can use Docker to
|
2022-02-19 05:56:20 +03:00
|
|
|
build it in a Docker environment. To do so, just run `./dist.sh` in this
|
2022-09-27 06:53:08 +03:00
|
|
|
directory instead of `cmake`. The shell script pulls a Docker image,
|
|
|
|
builds mold and auxiliary files inside it, and packs them into a
|
|
|
|
single tar file `mold-$version-$arch-linux.tar.gz`. You can extract
|
|
|
|
the tar file anywhere and use `mold` executable in it.
|
2021-04-19 17:08:29 +03:00
|
|
|
|
2021-03-26 11:06:35 +03:00
|
|
|
## How to use
|
|
|
|
|
2021-12-27 06:14:30 +03:00
|
|
|
<details><summary>A classic way to use mold</summary>
|
|
|
|
|
2021-03-26 11:06:35 +03:00
|
|
|
On Unix, the linker command (which is usually `/usr/bin/ld`) is
|
2021-12-27 06:14:30 +03:00
|
|
|
invoked indirectly by the compiler driver (which is usually `cc`,
|
|
|
|
`gcc` or `clang`), which is typically in turn indirectly invoked by
|
|
|
|
`make` or some other build system command.
|
|
|
|
|
|
|
|
If you can specify an additional command line option to your compiler
|
|
|
|
driver by modifying build system's config files, add one of the
|
|
|
|
following flags to use `mold` instead of `/usr/bin/ld`:
|
2021-06-30 20:45:04 +03:00
|
|
|
|
2021-12-29 15:36:06 +03:00
|
|
|
- Clang: pass `-fuse-ld=mold`
|
2021-12-27 07:37:25 +03:00
|
|
|
|
2022-05-09 12:11:08 +03:00
|
|
|
- GCC 12.1.0 or later: pass `-fuse-ld=mold`
|
2021-12-27 07:37:25 +03:00
|
|
|
|
2021-12-29 15:21:06 +03:00
|
|
|
- GCC before 12.1.0: `-fuse-ld` does not accept `mold` as a valid
|
|
|
|
argument, so you need to use `-B` option instead. `-B` is an option
|
|
|
|
to tell GCC where to look for external commands such as `ld`.
|
2021-12-27 07:37:25 +03:00
|
|
|
|
|
|
|
If you have installed mold with `make install`, there should be a
|
|
|
|
directory named `/usr/libexec/mold` (or `/usr/local/libexec/mold`,
|
2022-04-20 05:14:42 +03:00
|
|
|
depending on your `$PREFIX`), and `ld` command should be there. The
|
2021-12-27 07:37:25 +03:00
|
|
|
`ld` is actually a symlink to `mold`. So, all you need is to pass
|
|
|
|
`-B/usr/libexec/mold` (or `-B/usr/local/libexec/mold`) to GCC.
|
2021-12-27 06:14:30 +03:00
|
|
|
|
2021-12-29 15:36:06 +03:00
|
|
|
If you haven't installed `mold` to any `$PATH`, you can still pass
|
|
|
|
`-fuse-ld=/absolute/path/to/mold` to clang to use mold. GCC does not
|
|
|
|
take an absolute path as an argument for `-fuse-ld` though.
|
|
|
|
|
2021-12-27 06:14:30 +03:00
|
|
|
</details>
|
|
|
|
|
|
|
|
<details><summary>If you are using Rust</summary>
|
|
|
|
|
|
|
|
Create `.cargo/config.toml` in your project directory with the following:
|
|
|
|
|
2022-08-18 20:45:55 +03:00
|
|
|
```toml
|
2021-12-27 06:14:30 +03:00
|
|
|
[target.x86_64-unknown-linux-gnu]
|
|
|
|
linker = "clang"
|
|
|
|
rustflags = ["-C", "link-arg=-fuse-ld=/path/to/mold"]
|
|
|
|
```
|
|
|
|
|
2022-10-09 06:32:55 +03:00
|
|
|
where `/path/to/mold` is an absolute path to `mold` exectuable. In the
|
|
|
|
above example, we use `clang` as a linker driver as it can always take
|
|
|
|
the `-fuse-ldd` option. If your GCC is recent enough to recognize the
|
|
|
|
option, you may be able to remove the `linker = "clang"` line.
|
2022-10-08 20:40:30 +03:00
|
|
|
|
|
|
|
```toml
|
|
|
|
[target.x86_64-unknown-linux-gnu]
|
2022-10-09 06:32:55 +03:00
|
|
|
rustflags = ["-C", "link-arg=-fuse-ld=/path/to/mold"]
|
2022-10-08 20:40:30 +03:00
|
|
|
```
|
|
|
|
|
2022-10-09 06:32:55 +03:00
|
|
|
If you want to use mold for all projects, put the above snippet to
|
|
|
|
`~/.cargo/config.toml`.
|
|
|
|
|
2022-08-20 04:39:07 +03:00
|
|
|
If you are using macOS, you can modify `config.toml` in a similar manner.
|
|
|
|
Here is an example with `mold` installed via [Homebrew](https://brew.sh).
|
|
|
|
|
|
|
|
```toml
|
|
|
|
[target.x86_64-apple-darwin]
|
|
|
|
linker = "clang"
|
|
|
|
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
|
|
|
|
|
|
|
|
[target.aarch64-apple-darwin]
|
|
|
|
linker = "clang"
|
|
|
|
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
|
|
|
|
```
|
2022-08-18 20:45:55 +03:00
|
|
|
|
2021-12-27 06:14:30 +03:00
|
|
|
</details>
|
|
|
|
|
|
|
|
<details><summary>mold -run</summary>
|
2021-03-26 11:06:35 +03:00
|
|
|
|
2021-09-23 08:31:08 +03:00
|
|
|
It is sometimes very hard to pass an appropriate command line option
|
|
|
|
to `cc` to specify an alternative linker. To deal with the situation,
|
|
|
|
mold has a feature to intercept all invocations of `ld`, `ld.lld` or
|
|
|
|
`ld.gold` and redirect it to itself. To use the feature, run `make`
|
|
|
|
(or another build command) as a subcommand of mold as follows:
|
2021-03-24 12:38:08 +03:00
|
|
|
|
2021-10-27 20:22:38 +03:00
|
|
|
```shell
|
2021-12-13 09:28:26 +03:00
|
|
|
mold -run make <make-options-if-any>
|
2021-03-24 12:38:08 +03:00
|
|
|
```
|
|
|
|
|
2021-03-26 11:06:35 +03:00
|
|
|
Internally, mold invokes a given command with `LD_PRELOAD` environment
|
|
|
|
variable set to its companion shared object file. The shared object
|
2021-09-23 08:31:08 +03:00
|
|
|
file intercepts all function calls to `exec(3)`-family functions to
|
|
|
|
replace `argv[0]` with `mold` if it is `ld`, `ld.gold` or `ld.lld`.
|
2021-03-26 11:06:35 +03:00
|
|
|
|
2021-12-27 06:14:30 +03:00
|
|
|
</details>
|
|
|
|
|
2022-08-17 12:40:16 +03:00
|
|
|
<details><summary>On macOS</summary>
|
|
|
|
|
|
|
|
mold/macOS is available as an alpha version. It can be used to build not
|
|
|
|
only macOS apps but also iOS apps because their binary formats are the same.
|
|
|
|
|
|
|
|
The command name of mold/macOS is `ld64.mold`. If you build mold on macOS,
|
|
|
|
it still produces `mold` and `ld.mold`, but these executables are useful
|
|
|
|
only for cross compilation (i.e. building Linux apps on macOS.)
|
|
|
|
|
|
|
|
If you find any issue with mold/macOS, please file it to
|
|
|
|
<a href=https://github.com/rui314/mold/issues>our GitHub Issues</a>.
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
2022-06-03 14:38:05 +03:00
|
|
|
<details><summary>GitHub Actions</summary>
|
|
|
|
|
|
|
|
You can use our <a href=https://github.com/rui314/setup-mold>setup-mold</a>
|
|
|
|
GitHub Action to speed up GitHub-hosted continuous build. GitHub Actions
|
|
|
|
runs on a two-core machine, but mold is still significantly faster than
|
|
|
|
the default GNU linker there especially when a program being linked is
|
|
|
|
large.
|
|
|
|
|
2022-04-10 04:03:06 +03:00
|
|
|
</details>
|
|
|
|
|
2022-02-13 09:16:05 +03:00
|
|
|
<details><summary>Verify that you are using mold</summary>
|
|
|
|
|
2021-03-24 12:38:08 +03:00
|
|
|
mold leaves its identification string in `.comment` section in an output
|
|
|
|
file. You can print it out to verify that you are actually using mold.
|
|
|
|
|
2021-10-27 20:22:38 +03:00
|
|
|
```shell
|
2022-04-20 05:00:48 +03:00
|
|
|
$ readelf -p .comment <executable-file>
|
2021-03-24 12:38:08 +03:00
|
|
|
|
|
|
|
String dump of section '.comment':
|
|
|
|
[ 0] GCC: (Ubuntu 10.2.0-5ubuntu1~20.04) 10.2.0
|
|
|
|
[ 2b] mold 9a1679b47d9b22012ec7dfbda97c8983956716f7
|
|
|
|
```
|
|
|
|
|
|
|
|
If `mold` is in `.comment`, the file is created by mold.
|
|
|
|
|
2022-02-13 09:16:05 +03:00
|
|
|
</details>
|
|
|
|
|
2022-08-14 10:06:15 +03:00
|
|
|
<details><summary>Online manual</summary>
|
|
|
|
|
|
|
|
Since mold is a drop-in replacement, you should be able to use it
|
|
|
|
without reading its manual. But just in case you need it, it's available
|
|
|
|
online at <a href=https://rui314.github.io/mold.html>here</a>.
|
|
|
|
You can also read the same manual by `man mold`.
|
|
|
|
|
|
|
|
</details>
|
|
|
|
|
2021-12-12 15:19:12 +03:00
|
|
|
## Why is mold so fast?
|
|
|
|
|
2021-12-13 09:28:26 +03:00
|
|
|
One reason is because it simply uses faster algorithms and efficient
|
|
|
|
data structures than other linkers do. The other reason is that the
|
|
|
|
new linker is highly parallelized.
|
2021-12-12 15:19:12 +03:00
|
|
|
|
|
|
|
Here is a side-by-side comparison of per-core CPU usage of lld (left)
|
|
|
|
and mold (right). They are linking the same program, Chromium
|
|
|
|
executable.
|
|
|
|
|
|
|
|
![CPU usage comparison in htop animation](docs/htop.gif)
|
|
|
|
|
|
|
|
As you can see, mold uses all available cores throughout its execution
|
|
|
|
and finishes quickly. On the other hand, lld failed to use available
|
|
|
|
cores most of the time. In this demo, the maximum parallelism is
|
|
|
|
artificially capped to 16 so that the bars fit in the GIF.
|
|
|
|
|
2021-12-13 09:28:26 +03:00
|
|
|
For details, please read [design notes](docs/design.md).
|
2022-05-05 16:37:42 +03:00
|
|
|
|
|
|
|
## License
|
|
|
|
|
|
|
|
mold is available under AGPL. Note that that does not mean that you
|
2022-05-14 09:47:38 +03:00
|
|
|
have to license your program under AGPL if you use mold to link your
|
2022-05-05 16:37:42 +03:00
|
|
|
program. An output of the mold linker is a derived work of the object
|
|
|
|
files and libraries you pass to the linker but not a derived work of
|
|
|
|
the mold linker itself.
|
|
|
|
|
2022-05-14 09:47:38 +03:00
|
|
|
Besides that, you can also buy a commercial, non-AGPL license with
|
|
|
|
technical support from our company, Blue Whale Systems PTE LTD. If you
|
|
|
|
are a big company, please consider obtaining it before making hundreds
|
|
|
|
or thousands of developers of your company to depend on mold. mold is
|
|
|
|
mostly a single-person open-source project, and just like other
|
|
|
|
open-source projects, we are not legally obligated to keep maintaining
|
|
|
|
it. A legally-binding commercial license contract addresses the
|
|
|
|
concern. By purchasing a license, you are guaranteed that mold will be
|
|
|
|
maintained for you. Please [contact us](mailto:contact@bluewhale.systems)
|
|
|
|
for a commercial license inquiry.
|
2022-08-04 10:22:01 +03:00
|
|
|
|
2022-11-19 06:31:58 +03:00
|
|
|
## Sponsors
|
2022-08-04 10:22:01 +03:00
|
|
|
|
|
|
|
We accept donations via [GitHub Sponsors](https://github.com/sponsors/rui314)
|
|
|
|
and [OpenCollective](https://opencollective.com/mold-linker).
|
|
|
|
We thank you to everybody who sponsors our project. In particular,
|
|
|
|
we'd like to acknowledge the following people and organizations who
|
|
|
|
have sponsored $128/month or more:
|
|
|
|
|
2022-11-19 06:31:58 +03:00
|
|
|
### Corporate sponsors
|
|
|
|
|
|
|
|
<a href="https://mercury.com/"><img src="docs/mercury-logo.png" align=center height=120 width=400 alt=Mercury></a>
|
|
|
|
|
2022-11-19 07:27:49 +03:00
|
|
|
- [Uber](https://uber.com)
|
2022-11-19 06:31:58 +03:00
|
|
|
- [Signal Slot Inc.](https://github.com/signal-slot)
|
|
|
|
|
|
|
|
### Individual sponsors
|
|
|
|
|
2022-08-04 10:22:01 +03:00
|
|
|
- [300baud](https://github.com/300baud)
|
2022-11-19 06:31:58 +03:00
|
|
|
- [Johan Andersson](https://github.com/repi)
|
2022-08-04 10:22:01 +03:00
|
|
|
- [Wei Wu](https://github.com/lazyparser)
|
2022-11-19 06:31:58 +03:00
|
|
|
- [kyle-elliott](https://github.com/kyle-elliott)
|