From d577883f929b00b8a35204acef10e40f58f064d5 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sun, 9 Mar 2025 14:06:51 +0300
Subject: [PATCH] metadata: Ignore sysroot when doing the manual native lib
 search in rustc

---
 compiler/rustc_codegen_ssa/src/back/link.rs | 26 ++++-----
 compiler/rustc_metadata/src/lib.rs          |  4 +-
 compiler/rustc_metadata/src/native_libs.rs  | 63 +++++++++++----------
 3 files changed, 46 insertions(+), 47 deletions(-)

diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 3407117a06e3b..0ce0eb1b5386e 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -22,7 +22,9 @@ use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_macros::LintDiagnostic;
 use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file};
-use rustc_metadata::{find_native_static_library, walk_native_lib_search_dirs};
+use rustc_metadata::{
+    NativeLibSearchFallback, find_native_static_library, walk_native_lib_search_dirs,
+};
 use rustc_middle::bug;
 use rustc_middle::lint::lint_level;
 use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
@@ -2129,19 +2131,15 @@ fn add_library_search_dirs(
         return;
     }
 
-    walk_native_lib_search_dirs(
-        sess,
-        self_contained_components,
-        apple_sdk_root,
-        |dir, is_framework| {
-            if is_framework {
-                cmd.framework_path(dir);
-            } else {
-                cmd.include_path(&fix_windows_verbatim_for_gcc(dir));
-            }
-            ControlFlow::<()>::Continue(())
-        },
-    );
+    let fallback = Some(NativeLibSearchFallback { self_contained_components, apple_sdk_root });
+    walk_native_lib_search_dirs(sess, fallback, |dir, is_framework| {
+        if is_framework {
+            cmd.framework_path(dir);
+        } else {
+            cmd.include_path(&fix_windows_verbatim_for_gcc(dir));
+        }
+        ControlFlow::<()>::Continue(())
+    });
 }
 
 /// Add options making relocation sections in the produced ELF files read-only
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index ebcc0efd5a67a..b052f5699f72c 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -35,8 +35,8 @@ pub mod locator;
 pub use creader::{DylibError, load_symbol_from_dylib};
 pub use fs::{METADATA_FILENAME, emit_wrapper_file};
 pub use native_libs::{
-    find_native_static_library, try_find_native_dynamic_library, try_find_native_static_library,
-    walk_native_lib_search_dirs,
+    NativeLibSearchFallback, find_native_static_library, try_find_native_dynamic_library,
+    try_find_native_static_library, walk_native_lib_search_dirs,
 };
 pub use rmeta::{EncodedMetadata, METADATA_HEADER, encode_metadata, rendered_const};
 
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index b96921a63f352..1671b7e06b0af 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -21,10 +21,17 @@ use rustc_target::spec::{BinaryFormat, LinkSelfContainedComponents};
 
 use crate::{errors, fluent_generated};
 
+/// The fallback directories are passed to linker, but not used when rustc does the search,
+/// because in the latter case the set of fallback directories cannot always be determined
+/// consistently at the moment.
+pub struct NativeLibSearchFallback<'a> {
+    pub self_contained_components: LinkSelfContainedComponents,
+    pub apple_sdk_root: Option<&'a Path>,
+}
+
 pub fn walk_native_lib_search_dirs<R>(
     sess: &Session,
-    self_contained_components: LinkSelfContainedComponents,
-    apple_sdk_root: Option<&Path>,
+    fallback: Option<NativeLibSearchFallback<'_>>,
     mut f: impl FnMut(&Path, bool /*is_framework*/) -> ControlFlow<R>,
 ) -> ControlFlow<R> {
     // Library search paths explicitly supplied by user (`-L` on the command line).
@@ -38,6 +45,11 @@ pub fn walk_native_lib_search_dirs<R>(
         }
     }
 
+    let Some(NativeLibSearchFallback { self_contained_components, apple_sdk_root }) = fallback
+    else {
+        return ControlFlow::Continue(());
+    };
+
     // The toolchain ships some native library components and self-contained linking was enabled.
     // Add the self-contained library directory to search paths.
     if self_contained_components.intersects(
@@ -93,23 +105,17 @@ pub fn try_find_native_static_library(
         if os == unix { vec![os] } else { vec![os, unix] }
     };
 
-    // FIXME: Account for self-contained linking settings and Apple SDK.
-    walk_native_lib_search_dirs(
-        sess,
-        LinkSelfContainedComponents::empty(),
-        None,
-        |dir, is_framework| {
-            if !is_framework {
-                for (prefix, suffix) in &formats {
-                    let test = dir.join(format!("{prefix}{name}{suffix}"));
-                    if test.exists() {
-                        return ControlFlow::Break(test);
-                    }
+    walk_native_lib_search_dirs(sess, None, |dir, is_framework| {
+        if !is_framework {
+            for (prefix, suffix) in &formats {
+                let test = dir.join(format!("{prefix}{name}{suffix}"));
+                if test.exists() {
+                    return ControlFlow::Break(test);
                 }
             }
-            ControlFlow::Continue(())
-        },
-    )
+        }
+        ControlFlow::Continue(())
+    })
     .break_value()
 }
 
@@ -132,22 +138,17 @@ pub fn try_find_native_dynamic_library(
         vec![os, meson, mingw]
     };
 
-    walk_native_lib_search_dirs(
-        sess,
-        LinkSelfContainedComponents::empty(),
-        None,
-        |dir, is_framework| {
-            if !is_framework {
-                for (prefix, suffix) in &formats {
-                    let test = dir.join(format!("{prefix}{name}{suffix}"));
-                    if test.exists() {
-                        return ControlFlow::Break(test);
-                    }
+    walk_native_lib_search_dirs(sess, None, |dir, is_framework| {
+        if !is_framework {
+            for (prefix, suffix) in &formats {
+                let test = dir.join(format!("{prefix}{name}{suffix}"));
+                if test.exists() {
+                    return ControlFlow::Break(test);
                 }
             }
-            ControlFlow::Continue(())
-        },
-    )
+        }
+        ControlFlow::Continue(())
+    })
     .break_value()
 }