Skip to content

Commit a83783a

Browse files
committed
linker: Pass fewer search directories to the linker
1 parent f8060d2 commit a83783a

File tree

2 files changed

+61
-38
lines changed

2 files changed

+61
-38
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+56-38
Original file line numberDiff line numberDiff line change
@@ -2065,17 +2065,57 @@ fn add_local_crate_metadata_objects(
20652065
}
20662066

20672067
/// Add sysroot and other globally set directories to the directory search list.
2068-
fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session, self_contained: bool) {
2069-
// The default library location, we need this to find the runtime.
2070-
// The location of crates will be determined as needed.
2071-
let lib_path = sess.target_filesearch(PathKind::All).get_lib_path();
2072-
cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
2068+
fn add_library_search_dirs(
2069+
cmd: &mut dyn Linker,
2070+
sess: &Session,
2071+
self_contained_components: LinkSelfContainedComponents,
2072+
apple_sdk_root: Option<&Path>,
2073+
) {
2074+
if !sess.opts.unstable_opts.link_native_libraries {
2075+
return;
2076+
}
20732077

2074-
// Special directory with libraries used only in self-contained linkage mode
2075-
if self_contained {
2076-
let lib_path = sess.target_filesearch(PathKind::All).get_self_contained_lib_path();
2078+
// Library search paths explicitly supplied by user (`-L` on the command line).
2079+
for search_path in sess.target_filesearch(PathKind::Native).cli_search_paths() {
2080+
cmd.include_path(&fix_windows_verbatim_for_gcc(&search_path.dir));
2081+
}
2082+
for search_path in sess.target_filesearch(PathKind::Framework).cli_search_paths() {
2083+
// Contrary to the `-L` docs only framework-specific paths are considered here.
2084+
if search_path.kind != PathKind::All {
2085+
cmd.framework_path(&search_path.dir);
2086+
}
2087+
}
2088+
2089+
// The toolchain ships some native library components and self-contained linking was enabled.
2090+
// Add the self-contained library directory to search paths.
2091+
if self_contained_components.intersects(
2092+
LinkSelfContainedComponents::LIBC
2093+
| LinkSelfContainedComponents::UNWIND
2094+
| LinkSelfContainedComponents::MINGW,
2095+
) {
2096+
let lib_path = sess.target_filesearch(PathKind::Native).get_self_contained_lib_path();
20772097
cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
20782098
}
2099+
2100+
// Toolchains for some targets may ship `libunwind.a`, but place it into the main sysroot
2101+
// library directory instead of the self-contained directories.
2102+
// The targets here should be in sync with `copy_third_party_objects` in bootstrap.
2103+
// FIXME: implement `-Clink-self-contained=+/-unwind`, move the shipped libunwind
2104+
// to self-contained directory, and stop adding this search path.
2105+
if sess.target.vendor == "fortanix" || sess.target.os == "linux" || sess.target.os == "fuchsia"
2106+
{
2107+
let lib_path = sess.target_filesearch(PathKind::Native).get_lib_path();
2108+
cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
2109+
}
2110+
2111+
// Mac Catalyst uses the macOS SDK, but to link to iOS-specific frameworks
2112+
// we must have the support library stubs in the library search path (#121430).
2113+
if let Some(sdk_root) = apple_sdk_root
2114+
&& sess.target.llvm_target.contains("macabi")
2115+
{
2116+
cmd.include_path(&sdk_root.join("System/iOSSupport/usr/lib"));
2117+
cmd.framework_path(&sdk_root.join("System/iOSSupport/System/Library/Frameworks"));
2118+
}
20792119
}
20802120

20812121
/// Add options making relocation sections in the produced ELF files read-only
@@ -2367,7 +2407,7 @@ fn add_order_independent_options(
23672407
// Take care of the flavors and CLI options requesting the `lld` linker.
23682408
add_lld_args(cmd, sess, flavor, self_contained_components);
23692409

2370-
add_apple_sdk(cmd, sess, flavor);
2410+
let apple_sdk_root = add_apple_sdk(cmd, sess, flavor);
23712411

23722412
add_link_script(cmd, sess, tmpdir, crate_type);
23732413

@@ -2423,7 +2463,7 @@ fn add_order_independent_options(
24232463

24242464
cmd.linker_plugin_lto();
24252465

2426-
add_library_search_dirs(cmd, sess, self_contained_components.are_any_components_enabled());
2466+
add_library_search_dirs(cmd, sess, self_contained_components, apple_sdk_root.as_deref());
24272467

24282468
cmd.output_filename(out_filename);
24292469

@@ -2637,19 +2677,6 @@ fn add_local_native_libraries(
26372677
tmpdir: &Path,
26382678
link_output_kind: LinkOutputKind,
26392679
) {
2640-
if sess.opts.unstable_opts.link_native_libraries {
2641-
// User-supplied library search paths (-L on the command line). These are the same paths
2642-
// used to find Rust crates, so some of them may have been added already by the previous
2643-
// crate linking code. This only allows them to be found at compile time so it is still
2644-
// entirely up to outside forces to make sure that library can be found at runtime.
2645-
for search_path in sess.target_filesearch(PathKind::All).search_paths() {
2646-
match search_path.kind {
2647-
PathKind::Framework => cmd.framework_path(&search_path.dir),
2648-
_ => cmd.include_path(&fix_windows_verbatim_for_gcc(&search_path.dir)),
2649-
}
2650-
}
2651-
}
2652-
26532680
// All static and dynamic native library dependencies are linked to the local crate.
26542681
let link_static = true;
26552682
let link_dynamic = true;
@@ -2943,19 +2970,19 @@ pub(crate) fn are_upstream_rust_objects_already_included(sess: &Session) -> bool
29432970
}
29442971
}
29452972

2946-
fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
2973+
fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) -> Option<PathBuf> {
29472974
let arch = &sess.target.arch;
29482975
let os = &sess.target.os;
29492976
let llvm_target = &sess.target.llvm_target;
29502977
if sess.target.vendor != "apple"
29512978
|| !matches!(os.as_ref(), "ios" | "tvos" | "watchos" | "visionos" | "macos")
29522979
|| !matches!(flavor, LinkerFlavor::Darwin(..))
29532980
{
2954-
return;
2981+
return None;
29552982
}
29562983

29572984
if os == "macos" && !matches!(flavor, LinkerFlavor::Darwin(Cc::No, _)) {
2958-
return;
2985+
return None;
29592986
}
29602987

29612988
let sdk_name = match (arch.as_ref(), os.as_ref()) {
@@ -2979,14 +3006,14 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
29793006
(_, "macos") => "macosx",
29803007
_ => {
29813008
sess.dcx().emit_err(errors::UnsupportedArch { arch, os });
2982-
return;
3009+
return None;
29833010
}
29843011
};
29853012
let sdk_root = match get_apple_sdk_root(sdk_name) {
29863013
Ok(s) => s,
29873014
Err(e) => {
29883015
sess.dcx().emit_err(e);
2989-
return;
3016+
return None;
29903017
}
29913018
};
29923019

@@ -3006,16 +3033,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
30063033
_ => unreachable!(),
30073034
}
30083035

3009-
if llvm_target.contains("macabi") {
3010-
// Mac Catalyst uses the macOS SDK, but to link to iOS-specific
3011-
// frameworks, we must have the support library stubs in the library
3012-
// search path.
3013-
3014-
// The flags are called `-L` and `-F` both in Clang, ld64 and ldd.
3015-
let sdk_root = Path::new(&sdk_root);
3016-
cmd.include_path(&sdk_root.join("System/iOSSupport/usr/lib"));
3017-
cmd.framework_path(&sdk_root.join("System/iOSSupport/System/Library/Frameworks"));
3018-
}
3036+
Some(sdk_root.into())
30193037
}
30203038

30213039
fn get_apple_sdk_root(sdk_name: &str) -> Result<String, errors::AppleSdkRootError<'_>> {

compiler/rustc_session/src/filesearch.rs

+5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ pub struct FileSearch<'a> {
1919
}
2020

2121
impl<'a> FileSearch<'a> {
22+
pub fn cli_search_paths(&self) -> impl Iterator<Item = &'a SearchPath> {
23+
let kind = self.kind;
24+
self.cli_search_paths.iter().filter(move |sp| sp.kind.matches(kind))
25+
}
26+
2227
pub fn search_paths(&self) -> impl Iterator<Item = &'a SearchPath> {
2328
let kind = self.kind;
2429
self.cli_search_paths

0 commit comments

Comments
 (0)