diff --git a/src/lib.rs b/src/lib.rs index 284463e4d..a16e8967e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1016,7 +1016,7 @@ impl Build { None => "none", }; if cudart != "none" { - if let Some(nvcc) = which(&self.get_compiler().path) { + if let Some(nvcc) = which(&self.get_compiler().path, None) { // Try to figure out the -L search path. If it fails, // it's on user to specify one by passing it through // RUSTFLAGS environment variable. @@ -2496,7 +2496,15 @@ impl Build { None => default_ar, } } else { - default_ar + let compiler = self.get_base_compiler()?; + if compiler.family == ToolFamily::Clang { + match find_llvm_ar(&mut self.cmd(&compiler.path)) { + Some(ar) => ar.to_str().unwrap().to_owned(), + None => default_ar, + } + } else { + default_ar + } }; Ok((self.cmd(&program), program)) } @@ -3242,7 +3250,7 @@ fn map_darwin_target_from_rust_to_compiler_architecture(target: &str) -> Option< } } -fn which(tool: &Path) -> Option { +fn which(tool: &Path, path_entries: Option) -> Option { fn check_exe(exe: &mut PathBuf) -> bool { let exe_ext = std::env::consts::EXE_EXTENSION; exe.exists() || (!exe_ext.is_empty() && exe.set_extension(exe_ext) && exe.exists()) @@ -3255,9 +3263,23 @@ fn which(tool: &Path) -> Option { } // Loop through PATH entries searching for the |tool|. - let path_entries = env::var_os("PATH")?; + let path_entries = path_entries.or(env::var_os("PATH"))?; env::split_paths(&path_entries).find_map(|path_entry| { let mut exe = path_entry.join(tool); return if check_exe(&mut exe) { Some(exe) } else { None }; }) } + +// search for 'llvm-ar' on 'programs' path in 'clang -print-search-dirs' output +fn find_llvm_ar(clang: &mut Command) -> Option { + let search_dirs = run_output(clang.arg("-print-search-dirs"), "clang").ok()?; + // clang driver appears to be forcing UTF-8 output even on Windows, + // hence from_utf8 is assumed to be usable in all cases. + let search_dirs = std::str::from_utf8(&search_dirs).ok()?; + for dirs in search_dirs.split(|c| c == '\r' || c == '\n') { + if dirs.starts_with("programs: =") { + return which(Path::new("llvm-ar"), Some(OsString::from(&dirs[11..]))); + } + } + None +}