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