@@ -280,27 +280,46 @@ impl ToolchainComponents {
280280
281281 /// Finds known library components in the given `dir` and stores them in `self`.
282282 fn fill_libraries ( & mut self , dir : & Path ) -> anyhow:: Result < ( ) > {
283- for entry in fs:: read_dir ( dir) . context ( "Cannot read lib dir to find components" ) ? {
284- let entry = entry?;
285- let path = entry. path ( ) ;
286- if path. is_file ( ) {
287- if let Some ( filename) = path. file_name ( ) . and_then ( |s| s. to_str ( ) ) {
288- // libLLVM.so can have a weird suffix, like libLLVM.so.<suffix>, so we don't
289- // check its .so suffix directly.
290- if filename. starts_with ( "libLLVM" ) {
291- self . lib_llvm = Some ( path) ;
292- } else if path. extension ( ) == Some ( OsStr :: new ( "so" ) ) {
293- if filename. starts_with ( "librustc_driver" ) {
294- self . lib_rustc = Some ( path) ;
295- } else if filename. starts_with ( "libstd" ) {
296- self . lib_std = Some ( path) ;
297- } else if filename. starts_with ( "libtest" ) {
298- self . lib_test = Some ( path) ;
299- }
300- }
283+ let files: Vec < ( PathBuf , String ) > = fs:: read_dir ( dir)
284+ . context ( "Cannot read lib dir to find components" ) ?
285+ . map ( |entry| Ok ( entry?) )
286+ . collect :: < anyhow:: Result < Vec < _ > > > ( ) ?
287+ . into_iter ( )
288+ . filter ( |entry| entry. path ( ) . is_file ( ) )
289+ . filter_map ( |entry| {
290+ entry
291+ . path ( )
292+ . file_name ( )
293+ . and_then ( |s| s. to_str ( ) )
294+ . map ( |s| ( entry. path ( ) , s. to_string ( ) ) )
295+ } )
296+ . collect ( ) ;
297+
298+ for ( path, filename) in & files {
299+ if path. extension ( ) == Some ( OsStr :: new ( "so" ) ) {
300+ if filename. starts_with ( "librustc_driver" ) {
301+ self . lib_rustc = Some ( path. clone ( ) ) ;
302+ } else if filename. starts_with ( "libstd" ) {
303+ self . lib_std = Some ( path. clone ( ) ) ;
304+ } else if filename. starts_with ( "libtest" ) {
305+ self . lib_test = Some ( path. clone ( ) ) ;
301306 }
302307 }
303308 }
309+
310+ // In older toolchains, the LLVM library is stored as libLLVM-<version>.so
311+ // In newer ones, this file is only a linker shim that actually redirects to
312+ // libLLVM.so.<version>.
313+ // So we need to check if we have the new name, and use it.
314+ // If not, we want to look up the original name.
315+ let new_llvm = files
316+ . iter ( )
317+ . find ( |( _, filename) | filename. starts_with ( "libLLVM.so" ) ) ;
318+ let old_llvm = files. iter ( ) . find ( |( path, filename) | {
319+ path. extension ( ) == Some ( OsStr :: new ( "so" ) ) && filename. starts_with ( "libLLVM" )
320+ } ) ;
321+ self . lib_llvm = new_llvm. or ( old_llvm) . map ( |( path, _) | path. clone ( ) ) ;
322+
304323 Ok ( ( ) )
305324 }
306325}
0 commit comments