Skip to content

Commit 8bed330

Browse files
authored
Cache compiler versions detected (#932)
1 parent df59d43 commit 8bed330

File tree

2 files changed

+67
-12
lines changed

2 files changed

+67
-12
lines changed

src/lib.rs

+35-6
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ pub struct Build {
291291
apple_sdk_root_cache: Arc<Mutex<HashMap<String, OsString>>>,
292292
apple_versions_cache: Arc<Mutex<HashMap<String, String>>>,
293293
emit_rerun_if_env_changed: bool,
294+
cached_compiler_family: Arc<Mutex<HashMap<Box<Path>, ToolFamily>>>,
294295
}
295296

296297
/// Represents the types of errors that may occur while using cc-rs.
@@ -406,6 +407,7 @@ impl Build {
406407
apple_sdk_root_cache: Arc::new(Mutex::new(HashMap::new())),
407408
apple_versions_cache: Arc::new(Mutex::new(HashMap::new())),
408409
emit_rerun_if_env_changed: true,
410+
cached_compiler_family: Arc::default(),
409411
}
410412
}
411413

@@ -2603,7 +2605,11 @@ impl Build {
26032605

26042606
fn get_base_compiler(&self) -> Result<Tool, Error> {
26052607
if let Some(c) = &self.compiler {
2606-
return Ok(Tool::new((**c).to_owned(), &self.cargo_output));
2608+
return Ok(Tool::new(
2609+
(**c).to_owned(),
2610+
&self.cached_compiler_family,
2611+
&self.cargo_output,
2612+
));
26072613
}
26082614
let host = self.get_host()?;
26092615
let target = self.get_target()?;
@@ -2639,7 +2645,12 @@ impl Build {
26392645
// semi-buggy build scripts which are shared in
26402646
// makefiles/configure scripts (where spaces are far more
26412647
// lenient)
2642-
let mut t = Tool::with_clang_driver(tool, driver_mode, &self.cargo_output);
2648+
let mut t = Tool::with_clang_driver(
2649+
tool,
2650+
driver_mode,
2651+
&self.cached_compiler_family,
2652+
&self.cargo_output,
2653+
);
26432654
if let Some(cc_wrapper) = wrapper {
26442655
t.cc_wrapper_path = Some(PathBuf::from(cc_wrapper));
26452656
}
@@ -2653,12 +2664,20 @@ impl Build {
26532664
let tool = if self.cpp { "em++" } else { "emcc" };
26542665
// Windows uses bat file so we have to be a bit more specific
26552666
if cfg!(windows) {
2656-
let mut t = Tool::new(PathBuf::from("cmd"), &self.cargo_output);
2667+
let mut t = Tool::new(
2668+
PathBuf::from("cmd"),
2669+
&self.cached_compiler_family,
2670+
&self.cargo_output,
2671+
);
26572672
t.args.push("/c".into());
26582673
t.args.push(format!("{}.bat", tool).into());
26592674
Some(t)
26602675
} else {
2661-
Some(Tool::new(PathBuf::from(tool), &self.cargo_output))
2676+
Some(Tool::new(
2677+
PathBuf::from(tool),
2678+
&self.cached_compiler_family,
2679+
&self.cargo_output,
2680+
))
26622681
}
26632682
} else {
26642683
None
@@ -2713,7 +2732,11 @@ impl Build {
27132732
default.to_string()
27142733
};
27152734

2716-
let mut t = Tool::new(PathBuf::from(compiler), &self.cargo_output);
2735+
let mut t = Tool::new(
2736+
PathBuf::from(compiler),
2737+
&self.cached_compiler_family,
2738+
&self.cargo_output,
2739+
);
27172740
if let Some(cc_wrapper) = Self::rustc_wrapper_fallback() {
27182741
t.cc_wrapper_path = Some(PathBuf::from(cc_wrapper));
27192742
}
@@ -2730,7 +2753,13 @@ impl Build {
27302753
Err(_) => PathBuf::from("nvcc"),
27312754
Ok(nvcc) => PathBuf::from(&*nvcc),
27322755
};
2733-
let mut nvcc_tool = Tool::with_features(nvcc, None, self.cuda, &self.cargo_output);
2756+
let mut nvcc_tool = Tool::with_features(
2757+
nvcc,
2758+
None,
2759+
self.cuda,
2760+
&self.cached_compiler_family,
2761+
&self.cargo_output,
2762+
);
27342763
nvcc_tool
27352764
.args
27362765
.push(format!("-ccbin={}", tool.path.display()).into());

src/tool.rs

+32-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use std::{
2+
collections::HashMap,
23
ffi::OsString,
34
path::{Path, PathBuf},
45
process::Command,
6+
sync::Mutex,
57
};
68

79
use crate::command_helpers::{run_output, CargoOutput};
@@ -28,16 +30,27 @@ pub struct Tool {
2830
}
2931

3032
impl Tool {
31-
pub(crate) fn new(path: PathBuf, cargo_output: &CargoOutput) -> Self {
32-
Tool::with_features(path, None, false, cargo_output)
33+
pub(crate) fn new(
34+
path: PathBuf,
35+
cached_compiler_family: &Mutex<HashMap<Box<Path>, ToolFamily>>,
36+
cargo_output: &CargoOutput,
37+
) -> Self {
38+
Self::with_features(path, None, false, cached_compiler_family, cargo_output)
3339
}
3440

3541
pub(crate) fn with_clang_driver(
3642
path: PathBuf,
3743
clang_driver: Option<&str>,
44+
cached_compiler_family: &Mutex<HashMap<Box<Path>, ToolFamily>>,
3845
cargo_output: &CargoOutput,
3946
) -> Self {
40-
Self::with_features(path, clang_driver, false, cargo_output)
47+
Self::with_features(
48+
path,
49+
clang_driver,
50+
false,
51+
cached_compiler_family,
52+
cargo_output,
53+
)
4154
}
4255

4356
#[cfg(windows)]
@@ -60,9 +73,10 @@ impl Tool {
6073
path: PathBuf,
6174
clang_driver: Option<&str>,
6275
cuda: bool,
76+
cached_compiler_family: &Mutex<HashMap<Box<Path>, ToolFamily>>,
6377
cargo_output: &CargoOutput,
6478
) -> Self {
65-
fn detect_family(path: &Path, cargo_output: &CargoOutput) -> ToolFamily {
79+
fn detect_family_inner(path: &Path, cargo_output: &CargoOutput) -> ToolFamily {
6680
let mut cmd = Command::new(path);
6781
cmd.arg("--version");
6882

@@ -95,6 +109,18 @@ impl Tool {
95109
ToolFamily::Gnu
96110
}
97111
}
112+
let detect_family = |path: &Path| -> ToolFamily {
113+
if let Some(family) = cached_compiler_family.lock().unwrap().get(path) {
114+
return *family;
115+
}
116+
117+
let family = detect_family_inner(path, cargo_output);
118+
cached_compiler_family
119+
.lock()
120+
.unwrap()
121+
.insert(path.into(), family);
122+
family
123+
};
98124

99125
// Try to detect family of the tool from its name, falling back to Gnu.
100126
let family = if let Some(fname) = path.file_name().and_then(|p| p.to_str()) {
@@ -108,10 +134,10 @@ impl Tool {
108134
_ => ToolFamily::Clang,
109135
}
110136
} else {
111-
detect_family(&path, cargo_output)
137+
detect_family(&path)
112138
}
113139
} else {
114-
detect_family(&path, cargo_output)
140+
detect_family(&path)
115141
};
116142

117143
Tool {

0 commit comments

Comments
 (0)