Skip to content

Commit 750671b

Browse files
Include wrapper args. in stdout family heuristics to restore classifying clang --driver-mode=cl as Msvc { clang_cl: true } (rust-lang#1378)
1 parent dcd8ed3 commit 750671b

File tree

2 files changed

+53
-38
lines changed

2 files changed

+53
-38
lines changed

src/lib.rs

+5-11
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ use command_helpers::*;
237237

238238
mod tool;
239239
pub use tool::Tool;
240-
use tool::ToolFamily;
240+
use tool::{CompilerFamilyLookupCache, ToolFamily};
241241

242242
mod target_info;
243243
mod tempfile;
@@ -301,7 +301,7 @@ pub struct Build {
301301
apple_sdk_root_cache: Arc<RwLock<HashMap<Box<str>, Arc<OsStr>>>>,
302302
apple_versions_cache: Arc<RwLock<HashMap<Box<str>, Arc<str>>>>,
303303
emit_rerun_if_env_changed: bool,
304-
cached_compiler_family: Arc<RwLock<HashMap<Box<Path>, ToolFamily>>>,
304+
cached_compiler_family: Arc<RwLock<CompilerFamilyLookupCache>>,
305305
}
306306

307307
/// Represents the types of errors that may occur while using cc-rs.
@@ -2844,19 +2844,13 @@ impl Build {
28442844
let tool_opt: Option<Tool> = self
28452845
.env_tool(env)
28462846
.map(|(tool, wrapper, args)| {
2847-
// find the driver mode, if any
2848-
const DRIVER_MODE: &str = "--driver-mode=";
2849-
let driver_mode = args
2850-
.iter()
2851-
.find(|a| a.starts_with(DRIVER_MODE))
2852-
.map(|a| &a[DRIVER_MODE.len()..]);
28532847
// Chop off leading/trailing whitespace to work around
28542848
// semi-buggy build scripts which are shared in
28552849
// makefiles/configure scripts (where spaces are far more
28562850
// lenient)
2857-
let mut t = Tool::with_clang_driver(
2851+
let mut t = Tool::with_args(
28582852
tool,
2859-
driver_mode,
2853+
args.clone(),
28602854
&self.cached_compiler_family,
28612855
&self.cargo_output,
28622856
out_dir,
@@ -2968,7 +2962,7 @@ impl Build {
29682962
};
29692963
let mut nvcc_tool = Tool::with_features(
29702964
nvcc,
2971-
None,
2965+
vec![],
29722966
self.cuda,
29732967
&self.cached_compiler_family,
29742968
&self.cargo_output,

src/tool.rs

+48-27
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ use crate::{
1616
Error, ErrorKind, OutputKind,
1717
};
1818

19+
pub(crate) type CompilerFamilyLookupCache = HashMap<Box<[Box<OsStr>]>, ToolFamily>;
20+
1921
/// Configuration used to represent an invocation of a C compiler.
2022
///
2123
/// This can be used to figure out what compiler is in use, what the arguments
@@ -40,30 +42,30 @@ pub struct Tool {
4042
impl Tool {
4143
pub(crate) fn new(
4244
path: PathBuf,
43-
cached_compiler_family: &RwLock<HashMap<Box<Path>, ToolFamily>>,
45+
cached_compiler_family: &std::sync::Arc<RwLock<CompilerFamilyLookupCache>>,
4446
cargo_output: &CargoOutput,
4547
out_dir: Option<&Path>,
4648
) -> Self {
4749
Self::with_features(
4850
path,
49-
None,
51+
vec![],
5052
false,
5153
cached_compiler_family,
5254
cargo_output,
5355
out_dir,
5456
)
5557
}
5658

57-
pub(crate) fn with_clang_driver(
59+
pub(crate) fn with_args(
5860
path: PathBuf,
59-
clang_driver: Option<&str>,
60-
cached_compiler_family: &RwLock<HashMap<Box<Path>, ToolFamily>>,
61+
args: Vec<String>,
62+
cached_compiler_family: &std::sync::Arc<RwLock<CompilerFamilyLookupCache>>,
6163
cargo_output: &CargoOutput,
6264
out_dir: Option<&Path>,
6365
) -> Self {
6466
Self::with_features(
6567
path,
66-
clang_driver,
68+
args,
6769
false,
6870
cached_compiler_family,
6971
cargo_output,
@@ -88,9 +90,9 @@ impl Tool {
8890

8991
pub(crate) fn with_features(
9092
path: PathBuf,
91-
clang_driver: Option<&str>,
93+
args: Vec<String>,
9294
cuda: bool,
93-
cached_compiler_family: &RwLock<HashMap<Box<Path>, ToolFamily>>,
95+
cached_compiler_family: &std::sync::Arc<RwLock<CompilerFamilyLookupCache>>,
9496
cargo_output: &CargoOutput,
9597
out_dir: Option<&Path>,
9698
) -> Self {
@@ -107,6 +109,7 @@ impl Tool {
107109

108110
fn detect_family_inner(
109111
path: &Path,
112+
args: &[String],
110113
cargo_output: &CargoOutput,
111114
out_dir: Option<&Path>,
112115
) -> Result<ToolFamily, Error> {
@@ -158,15 +161,21 @@ impl Tool {
158161
cargo_output.print_debug(&stdout);
159162

160163
// https://gitlab.kitware.com/cmake/cmake/-/blob/69a2eeb9dff5b60f2f1e5b425002a0fd45b7cadb/Modules/CMakeDetermineCompilerId.cmake#L267-271
161-
let accepts_cl_style_flags = run(Command::new(path).arg("-?"), path, &{
162-
// the errors are not errors!
163-
let mut cargo_output = cargo_output.clone();
164-
cargo_output.warnings = cargo_output.debug;
165-
cargo_output.output = OutputKind::Discard;
166-
cargo_output
167-
})
164+
let accepts_cl_style_flags = run(
165+
Command::new(path)
166+
.args(args)
167+
.arg("-?")
168+
.stdin(std::process::Stdio::null()),
169+
path,
170+
&{
171+
// the errors are not errors!
172+
let mut cargo_output = cargo_output.clone();
173+
cargo_output.warnings = cargo_output.debug;
174+
cargo_output.output = OutputKind::Discard;
175+
cargo_output
176+
},
177+
)
168178
.is_ok();
169-
170179
let clang = stdout.contains(r#""clang""#);
171180
let gcc = stdout.contains(r#""gcc""#);
172181

@@ -185,20 +194,26 @@ impl Tool {
185194
}
186195
}
187196
}
188-
let detect_family = |path: &Path| -> Result<ToolFamily, Error> {
189-
if let Some(family) = cached_compiler_family.read().unwrap().get(path) {
197+
let detect_family = |path: &Path, args: &[String]| -> Result<ToolFamily, Error> {
198+
let cache_key = [path.as_os_str()]
199+
.iter()
200+
.cloned()
201+
.chain(args.iter().map(OsStr::new))
202+
.map(Into::into)
203+
.collect();
204+
if let Some(family) = cached_compiler_family.read().unwrap().get(&cache_key) {
190205
return Ok(*family);
191206
}
192207

193-
let family = detect_family_inner(path, cargo_output, out_dir)?;
208+
let family = detect_family_inner(path, args, cargo_output, out_dir)?;
194209
cached_compiler_family
195210
.write()
196211
.unwrap()
197-
.insert(path.into(), family);
212+
.insert(cache_key, family);
198213
Ok(family)
199214
};
200215

201-
let family = detect_family(&path).unwrap_or_else(|e| {
216+
let family = detect_family(&path, &args).unwrap_or_else(|e| {
202217
cargo_output.print_warning(&format_args!(
203218
"Compiler family detection failed due to error: {}",
204219
e
@@ -208,12 +223,18 @@ impl Tool {
208223
Some(fname) if fname.ends_with("cl") || fname == "cl.exe" => {
209224
ToolFamily::Msvc { clang_cl: false }
210225
}
211-
Some(fname) if fname.contains("clang") => match clang_driver {
212-
Some("cl") => ToolFamily::Msvc { clang_cl: true },
213-
_ => ToolFamily::Clang {
214-
zig_cc: is_zig_cc(&path, cargo_output),
215-
},
216-
},
226+
Some(fname) if fname.contains("clang") => {
227+
let is_clang_cl = args
228+
.iter()
229+
.any(|a| a.strip_prefix("--driver-mode=") == Some("cl"));
230+
if is_clang_cl {
231+
ToolFamily::Msvc { clang_cl: true }
232+
} else {
233+
ToolFamily::Clang {
234+
zig_cc: is_zig_cc(&path, cargo_output),
235+
}
236+
}
237+
}
217238
Some(fname) if fname.contains("zig") => ToolFamily::Clang { zig_cc: true },
218239
_ => ToolFamily::Gnu,
219240
}

0 commit comments

Comments
 (0)