1- use std:: path:: PathBuf ;
1+ use std:: path:: { Path , PathBuf } ;
22
33use rustc_ast:: { NestedMetaItem , CRATE_NODE_ID } ;
44use rustc_attr as attr;
@@ -16,10 +16,68 @@ use rustc_session::Session;
1616use rustc_span:: def_id:: { DefId , LOCAL_CRATE } ;
1717use rustc_span:: symbol:: { sym, Symbol } ;
1818use rustc_target:: spec:: abi:: Abi ;
19+ use rustc_target:: spec:: LinkSelfContainedComponents ;
1920
2021use crate :: { errors, fluent_generated} ;
2122
22- pub fn find_native_static_library ( name : & str , verbatim : bool , sess : & Session ) -> PathBuf {
23+ pub fn walk_native_lib_search_dirs < R > (
24+ sess : & Session ,
25+ self_contained_components : LinkSelfContainedComponents ,
26+ apple_sdk_root : Option < & Path > ,
27+ mut f : impl FnMut ( & Path , bool /*is_framework*/ ) -> Option < R > ,
28+ ) -> Option < R > {
29+ // Library search paths explicitly supplied by user (`-L` on the command line).
30+ for search_path in sess. target_filesearch ( PathKind :: Native ) . cli_search_paths ( ) {
31+ f ( & search_path. dir , false ) ?;
32+ }
33+ for search_path in sess. target_filesearch ( PathKind :: Framework ) . cli_search_paths ( ) {
34+ // Contrary to the `-L` docs only framework-specific paths are considered here.
35+ if search_path. kind != PathKind :: All {
36+ f ( & search_path. dir , true ) ?;
37+ }
38+ }
39+
40+ // The toolchain ships some native library components and self-contained linking was enabled.
41+ // Add the self-contained library directory to search paths.
42+ if self_contained_components. intersects (
43+ LinkSelfContainedComponents :: LIBC
44+ | LinkSelfContainedComponents :: UNWIND
45+ | LinkSelfContainedComponents :: MINGW ,
46+ ) {
47+ f ( & sess. target_filesearch ( PathKind :: Native ) . get_self_contained_lib_path ( ) , false ) ?;
48+ }
49+
50+ // Toolchains for some targets may ship `libunwind.a`, but place it into the main sysroot
51+ // library directory instead of the self-contained directories.
52+ // Sanitizer libraries have the same issue and are also linked by name on Apple targets.
53+ // The targets here should be in sync with `copy_third_party_objects` in bootstrap.
54+ // FIXME: implement `-Clink-self-contained=+/-unwind,+/-sanitizers`, move the shipped libunwind
55+ // and sanitizers to self-contained directory, and stop adding this search path.
56+ if sess. target . vendor == "fortanix"
57+ || sess. target . os == "linux"
58+ || sess. target . os == "fuchsia"
59+ || sess. target . is_like_osx && !sess. opts . unstable_opts . sanitizer . is_empty ( )
60+ {
61+ f ( & sess. target_filesearch ( PathKind :: Native ) . get_lib_path ( ) , false ) ?;
62+ }
63+
64+ // Mac Catalyst uses the macOS SDK, but to link to iOS-specific frameworks
65+ // we must have the support library stubs in the library search path (#121430).
66+ if let Some ( sdk_root) = apple_sdk_root
67+ && sess. target . llvm_target . contains ( "macabi" )
68+ {
69+ f ( & sdk_root. join ( "System/iOSSupport/usr/lib" ) , false ) ?;
70+ f ( & sdk_root. join ( "System/iOSSupport/System/Library/Frameworks" ) , true ) ?;
71+ }
72+
73+ None
74+ }
75+
76+ pub fn try_find_native_static_library (
77+ sess : & Session ,
78+ name : & str ,
79+ verbatim : bool ,
80+ ) -> Option < PathBuf > {
2381 let formats = if verbatim {
2482 vec ! [ ( "" . into( ) , "" . into( ) ) ]
2583 } else {
@@ -30,16 +88,28 @@ pub fn find_native_static_library(name: &str, verbatim: bool, sess: &Session) ->
3088 if os == unix { vec ! [ os] } else { vec ! [ os, unix] }
3189 } ;
3290
33- for path in sess. target_filesearch ( PathKind :: Native ) . search_paths ( ) {
34- for ( prefix, suffix) in & formats {
35- let test = path. dir . join ( format ! ( "{prefix}{name}{suffix}" ) ) ;
36- if test. exists ( ) {
37- return test;
91+ // FIXME: Account for self-contained linking settings and Apple SDK.
92+ walk_native_lib_search_dirs (
93+ sess,
94+ LinkSelfContainedComponents :: empty ( ) ,
95+ None ,
96+ |dir, is_framework| {
97+ if !is_framework {
98+ for ( prefix, suffix) in & formats {
99+ let test = dir. join ( format ! ( "{prefix}{name}{suffix}" ) ) ;
100+ if test. exists ( ) {
101+ return Some ( test) ;
102+ }
103+ }
38104 }
39- }
40- }
105+ None
106+ } ,
107+ )
108+ }
41109
42- sess. dcx ( ) . emit_fatal ( errors:: MissingNativeLibrary :: new ( name, verbatim) ) ;
110+ pub fn find_native_static_library ( name : & str , verbatim : bool , sess : & Session ) -> PathBuf {
111+ try_find_native_static_library ( sess, name, verbatim)
112+ . unwrap_or_else ( || sess. dcx ( ) . emit_fatal ( errors:: MissingNativeLibrary :: new ( name, verbatim) ) )
43113}
44114
45115fn find_bundled_library (
0 commit comments