@@ -9,7 +9,7 @@ use semver::Version;
9
9
use shlex:: Shlex ;
10
10
11
11
use super :: library:: Linkage ;
12
- use super :: Result ;
12
+ use super :: { Result , TARGET_ENV_MSVC } ;
13
13
14
14
#[ derive( Debug , PartialEq , Eq ) ]
15
15
pub struct LinkLib ( pub Linkage , pub String ) ;
@@ -25,6 +25,46 @@ impl LinkLib {
25
25
} ;
26
26
format ! ( "cargo:rustc-link-lib={link_spec}{}" , self . 1 )
27
27
}
28
+
29
+ /// Returns Some(new_file_name) if some parts of the filename were removed, None otherwise
30
+ pub fn with_cleaned_up_lib_filename ( self ) -> Option < Self > {
31
+ if matches ! ( self . 0 , Linkage :: Static ) {
32
+ Some ( self )
33
+ } else {
34
+ let mut new_filename = Path :: new ( & self . 1 ) . as_os_str ( ) ;
35
+ // used to check for the file extension (with dots stripped) and for the part of the filename
36
+ const LIB_EXTS : [ & str ; 7 ] = [ ".so." , ".a." , ".dll." , ".lib." , ".dylib." , ".framework." , ".tbd." ] ;
37
+ let filename_path = Path :: new ( new_filename) ;
38
+ // strip lib extension from the filename
39
+ if let ( Some ( stem) , Some ( extension) ) = ( filename_path. file_stem ( ) , filename_path. extension ( ) . and_then ( OsStr :: to_str) ) {
40
+ if LIB_EXTS . iter ( ) . any ( |e| e. trim_matches ( '.' ) . eq_ignore_ascii_case ( extension) ) {
41
+ new_filename = stem;
42
+ }
43
+ }
44
+ if let Some ( mut file) = new_filename. to_str ( ) {
45
+ let orig_len = file. len ( ) ;
46
+
47
+ // strip "lib" prefix from the filename unless targeting MSVC
48
+ if !* TARGET_ENV_MSVC {
49
+ file = file. strip_prefix ( "lib" ) . unwrap_or ( file) ;
50
+ }
51
+
52
+ // strip lib extension + suffix (e.g. .so.4.6.0) from the filename
53
+ LIB_EXTS . iter ( ) . for_each ( |& inner_ext| {
54
+ if let Some ( inner_ext_idx) = file. find ( inner_ext) {
55
+ file = & file[ ..inner_ext_idx] ;
56
+ }
57
+ } ) ;
58
+ if orig_len != file. len ( ) {
59
+ new_filename = OsStr :: new ( file) ;
60
+ }
61
+ }
62
+ new_filename
63
+ . to_str ( )
64
+ . filter ( |new_filename| new_filename. len ( ) != self . 1 . len ( ) )
65
+ . map ( |new_filename| Self ( self . 0 , new_filename. to_string ( ) ) )
66
+ }
67
+ }
28
68
}
29
69
30
70
impl From < & str > for LinkLib {
@@ -203,30 +243,27 @@ impl<'r> CmakeProbe<'r> {
203
243
link_libs. push ( LinkLib ( Linkage :: Framework , name) ) ;
204
244
} else if !arg. starts_with ( '-' ) {
205
245
let path = Path :: new ( arg) ;
206
- let linkage = if Self :: is_library_static ( path) {
246
+ let linkage = if Self :: is_library_static_archive ( path) {
207
247
Linkage :: Static
208
248
} else {
209
- Linkage :: Default
210
- } ;
211
- if let Some ( file) = path. file_name ( ) . and_then ( super :: cleanup_lib_filename) {
212
249
if let Some ( parent) = path. parent ( ) . map ( |p| p. to_owned ( ) ) {
213
- let search_path = LinkSearch ( linkage , parent) ;
250
+ let search_path = LinkSearch ( Linkage :: Default , parent) ;
214
251
if !link_paths. contains ( & search_path) {
215
252
link_paths. push ( search_path) ;
216
253
}
217
254
} else {
218
255
panic ! ( "{}" , arg. to_string( ) ) ;
219
256
}
220
- let file = file . to_str ( ) . expect ( "Non-UTF8 filename" ) ;
221
- link_libs . push ( LinkLib ( linkage , file . to_string ( ) ) ) ;
222
- }
257
+ Linkage :: Default
258
+ } ;
259
+ link_libs . push ( LinkLib ( linkage , path . to_str ( ) . expect ( "Non-UTF8 filename" ) . to_string ( ) ) ) ;
223
260
} else {
224
261
eprintln ! ( "=== Unexpected cmake compiler argument found: {arg}" ) ;
225
262
}
226
263
}
227
264
}
228
265
229
- fn is_library_static ( path : & Path ) -> bool {
266
+ fn is_library_static_archive ( path : & Path ) -> bool {
230
267
path. extension ( ) . map_or ( false , |ext| ext. eq_ignore_ascii_case ( "a" ) )
231
268
}
232
269
0 commit comments