@@ -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