Skip to content

Commit 58e66f5

Browse files
authored
Default to llvm-ar when compiling for wasm. (#657)
1 parent c60f69a commit 58e66f5

File tree

1 file changed

+33
-5
lines changed

1 file changed

+33
-5
lines changed

src/lib.rs

+33-5
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,7 @@ impl Build {
11201120
None => "none",
11211121
};
11221122
if cudart != "none" {
1123-
if let Some(nvcc) = which(&self.get_compiler().path) {
1123+
if let Some(nvcc) = which(&self.get_compiler().path, None) {
11241124
// Try to figure out the -L search path. If it fails,
11251125
// it's on user to specify one by passing it through
11261126
// RUSTFLAGS environment variable.
@@ -2798,6 +2798,20 @@ impl Build {
27982798
name = format!("em{}", tool);
27992799
Some(self.cmd(&name))
28002800
}
2801+
} else if target.starts_with("wasm32") {
2802+
// Formally speaking one should be able to use this approach,
2803+
// parsing -print-search-dirs output, to cover all clang targets,
2804+
// including Android SDKs and other cross-compilation scenarios...
2805+
// And even extend it to gcc targets by seaching for "ar" instead
2806+
// of "llvm-ar"...
2807+
let compiler = self.get_base_compiler().ok()?;
2808+
if compiler.family == ToolFamily::Clang {
2809+
name = format!("llvm-{}", tool);
2810+
search_programs(&mut self.cmd(&compiler.path), &name)
2811+
.map(|name| self.cmd(&name))
2812+
} else {
2813+
None
2814+
}
28012815
} else {
28022816
None
28032817
}
@@ -2824,10 +2838,10 @@ impl Build {
28242838
// next to 'clang-cl' and use 'search_programs()' to locate
28252839
// 'llvm-lib'. This is because 'clang-cl' doesn't support
28262840
// the -print-search-dirs option.
2827-
if let Some(mut cmd) = which(&compiler.path) {
2841+
if let Some(mut cmd) = which(&compiler.path, None) {
28282842
cmd.pop();
28292843
cmd.push("llvm-lib.exe");
2830-
if let Some(llvm_lib) = which(&cmd) {
2844+
if let Some(llvm_lib) = which(&cmd, None) {
28312845
lib = llvm_lib.to_str().unwrap().to_owned();
28322846
}
28332847
}
@@ -3684,7 +3698,7 @@ fn map_darwin_target_from_rust_to_compiler_architecture(target: &str) -> Option<
36843698
}
36853699
}
36863700

3687-
fn which(tool: &Path) -> Option<PathBuf> {
3701+
fn which(tool: &Path, path_entries: Option<OsString>) -> Option<PathBuf> {
36883702
fn check_exe(exe: &mut PathBuf) -> bool {
36893703
let exe_ext = std::env::consts::EXE_EXTENSION;
36903704
exe.exists() || (!exe_ext.is_empty() && exe.set_extension(exe_ext) && exe.exists())
@@ -3697,13 +3711,27 @@ fn which(tool: &Path) -> Option<PathBuf> {
36973711
}
36983712

36993713
// Loop through PATH entries searching for the |tool|.
3700-
let path_entries = env::var_os("PATH")?;
3714+
let path_entries = path_entries.or(env::var_os("PATH"))?;
37013715
env::split_paths(&path_entries).find_map(|path_entry| {
37023716
let mut exe = path_entry.join(tool);
37033717
return if check_exe(&mut exe) { Some(exe) } else { None };
37043718
})
37053719
}
37063720

3721+
// search for |prog| on 'programs' path in '|cc| -print-search-dirs' output
3722+
fn search_programs(cc: &mut Command, prog: &str) -> Option<PathBuf> {
3723+
let search_dirs = run_output(cc.arg("-print-search-dirs"), "cc").ok()?;
3724+
// clang driver appears to be forcing UTF-8 output even on Windows,
3725+
// hence from_utf8 is assumed to be usable in all cases.
3726+
let search_dirs = std::str::from_utf8(&search_dirs).ok()?;
3727+
for dirs in search_dirs.split(|c| c == '\r' || c == '\n') {
3728+
if let Some(path) = dirs.strip_prefix("programs: =") {
3729+
return which(Path::new(prog), Some(OsString::from(path)));
3730+
}
3731+
}
3732+
None
3733+
}
3734+
37073735
#[derive(Clone, Copy, PartialEq)]
37083736
enum AsmFileExt {
37093737
/// `.asm` files. On MSVC targets, we assume these should be passed to MASM

0 commit comments

Comments
 (0)