Skip to content

Commit

Permalink
Default to llvm-ar when compiling with clang.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dot-asm committed Feb 14, 2022
1 parent 030baed commit 1dd32c3
Showing 1 changed file with 26 additions and 4 deletions.
30 changes: 26 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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))
}
Expand Down Expand Up @@ -3242,7 +3250,7 @@ fn map_darwin_target_from_rust_to_compiler_architecture(target: &str) -> Option<
}
}

fn which(tool: &Path) -> Option<PathBuf> {
fn which(tool: &Path, path_entries: Option<OsString>) -> Option<PathBuf> {
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())
Expand All @@ -3255,9 +3263,23 @@ fn which(tool: &Path) -> Option<PathBuf> {
}

// 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<PathBuf> {
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
}

0 comments on commit 1dd32c3

Please sign in to comment.