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)); } }); }