@@ -1029,7 +1029,7 @@ impl Build {
10291029 None => "none" ,
10301030 } ;
10311031 if cudart != "none" {
1032- if let Some ( nvcc) = which ( & self . get_compiler ( ) . path ) {
1032+ if let Some ( nvcc) = which ( & self . get_compiler ( ) . path , None ) {
10331033 // Try to figure out the -L search path. If it fails,
10341034 // it's on user to specify one by passing it through
10351035 // RUSTFLAGS environment variable.
@@ -2533,6 +2533,21 @@ impl Build {
25332533 }
25342534 None => default_ar,
25352535 }
2536+ } else if target. starts_with ( "wasm32" ) {
2537+ // Formally speaking one should be able to use this approach,
2538+ // parsing -print-search-dirs output, to cover all clang targets,
2539+ // including Android SDKs and other cross-compilation scenarios...
2540+ // And even extend it to gcc targets by seaching for "ar" instead
2541+ // of "llvm-ar"...
2542+ let compiler = self . get_base_compiler ( ) ?;
2543+ if compiler. family == ToolFamily :: Clang {
2544+ match search_programs ( & mut self . cmd ( & compiler. path ) , "llvm-ar" ) {
2545+ Some ( ar) => ar. to_str ( ) . unwrap ( ) . to_owned ( ) ,
2546+ None => default_ar,
2547+ }
2548+ } else {
2549+ default_ar
2550+ }
25362551 } else {
25372552 default_ar
25382553 } ;
@@ -3280,7 +3295,7 @@ fn map_darwin_target_from_rust_to_compiler_architecture(target: &str) -> Option<
32803295 }
32813296}
32823297
3283- fn which ( tool : & Path ) -> Option < PathBuf > {
3298+ fn which ( tool : & Path , path_entries : Option < OsString > ) -> Option < PathBuf > {
32843299 fn check_exe ( exe : & mut PathBuf ) -> bool {
32853300 let exe_ext = std:: env:: consts:: EXE_EXTENSION ;
32863301 exe. exists ( ) || ( !exe_ext. is_empty ( ) && exe. set_extension ( exe_ext) && exe. exists ( ) )
@@ -3293,9 +3308,23 @@ fn which(tool: &Path) -> Option<PathBuf> {
32933308 }
32943309
32953310 // Loop through PATH entries searching for the |tool|.
3296- let path_entries = env:: var_os ( "PATH" ) ?;
3311+ let path_entries = path_entries . or ( env:: var_os ( "PATH" ) ) ?;
32973312 env:: split_paths ( & path_entries) . find_map ( |path_entry| {
32983313 let mut exe = path_entry. join ( tool) ;
32993314 return if check_exe ( & mut exe) { Some ( exe) } else { None } ;
33003315 } )
33013316}
3317+
3318+ // search for |prog| on 'programs' path in '|cc| -print-search-dirs' output
3319+ fn search_programs ( cc : & mut Command , prog : & str ) -> Option < PathBuf > {
3320+ let search_dirs = run_output ( cc. arg ( "-print-search-dirs" ) , "cc" ) . ok ( ) ?;
3321+ // clang driver appears to be forcing UTF-8 output even on Windows,
3322+ // hence from_utf8 is assumed to be usable in all cases.
3323+ let search_dirs = std:: str:: from_utf8 ( & search_dirs) . ok ( ) ?;
3324+ for dirs in search_dirs. split ( |c| c == '\r' || c == '\n' ) {
3325+ if dirs. starts_with ( "programs: =" ) {
3326+ return which ( Path :: new ( prog) , Some ( OsString :: from ( & dirs[ 11 ..] ) ) ) ;
3327+ }
3328+ }
3329+ None
3330+ }
0 commit comments