Skip to content

Commit 27efba8

Browse files
committed
Add tests for prefer_clang_cl_over_msvc
1 parent f194932 commit 27efba8

File tree

3 files changed

+107
-2
lines changed

3 files changed

+107
-2
lines changed

src/windows/find_tools.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ mod impl_ {
287287

288288
use super::{EnvGetter, TargetArch, MSVC_FAMILY};
289289
use crate::Tool;
290+
use crate::ToolFamily;
290291

291292
struct MsvcTool {
292293
tool: PathBuf,
@@ -555,7 +556,7 @@ mod impl_ {
555556
base_path.push(tool);
556557
base_path
557558
.is_file()
558-
.then(|| Tool::with_family(base_path, MSVC_FAMILY))
559+
.then(|| Tool::with_family(base_path, ToolFamily::Msvc { clang_cl: true }))
559560
})
560561
.next()
561562
}

tests/support/mod.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub struct Test {
1414
pub td: TempDir,
1515
pub gcc: PathBuf,
1616
pub msvc: bool,
17+
pub msvc_autodetect: bool,
1718
}
1819

1920
pub struct Execution {
@@ -53,6 +54,7 @@ impl Test {
5354
td,
5455
gcc,
5556
msvc: false,
57+
msvc_autodetect: false,
5658
}
5759
}
5860

@@ -69,6 +71,14 @@ impl Test {
6971
t
7072
}
7173

74+
// For msvc_autodetect, don't explicitly set the compiler - let the build system discover it
75+
pub fn msvc_autodetect() -> Test {
76+
let mut t = Test::new();
77+
t.shim("cl").shim("clang-cl.exe").shim("lib.exe");
78+
t.msvc_autodetect = true;
79+
t
80+
}
81+
7282
pub fn clang() -> Test {
7383
let t = Test::new();
7484
t.shim("clang").shim("clang++").shim("ar");
@@ -87,7 +97,7 @@ impl Test {
8797

8898
pub fn gcc(&self) -> cc::Build {
8999
let mut cfg = cc::Build::new();
90-
let target = if self.msvc {
100+
let target = if self.msvc || self.msvc_autodetect {
91101
"x86_64-pc-windows-msvc"
92102
} else if cfg!(target_os = "macos") {
93103
"x86_64-apple-darwin"

tests/test.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,3 +851,97 @@ fn clang_android() {
851851
test.cmd(0).must_not_have("--target=arm-linux-androideabi");
852852
}
853853
}
854+
855+
#[test]
856+
#[cfg(windows)]
857+
fn msvc_prefer_clang_cl_over_msvc_disabled_by_default() {
858+
reset_env();
859+
860+
let test = Test::msvc_autodetect();
861+
862+
// When prefer_clang_cl_over_msvc is not called (default false), should use MSVC
863+
let compiler = test
864+
.gcc()
865+
.try_get_compiler()
866+
.expect("Failed to get compiler");
867+
868+
// By default, should be using MSVC (cl.exe) and NOT clang-cl
869+
assert!(compiler.is_like_msvc(), "Should use MSVC by default");
870+
assert!(
871+
!compiler.is_like_clang_cl(),
872+
"Should not use clang-cl by default"
873+
);
874+
}
875+
876+
#[test]
877+
#[cfg(windows)]
878+
fn msvc_prefer_clang_cl_over_msvc_enabled() {
879+
reset_env();
880+
881+
let test = Test::msvc_autodetect();
882+
883+
let compiler = test
884+
.gcc()
885+
// When prefer_clang_cl_over_msvc is true, should use clang-cl.exe
886+
.prefer_clang_cl_over_msvc(true)
887+
.try_get_compiler()
888+
.expect("Failed to get compiler");
889+
890+
assert!(
891+
compiler.is_like_clang_cl(),
892+
"clang-cl.exe should be identified as clang-cl-like, got {:?}",
893+
compiler
894+
);
895+
assert!(
896+
compiler.is_like_msvc(),
897+
"clang-cl should still be MSVC-like"
898+
);
899+
}
900+
901+
#[test]
902+
#[cfg(windows)]
903+
fn msvc_prefer_clang_cl_over_msvc_respects_explicit_cc_env() {
904+
reset_env();
905+
906+
let test = Test::msvc_autodetect();
907+
let compiler = test
908+
.gcc()
909+
// We can't set the CC=cl.exe environment variable directly in the test as it's removed
910+
// in mod.rs, so we simulate it by setting the compiler directly
911+
.compiler("cl.exe")
912+
.prefer_clang_cl_over_msvc(true)
913+
.try_get_compiler()
914+
.expect("Failed to get compiler");
915+
916+
// The preference should not override explicit compiler setting
917+
assert!(compiler.is_like_msvc(), "Should still be MSVC-like");
918+
assert!(
919+
!compiler.is_like_clang_cl(),
920+
"Should NOT use clang-cl when CC is explicitly set to cl.exe, got {:?}",
921+
compiler
922+
);
923+
}
924+
925+
#[test]
926+
#[cfg(windows)]
927+
fn msvc_prefer_clang_cl_over_msvc_cpp_mode() {
928+
reset_env();
929+
930+
let test = Test::msvc_autodetect();
931+
let compiler = test
932+
.gcc()
933+
.cpp(true)
934+
.prefer_clang_cl_over_msvc(true)
935+
.try_get_compiler()
936+
.expect("Failed to get compiler");
937+
938+
// Verify clang-cl.exe works correctly in C++ mode
939+
assert!(
940+
compiler.is_like_clang_cl(),
941+
"clang-cl.exe should be identified as clang-cl-like in C++ mode"
942+
);
943+
assert!(
944+
compiler.is_like_msvc(),
945+
"clang-cl should still be MSVC-like in C++ mode"
946+
);
947+
}

0 commit comments

Comments
 (0)