@@ -1106,7 +1106,7 @@ impl Build {
11061106 None => "none" ,
11071107 } ;
11081108 if cudart != "none" {
1109- if let Some ( nvcc) = which ( & self . get_compiler ( ) . path ) {
1109+ if let Some ( nvcc) = which ( & self . get_compiler ( ) . path , None ) {
11101110 // Try to figure out the -L search path. If it fails,
11111111 // it's on user to specify one by passing it through
11121112 // RUSTFLAGS environment variable.
@@ -2664,6 +2664,21 @@ impl Build {
26642664 }
26652665
26662666 "emar" . to_string ( )
2667+ } else if target. starts_with ( "wasm32" ) {
2668+ // Formally speaking one should be able to use this approach,
2669+ // parsing -print-search-dirs output, to cover all clang targets,
2670+ // including Android SDKs and other cross-compilation scenarios...
2671+ // And even extend it to gcc targets by seaching for "ar" instead
2672+ // of "llvm-ar"...
2673+ let compiler = self . get_base_compiler ( ) ?;
2674+ if compiler. family == ToolFamily :: Clang {
2675+ match search_programs ( & mut self . cmd ( & compiler. path ) , "llvm-ar" ) {
2676+ Some ( ar) => ar. to_str ( ) . unwrap ( ) . to_owned ( ) ,
2677+ None => default_ar,
2678+ }
2679+ } else {
2680+ default_ar
2681+ }
26672682 } else if target. contains ( "msvc" ) {
26682683 let compiler = self . get_base_compiler ( ) ?;
26692684 let mut lib = String :: new ( ) ;
@@ -2673,10 +2688,10 @@ impl Build {
26732688 // next to 'clang-cl' and use 'search_programs()' to locate
26742689 // 'llvm-lib'. This is because 'clang-cl' doesn't support
26752690 // the -print-search-dirs option.
2676- if let Some ( mut cmd) = which ( & compiler. path ) {
2691+ if let Some ( mut cmd) = which ( & compiler. path , None ) {
26772692 cmd. pop ( ) ;
26782693 cmd. push ( "llvm-lib.exe" ) ;
2679- if let Some ( llvm_lib) = which ( & cmd) {
2694+ if let Some ( llvm_lib) = which ( & cmd, None ) {
26802695 lib = llvm_lib. to_str ( ) . unwrap ( ) . to_owned ( ) ;
26812696 }
26822697 }
@@ -3522,7 +3537,7 @@ fn map_darwin_target_from_rust_to_compiler_architecture(target: &str) -> Option<
35223537 }
35233538}
35243539
3525- fn which ( tool : & Path ) -> Option < PathBuf > {
3540+ fn which ( tool : & Path , path_entries : Option < OsString > ) -> Option < PathBuf > {
35263541 fn check_exe ( exe : & mut PathBuf ) -> bool {
35273542 let exe_ext = std:: env:: consts:: EXE_EXTENSION ;
35283543 exe. exists ( ) || ( !exe_ext. is_empty ( ) && exe. set_extension ( exe_ext) && exe. exists ( ) )
@@ -3535,7 +3550,7 @@ fn which(tool: &Path) -> Option<PathBuf> {
35353550 }
35363551
35373552 // Loop through PATH entries searching for the |tool|.
3538- let path_entries = env:: var_os ( "PATH" ) ?;
3553+ let path_entries = path_entries . or ( env:: var_os ( "PATH" ) ) ?;
35393554 env:: split_paths ( & path_entries) . find_map ( |path_entry| {
35403555 let mut exe = path_entry. join ( tool) ;
35413556 return if check_exe ( & mut exe) { Some ( exe) } else { None } ;
@@ -3566,3 +3581,17 @@ impl AsmFileExt {
35663581 None
35673582 }
35683583}
3584+
3585+ // search for |prog| on 'programs' path in '|cc| -print-search-dirs' output
3586+ fn search_programs ( cc : & mut Command , prog : & str ) -> Option < PathBuf > {
3587+ let search_dirs = run_output ( cc. arg ( "-print-search-dirs" ) , "cc" ) . ok ( ) ?;
3588+ // clang driver appears to be forcing UTF-8 output even on Windows,
3589+ // hence from_utf8 is assumed to be usable in all cases.
3590+ let search_dirs = std:: str:: from_utf8 ( & search_dirs) . ok ( ) ?;
3591+ for dirs in search_dirs. split ( |c| c == '\r' || c == '\n' ) {
3592+ if dirs. starts_with ( "programs: =" ) {
3593+ return which ( Path :: new ( prog) , Some ( OsString :: from ( & dirs[ 11 ..] ) ) ) ;
3594+ }
3595+ }
3596+ None
3597+ }
0 commit comments