1
- use std:: path:: PathBuf ;
1
+ use std:: ops:: ControlFlow ;
2
+ use std:: path:: { Path , PathBuf } ;
2
3
3
4
use rustc_ast:: { NestedMetaItem , CRATE_NODE_ID } ;
4
5
use rustc_attr as attr;
@@ -16,10 +17,68 @@ use rustc_session::Session;
16
17
use rustc_span:: def_id:: { DefId , LOCAL_CRATE } ;
17
18
use rustc_span:: symbol:: { sym, Symbol } ;
18
19
use rustc_target:: spec:: abi:: Abi ;
20
+ use rustc_target:: spec:: LinkSelfContainedComponents ;
19
21
20
22
use crate :: { errors, fluent_generated} ;
21
23
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 > {
23
82
let formats = if verbatim {
24
83
vec ! [ ( "" . into( ) , "" . into( ) ) ]
25
84
} else {
@@ -30,16 +89,29 @@ pub fn find_native_static_library(name: &str, verbatim: bool, sess: &Session) ->
30
89
if os == unix { vec ! [ os] } else { vec ! [ os, unix] }
31
90
} ;
32
91
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
+ }
38
105
}
39
- }
40
- }
106
+ ControlFlow :: Continue ( ( ) )
107
+ } ,
108
+ )
109
+ . break_value ( )
110
+ }
41
111
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) ) )
43
115
}
44
116
45
117
fn find_bundled_library (
0 commit comments