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 ;
18use 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-
1919pub ( 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