@@ -1120,7 +1120,7 @@ impl Build {
11201120            None  => "none" , 
11211121        } ; 
11221122        if  cudart != "none"  { 
1123-             if  let  Some ( nvcc)  = which ( & self . get_compiler ( ) . path )  { 
1123+             if  let  Some ( nvcc)  = which ( & self . get_compiler ( ) . path ,   None )  { 
11241124                // Try to figure out the -L search path. If it fails, 
11251125                // it's on user to specify one by passing it through 
11261126                // RUSTFLAGS environment variable. 
@@ -2798,6 +2798,20 @@ impl Build {
27982798                        name = format ! ( "em{}" ,  tool) ; 
27992799                        Some ( self . cmd ( & name) ) 
28002800                    } 
2801+                 }  else  if  target. starts_with ( "wasm32" )  { 
2802+                     // Formally speaking one should be able to use this approach, 
2803+                     // parsing -print-search-dirs output, to cover all clang targets, 
2804+                     // including Android SDKs and other cross-compilation scenarios... 
2805+                     // And even extend it to gcc targets by seaching for "ar" instead 
2806+                     // of "llvm-ar"... 
2807+                     let  compiler = self . get_base_compiler ( ) . ok ( ) ?; 
2808+                     if  compiler. family  == ToolFamily :: Clang  { 
2809+                         name = format ! ( "llvm-{}" ,  tool) ; 
2810+                         search_programs ( & mut  self . cmd ( & compiler. path ) ,  & name) 
2811+                             . map ( |name| self . cmd ( & name) ) 
2812+                     }  else  { 
2813+                         None 
2814+                     } 
28012815                }  else  { 
28022816                    None 
28032817                } 
@@ -2824,10 +2838,10 @@ impl Build {
28242838                        // next to 'clang-cl' and use 'search_programs()' to locate 
28252839                        // 'llvm-lib'. This is because 'clang-cl' doesn't support 
28262840                        // the -print-search-dirs option. 
2827-                         if  let  Some ( mut  cmd)  = which ( & compiler. path )  { 
2841+                         if  let  Some ( mut  cmd)  = which ( & compiler. path ,   None )  { 
28282842                            cmd. pop ( ) ; 
28292843                            cmd. push ( "llvm-lib.exe" ) ; 
2830-                             if  let  Some ( llvm_lib)  = which ( & cmd)  { 
2844+                             if  let  Some ( llvm_lib)  = which ( & cmd,   None )  { 
28312845                                lib = llvm_lib. to_str ( ) . unwrap ( ) . to_owned ( ) ; 
28322846                            } 
28332847                        } 
@@ -3684,7 +3698,7 @@ fn map_darwin_target_from_rust_to_compiler_architecture(target: &str) -> Option<
36843698    } 
36853699} 
36863700
3687- fn  which ( tool :  & Path )  -> Option < PathBuf >  { 
3701+ fn  which ( tool :  & Path ,   path_entries :   Option < OsString > )  -> Option < PathBuf >  { 
36883702    fn  check_exe ( exe :  & mut  PathBuf )  -> bool  { 
36893703        let  exe_ext = std:: env:: consts:: EXE_EXTENSION ; 
36903704        exe. exists ( )  || ( !exe_ext. is_empty ( )  && exe. set_extension ( exe_ext)  && exe. exists ( ) ) 
@@ -3697,13 +3711,27 @@ fn which(tool: &Path) -> Option<PathBuf> {
36973711    } 
36983712
36993713    // Loop through PATH entries searching for the |tool|. 
3700-     let  path_entries = env:: var_os ( "PATH" ) ?; 
3714+     let  path_entries = path_entries . or ( env:: var_os ( "PATH" ) ) ?; 
37013715    env:: split_paths ( & path_entries) . find_map ( |path_entry| { 
37023716        let  mut  exe = path_entry. join ( tool) ; 
37033717        return  if  check_exe ( & mut  exe)  {  Some ( exe)  }  else  {  None  } ; 
37043718    } ) 
37053719} 
37063720
3721+ // search for |prog| on 'programs' path in '|cc| -print-search-dirs' output 
3722+ fn  search_programs ( cc :  & mut  Command ,  prog :  & str )  -> Option < PathBuf >  { 
3723+     let  search_dirs = run_output ( cc. arg ( "-print-search-dirs" ) ,  "cc" ) . ok ( ) ?; 
3724+     // clang driver appears to be forcing UTF-8 output even on Windows, 
3725+     // hence from_utf8 is assumed to be usable in all cases. 
3726+     let  search_dirs = std:: str:: from_utf8 ( & search_dirs) . ok ( ) ?; 
3727+     for  dirs in  search_dirs. split ( |c| c == '\r'  || c == '\n' )  { 
3728+         if  let  Some ( path)  = dirs. strip_prefix ( "programs: =" )  { 
3729+             return  which ( Path :: new ( prog) ,  Some ( OsString :: from ( path) ) ) ; 
3730+         } 
3731+     } 
3732+     None 
3733+ } 
3734+ 
37073735#[ derive( Clone ,  Copy ,  PartialEq ) ]  
37083736enum  AsmFileExt  { 
37093737    /// `.asm` files. On MSVC targets, we assume these should be passed to MASM 
0 commit comments