-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
speed up static linking by combining ar
invocations
#15670
Conversation
@@ -1064,11 +1067,12 @@ fn link_rlib<'a>(sess: &'a Session, | |||
abi::OsMacos | abi::OsiOS => {} | |||
_ => { a.update_symbols(); } | |||
} |
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 may not be necessary now that the entire archive is built in one step, could you try omitting the call to update_symbols
entirely?
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.
To eliminate the extra ar
invocation here, I've moved update_symbols
into ArchiveBuilder
, where it simply sets a flag to indicate that the s
(update symbols) option should be used when build
runs ar
. (Originally I had build
pass s
always, but after reading the comment above this line and #11162, it sounds like that will crash ar
on OSX.)
Those are some nice speedups, nice catch! |
needs a rebase |
I've rebased this, which required a bit of refactoring - there was a conflict with #15511, which refactored |
Well that's a surprising error! I suppose we could batch the commands on windows instead of doing it all in one go. If you feel like going whole-hog on this issue, I know that LLVM has an |
I've modified I looked at |
Sounds like a good plan. |
I've fixed the error on OSX by changing how the rlib symbol index is updated on that platform. Previously, On non-OSX platforms, |
When rustc produces an rlib, it includes the contents of each static library required by the crate. Currently each static library is added individually, by extracting the library with `ar x` and adding the objects to the rlib using `ar r`. Each `ar r` has significant overhead - it appears to scan through the full contents of the rlib before adding the new files. This patch avoids most of the overhead by adding all library objects (and other rlib components) at once using a single `ar r`. When building `librustc` (on Linux, using GNU ar), this patch gives a 60-80% reduction in linking time, from 90s to 10s one machine I tried and 25s to 8s on another. (Though `librustc` is a bit of a special case - it's a very large crate, so the rlib is large to begin with, and it also relies on a total of 45 static libraries due to the way LLVM is organized.) More reasonable crates such as `libstd` and `libcore` also get a small reduction in linking time (just from adding metadata, bitcode, and object code in one `ar` invocation instead of three), but this is not very noticeable since the time there is small to begin with (around 1s).
When rustc produces an rlib, it includes the contents of each static library required by the crate. Currently each static library is added individually, by extracting the library with
ar x
and adding the objects to the rlib usingar r
. Eachar r
has significant overhead - it appears to scan through the full contents of the rlib before adding the new files. This patch avoids most of the overhead by adding all library objects (and other rlib components) at once using a singlear r
.When building
librustc
(on Linux, using GNU ar), this patch gives a 60-80% reduction in linking time, from 90s to 10s one machine I tried and 25s to 8s on another. (Thoughlibrustc
is a bit of a special case - it's a very large crate, so the rlib is large to begin with, and it also relies on a total of 45 static libraries due to the way LLVM is organized.) More reasonable crates such aslibstd
andlibcore
also get a small reduction in linking time (just from adding metadata, bitcode, and object code in onear
invocation instead of three), but this is not very noticeable since the time there is small to begin with (around 1s).