Skip to content

Commit 8f6fe69

Browse files
authored
Detect -Wslash-u-filename warning on clang-cl (#1477)
1 parent 0012da5 commit 8f6fe69

File tree

1 file changed

+44
-19
lines changed

1 file changed

+44
-19
lines changed

src/tool.rs

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
use crate::{
2+
command_helpers::{run_output, spawn, CargoOutput},
3+
run,
4+
tempfile::NamedTempfile,
5+
Error, ErrorKind, OutputKind,
6+
};
7+
use std::io::Read;
18
use std::{
29
borrow::Cow,
310
collections::HashMap,
@@ -9,13 +16,6 @@ use std::{
916
sync::RwLock,
1017
};
1118

12-
use crate::{
13-
command_helpers::{run_output, CargoOutput},
14-
run,
15-
tempfile::NamedTempfile,
16-
Error, ErrorKind, OutputKind,
17-
};
18-
1919
pub(crate) type CompilerFamilyLookupCache = HashMap<Box<[Box<OsStr>]>, ToolFamily>;
2020

2121
/// Configuration used to represent an invocation of a C compiler.
@@ -198,22 +198,47 @@ impl Tool {
198198
let mut compiler_detect_output = cargo_output.clone();
199199
compiler_detect_output.warnings = compiler_detect_output.debug;
200200

201-
let stdout = run_output(
202-
Command::new(path).arg("-E").arg(tmp.path()),
203-
&compiler_detect_output,
204-
)?;
205-
let stdout = String::from_utf8_lossy(&stdout);
201+
let mut cmd = Command::new(path);
202+
cmd.arg("-E").arg(tmp.path());
203+
204+
// The -Wslash-u-filename warning is normally part of stdout.
205+
// But with clang-cl it can be part of stderr instead and exit with a
206+
// non-zero exit code.
207+
let mut captured_cargo_output = compiler_detect_output.clone();
208+
captured_cargo_output.output = OutputKind::Capture;
209+
captured_cargo_output.warnings = true;
210+
let mut child = spawn(&mut cmd, &captured_cargo_output)?;
211+
212+
let mut out = vec![];
213+
let mut err = vec![];
214+
child.stdout.take().unwrap().read_to_end(&mut out)?;
215+
child.stderr.take().unwrap().read_to_end(&mut err)?;
206216

207-
if stdout.contains("-Wslash-u-filename") {
208-
let stdout = run_output(
217+
let status = child.wait()?;
218+
219+
let stdout = if [&out, &err]
220+
.iter()
221+
.any(|o| String::from_utf8_lossy(o).contains("-Wslash-u-filename"))
222+
{
223+
run_output(
209224
Command::new(path).arg("-E").arg("--").arg(tmp.path()),
210225
&compiler_detect_output,
211-
)?;
212-
let stdout = String::from_utf8_lossy(&stdout);
213-
guess_family_from_stdout(&stdout, path, args, cargo_output)
226+
)?
214227
} else {
215-
guess_family_from_stdout(&stdout, path, args, cargo_output)
216-
}
228+
if !status.success() {
229+
return Err(Error::new(
230+
ErrorKind::ToolExecError,
231+
format!(
232+
"command did not execute successfully (status code {status}): {cmd:?}"
233+
),
234+
));
235+
}
236+
237+
out
238+
};
239+
240+
let stdout = String::from_utf8_lossy(&stdout);
241+
guess_family_from_stdout(&stdout, path, args, cargo_output)
217242
}
218243
let detect_family = |path: &Path, args: &[String]| -> Result<ToolFamily, Error> {
219244
let cache_key = [path.as_os_str()]

0 commit comments

Comments
 (0)