@@ -2065,17 +2065,61 @@ 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+ // Sanitizer libraries have the same issue and are also linked by name on Apple targets.
2103+ // The targets here should be in sync with `copy_third_party_objects` in bootstrap.
2104+ // FIXME: implement `-Clink-self-contained=+/-unwind,+/-sanitizers`, move the shipped libunwind
2105+ // and sanitizers to self-contained directory, and stop adding this search path.
2106+ if sess. target . vendor == "fortanix"
2107+ || sess. target . os == "linux"
2108+ || sess. target . os == "fuchsia"
2109+ || sess. target . is_like_osx && !sess. opts . unstable_opts . sanitizer . is_empty ( )
2110+ {
2111+ let lib_path = sess. target_filesearch ( PathKind :: Native ) . get_lib_path ( ) ;
2112+ cmd. include_path ( & fix_windows_verbatim_for_gcc ( & lib_path) ) ;
2113+ }
2114+
2115+ // Mac Catalyst uses the macOS SDK, but to link to iOS-specific frameworks
2116+ // we must have the support library stubs in the library search path (#121430).
2117+ if let Some ( sdk_root) = apple_sdk_root
2118+ && sess. target . llvm_target . contains ( "macabi" )
2119+ {
2120+ cmd. include_path ( & sdk_root. join ( "System/iOSSupport/usr/lib" ) ) ;
2121+ cmd. framework_path ( & sdk_root. join ( "System/iOSSupport/System/Library/Frameworks" ) ) ;
2122+ }
20792123}
20802124
20812125/// Add options making relocation sections in the produced ELF files read-only
@@ -2367,7 +2411,7 @@ fn add_order_independent_options(
23672411 // Take care of the flavors and CLI options requesting the `lld` linker.
23682412 add_lld_args ( cmd, sess, flavor, self_contained_components) ;
23692413
2370- add_apple_sdk ( cmd, sess, flavor) ;
2414+ let apple_sdk_root = add_apple_sdk ( cmd, sess, flavor) ;
23712415
23722416 add_link_script ( cmd, sess, tmpdir, crate_type) ;
23732417
@@ -2423,7 +2467,7 @@ fn add_order_independent_options(
24232467
24242468 cmd. linker_plugin_lto ( ) ;
24252469
2426- add_library_search_dirs ( cmd, sess, self_contained_components. are_any_components_enabled ( ) ) ;
2470+ add_library_search_dirs ( cmd, sess, self_contained_components, apple_sdk_root . as_deref ( ) ) ;
24272471
24282472 cmd. output_filename ( out_filename) ;
24292473
@@ -2637,19 +2681,6 @@ fn add_local_native_libraries(
26372681 tmpdir : & Path ,
26382682 link_output_kind : LinkOutputKind ,
26392683) {
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-
26532684 // All static and dynamic native library dependencies are linked to the local crate.
26542685 let link_static = true ;
26552686 let link_dynamic = true ;
@@ -2944,19 +2975,19 @@ pub(crate) fn are_upstream_rust_objects_already_included(sess: &Session) -> bool
29442975 }
29452976}
29462977
2947- fn add_apple_sdk ( cmd : & mut dyn Linker , sess : & Session , flavor : LinkerFlavor ) {
2978+ fn add_apple_sdk ( cmd : & mut dyn Linker , sess : & Session , flavor : LinkerFlavor ) -> Option < PathBuf > {
29482979 let arch = & sess. target . arch ;
29492980 let os = & sess. target . os ;
29502981 let llvm_target = & sess. target . llvm_target ;
29512982 if sess. target . vendor != "apple"
29522983 || !matches ! ( os. as_ref( ) , "ios" | "tvos" | "watchos" | "visionos" | "macos" )
29532984 || !matches ! ( flavor, LinkerFlavor :: Darwin ( ..) )
29542985 {
2955- return ;
2986+ return None ;
29562987 }
29572988
29582989 if os == "macos" && !matches ! ( flavor, LinkerFlavor :: Darwin ( Cc :: No , _) ) {
2959- return ;
2990+ return None ;
29602991 }
29612992
29622993 let sdk_name = match ( arch. as_ref ( ) , os. as_ref ( ) ) {
@@ -2980,14 +3011,14 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
29803011 ( _, "macos" ) => "macosx" ,
29813012 _ => {
29823013 sess. dcx ( ) . emit_err ( errors:: UnsupportedArch { arch, os } ) ;
2983- return ;
3014+ return None ;
29843015 }
29853016 } ;
29863017 let sdk_root = match get_apple_sdk_root ( sdk_name) {
29873018 Ok ( s) => s,
29883019 Err ( e) => {
29893020 sess. dcx ( ) . emit_err ( e) ;
2990- return ;
3021+ return None ;
29913022 }
29923023 } ;
29933024
@@ -3007,16 +3038,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
30073038 _ => unreachable ! ( ) ,
30083039 }
30093040
3010- if llvm_target. contains ( "macabi" ) {
3011- // Mac Catalyst uses the macOS SDK, but to link to iOS-specific
3012- // frameworks, we must have the support library stubs in the library
3013- // search path.
3014-
3015- // The flags are called `-L` and `-F` both in Clang, ld64 and ldd.
3016- let sdk_root = Path :: new ( & sdk_root) ;
3017- cmd. include_path ( & sdk_root. join ( "System/iOSSupport/usr/lib" ) ) ;
3018- cmd. framework_path ( & sdk_root. join ( "System/iOSSupport/System/Library/Frameworks" ) ) ;
3019- }
3041+ Some ( sdk_root. into ( ) )
30203042}
30213043
30223044fn get_apple_sdk_root ( sdk_name : & str ) -> Result < String , errors:: AppleSdkRootError < ' _ > > {
0 commit comments