From 769a8a650e18b93df93feb036c9a7f95ec1f701f Mon Sep 17 00:00:00 2001 From: Sergey Cherepanoff Date: Tue, 4 Nov 2025 23:14:54 +0300 Subject: [PATCH] windows: Automatically find Windows SDK when building gpui (#38711) ### Summary This PR changes `gpui/build.rs` to look up the Windows SDK directory in the registry instead of falling back to a hard-coded path. --- ### Problem Currently, building `gpui` on Windows requires `fxc.exe` to be in `PATH` or at a predefined location (unless `GPUI_FXC_PATH` is set). This requires to maintain a certain build environment with proper paths/vars or to install the specific SDK version. It is possible to find the SDK automatically using the registry keys it creates upon installation. Specifically in `SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0` branch there are: * `InstallationFolder` telling the SDK installation location; * `ProductVersion` telling the SDK version in use. These keys provide enough information to locate the SDK binaries, with added robustness: * handles non-standard SDK installation path; * deterministically selects the latest SDK when multiple versions are present. --- ### Changes Made * **Updated `crates/gpui/build.rs`**: * added dependency on `winreg` * introduced `find_latest_windows_sdk_binary()` helper * updated fallback logic to use registry lookup This PR only changes the fallback location, and does not touch the established environment-based workflow. Release Notes: - N/A --- ### Impact Reduces manual configuration needed to build GPUI on Windows. --------- Co-authored-by: John Tur --- crates/gpui/Cargo.toml | 1 + crates/gpui/build.rs | 52 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index 3bec72b2f2726d6373449f6c6828943d7c086909..6523bbe526848c15053a4bad45dce208a5ecd7e0 100644 --- a/crates/gpui/Cargo.toml +++ b/crates/gpui/Cargo.toml @@ -253,6 +253,7 @@ util = { workspace = true, features = ["test-support"] } [target.'cfg(target_os = "windows")'.build-dependencies] embed-resource = "3.0" +windows-registry = "0.5" [target.'cfg(target_os = "macos")'.build-dependencies] bindgen = "0.71" diff --git a/crates/gpui/build.rs b/crates/gpui/build.rs index 83aea8a17911aa3d8f63938d3cccdd00dd0935c3..ec35ec0bc63113582a945c71198cd7bc14301dcc 100644 --- a/crates/gpui/build.rs +++ b/crates/gpui/build.rs @@ -248,6 +248,7 @@ mod macos { #[cfg(target_os = "windows")] mod windows { use std::{ + ffi::OsString, fs, io::Write, path::{Path, PathBuf}, @@ -325,6 +326,49 @@ mod windows { } } + /// Locate `binary` in the newest installed Windows SDK. + pub fn find_latest_windows_sdk_binary( + binary: &str, + ) -> Result, Box> { + let key = windows_registry::LOCAL_MACHINE + .open("SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0")?; + + let install_folder: String = key.get_string("InstallationFolder")?; // "C:\Program Files (x86)\Windows Kits\10\" + let install_folder_bin = Path::new(&install_folder).join("bin"); + + let mut versions: Vec<_> = std::fs::read_dir(&install_folder_bin)? + .flatten() + .filter(|entry| entry.path().is_dir()) + .filter_map(|entry| entry.file_name().into_string().ok()) + .collect(); + + versions.sort_by_key(|s| { + s.split('.') + .filter_map(|p| p.parse().ok()) + .collect::>() + }); + + let arch = match std::env::consts::ARCH { + "x86_64" => "x64", + "aarch64" => "arm64", + _ => Err(format!( + "Unsupported architecture: {}", + std::env::consts::ARCH + ))?, + }; + + if let Some(highest_version) = versions.last() { + return Ok(Some( + install_folder_bin + .join(highest_version) + .join(arch) + .join(binary), + )); + } + + Ok(None) + } + /// You can set the `GPUI_FXC_PATH` environment variable to specify the path to the fxc.exe compiler. fn find_fxc_compiler() -> String { // Check environment variable @@ -345,12 +389,8 @@ mod windows { return path.trim().to_string(); } - // Check the default path - if Path::new(r"C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\fxc.exe") - .exists() - { - return r"C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\fxc.exe" - .to_string(); + if let Ok(Some(path)) = find_latest_windows_sdk_binary("fxc.exe") { + return path.to_string_lossy().into_owned(); } panic!("Failed to find fxc.exe");