Skip to content

Commit 81bf238

Browse files
committed
Default to llvm-ar when compiling with clang.
Defaulting to llvm-ar facilitates cases when system ar(1) doesn't support any given cross-compile target. This is because accompanying llvm-ar is known to match targets supported by the clang installation at hand.
1 parent 8159cda commit 81bf238

File tree

1 file changed

+26
-4
lines changed

1 file changed

+26
-4
lines changed

src/lib.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
@@ -2534,7 +2534,15 @@ impl Build {
25342534
None => default_ar,
25352535
}
25362536
} else {
2537-
default_ar
2537+
let compiler = self.get_base_compiler()?;
2538+
if compiler.family == ToolFamily::Clang {
2539+
match search_programs(&mut self.cmd(&compiler.path), "llvm-ar") {
2540+
Some(ar) => ar.to_str().unwrap().to_owned(),
2541+
None => default_ar,
2542+
}
2543+
} else {
2544+
default_ar
2545+
}
25382546
};
25392547
Ok((self.cmd(&program), program))
25402548
}
@@ -3280,7 +3288,7 @@ fn map_darwin_target_from_rust_to_compiler_architecture(target: &str) -> Option<
32803288
}
32813289
}
32823290

3283-
fn which(tool: &Path) -> Option<PathBuf> {
3291+
fn which(tool: &Path, path_entries: Option<OsString>) -> Option<PathBuf> {
32843292
fn check_exe(exe: &mut PathBuf) -> bool {
32853293
let exe_ext = std::env::consts::EXE_EXTENSION;
32863294
exe.exists() || (!exe_ext.is_empty() && exe.set_extension(exe_ext) && exe.exists())
@@ -3293,9 +3301,23 @@ fn which(tool: &Path) -> Option<PathBuf> {
32933301
}
32943302

32953303
// Loop through PATH entries searching for the |tool|.
3296-
let path_entries = env::var_os("PATH")?;
3304+
let path_entries = path_entries.or(env::var_os("PATH"))?;
32973305
env::split_paths(&path_entries).find_map(|path_entry| {
32983306
let mut exe = path_entry.join(tool);
32993307
return if check_exe(&mut exe) { Some(exe) } else { None };
33003308
})
33013309
}
3310+
3311+
// search for |prog| on 'programs' path in '|cc| -print-search-dirs' output
3312+
fn search_programs(cc: &mut Command, prog: &str) -> Option<PathBuf> {
3313+
let search_dirs = run_output(cc.arg("-print-search-dirs"), "cc").ok()?;
3314+
// clang driver appears to be forcing UTF-8 output even on Windows,
3315+
// hence from_utf8 is assumed to be usable in all cases.
3316+
let search_dirs = std::str::from_utf8(&search_dirs).ok()?;
3317+
for dirs in search_dirs.split(|c| c == '\r' || c == '\n') {
3318+
if dirs.starts_with("programs: =") {
3319+
return which(Path::new(prog), Some(OsString::from(&dirs[11..])));
3320+
}
3321+
}
3322+
None
3323+
}

0 commit comments

Comments
 (0)