@@ -129,12 +129,15 @@ impl SysrootDownload {
129129 } )
130130 } ;
131131
132+ let host_libdir = self . directory . join ( & self . rust_sha ) . join ( "lib" ) ;
133+ let target_libdir = target_libdir_from_host_libdir ( & host_libdir, & self . triple ) ;
132134 let components = ToolchainComponents :: from_binaries_and_libdir (
133135 sysroot_bin ( "rustc" ) ?,
134136 Some ( sysroot_bin ( "rustdoc" ) ?) ,
135137 sysroot_bin ( "clippy-driver" ) . ok ( ) ,
136138 sysroot_bin ( "cargo" ) ?,
137- & self . directory . join ( & self . rust_sha ) . join ( "lib" ) ,
139+ & host_libdir,
140+ & target_libdir,
138141 ) ?;
139142
140143 Ok ( Sysroot {
@@ -230,6 +233,10 @@ impl SysrootDownload {
230233 }
231234}
232235
236+ fn target_libdir_from_host_libdir ( dir : & Path , target : & str ) -> PathBuf {
237+ dir. join ( "rustlib" ) . join ( target) . join ( "lib" )
238+ }
239+
233240/// Representation of a toolchain that can be used to compile Rust programs.
234241#[ derive( Debug , Clone ) ]
235242pub struct Toolchain {
@@ -266,7 +273,8 @@ impl ToolchainComponents {
266273 rustdoc : Option < PathBuf > ,
267274 clippy : Option < PathBuf > ,
268275 cargo : PathBuf ,
269- libdir : & Path ,
276+ host_libdir : & Path ,
277+ target_libdir : & Path ,
270278 ) -> anyhow:: Result < Self > {
271279 let mut component = ToolchainComponents {
272280 rustc,
@@ -275,34 +283,41 @@ impl ToolchainComponents {
275283 cargo,
276284 ..Default :: default ( )
277285 } ;
278- component. fill_libraries ( libdir ) ?;
286+ component. fill_libraries ( host_libdir , target_libdir ) ?;
279287 Ok ( component)
280288 }
281289
282290 /// Finds known library components in the given `dir` and stores them in `self`.
283- fn fill_libraries ( & mut self , dir : & Path ) -> anyhow:: Result < ( ) > {
284- let files: Vec < ( PathBuf , String ) > = fs:: read_dir ( dir)
285- . with_context ( || format ! ( "Cannot read lib dir `{}` to find components" , dir. display( ) ) ) ?
286- . map ( |entry| Ok ( entry?) )
287- . collect :: < anyhow:: Result < Vec < _ > > > ( ) ?
288- . into_iter ( )
289- . filter ( |entry| entry. path ( ) . is_file ( ) )
290- . filter_map ( |entry| {
291- entry
292- . path ( )
293- . file_name ( )
294- . and_then ( |s| s. to_str ( ) )
295- . map ( |s| ( entry. path ( ) , s. to_string ( ) ) )
296- } )
297- . collect ( ) ;
298-
299- for ( path, filename) in & files {
300- if path. extension ( ) == Some ( OsStr :: new ( "so" ) ) {
301- if filename. starts_with ( "librustc_driver" ) {
302- self . lib_rustc = Some ( path. clone ( ) ) ;
303- } else if filename. starts_with ( "libstd" ) {
304- self . lib_std = Some ( path. clone ( ) ) ;
305- }
291+ fn fill_libraries ( & mut self , host_libdir : & Path , target_libdir : & Path ) -> anyhow:: Result < ( ) > {
292+ let load_files = |path : & Path | -> anyhow:: Result < Vec < ( PathBuf , String ) > > {
293+ let files = fs:: read_dir ( path)
294+ . with_context ( || {
295+ format ! (
296+ "Cannot read lib dir `{}` to find components" ,
297+ path. display( )
298+ )
299+ } ) ?
300+ . map ( |entry| Ok ( entry?) )
301+ . collect :: < anyhow:: Result < Vec < _ > > > ( ) ?
302+ . into_iter ( )
303+ . filter ( |entry| entry. path ( ) . is_file ( ) )
304+ . filter_map ( |entry| {
305+ entry
306+ . path ( )
307+ . file_name ( )
308+ . and_then ( |s| s. to_str ( ) )
309+ . map ( |s| ( entry. path ( ) , s. to_string ( ) ) )
310+ } )
311+ . collect ( ) ;
312+ Ok ( files)
313+ } ;
314+
315+ // Look for librustc_driver.so and libLLVM.so in the *host* libdir
316+ let host_files = load_files ( host_libdir) ?;
317+ for ( path, filename) in & host_files {
318+ if path. extension ( ) == Some ( OsStr :: new ( "so" ) ) && filename. starts_with ( "librustc_driver" )
319+ {
320+ self . lib_rustc = Some ( path. clone ( ) ) ;
306321 }
307322 }
308323
@@ -311,14 +326,22 @@ impl ToolchainComponents {
311326 // libLLVM.so.<version>.
312327 // So we need to check if we have the new name, and use it.
313328 // If not, we want to look up the original name.
314- let new_llvm = files
329+ let new_llvm = host_files
315330 . iter ( )
316331 . find ( |( _, filename) | filename. starts_with ( "libLLVM.so" ) ) ;
317- let old_llvm = files . iter ( ) . find ( |( path, filename) | {
332+ let old_llvm = host_files . iter ( ) . find ( |( path, filename) | {
318333 path. extension ( ) == Some ( OsStr :: new ( "so" ) ) && filename. starts_with ( "libLLVM" )
319334 } ) ;
320335 self . lib_llvm = new_llvm. or ( old_llvm) . map ( |( path, _) | path. clone ( ) ) ;
321336
337+ // Now find libstd in the *target* libdir
338+ let target_files = load_files ( target_libdir) ?;
339+ for ( path, filename) in target_files {
340+ if path. extension ( ) == Some ( OsStr :: new ( "so" ) ) && filename. starts_with ( "libstd" ) {
341+ self . lib_std = Some ( path. clone ( ) ) ;
342+ }
343+ }
344+
322345 Ok ( ( ) )
323346 }
324347}
@@ -523,10 +546,17 @@ pub fn get_local_toolchain(
523546 debug ! ( "found cargo: {:?}" , & cargo) ;
524547 cargo
525548 } ;
526- let lib_dir = get_lib_dir_from_rustc ( & rustc) . context ( "Cannot find libdir for rustc" ) ?;
549+ let host_lib_dir = get_lib_dir_from_rustc ( & rustc) . context ( "Cannot find libdir for rustc" ) ?;
550+ let target_lib_dir = target_libdir_from_host_libdir ( & host_lib_dir, & target_triple) ;
527551
528- let mut components =
529- ToolchainComponents :: from_binaries_and_libdir ( rustc, rustdoc, clippy, cargo, & lib_dir) ?;
552+ let mut components = ToolchainComponents :: from_binaries_and_libdir (
553+ rustc,
554+ rustdoc,
555+ clippy,
556+ cargo,
557+ & host_lib_dir,
558+ & target_lib_dir,
559+ ) ?;
530560 components. cargo_configs = toolchain_config. cargo_configs . to_vec ( ) ;
531561 Ok ( Toolchain {
532562 components,
@@ -574,14 +604,16 @@ pub fn create_toolchain_from_published_version(
574604 debug ! ( "Found clippy: {}" , clippy. display( ) ) ;
575605 debug ! ( "Found cargo: {}" , cargo. display( ) ) ;
576606
577- let lib_dir = get_lib_dir_from_rustc ( & rustc) ?;
607+ let host_lib_dir = get_lib_dir_from_rustc ( & rustc) ?;
608+ let target_lib_dir = target_libdir_from_host_libdir ( & host_lib_dir, target_triple) ;
578609
579610 let components = ToolchainComponents :: from_binaries_and_libdir (
580611 rustc,
581612 Some ( rustdoc) ,
582613 Some ( clippy) ,
583614 cargo,
584- & lib_dir,
615+ & host_lib_dir,
616+ & target_lib_dir,
585617 ) ?;
586618
587619 Ok ( Toolchain {
@@ -619,14 +651,21 @@ mod tests {
619651 fn fill_libraries ( ) {
620652 let mut components = ToolchainComponents :: default ( ) ;
621653
622- // create mock dir and libraries
623654 let temp_dir: tempfile:: TempDir = tempfile:: tempdir ( ) . unwrap ( ) ;
624- let lib_rustc_path = create_temp_lib_path ( "librustc_driver.so" , & temp_dir) ;
625- let lib_std_path = create_temp_lib_path ( "libstd.so" , & temp_dir) ;
626- let lib_new_llvm_path =
627- create_temp_lib_path ( "libLLVM.so.18.1-rust-1.78.0-nightly" , & temp_dir) ;
655+ let host_libdir = temp_dir. path ( ) ;
656+ let target_libdir = target_libdir_from_host_libdir ( host_libdir, "foo" ) ;
657+ std:: fs:: create_dir_all ( & target_libdir) . unwrap ( ) ;
658+
659+ let lib_rustc_path = create_lib ( host_libdir, "librustc_driver.so" ) ;
660+ let lib_std_path = create_lib (
661+ & host_libdir. join ( "rustlib" ) . join ( "foo" ) . join ( "lib" ) ,
662+ "libstd.so" ,
663+ ) ;
664+ let lib_new_llvm_path = create_lib ( host_libdir, "libLLVM.so.18.1-rust-1.78.0-nightly" ) ;
628665
629- components. fill_libraries ( temp_dir. path ( ) ) . unwrap ( ) ;
666+ components
667+ . fill_libraries ( host_libdir, & target_libdir)
668+ . unwrap ( ) ;
630669
631670 assert_eq ! ( components. lib_rustc, Some ( lib_rustc_path) ) ;
632671 assert_eq ! ( components. lib_std, Some ( lib_std_path) ) ;
@@ -640,18 +679,25 @@ mod tests {
640679
641680 // create mock dir and libraries
642681 let temp_dir: tempfile:: TempDir = tempfile:: tempdir ( ) . unwrap ( ) ;
643- let lib_old_llvm_path = create_temp_lib_path ( lib_old_llvm, & temp_dir) ;
682+ let host_libdir = temp_dir. path ( ) ;
683+ let target_libdir = target_libdir_from_host_libdir ( host_libdir, "foo" ) ;
684+ std:: fs:: create_dir_all ( & target_libdir) . unwrap ( ) ;
685+
686+ let lib_old_llvm_path = create_lib ( host_libdir, lib_old_llvm) ;
644687
645- components. fill_libraries ( temp_dir. path ( ) ) . unwrap ( ) ;
688+ components
689+ . fill_libraries (
690+ host_libdir,
691+ & target_libdir_from_host_libdir ( temp_dir. path ( ) , "foo" ) ,
692+ )
693+ . unwrap ( ) ;
646694
647695 assert_eq ! ( components. lib_llvm, Some ( lib_old_llvm_path) ) ;
648696 }
649697
650- fn create_temp_lib_path ( lib_name : & str , temp_dir : & tempfile:: TempDir ) -> PathBuf {
651- let lib_path = temp_dir. path ( ) . join ( lib_name) ;
652- // create mock file
698+ fn create_lib ( path : & Path , lib_name : & str ) -> PathBuf {
699+ let lib_path = path. join ( lib_name) ;
653700 File :: create ( & lib_path) . unwrap ( ) ;
654-
655701 lib_path
656702 }
657703}
0 commit comments