@@ -197,12 +197,15 @@ impl SysrootDownload {
197197 } )
198198 } ;
199199
200+ let host_libdir = self . cache_directory . join ( "lib" ) ;
201+ let target_libdir = target_libdir_from_host_libdir ( & host_libdir, & self . triple ) ;
200202 let components = ToolchainComponents :: from_binaries_and_libdir (
201203 sysroot_bin ( "rustc" ) ?,
202204 Some ( sysroot_bin ( "rustdoc" ) ?) ,
203205 sysroot_bin ( "clippy-driver" ) . ok ( ) ,
204206 sysroot_bin ( "cargo" ) ?,
205- & self . cache_directory . join ( "lib" ) ,
207+ & host_libdir,
208+ & target_libdir,
206209 ) ?;
207210
208211 Ok ( Sysroot {
@@ -302,6 +305,10 @@ impl SysrootDownload {
302305 }
303306}
304307
308+ fn target_libdir_from_host_libdir ( dir : & Path , target : & str ) -> PathBuf {
309+ dir. join ( "rustlib" ) . join ( target) . join ( "lib" )
310+ }
311+
305312/// Representation of a toolchain that can be used to compile Rust programs.
306313#[ derive( Debug , Clone ) ]
307314pub struct Toolchain {
@@ -338,7 +345,8 @@ impl ToolchainComponents {
338345 rustdoc : Option < PathBuf > ,
339346 clippy : Option < PathBuf > ,
340347 cargo : PathBuf ,
341- libdir : & Path ,
348+ host_libdir : & Path ,
349+ target_libdir : & Path ,
342350 ) -> anyhow:: Result < Self > {
343351 let mut component = ToolchainComponents {
344352 rustc,
@@ -347,34 +355,41 @@ impl ToolchainComponents {
347355 cargo,
348356 ..Default :: default ( )
349357 } ;
350- component. fill_libraries ( libdir ) ?;
358+ component. fill_libraries ( host_libdir , target_libdir ) ?;
351359 Ok ( component)
352360 }
353361
354362 /// Finds known library components in the given `dir` and stores them in `self`.
355- fn fill_libraries ( & mut self , dir : & Path ) -> anyhow:: Result < ( ) > {
356- let files: Vec < ( PathBuf , String ) > = fs:: read_dir ( dir)
357- . with_context ( || format ! ( "Cannot read lib dir `{}` to find components" , dir. display( ) ) ) ?
358- . map ( |entry| Ok ( entry?) )
359- . collect :: < anyhow:: Result < Vec < _ > > > ( ) ?
360- . into_iter ( )
361- . filter ( |entry| entry. path ( ) . is_file ( ) )
362- . filter_map ( |entry| {
363- entry
364- . path ( )
365- . file_name ( )
366- . and_then ( |s| s. to_str ( ) )
367- . map ( |s| ( entry. path ( ) , s. to_string ( ) ) )
368- } )
369- . collect ( ) ;
370-
371- for ( path, filename) in & files {
372- if path. extension ( ) == Some ( OsStr :: new ( "so" ) ) {
373- if filename. starts_with ( "librustc_driver" ) {
374- self . lib_rustc = Some ( path. clone ( ) ) ;
375- } else if filename. starts_with ( "libstd" ) {
376- self . lib_std = Some ( path. clone ( ) ) ;
377- }
363+ fn fill_libraries ( & mut self , host_libdir : & Path , target_libdir : & Path ) -> anyhow:: Result < ( ) > {
364+ let load_files = |path : & Path | -> anyhow:: Result < Vec < ( PathBuf , String ) > > {
365+ let files = fs:: read_dir ( path)
366+ . with_context ( || {
367+ format ! (
368+ "Cannot read lib dir `{}` to find components" ,
369+ path. display( )
370+ )
371+ } ) ?
372+ . map ( |entry| Ok ( entry?) )
373+ . collect :: < anyhow:: Result < Vec < _ > > > ( ) ?
374+ . into_iter ( )
375+ . filter ( |entry| entry. path ( ) . is_file ( ) )
376+ . filter_map ( |entry| {
377+ entry
378+ . path ( )
379+ . file_name ( )
380+ . and_then ( |s| s. to_str ( ) )
381+ . map ( |s| ( entry. path ( ) , s. to_string ( ) ) )
382+ } )
383+ . collect ( ) ;
384+ Ok ( files)
385+ } ;
386+
387+ // Look for librustc_driver.so and libLLVM.so in the *host* libdir
388+ let host_files = load_files ( host_libdir) ?;
389+ for ( path, filename) in & host_files {
390+ if path. extension ( ) == Some ( OsStr :: new ( "so" ) ) && filename. starts_with ( "librustc_driver" )
391+ {
392+ self . lib_rustc = Some ( path. clone ( ) ) ;
378393 }
379394 }
380395
@@ -383,14 +398,22 @@ impl ToolchainComponents {
383398 // libLLVM.so.<version>.
384399 // So we need to check if we have the new name, and use it.
385400 // If not, we want to look up the original name.
386- let new_llvm = files
401+ let new_llvm = host_files
387402 . iter ( )
388403 . find ( |( _, filename) | filename. starts_with ( "libLLVM.so" ) ) ;
389- let old_llvm = files . iter ( ) . find ( |( path, filename) | {
404+ let old_llvm = host_files . iter ( ) . find ( |( path, filename) | {
390405 path. extension ( ) == Some ( OsStr :: new ( "so" ) ) && filename. starts_with ( "libLLVM" )
391406 } ) ;
392407 self . lib_llvm = new_llvm. or ( old_llvm) . map ( |( path, _) | path. clone ( ) ) ;
393408
409+ // Now find libstd in the *target* libdir
410+ let target_files = load_files ( target_libdir) ?;
411+ for ( path, filename) in target_files {
412+ if path. extension ( ) == Some ( OsStr :: new ( "so" ) ) && filename. starts_with ( "libstd" ) {
413+ self . lib_std = Some ( path. clone ( ) ) ;
414+ }
415+ }
416+
394417 Ok ( ( ) )
395418 }
396419}
@@ -595,10 +618,17 @@ pub fn get_local_toolchain(
595618 debug ! ( "found cargo: {:?}" , & cargo) ;
596619 cargo
597620 } ;
598- let lib_dir = get_lib_dir_from_rustc ( & rustc) . context ( "Cannot find libdir for rustc" ) ?;
621+ let host_lib_dir = get_lib_dir_from_rustc ( & rustc) . context ( "Cannot find libdir for rustc" ) ?;
622+ let target_lib_dir = target_libdir_from_host_libdir ( & host_lib_dir, & target_triple) ;
599623
600- let mut components =
601- ToolchainComponents :: from_binaries_and_libdir ( rustc, rustdoc, clippy, cargo, & lib_dir) ?;
624+ let mut components = ToolchainComponents :: from_binaries_and_libdir (
625+ rustc,
626+ rustdoc,
627+ clippy,
628+ cargo,
629+ & host_lib_dir,
630+ & target_lib_dir,
631+ ) ?;
602632 components. cargo_configs = toolchain_config. cargo_configs . to_vec ( ) ;
603633 Ok ( Toolchain {
604634 components,
@@ -646,14 +676,16 @@ pub fn create_toolchain_from_published_version(
646676 debug ! ( "Found clippy: {}" , clippy. display( ) ) ;
647677 debug ! ( "Found cargo: {}" , cargo. display( ) ) ;
648678
649- let lib_dir = get_lib_dir_from_rustc ( & rustc) ?;
679+ let host_lib_dir = get_lib_dir_from_rustc ( & rustc) ?;
680+ let target_lib_dir = target_libdir_from_host_libdir ( & host_lib_dir, target_triple) ;
650681
651682 let components = ToolchainComponents :: from_binaries_and_libdir (
652683 rustc,
653684 Some ( rustdoc) ,
654685 Some ( clippy) ,
655686 cargo,
656- & lib_dir,
687+ & host_lib_dir,
688+ & target_lib_dir,
657689 ) ?;
658690
659691 Ok ( Toolchain {
@@ -692,14 +724,21 @@ mod tests {
692724 fn fill_libraries ( ) {
693725 let mut components = ToolchainComponents :: default ( ) ;
694726
695- // create mock dir and libraries
696727 let temp_dir: tempfile:: TempDir = tempfile:: tempdir ( ) . unwrap ( ) ;
697- let lib_rustc_path = create_temp_lib_path ( "librustc_driver.so" , & temp_dir) ;
698- let lib_std_path = create_temp_lib_path ( "libstd.so" , & temp_dir) ;
699- let lib_new_llvm_path =
700- create_temp_lib_path ( "libLLVM.so.18.1-rust-1.78.0-nightly" , & temp_dir) ;
728+ let host_libdir = temp_dir. path ( ) ;
729+ let target_libdir = target_libdir_from_host_libdir ( host_libdir, "foo" ) ;
730+ std:: fs:: create_dir_all ( & target_libdir) . unwrap ( ) ;
731+
732+ let lib_rustc_path = create_lib ( host_libdir, "librustc_driver.so" ) ;
733+ let lib_std_path = create_lib (
734+ & host_libdir. join ( "rustlib" ) . join ( "foo" ) . join ( "lib" ) ,
735+ "libstd.so" ,
736+ ) ;
737+ let lib_new_llvm_path = create_lib ( host_libdir, "libLLVM.so.18.1-rust-1.78.0-nightly" ) ;
701738
702- components. fill_libraries ( temp_dir. path ( ) ) . unwrap ( ) ;
739+ components
740+ . fill_libraries ( host_libdir, & target_libdir)
741+ . unwrap ( ) ;
703742
704743 assert_eq ! ( components. lib_rustc, Some ( lib_rustc_path) ) ;
705744 assert_eq ! ( components. lib_std, Some ( lib_std_path) ) ;
@@ -713,18 +752,25 @@ mod tests {
713752
714753 // create mock dir and libraries
715754 let temp_dir: tempfile:: TempDir = tempfile:: tempdir ( ) . unwrap ( ) ;
716- let lib_old_llvm_path = create_temp_lib_path ( lib_old_llvm, & temp_dir) ;
755+ let host_libdir = temp_dir. path ( ) ;
756+ let target_libdir = target_libdir_from_host_libdir ( host_libdir, "foo" ) ;
757+ std:: fs:: create_dir_all ( & target_libdir) . unwrap ( ) ;
758+
759+ let lib_old_llvm_path = create_lib ( host_libdir, lib_old_llvm) ;
717760
718- components. fill_libraries ( temp_dir. path ( ) ) . unwrap ( ) ;
761+ components
762+ . fill_libraries (
763+ host_libdir,
764+ & target_libdir_from_host_libdir ( temp_dir. path ( ) , "foo" ) ,
765+ )
766+ . unwrap ( ) ;
719767
720768 assert_eq ! ( components. lib_llvm, Some ( lib_old_llvm_path) ) ;
721769 }
722770
723- fn create_temp_lib_path ( lib_name : & str , temp_dir : & tempfile:: TempDir ) -> PathBuf {
724- let lib_path = temp_dir. path ( ) . join ( lib_name) ;
725- // create mock file
771+ fn create_lib ( path : & Path , lib_name : & str ) -> PathBuf {
772+ let lib_path = path. join ( lib_name) ;
726773 File :: create ( & lib_path) . unwrap ( ) ;
727-
728774 lib_path
729775 }
730776}
0 commit comments