diff --git a/src/bin/gcc-shim.rs b/src/bin/cc-shim.rs similarity index 62% rename from src/bin/gcc-shim.rs rename to src/bin/cc-shim.rs index da7a8b35e..5271c6879 100644 --- a/src/bin/gcc-shim.rs +++ b/src/bin/cc-shim.rs @@ -8,14 +8,16 @@ use std::env; use std::fs::File; use std::io::{self, prelude::*}; use std::path::PathBuf; +use std::process::ExitCode; -fn main() { - let mut args = env::args(); +fn main() -> ExitCode { + let args = env::args().collect::>(); + let mut args = args.iter(); let program = args.next().expect("Unexpected empty args"); let out_dir = PathBuf::from( - env::var_os("GCCTEST_OUT_DIR") - .unwrap_or_else(|| panic!("{}: GCCTEST_OUT_DIR not found", program)), + env::var_os("CC_SHIM_OUT_DIR") + .unwrap_or_else(|| panic!("{}: CC_SHIM_OUT_DIR not found", program)), ); // Find the first nonexistent candidate file to which the program's args can be written. @@ -42,7 +44,7 @@ fn main() { let mut f = io::BufWriter::new(f); (|| { - for arg in args { + for arg in args.clone() { writeln!(f, "{}", arg)?; } @@ -61,6 +63,27 @@ fn main() { ) }); + if program.starts_with("clang") { + // Validate that we got no `-?` without a preceding `--driver-mode=cl`. Compiler family + // detection depends on this. + if let Some(cl_like_help_option_idx) = args.clone().position(|a| a == "-?") { + let has_cl_clang_driver_before_cl_like_help_option = args + .clone() + .take(cl_like_help_option_idx) + .rev() + .find_map(|a| a.strip_prefix("--driver-mode=")) + .is_some_and(|a| a == "cl"); + if has_cl_clang_driver_before_cl_like_help_option { + return ExitCode::SUCCESS; + } else { + eprintln!( + "Found `-?` argument, but it was not preceded by a `--driver-mode=cl` argument." + ); + return ExitCode::FAILURE; + } + } + } + // Create a file used by some tests. let path = &out_dir.join("libfoo.a"); File::create(path).unwrap_or_else(|e| { @@ -71,4 +94,6 @@ fn main() { e ) }); + + ExitCode::SUCCESS } diff --git a/tests/cc_env.rs b/tests/cc_env.rs index ced77ca92..a4938732e 100644 --- a/tests/cc_env.rs +++ b/tests/cc_env.rs @@ -15,6 +15,7 @@ fn main() { extra_flags(); path_to_ccache(); more_spaces(); + clang_cl(); } fn ccache() { @@ -110,3 +111,18 @@ fn more_spaces() { let compiler = test.gcc().file("foo.c").get_compiler(); assert_eq!(compiler.path(), Path::new("cc")); } + +fn clang_cl() { + for exe_suffix in ["", ".exe"] { + let test = Test::clang(); + let bin = format!("clang{exe_suffix}"); + env::set_var("CC", &format!("{bin} --driver-mode=cl")); + let test_compiler = |build: cc::Build| { + let compiler = build.get_compiler(); + assert_eq!(compiler.path(), Path::new(&*bin)); + assert!(compiler.is_like_msvc()); + assert!(compiler.is_like_clang_cl()); + }; + test_compiler(test.gcc()); + } +} diff --git a/tests/support/mod.rs b/tests/support/mod.rs index 5e87001e5..67516a3be 100644 --- a/tests/support/mod.rs +++ b/tests/support/mod.rs @@ -44,8 +44,11 @@ impl Test { if gcc.ends_with("deps") { gcc.pop(); } - let td = Builder::new().prefix("gcc-test").tempdir_in(&gcc).unwrap(); - gcc.push(format!("gcc-shim{}", env::consts::EXE_SUFFIX)); + let td = Builder::new() + .prefix("cc-shim-test") + .tempdir_in(&gcc) + .unwrap(); + gcc.push(format!("cc-shim{}", env::consts::EXE_SUFFIX)); Test { td, gcc, @@ -98,7 +101,7 @@ impl Test { .debug(false) .out_dir(self.td.path()) .__set_env("PATH", self.path()) - .__set_env("GCCTEST_OUT_DIR", self.td.path()); + .__set_env("CC_SHIM_OUT_DIR", self.td.path()); if self.msvc { cfg.compiler(self.td.path().join("cl")); cfg.archiver(self.td.path().join("lib.exe"));