Skip to content

Commit 3fe0e09

Browse files
committed
Fix compiler family detection issue with clang-cl
Fixed #1327 Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
1 parent 18307cf commit 3fe0e09

File tree

1 file changed

+58
-41
lines changed

1 file changed

+58
-41
lines changed

src/tool.rs

+58-41
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,46 @@ impl Tool {
105105
.unwrap_or_default()
106106
}
107107

108+
fn guess_family_from_stdout(
109+
stdout: &str,
110+
path: &Path,
111+
cargo_output: &CargoOutput,
112+
) -> Result<ToolFamily, Error> {
113+
cargo_output.print_debug(&stdout);
114+
115+
// https://gitlab.kitware.com/cmake/cmake/-/blob/69a2eeb9dff5b60f2f1e5b425002a0fd45b7cadb/Modules/CMakeDetermineCompilerId.cmake#L267-271
116+
// stdin is set to null to ensure that the help output is never paginated.
117+
let accepts_cl_style_flags =
118+
run(Command::new(path).arg("-?").stdin(Stdio::null()), path, &{
119+
// the errors are not errors!
120+
let mut cargo_output = cargo_output.clone();
121+
cargo_output.warnings = cargo_output.debug;
122+
cargo_output.output = OutputKind::Discard;
123+
cargo_output
124+
})
125+
.is_ok();
126+
127+
let clang = stdout.contains(r#""clang""#);
128+
let gcc = stdout.contains(r#""gcc""#);
129+
let emscripten = stdout.contains(r#""emscripten""#);
130+
let vxworks = stdout.contains(r#""VxWorks""#);
131+
132+
match (clang, accepts_cl_style_flags, gcc, emscripten, vxworks) {
133+
(clang_cl, true, _, false, false) => Ok(ToolFamily::Msvc { clang_cl }),
134+
(true, _, _, _, false) | (_, _, _, true, false) => Ok(ToolFamily::Clang {
135+
zig_cc: is_zig_cc(path, cargo_output),
136+
}),
137+
(false, false, true, _, false) | (_, _, _, _, true) => Ok(ToolFamily::Gnu),
138+
(false, false, false, false, false) => {
139+
cargo_output.print_warning(&"Compiler family detection failed since it does not define `__clang__`, `__GNUC__`, `__EMSCRIPTEN__` or `__VXWORKS__`, also does not accept cl style flag `-?`, fallback to treating it as GNU");
140+
Err(Error::new(
141+
ErrorKind::ToolFamilyMacroNotFound,
142+
"Expects macro `__clang__`, `__GNUC__` or `__EMSCRIPTEN__`, `__VXWORKS__` or accepts cl style flag `-?`, but found none",
143+
))
144+
}
145+
}
146+
}
147+
108148
fn detect_family_inner(
109149
path: &Path,
110150
cargo_output: &CargoOutput,
@@ -140,53 +180,30 @@ impl Tool {
140180
tmp_file.sync_data()?;
141181
drop(tmp_file);
142182

183+
// When expanding the file, the compiler prints a lot of information to stderr
184+
// that it is not an error, but related to expanding itself.
185+
//
186+
// cc would have to disable warning here to prevent generation of too many warnings.
187+
let mut compiler_detect_output = cargo_output.clone();
188+
compiler_detect_output.warnings = compiler_detect_output.debug;
189+
143190
let stdout = run_output(
144191
Command::new(path).arg("-E").arg(tmp.path()),
145192
path,
146-
// When expanding the file, the compiler prints a lot of information to stderr
147-
// that it is not an error, but related to expanding itself.
148-
//
149-
// cc would have to disable warning here to prevent generation of too many warnings.
150-
&{
151-
let mut cargo_output = cargo_output.clone();
152-
cargo_output.warnings = cargo_output.debug;
153-
cargo_output
154-
},
193+
&compiler_detect_output,
155194
)?;
156195
let stdout = String::from_utf8_lossy(&stdout);
157196

158-
cargo_output.print_debug(&stdout);
159-
160-
// https://gitlab.kitware.com/cmake/cmake/-/blob/69a2eeb9dff5b60f2f1e5b425002a0fd45b7cadb/Modules/CMakeDetermineCompilerId.cmake#L267-271
161-
// stdin is set to null to ensure that the help output is never paginated.
162-
let accepts_cl_style_flags =
163-
run(Command::new(path).arg("-?").stdin(Stdio::null()), path, &{
164-
// the errors are not errors!
165-
let mut cargo_output = cargo_output.clone();
166-
cargo_output.warnings = cargo_output.debug;
167-
cargo_output.output = OutputKind::Discard;
168-
cargo_output
169-
})
170-
.is_ok();
171-
172-
let clang = stdout.contains(r#""clang""#);
173-
let gcc = stdout.contains(r#""gcc""#);
174-
let emscripten = stdout.contains(r#""emscripten""#);
175-
let vxworks = stdout.contains(r#""VxWorks""#);
176-
177-
match (clang, accepts_cl_style_flags, gcc, emscripten, vxworks) {
178-
(clang_cl, true, _, false, false) => Ok(ToolFamily::Msvc { clang_cl }),
179-
(true, _, _, _, false) | (_, _, _, true, false) => Ok(ToolFamily::Clang {
180-
zig_cc: is_zig_cc(path, cargo_output),
181-
}),
182-
(false, false, true, _, false) | (_, _, _, _, true) => Ok(ToolFamily::Gnu),
183-
(false, false, false, false, false) => {
184-
cargo_output.print_warning(&"Compiler family detection failed since it does not define `__clang__`, `__GNUC__`, `__EMSCRIPTEN__` or `__VXWORKS__`, also does not accept cl style flag `-?`, fallback to treating it as GNU");
185-
Err(Error::new(
186-
ErrorKind::ToolFamilyMacroNotFound,
187-
"Expects macro `__clang__`, `__GNUC__` or `__EMSCRIPTEN__`, `__VXWORKS__` or accepts cl style flag `-?`, but found none",
188-
))
189-
}
197+
if stdout.contains("-Wslash-u-filename") {
198+
let stdout = run_output(
199+
Command::new(path).arg("-E").arg("--").arg(tmp.path()),
200+
path,
201+
&compiler_detect_output,
202+
)?;
203+
let stdout = String::from_utf8_lossy(&stdout);
204+
guess_family_from_stdout(&stdout, path, cargo_output)
205+
} else {
206+
guess_family_from_stdout(&stdout, path, cargo_output)
190207
}
191208
}
192209
let detect_family = |path: &Path| -> Result<ToolFamily, Error> {

0 commit comments

Comments
 (0)