Skip to content

Commit 4a2df61

Browse files
authored
Unrolled build for rust-lang#120099
Rollup merge of rust-lang#120099 - petrochenkov:linkapi, r=WaffleLapkin linker: Refactor library linking methods in `trait Linker` Linkers are not aware of Rust libraries, they look like regular static or dynamic libraries to them, so Rust-specific methods in `trait Linker` do not make much sense. They can be either removed or renamed to something more suitable. Commits after the second one are cleanups.
2 parents 5bd5d21 + 03f23c1 commit 4a2df61

File tree

2 files changed

+258
-295
lines changed

2 files changed

+258
-295
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+36-28
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ use std::path::{Path, PathBuf};
5252
use std::process::{ExitStatus, Output, Stdio};
5353
use std::{env, fmt, fs, io, mem, str};
5454

55+
#[derive(Default)]
56+
pub struct SearchPaths(OnceCell<Vec<PathBuf>>);
57+
58+
impl SearchPaths {
59+
pub(super) fn get(&self, sess: &Session) -> &[PathBuf] {
60+
self.0.get_or_init(|| archive_search_paths(sess))
61+
}
62+
}
63+
5564
pub fn ensure_removed(dcx: &DiagCtxt, path: &Path) {
5665
if let Err(e) = fs::remove_file(path) {
5766
if e.kind() != io::ErrorKind::NotFound {
@@ -1265,15 +1274,15 @@ fn link_sanitizer_runtime(
12651274
let path = find_sanitizer_runtime(sess, &filename);
12661275
let rpath = path.to_str().expect("non-utf8 component in path");
12671276
linker.args(&["-Wl,-rpath", "-Xlinker", rpath]);
1268-
linker.link_dylib(&filename, false, true);
1277+
linker.link_dylib_by_name(&filename, false, true);
12691278
} else if sess.target.is_like_msvc && flavor == LinkerFlavor::Msvc(Lld::No) && name == "asan" {
12701279
// MSVC provides the `/INFERASANLIBS` argument to automatically find the
12711280
// compatible ASAN library.
12721281
linker.arg("/INFERASANLIBS");
12731282
} else {
12741283
let filename = format!("librustc{channel}_rt.{name}.a");
12751284
let path = find_sanitizer_runtime(sess, &filename).join(&filename);
1276-
linker.link_whole_rlib(&path);
1285+
linker.link_staticlib_by_path(&path, true);
12771286
}
12781287
}
12791288

@@ -2445,7 +2454,7 @@ fn add_native_libs_from_crate(
24452454
archive_builder_builder: &dyn ArchiveBuilderBuilder,
24462455
codegen_results: &CodegenResults,
24472456
tmpdir: &Path,
2448-
search_paths: &OnceCell<Vec<PathBuf>>,
2457+
search_paths: &SearchPaths,
24492458
bundled_libs: &FxHashSet<Symbol>,
24502459
cnum: CrateNum,
24512460
link_static: bool,
@@ -2505,46 +2514,34 @@ fn add_native_libs_from_crate(
25052514
if let Some(filename) = lib.filename {
25062515
// If rlib contains native libs as archives, they are unpacked to tmpdir.
25072516
let path = tmpdir.join(filename.as_str());
2508-
if whole_archive {
2509-
cmd.link_whole_rlib(&path);
2510-
} else {
2511-
cmd.link_rlib(&path);
2512-
}
2517+
cmd.link_staticlib_by_path(&path, whole_archive);
25132518
}
25142519
} else {
2515-
if whole_archive {
2516-
cmd.link_whole_staticlib(
2517-
name,
2518-
verbatim,
2519-
search_paths.get_or_init(|| archive_search_paths(sess)),
2520-
);
2521-
} else {
2522-
cmd.link_staticlib(name, verbatim)
2523-
}
2520+
cmd.link_staticlib_by_name(name, verbatim, whole_archive, search_paths);
25242521
}
25252522
}
25262523
}
25272524
NativeLibKind::Dylib { as_needed } => {
25282525
if link_dynamic {
2529-
cmd.link_dylib(name, verbatim, as_needed.unwrap_or(true))
2526+
cmd.link_dylib_by_name(name, verbatim, as_needed.unwrap_or(true))
25302527
}
25312528
}
25322529
NativeLibKind::Unspecified => {
25332530
// If we are generating a static binary, prefer static library when the
25342531
// link kind is unspecified.
25352532
if !link_output_kind.can_link_dylib() && !sess.target.crt_static_allows_dylibs {
25362533
if link_static {
2537-
cmd.link_staticlib(name, verbatim)
2534+
cmd.link_staticlib_by_name(name, verbatim, false, search_paths);
25382535
}
25392536
} else {
25402537
if link_dynamic {
2541-
cmd.link_dylib(name, verbatim, true);
2538+
cmd.link_dylib_by_name(name, verbatim, true);
25422539
}
25432540
}
25442541
}
25452542
NativeLibKind::Framework { as_needed } => {
25462543
if link_dynamic {
2547-
cmd.link_framework(name, as_needed.unwrap_or(true))
2544+
cmd.link_framework_by_name(name, verbatim, as_needed.unwrap_or(true))
25482545
}
25492546
}
25502547
NativeLibKind::RawDylib => {
@@ -2581,7 +2578,7 @@ fn add_local_native_libraries(
25812578
}
25822579
}
25832580

2584-
let search_paths = OnceCell::new();
2581+
let search_paths = SearchPaths::default();
25852582
// All static and dynamic native library dependencies are linked to the local crate.
25862583
let link_static = true;
25872584
let link_dynamic = true;
@@ -2623,7 +2620,7 @@ fn add_upstream_rust_crates<'a>(
26232620
.find(|(ty, _)| *ty == crate_type)
26242621
.expect("failed to find crate type in dependency format list");
26252622

2626-
let search_paths = OnceCell::new();
2623+
let search_paths = SearchPaths::default();
26272624
for &cnum in &codegen_results.crate_info.used_crates {
26282625
// We may not pass all crates through to the linker. Some crates may appear statically in
26292626
// an existing dylib, meaning we'll pick up all the symbols from the dylib.
@@ -2698,7 +2695,7 @@ fn add_upstream_native_libraries(
26982695
tmpdir: &Path,
26992696
link_output_kind: LinkOutputKind,
27002697
) {
2701-
let search_path = OnceCell::new();
2698+
let search_paths = SearchPaths::default();
27022699
for &cnum in &codegen_results.crate_info.used_crates {
27032700
// Static libraries are not linked here, they are linked in `add_upstream_rust_crates`.
27042701
// FIXME: Merge this function to `add_upstream_rust_crates` so that all native libraries
@@ -2720,7 +2717,7 @@ fn add_upstream_native_libraries(
27202717
archive_builder_builder,
27212718
codegen_results,
27222719
tmpdir,
2723-
&search_path,
2720+
&search_paths,
27242721
&Default::default(),
27252722
cnum,
27262723
link_static,
@@ -2791,7 +2788,7 @@ fn add_static_crate<'a>(
27912788
} else {
27922789
fix_windows_verbatim_for_gcc(path)
27932790
};
2794-
cmd.link_rlib(&rlib_path);
2791+
cmd.link_staticlib_by_path(&rlib_path, false);
27952792
};
27962793

27972794
if !are_upstream_rust_objects_already_included(sess)
@@ -2859,13 +2856,24 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
28592856
// Just need to tell the linker about where the library lives and
28602857
// what its name is
28612858
let parent = cratepath.parent();
2859+
// When producing a dll, the MSVC linker may not actually emit a
2860+
// `foo.lib` file if the dll doesn't actually export any symbols, so we
2861+
// check to see if the file is there and just omit linking to it if it's
2862+
// not present.
2863+
if sess.target.is_like_msvc && !cratepath.with_extension("dll.lib").exists() {
2864+
return;
2865+
}
28622866
if let Some(dir) = parent {
28632867
cmd.include_path(&rehome_sysroot_lib_dir(sess, dir));
28642868
}
2865-
let stem = cratepath.file_stem().unwrap().to_str().unwrap();
2869+
// "<dir>/name.dll -> name.dll" on windows-msvc
2870+
// "<dir>/name.dll -> name" on windows-gnu
2871+
// "<dir>/libname.<ext> -> name" elsewhere
2872+
let stem = if sess.target.is_like_msvc { cratepath.file_name() } else { cratepath.file_stem() };
2873+
let stem = stem.unwrap().to_str().unwrap();
28662874
// Convert library file-stem into a cc -l argument.
28672875
let prefix = if stem.starts_with("lib") && !sess.target.is_like_windows { 3 } else { 0 };
2868-
cmd.link_rust_dylib(&stem[prefix..], parent.unwrap_or_else(|| Path::new("")));
2876+
cmd.link_dylib_by_name(&stem[prefix..], false, true);
28692877
}
28702878

28712879
fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {

0 commit comments

Comments
 (0)