Skip to content

Commit 73317f8

Browse files
committed
linker: Stop using whole-archive on dependencies of dylibs
#95604 implemented a better and more fine-grained way of keeping exported symbols alive.
1 parent 082e4ca commit 73317f8

File tree

3 files changed

+8
-44
lines changed

3 files changed

+8
-44
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+6-31
Original file line numberDiff line numberDiff line change
@@ -1920,7 +1920,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
19201920
// This change is somewhat breaking in practice due to local static libraries being linked
19211921
// as whole-archive (#85144), so removing whole-archive may be a pre-requisite.
19221922
if sess.opts.debugging_opts.link_native_libraries {
1923-
add_local_native_libraries(cmd, sess, codegen_results, crate_type);
1923+
add_local_native_libraries(cmd, sess, codegen_results);
19241924
}
19251925

19261926
// Upstream rust libraries and their nobundle static libraries
@@ -2092,16 +2092,6 @@ fn add_order_independent_options(
20922092
add_rpath_args(cmd, sess, codegen_results, out_filename);
20932093
}
20942094

2095-
// A dylib may reexport symbols from the linked rlib or native static library.
2096-
// Even if some symbol is reexported it's still not necessarily counted as used and may be
2097-
// dropped, at least with `ld`-like ELF linkers. So we have to link some rlibs and static
2098-
// libraries as whole-archive to avoid losing reexported symbols.
2099-
// FIXME: Find a way to mark reexported symbols as used and avoid this use of whole-archive.
2100-
fn default_to_whole_archive(sess: &Session, crate_type: CrateType, cmd: &dyn Linker) -> bool {
2101-
crate_type == CrateType::Dylib
2102-
&& !(sess.target.limit_rdylib_exports && cmd.exported_symbol_means_used_symbol())
2103-
}
2104-
21052095
/// # Native library linking
21062096
///
21072097
/// User-supplied library search paths (-L on the command line). These are the same paths used to
@@ -2115,7 +2105,6 @@ fn add_local_native_libraries(
21152105
cmd: &mut dyn Linker,
21162106
sess: &Session,
21172107
codegen_results: &CodegenResults,
2118-
crate_type: CrateType,
21192108
) {
21202109
let filesearch = sess.target_filesearch(PathKind::All);
21212110
for search_path in filesearch.search_paths() {
@@ -2157,7 +2146,6 @@ fn add_local_native_libraries(
21572146
}
21582147
NativeLibKind::Static { whole_archive, bundle, .. } => {
21592148
if whole_archive == Some(true)
2160-
|| (whole_archive == None && default_to_whole_archive(sess, crate_type, cmd))
21612149
// Backward compatibility case: this can be a rlib (so `+whole-archive` cannot
21622150
// be added explicitly if necessary, see the error in `fn link_rlib`) compiled
21632151
// as an executable due to `--test`. Use whole-archive implicitly, like before
@@ -2276,7 +2264,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
22762264
let src = &codegen_results.crate_info.used_crate_source[&cnum];
22772265
match data[cnum.as_usize() - 1] {
22782266
_ if codegen_results.crate_info.profiler_runtime == Some(cnum) => {
2279-
add_static_crate::<B>(cmd, sess, codegen_results, tmpdir, crate_type, cnum);
2267+
add_static_crate::<B>(cmd, sess, codegen_results, tmpdir, cnum);
22802268
}
22812269
// compiler-builtins are always placed last to ensure that they're
22822270
// linked correctly.
@@ -2286,7 +2274,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
22862274
}
22872275
Linkage::NotLinked | Linkage::IncludedFromDylib => {}
22882276
Linkage::Static => {
2289-
add_static_crate::<B>(cmd, sess, codegen_results, tmpdir, crate_type, cnum);
2277+
add_static_crate::<B>(cmd, sess, codegen_results, tmpdir, cnum);
22902278

22912279
// Link static native libs with "-bundle" modifier only if the crate they originate from
22922280
// is being linked statically to the current crate. If it's linked dynamically
@@ -2317,10 +2305,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
23172305
lib.kind
23182306
{
23192307
let verbatim = lib.verbatim.unwrap_or(false);
2320-
if whole_archive == Some(true)
2321-
|| (whole_archive == None
2322-
&& default_to_whole_archive(sess, crate_type, cmd))
2323-
{
2308+
if whole_archive == Some(true) {
23242309
cmd.link_whole_staticlib(
23252310
name,
23262311
verbatim,
@@ -2347,7 +2332,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
23472332
// was already "included" in a dylib (e.g., `libstd` when `-C prefer-dynamic`
23482333
// is used)
23492334
if let Some(cnum) = compiler_builtins {
2350-
add_static_crate::<B>(cmd, sess, codegen_results, tmpdir, crate_type, cnum);
2335+
add_static_crate::<B>(cmd, sess, codegen_results, tmpdir, cnum);
23512336
}
23522337

23532338
// Converts a library file-stem into a cc -l argument
@@ -2378,23 +2363,13 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
23782363
sess: &'a Session,
23792364
codegen_results: &CodegenResults,
23802365
tmpdir: &Path,
2381-
crate_type: CrateType,
23822366
cnum: CrateNum,
23832367
) {
23842368
let src = &codegen_results.crate_info.used_crate_source[&cnum];
23852369
let cratepath = &src.rlib.as_ref().unwrap().0;
23862370

23872371
let mut link_upstream = |path: &Path| {
2388-
// We don't want to include the whole compiler-builtins crate (e.g., compiler-rt)
2389-
// regardless of the default because it'll get repeatedly linked anyway.
2390-
let path = fix_windows_verbatim_for_gcc(path);
2391-
if default_to_whole_archive(sess, crate_type, cmd)
2392-
&& codegen_results.crate_info.compiler_builtins != Some(cnum)
2393-
{
2394-
cmd.link_whole_rlib(&path);
2395-
} else {
2396-
cmd.link_rlib(&path);
2397-
}
2372+
cmd.link_rlib(&fix_windows_verbatim_for_gcc(path));
23982373
};
23992374

24002375
// See the comment above in `link_staticlib` and `link_rlib` for why if

compiler/rustc_codegen_ssa/src/back/linker.rs

-11
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,6 @@ pub trait Linker {
187187
fn no_crt_objects(&mut self);
188188
fn no_default_libraries(&mut self);
189189
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]);
190-
fn exported_symbol_means_used_symbol(&self) -> bool {
191-
true
192-
}
193190
fn subsystem(&mut self, subsystem: &str);
194191
fn group_start(&mut self);
195192
fn group_end(&mut self);
@@ -728,10 +725,6 @@ impl<'a> Linker for GccLinker<'a> {
728725
}
729726
}
730727

731-
fn exported_symbol_means_used_symbol(&self) -> bool {
732-
self.sess.target.is_like_windows || self.sess.target.is_like_osx
733-
}
734-
735728
fn subsystem(&mut self, subsystem: &str) {
736729
self.linker_arg("--subsystem");
737730
self.linker_arg(&subsystem);
@@ -1479,10 +1472,6 @@ impl<'a> Linker for L4Bender<'a> {
14791472
return;
14801473
}
14811474

1482-
fn exported_symbol_means_used_symbol(&self) -> bool {
1483-
false
1484-
}
1485-
14861475
fn subsystem(&mut self, subsystem: &str) {
14871476
self.cmd.arg(&format!("--subsystem {}", subsystem));
14881477
}

src/doc/rustc/src/command-line-arguments.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ to `/WHOLEARCHIVE` for `link.exe`, and to `-force_load` for `ld64`.
8080
The modifier does nothing for linkers that don't support it.
8181

8282
The default for this modifier is `-whole-archive`. \
83-
NOTE: The default may currently be different when building dylibs for some targets,
84-
but it is not guaranteed.
83+
NOTE: The default may currently be different in some cases for backward compatibility,
84+
but it is not guaranteed. If you need whole archive semantics use `+whole-archive` explicitly.
8585

8686
<a id="option-crate-type"></a>
8787
## `--crate-type`: a list of types of crates for the compiler to emit

0 commit comments

Comments
 (0)