about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2016-09-13 07:59:42 -0700
committerAlex Crichton <alex@alexcrichton.com>2016-09-13 08:11:20 -0700
commit265620225d2fa122c27bb6221bf5afe1797e9e6e (patch)
treeb7e5e8eff7f470ffcfda54b9e138148d1ec6232e
parent2140c4ba36301a71f43f4d488c45bc8ca27bf386 (diff)
downloadrust-265620225d2fa122c27bb6221bf5afe1797e9e6e.tar.gz
rust-265620225d2fa122c27bb6221bf5afe1797e9e6e.zip
rustc: Don't pass --whole-archive for compiler-builtins
This flag is intended for rlibs included once, not rlibs that are repeatedly
included.
-rw-r--r--src/libcompiler_builtins/build.rs10
-rw-r--r--src/librustc_trans/back/link.rs44
2 files changed, 35 insertions, 19 deletions
diff --git a/src/libcompiler_builtins/build.rs b/src/libcompiler_builtins/build.rs
index fb8e45c1fe1..09c400b52bc 100644
--- a/src/libcompiler_builtins/build.rs
+++ b/src/libcompiler_builtins/build.rs
@@ -50,10 +50,12 @@ impl Sources {
     }
 
     fn extend(&mut self, sources: &[&'static str]) {
-        // NOTE Some intrinsics have both a generic implementation (e.g. `floatdidf.c`) and an arch
-        // optimized implementation (`x86_64/floatdidf.c`). In those cases, we keep the arch
-        // optimized implementation and discard the generic implementation. If we don't and keep
-        // both implementations, the linker will yell at us about duplicate symbols!
+        // NOTE Some intrinsics have both a generic implementation (e.g.
+        // `floatdidf.c`) and an arch optimized implementation
+        // (`x86_64/floatdidf.c`). In those cases, we keep the arch optimized
+        // implementation and discard the generic implementation. If we don't
+        // and keep both implementations, the linker will yell at us about
+        // duplicate symbols!
         for &src in sources {
             let symbol = Path::new(src).file_stem().unwrap().to_str().unwrap();
             if src.contains("/") {
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index 3433b866691..288249a7d99 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -943,8 +943,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
             Linkage::NotLinked |
             Linkage::IncludedFromDylib => {}
             Linkage::Static => {
-                add_static_crate(cmd, sess, tmpdir, crate_type,
-                                 &src.rlib.unwrap().0, sess.cstore.is_no_builtins(cnum))
+                add_static_crate(cmd, sess, tmpdir, crate_type, cnum);
             }
             Linkage::Dynamic => {
                 add_dynamic_crate(cmd, sess, &src.dylib.unwrap().0)
@@ -956,9 +955,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
     // was already "included" in a dylib (e.g. `libstd` when `-C prefer-dynamic`
     // is used)
     if let Some(cnum) = compiler_builtins {
-        let src = sess.cstore.used_crate_source(cnum);
-        add_static_crate(cmd, sess, tmpdir, crate_type,
-                         &src.rlib.unwrap().0, sess.cstore.is_no_builtins(cnum));
+        add_static_crate(cmd, sess, tmpdir, crate_type, cnum);
     }
 
     // Converts a library file-stem into a cc -l argument
@@ -1006,8 +1003,9 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
                         sess: &Session,
                         tmpdir: &Path,
                         crate_type: config::CrateType,
-                        cratepath: &Path,
-                        is_a_no_builtins_crate: bool) {
+                        cnum: ast::CrateNum) {
+        let src = sess.cstore.used_crate_source(cnum);
+        let cratepath = &src.rlib.unwrap().0;
         if !sess.lto() && crate_type != config::CrateTypeDylib {
             cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath));
             return
@@ -1031,7 +1029,13 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
                 }
                 let canonical = f.replace("-", "_");
                 let canonical_name = name.replace("-", "_");
-                if sess.lto() && !is_a_no_builtins_crate &&
+
+                // If we're performing LTO and this is a rust-generated object
+                // file, then we don't need the object file as it's part of the
+                // LTO module. Note that `#![no_builtins]` is excluded from LTO,
+                // though, so we let that object file slide.
+                if sess.lto() &&
+                   !sess.cstore.is_no_builtins(cnum) &&
                    canonical.starts_with(&canonical_name) &&
                    canonical.ends_with(".o") {
                     let num = &f[name.len()..f.len() - 2];
@@ -1043,13 +1047,23 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
                 any_objects = true;
             }
 
-            if any_objects {
-                archive.build();
-                if crate_type == config::CrateTypeDylib {
-                    cmd.link_whole_rlib(&fix_windows_verbatim_for_gcc(&dst));
-                } else {
-                    cmd.link_rlib(&fix_windows_verbatim_for_gcc(&dst));
-                }
+            if !any_objects {
+                return
+            }
+            archive.build();
+
+            // If we're creating a dylib, then we need to include the
+            // whole of each object in our archive into that artifact. This is
+            // because a `dylib` can be reused as an intermediate artifact.
+            //
+            // Note, though, that we don't want to include the whole of a
+            // compiler-builtins crate (e.g. compiler-rt) because it'll get
+            // repeatedly linked anyway.
+            if crate_type == config::CrateTypeDylib &&
+               !sess.cstore.is_compiler_builtins(cnum) {
+                cmd.link_whole_rlib(&fix_windows_verbatim_for_gcc(&dst));
+            } else {
+                cmd.link_rlib(&fix_windows_verbatim_for_gcc(&dst));
             }
         });
     }