-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Add alternative linker to the build performance guide #15991
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,7 +38,7 @@ This will: | |
- Provide an opt-in for when debugging via [`--profile debugging`](../reference/profiles.md#custom-profiles) | ||
|
||
Trade-offs: | ||
- ✅ Faster build times | ||
- ✅ Faster code generation (`cargo build`) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. imo that is too jargony without the surrounding context. When I see code generation, I think of the type of thing build scripts usually do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should I create some basic terminology at the start of the page, where we'll say that compilation is split into three categories (frontend, backend, codegen), and then we'll say in each mechanism which of these categories it helps? |
||
- ✅ Faster link times | ||
- ✅ Smaller disk usage of the `target` directory | ||
- ❌ Requires a full rebuild to have a high-quality debugger experience | ||
|
@@ -83,9 +83,33 @@ rustflags = "-Zthreads=8" | |
This [`rustflags`][build.rustflags] will enable the [parallel frontend][parallel-frontend-blog] of the Rust compiler, and tell it to use `n` threads. The value of `n` should be chosen according to the number of cores available on your system, although there are diminishing returns. We recommend using at most `8` threads. | ||
|
||
Trade-offs: | ||
- ✅ Faster build times | ||
- ✅ Faster build times (both `cargo check` and `cargo build`) | ||
- ❌ **Requires using nightly Rust and an [unstable Rust feature][parallel-frontend-issue]** | ||
|
||
[parallel-frontend-blog]: https://blog.rust-lang.org/2023/11/09/parallel-rustc/ | ||
[parallel-frontend-issue]: https://github.com/rust-lang/rust/issues/113349 | ||
[build.rustflags]: ../reference/config.md#buildrustflags | ||
|
||
### Use an alternative linker | ||
epage marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Consider: installing and configuring an alternative linker, like [LLD](https://lld.llvm.org/), [mold](https://github.com/rui314/mold) or [wild](https://github.com/davidlattimore/wild). For example, to configure mold on Linux, you can add to your `.cargo/config.toml`: | ||
|
||
```toml | ||
[target.'cfg(target_os = "linux")'] | ||
# mold, if you have GCC 12+ | ||
rustflags = ["-C", "link-arg=-fuse-ld=mold"] | ||
|
||
# mold, otherwise | ||
linker = "clang" | ||
rustflags = ["-C", "link-arg=-fuse-ld=/path/to/mold"] | ||
``` | ||
|
||
While dependencies may be built in parallel, linking all of your dependencies happens at once at the end of your build, which can make linking dominate your build times, especially for incremental rebuilds. Often, the linker Rust uses is already fairly fast and the gains from switching may not be worth it, but it is not always the case. For example, Linux targets besides `x86_64-unknown-linux-gnu` still use the Linux system linker which is quite slow (see [rust#39915](https://github.com/rust-lang/rust/issues/39915) for more details). | ||
|
||
Trade-offs: | ||
- ✅ Faster link times | ||
- ❌ Might not support all use-cases, in particular if you depend on C or C++ dependencies | ||
|
||
## Reducing built code | ||
|
||
### Removing unused dependencies | ||
|
@@ -103,7 +127,3 @@ it can be easy to miss that a dependency is no longer used and can be removed. | |
Trade-offs: | ||
- ✅ Faster full build and link times | ||
- ❌ May incorrectly flag dependencies as unused or miss some | ||
|
||
[parallel-frontend-blog]: https://blog.rust-lang.org/2023/11/09/parallel-rustc/ | ||
[parallel-frontend-issue]: https://github.com/rust-lang/rust/issues/113349 | ||
[build.rustflags]: ../reference/config.md#buildrustflags |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This reminds maybe we should consider a cargo native lld option for
build.linker
: #11378.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That might be nice indeed, but the situation with linkers is a bit complicated. You can use the self-contained LLD, or an external LLD, on Linux you invoke LLD through
cc
and-fuse-ld=lld
, while elsewhere through-Clinker
, if the linker is notlld
, but something else unsupported by the CC driver, it cannot be specified by name, but has to be passed through some hacks with an absolute path.. it's quite messy.