Skip to content

Commit 2656202

Browse files
committed
rustc: Don't pass --whole-archive for compiler-builtins
This flag is intended for rlibs included once, not rlibs that are repeatedly included.
1 parent 2140c4b commit 2656202

File tree

2 files changed

+35
-19
lines changed

2 files changed

+35
-19
lines changed

src/libcompiler_builtins/build.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,12 @@ impl Sources {
5050
}
5151

5252
fn extend(&mut self, sources: &[&'static str]) {
53-
// NOTE Some intrinsics have both a generic implementation (e.g. `floatdidf.c`) and an arch
54-
// optimized implementation (`x86_64/floatdidf.c`). In those cases, we keep the arch
55-
// optimized implementation and discard the generic implementation. If we don't and keep
56-
// both implementations, the linker will yell at us about duplicate symbols!
53+
// NOTE Some intrinsics have both a generic implementation (e.g.
54+
// `floatdidf.c`) and an arch optimized implementation
55+
// (`x86_64/floatdidf.c`). In those cases, we keep the arch optimized
56+
// implementation and discard the generic implementation. If we don't
57+
// and keep both implementations, the linker will yell at us about
58+
// duplicate symbols!
5759
for &src in sources {
5860
let symbol = Path::new(src).file_stem().unwrap().to_str().unwrap();
5961
if src.contains("/") {

src/librustc_trans/back/link.rs

+29-15
Original file line numberDiff line numberDiff line change
@@ -943,8 +943,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
943943
Linkage::NotLinked |
944944
Linkage::IncludedFromDylib => {}
945945
Linkage::Static => {
946-
add_static_crate(cmd, sess, tmpdir, crate_type,
947-
&src.rlib.unwrap().0, sess.cstore.is_no_builtins(cnum))
946+
add_static_crate(cmd, sess, tmpdir, crate_type, cnum);
948947
}
949948
Linkage::Dynamic => {
950949
add_dynamic_crate(cmd, sess, &src.dylib.unwrap().0)
@@ -956,9 +955,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
956955
// was already "included" in a dylib (e.g. `libstd` when `-C prefer-dynamic`
957956
// is used)
958957
if let Some(cnum) = compiler_builtins {
959-
let src = sess.cstore.used_crate_source(cnum);
960-
add_static_crate(cmd, sess, tmpdir, crate_type,
961-
&src.rlib.unwrap().0, sess.cstore.is_no_builtins(cnum));
958+
add_static_crate(cmd, sess, tmpdir, crate_type, cnum);
962959
}
963960

964961
// Converts a library file-stem into a cc -l argument
@@ -1006,8 +1003,9 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
10061003
sess: &Session,
10071004
tmpdir: &Path,
10081005
crate_type: config::CrateType,
1009-
cratepath: &Path,
1010-
is_a_no_builtins_crate: bool) {
1006+
cnum: ast::CrateNum) {
1007+
let src = sess.cstore.used_crate_source(cnum);
1008+
let cratepath = &src.rlib.unwrap().0;
10111009
if !sess.lto() && crate_type != config::CrateTypeDylib {
10121010
cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath));
10131011
return
@@ -1031,7 +1029,13 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
10311029
}
10321030
let canonical = f.replace("-", "_");
10331031
let canonical_name = name.replace("-", "_");
1034-
if sess.lto() && !is_a_no_builtins_crate &&
1032+
1033+
// If we're performing LTO and this is a rust-generated object
1034+
// file, then we don't need the object file as it's part of the
1035+
// LTO module. Note that `#![no_builtins]` is excluded from LTO,
1036+
// though, so we let that object file slide.
1037+
if sess.lto() &&
1038+
!sess.cstore.is_no_builtins(cnum) &&
10351039
canonical.starts_with(&canonical_name) &&
10361040
canonical.ends_with(".o") {
10371041
let num = &f[name.len()..f.len() - 2];
@@ -1043,13 +1047,23 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
10431047
any_objects = true;
10441048
}
10451049

1046-
if any_objects {
1047-
archive.build();
1048-
if crate_type == config::CrateTypeDylib {
1049-
cmd.link_whole_rlib(&fix_windows_verbatim_for_gcc(&dst));
1050-
} else {
1051-
cmd.link_rlib(&fix_windows_verbatim_for_gcc(&dst));
1052-
}
1050+
if !any_objects {
1051+
return
1052+
}
1053+
archive.build();
1054+
1055+
// If we're creating a dylib, then we need to include the
1056+
// whole of each object in our archive into that artifact. This is
1057+
// because a `dylib` can be reused as an intermediate artifact.
1058+
//
1059+
// Note, though, that we don't want to include the whole of a
1060+
// compiler-builtins crate (e.g. compiler-rt) because it'll get
1061+
// repeatedly linked anyway.
1062+
if crate_type == config::CrateTypeDylib &&
1063+
!sess.cstore.is_compiler_builtins(cnum) {
1064+
cmd.link_whole_rlib(&fix_windows_verbatim_for_gcc(&dst));
1065+
} else {
1066+
cmd.link_rlib(&fix_windows_verbatim_for_gcc(&dst));
10531067
}
10541068
});
10551069
}

0 commit comments

Comments
 (0)