@@ -238,6 +238,35 @@ use std::path::{Path, PathBuf};
238238use std:: { cmp, fmt, fs} ;
239239use tracing:: { debug, info, warn} ;
240240
241+ // Converts a library file-stem into a cc -l argument
242+ pub fn unlib < ' a > ( target : & Target , stem : & ' a str ) -> & ' a str {
243+ if stem. starts_with ( "lib" ) && !target. is_like_windows { & stem[ 3 ..] } else { stem }
244+ }
245+
246+ /// Returns Some(symbol_name) if `file` could be a valid dylib
247+ /// Example (assuming target is GNU/Linux):
248+ /// - `libsomecrate.asdf` -> `None`
249+ /// - `libsomecrate.so` -> `Some(somecreate)`
250+ /// - `libsomecrate.so.0.1` -> `Some(somecreate)`
251+ /// - `libsomecrate.so.a.4` -> `None`
252+ pub fn get_dylib_symbol_name < ' a > ( file : & ' a str , target : & Target ) -> Option < & ' a str > {
253+ // test if the targets dll_suffix is found within the filename. If it
254+ // is check if all of the chars following it are either a digit (0-9)
255+ // or a dot.
256+ file. find ( & target. dll_suffix )
257+ . map ( |idx| {
258+ match file
259+ . chars ( )
260+ . skip ( idx + idx + target. dll_suffix . len ( ) )
261+ . all ( |c| c. is_ascii_digit ( ) || c == '.' )
262+ {
263+ true => file. get ( 0 ..idx) . map ( |s| unlib ( target, s) ) ,
264+ false => None ,
265+ }
266+ } )
267+ . flatten ( )
268+ }
269+
241270#[ derive( Clone ) ]
242271crate struct CrateLocator < ' a > {
243272 // Immutable per-session configuration.
@@ -365,25 +394,6 @@ impl<'a> CrateLocator<'a> {
365394 self . find_library_crate ( "" , & mut seen_paths)
366395 }
367396
368- /// Returns true if `file` has a suffix that could be a valid dylib
369- /// Example (assuming target has .so as dll_suffix):
370- /// - `libsomecrate.asdf` -> `false`
371- /// - `libsomecrate.so` -> `true`
372- /// - `libsomecrate.so.0.1` -> `true`
373- /// - `libsomecrate.so.a.4` -> `false`
374- fn test_dylib_suffix ( & self , file : & str ) -> bool {
375- // test if the targets dll_suffix is found within the filename. If it
376- // is check if all of the chars following it are either in range 0x30
377- // to 0x39 (0-9) or 0x2E (.).
378- match file. find ( & self . target . dll_suffix ) {
379- Some ( idx) => file
380- . chars ( )
381- . skip ( idx + self . target . dll_suffix . len ( ) )
382- . all ( |c| c as u32 >= 0x30 && c as u32 <= 0x39 || c as u32 == 0x2E ) ,
383- None => false ,
384- }
385- }
386-
387397 fn find_library_crate (
388398 & mut self ,
389399 extra_prefix : & str ,
@@ -421,7 +431,9 @@ impl<'a> CrateLocator<'a> {
421431 ( & file[ ( rlib_prefix. len ( ) ) ..( file. len ( ) - ".rlib" . len ( ) ) ] , CrateFlavor :: Rlib )
422432 } else if file. starts_with ( & rlib_prefix) && file. ends_with ( ".rmeta" ) {
423433 ( & file[ ( rlib_prefix. len ( ) ) ..( file. len ( ) - ".rmeta" . len ( ) ) ] , CrateFlavor :: Rmeta )
424- } else if file. starts_with ( & dylib_prefix) && self . test_dylib_suffix ( file) {
434+ } else if file. starts_with ( & dylib_prefix)
435+ && get_dylib_symbol_name ( file, & self . target ) . is_some ( )
436+ {
425437 (
426438 & file[ ( dylib_prefix. len ( ) ) ..( file. len ( ) - self . target . dll_suffix . len ( ) ) ] ,
427439 CrateFlavor :: Dylib ,
@@ -700,7 +712,8 @@ impl<'a> CrateLocator<'a> {
700712 } ;
701713
702714 if file. starts_with ( "lib" ) && ( file. ends_with ( ".rlib" ) || file. ends_with ( ".rmeta" ) )
703- || file. starts_with ( & self . target . dll_prefix ) && self . test_dylib_suffix ( file)
715+ || file. starts_with ( & self . target . dll_prefix )
716+ && get_dylib_symbol_name ( file, & self . target ) . is_some ( )
704717 {
705718 // Make sure there's at most one rlib and at most one dylib.
706719 // Note to take care and match against the non-canonicalized name:
0 commit comments