From 47502d7826c9e757cfe7c0cf39489c4cb364c331 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Sat, 13 Dec 2025 10:09:23 +0000 Subject: [PATCH] MSVC: Fallback to bundled CMake if present Co-Authored-By: Matej Knopp --- src/lib.rs | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index be5c165..2b55a10 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -897,8 +897,9 @@ impl Config { dst } - fn cmake_executable(&mut self) -> OsString { + fn cmake_executable(&mut self, target: &str) -> OsString { self.getenv_target_os("CMAKE") + .or_else(|| find_cmake_executable(target)) .unwrap_or_else(|| OsString::from("cmake")) } @@ -912,10 +913,10 @@ impl Config { .getenv_target_os("EMCMAKE") .unwrap_or_else(|| OsString::from("emcmake")); let mut cmd = Command::new(emcmake); - cmd.arg(self.cmake_executable()); + cmd.arg(self.cmake_executable(target)); cmd } else { - Command::new(self.cmake_executable()) + Command::new(self.cmake_executable(target)) } } @@ -925,10 +926,10 @@ impl Config { .getenv_target_os("EMMAKE") .unwrap_or_else(|| OsString::from("emmake")); let mut cmd = Command::new(emmake); - cmd.arg(self.cmake_executable()); + cmd.arg(self.cmake_executable(target)); cmd } else { - Command::new(self.cmake_executable()) + Command::new(self.cmake_executable(target)) } } @@ -1166,6 +1167,31 @@ fn try_canonicalize(path: &Path) -> PathBuf { path } +#[cfg(windows)] +fn find_cmake_executable(target: &str) -> Option { + use cc::windows_registry::find_tool; + + // Try to find cmake.exe bundled with MSVC, but only if there isn't another one in path + let cmake_in_path = env::split_paths(&env::var_os("PATH").unwrap_or(OsString::new())) + .any(|p| p.join("cmake.exe").exists()); + if cmake_in_path { + None + } else { + find_tool(target, "devenv").and_then(|t| { + t.path() + .join("..\\CommonExtensions\\Microsoft\\CMake\\CMake\\bin\\cmake.exe") + .canonicalize() + .ok() + .map(OsString::from) + }) + } +} + +#[cfg(not(windows))] +fn find_cmake_executable(_target: &str) -> Option { + None +} + #[cfg(test)] mod tests { use super::uses_named_pipe_jobserver;