Skip to content

Commit 2372f80

Browse files
committed
Add CC_PREFER_CLANG_CL_OVER_MSVC environment variable to override prefer_clang_cl_over_msvc
Fixes #1673
1 parent 9eda981 commit 2372f80

2 files changed

Lines changed: 108 additions & 2 deletions

File tree

src/lib.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ impl Build {
552552
shell_escaped_flags: None,
553553
build_cache: Arc::default(),
554554
inherit_rustflags: true,
555-
prefer_clang_cl_over_msvc: false,
555+
prefer_clang_cl_over_msvc: get_prefer_clang_cl_over_msvc_from_env().unwrap_or(false),
556556
}
557557
}
558558

@@ -1386,8 +1386,17 @@ impl Build {
13861386
/// Prefer to use clang-cl over msvc.
13871387
///
13881388
/// This option defaults to `false`.
1389+
///
1390+
/// This option is always overridden by the environment variable `CC_PREFER_CLANG_CL_OVER_MSVC`, if set
13891391
pub fn prefer_clang_cl_over_msvc(&mut self, prefer_clang_cl_over_msvc: bool) -> &mut Build {
1390-
self.prefer_clang_cl_over_msvc = prefer_clang_cl_over_msvc;
1392+
match get_prefer_clang_cl_over_msvc_from_env() {
1393+
Some(b) => {
1394+
self.cargo_output.print_warning(&format_args!("`prefer_clang_cl_over_msvc` is overridden by {:?} to {:?}, the value set by this call is ignored", CC_PREFER_CLANG_CL_OVER_MSVC_ENV_VAR, b));
1395+
},
1396+
None => {
1397+
self.prefer_clang_cl_over_msvc = prefer_clang_cl_over_msvc;
1398+
}
1399+
}
13911400
self
13921401
}
13931402

@@ -4475,6 +4484,19 @@ fn check_exe(mut exe: PathBuf) -> Option<PathBuf> {
44754484
check.then_some(exe)
44764485
}
44774486

4487+
const CC_PREFER_CLANG_CL_OVER_MSVC_ENV_VAR: &str = "CC_PREFER_CLANG_CL_OVER_MSVC";
4488+
fn get_prefer_clang_cl_over_msvc_from_env() -> Option<bool> {
4489+
#[allow(clippy::disallowed_methods)]
4490+
match env::var_os(CC_PREFER_CLANG_CL_OVER_MSVC_ENV_VAR) {
4491+
None => None,
4492+
Some(v) => match v.to_str() {
4493+
Some("1") | Some("true") | Some("yes") => Some(true),
4494+
Some("0") | Some("false") | Some("no") => Some(false),
4495+
_ => None,
4496+
}
4497+
}
4498+
}
4499+
44784500
#[cfg(test)]
44794501
mod tests {
44804502
use super::*;

tests/test.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,4 +1081,88 @@ mod msvc_clang_cl_tests {
10811081
"clang-cl should still be MSVC-like in C++ mode"
10821082
);
10831083
}
1084+
1085+
#[test]
1086+
fn msvc_prefer_clang_cl_over_msvc_enabled_by_env() {
1087+
reset_env();
1088+
std::env::set_var("CC_PREFER_CLANG_CL_OVER_MSVC", "1");
1089+
1090+
let test = Test::msvc_autodetect();
1091+
1092+
let compiler = test
1093+
.gcc()
1094+
.try_get_compiler()
1095+
.expect("Failed to get compiler");
1096+
1097+
assert!(
1098+
compiler.is_like_clang_cl(),
1099+
"clang-cl.exe should be identified as clang-cl-like, got {:?}",
1100+
compiler
1101+
);
1102+
assert!(
1103+
compiler.is_like_msvc(),
1104+
"clang-cl should still be MSVC-like"
1105+
);
1106+
std::env::remove_var("CC_PREFER_CLANG_CL_OVER_MSVC"); // Clean up after test
1107+
}
1108+
1109+
#[test]
1110+
fn msvc_prefer_clang_cl_over_msvc_disabled_by_env() {
1111+
reset_env();
1112+
std::env::set_var("CC_PREFER_CLANG_CL_OVER_MSVC", "0");
1113+
1114+
let test = Test::msvc_autodetect();
1115+
1116+
let compiler = test
1117+
.gcc()
1118+
.try_get_compiler()
1119+
.expect("Failed to get compiler");
1120+
1121+
assert!(compiler.is_like_msvc(), "Should still be MSVC-like");
1122+
assert!(!compiler.is_like_clang_cl(), "Should not use clang-cl");
1123+
std::env::remove_var("CC_PREFER_CLANG_CL_OVER_MSVC"); // Clean up after test
1124+
}
1125+
1126+
#[test]
1127+
fn msvc_prefer_clang_cl_over_msvc_disabled_by_env_precedence() {
1128+
reset_env();
1129+
std::env::set_var("CC_PREFER_CLANG_CL_OVER_MSVC", "0");
1130+
1131+
let test = Test::msvc_autodetect();
1132+
1133+
let compiler = test
1134+
.gcc()
1135+
.prefer_clang_cl_over_msvc(true)
1136+
.try_get_compiler()
1137+
.expect("Failed to get compiler");
1138+
1139+
assert!(compiler.is_like_msvc(), "Should still be MSVC-like");
1140+
assert!(!compiler.is_like_clang_cl(), "Should not use clang-cl");
1141+
std::env::remove_var("CC_PREFER_CLANG_CL_OVER_MSVC"); // Clean up after test
1142+
}
1143+
1144+
#[test]
1145+
fn msvc_prefer_clang_cl_over_msvc_enabled_by_env_precedence() {
1146+
reset_env();
1147+
std::env::set_var("CC_PREFER_CLANG_CL_OVER_MSVC", "1");
1148+
1149+
let test = Test::msvc_autodetect();
1150+
1151+
let compiler = test
1152+
.gcc()
1153+
.prefer_clang_cl_over_msvc(false)
1154+
.try_get_compiler()
1155+
.expect("Failed to get compiler");
1156+
1157+
assert!(
1158+
compiler.is_like_clang_cl(),
1159+
"clang-cl.exe should be identified as clang-cl-like, got {:?}",
1160+
compiler
1161+
);
1162+
assert!(
1163+
compiler.is_like_msvc(),
1164+
"clang-cl should still be MSVC-like"
1165+
);
1166+
std::env::remove_var("CC_PREFER_CLANG_CL_OVER_MSVC"); // Clean up after test
1167+
}
10841168
}

0 commit comments

Comments
 (0)