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 ;
1
8
use std:: {
2
9
borrow:: Cow ,
3
10
collections:: HashMap ,
@@ -9,13 +16,6 @@ use std::{
9
16
sync:: RwLock ,
10
17
} ;
11
18
12
- use crate :: {
13
- command_helpers:: { run_output, CargoOutput } ,
14
- run,
15
- tempfile:: NamedTempfile ,
16
- Error , ErrorKind , OutputKind ,
17
- } ;
18
-
19
19
pub ( crate ) type CompilerFamilyLookupCache = HashMap < Box < [ Box < OsStr > ] > , ToolFamily > ;
20
20
21
21
/// Configuration used to represent an invocation of a C compiler.
@@ -198,22 +198,47 @@ impl Tool {
198
198
let mut compiler_detect_output = cargo_output. clone ( ) ;
199
199
compiler_detect_output. warnings = compiler_detect_output. debug ;
200
200
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) ?;
206
216
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 (
209
224
Command :: new ( path) . arg ( "-E" ) . arg ( "--" ) . arg ( tmp. path ( ) ) ,
210
225
& compiler_detect_output,
211
- ) ?;
212
- let stdout = String :: from_utf8_lossy ( & stdout) ;
213
- guess_family_from_stdout ( & stdout, path, args, cargo_output)
226
+ ) ?
214
227
} 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)
217
242
}
218
243
let detect_family = |path : & Path , args : & [ String ] | -> Result < ToolFamily , Error > {
219
244
let cache_key = [ path. as_os_str ( ) ]
0 commit comments