Skip to content

Commit 4a82427

Browse files
committed
trans: Use LLVM's writeArchive to modify archives
We have previously always relied upon an external tool, `ar`, to modify archives that the compiler produces (staticlibs, rlibs, etc). This approach, however, has a number of downsides: * Spawning a process is relatively expensive for small compilations * Encoding arguments across process boundaries often incurs unnecessary overhead or lossiness. For example `ar` has a tough time dealing with files that have the same name in archives, and the compiler copies many files around to ensure they can be passed to `ar` in a reasonable fashion. * Most `ar` programs found do **not** have the ability to target arbitrary platforms, so this is an extra tool which needs to be found/specified when cross compiling. The LLVM project has had a tool called `llvm-ar` for quite some time now, but it wasn't available in the standard LLVM libraries (it was just a standalone program). Recently, however, in LLVM 3.7, this functionality has been moved to a library and is now accessible by consumers of LLVM via the `writeArchive` function. This commit migrates our archive bindings to no longer invoke `ar` by default but instead make a library call to LLVM to do various operations. This solves all of the downsides listed above: * Archive management is now much faster, for example creating a "hello world" staticlib is now 6x faster (50ms => 8ms). Linking dynamic libraries also recently started requiring modification of rlibs, and linking a hello world dynamic library is now 2x faster. * The compiler is now one step closer to "hassle free" cross compilation because no external tool is needed for managing archives, LLVM does the right thing! This commit does not remove support for calling a system `ar` utility currently. We will continue to maintain compatibility with LLVM 3.5 and 3.6 looking forward (so the system LLVM can be used wherever possible), and in these cases we must shell out to a system utility. All nightly builds of Rust, however, will stop needing a system `ar`.
1 parent 66b9277 commit 4a82427

File tree

16 files changed

+788
-551
lines changed

16 files changed

+788
-551
lines changed

mk/rustllvm.mk

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ LLVM_EXTRA_INCDIRS_$(1)= $$(call CFG_CC_INCLUDE_$(1),$(S)src/llvm/include) \
2424
endif
2525

2626
RUSTLLVM_OBJS_CS_$(1) := $$(addprefix rustllvm/, \
27-
ExecutionEngineWrapper.cpp RustWrapper.cpp PassWrapper.cpp)
27+
ExecutionEngineWrapper.cpp RustWrapper.cpp PassWrapper.cpp \
28+
ArchiveWrapper.cpp)
2829

2930
RUSTLLVM_INCS_$(1) = $$(LLVM_EXTRA_INCDIRS_$(1)) \
3031
$$(call CFG_CC_INCLUDE_$(1),$$(LLVM_INCDIR_$(1))) \

src/librustc/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ pub mod diagnostics;
9999

100100
pub mod back {
101101
pub use rustc_back::abi;
102-
pub use rustc_back::archive;
103102
pub use rustc_back::arm;
104103
pub use rustc_back::mips;
105104
pub use rustc_back::mipsel;

src/librustc/metadata/loader.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,6 @@
212212
//! no means all of the necessary details. Take a look at the rest of
213213
//! metadata::loader or metadata::creader for all the juicy details!
214214
215-
use back::archive::METADATA_FILENAME;
216215
use back::svh::Svh;
217216
use session::Session;
218217
use session::search_paths::PathKind;
@@ -280,6 +279,8 @@ pub struct CratePaths {
280279
pub rlib: Option<PathBuf>
281280
}
282281

282+
pub const METADATA_FILENAME: &'static str = "rust.metadata.bin";
283+
283284
impl CratePaths {
284285
fn paths(&self) -> Vec<PathBuf> {
285286
match (&self.dylib, &self.rlib) {

src/librustc_back/archive.rs

-361
This file was deleted.

0 commit comments

Comments
 (0)