Skip to content

Commit 1dd32c3

Browse files
committed
Default to llvm-ar when compiling with clang.
Accompanying llvm-ar supports all the targets supported by clang. Defaulting to llvm-ar facilitates cases when system ar(1) doesn't support a cross-compile target.
1 parent 030baed commit 1dd32c3

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
@@ -1016,7 +1016,7 @@ impl Build {
10161016
None => "none",
10171017
};
10181018
if cudart != "none" {
1019-
if let Some(nvcc) = which(&self.get_compiler().path) {
1019+
if let Some(nvcc) = which(&self.get_compiler().path, None) {
10201020
// Try to figure out the -L search path. If it fails,
10211021
// it's on user to specify one by passing it through
10221022
// RUSTFLAGS environment variable.
@@ -2496,7 +2496,15 @@ impl Build {
24962496
None => default_ar,
24972497
}
24982498
} else {
2499-
default_ar
2499+
let compiler = self.get_base_compiler()?;
2500+
if compiler.family == ToolFamily::Clang {
2501+
match find_llvm_ar(&mut self.cmd(&compiler.path)) {
2502+
Some(ar) => ar.to_str().unwrap().to_owned(),
2503+
None => default_ar,
2504+
}
2505+
} else {
2506+
default_ar
2507+
}
25002508
};
25012509
Ok((self.cmd(&program), program))
25022510
}
@@ -3242,7 +3250,7 @@ fn map_darwin_target_from_rust_to_compiler_architecture(target: &str) -> Option<
32423250
}
32433251
}
32443252

3245-
fn which(tool: &Path) -> Option<PathBuf> {
3253+
fn which(tool: &Path, path_entries: Option<OsString>) -> Option<PathBuf> {
32463254
fn check_exe(exe: &mut PathBuf) -> bool {
32473255
let exe_ext = std::env::consts::EXE_EXTENSION;
32483256
exe.exists() || (!exe_ext.is_empty() && exe.set_extension(exe_ext) && exe.exists())
@@ -3255,9 +3263,23 @@ fn which(tool: &Path) -> Option<PathBuf> {
32553263
}
32563264

32573265
// Loop through PATH entries searching for the |tool|.
3258-
let path_entries = env::var_os("PATH")?;
3266+
let path_entries = path_entries.or(env::var_os("PATH"))?;
32593267
env::split_paths(&path_entries).find_map(|path_entry| {
32603268
let mut exe = path_entry.join(tool);
32613269
return if check_exe(&mut exe) { Some(exe) } else { None };
32623270
})
32633271
}
3272+
3273+
// search for 'llvm-ar' on 'programs' path in 'clang -print-search-dirs' output
3274+
fn find_llvm_ar(clang: &mut Command) -> Option<PathBuf> {
3275+
let search_dirs = run_output(clang.arg("-print-search-dirs"), "clang").ok()?;
3276+
// clang driver appears to be forcing UTF-8 output even on Windows,
3277+
// hence from_utf8 is assumed to be usable in all cases.
3278+
let search_dirs = std::str::from_utf8(&search_dirs).ok()?;
3279+
for dirs in search_dirs.split(|c| c == '\r' || c == '\n') {
3280+
if dirs.starts_with("programs: =") {
3281+
return which(Path::new("llvm-ar"), Some(OsString::from(&dirs[11..])));
3282+
}
3283+
}
3284+
None
3285+
}

0 commit comments

Comments
 (0)