From 63eb6cdbeb78671d51e445c83ecf90f1bb9f16a3 Mon Sep 17 00:00:00 2001 From: Damoy Date: Fri, 23 Oct 2026 02:54:12 +0800 Subject: [PATCH] Fix MSVC CRT selection for Rust debug builds --- snmalloc-rs/README.md | 2 +- snmalloc-rs/snmalloc-sys/build.rs | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/snmalloc-rs/README.md b/snmalloc-rs/README.md index e7db9576d..f0cd64003 100644 --- a/snmalloc-rs/README.md +++ b/snmalloc-rs/README.md @@ -47,7 +47,7 @@ The following environment variables are automatically detected and propagated: - `OPT_LEVEL`: Propagated to the C++ compiler to ensure optimization parity between Rust and C++ components. ### Windows CRT Consistency -On Windows, the build script enforces static CRT linking (`/MT` or `/MTd`) across both `cc` and `cmake` builders. This prevents linker errors and ensures consistency when `snmalloc` is used as a global allocator. +On Windows, the build script uses dynamic linking (`/MD`) by default and static linking (`/MT`) when the `crt-static` target feature is enabled. **To get the crates compiled, you need to choose either `1mib` or `16mib` to determine the chunk configuration** diff --git a/snmalloc-rs/snmalloc-sys/build.rs b/snmalloc-rs/snmalloc-sys/build.rs index 224c9b6b1..31dd5b561 100644 --- a/snmalloc-rs/snmalloc-sys/build.rs +++ b/snmalloc-rs/snmalloc-sys/build.rs @@ -215,6 +215,12 @@ impl BuildConfig { } } +fn target_uses_static_crt() -> bool { + env::var("CARGO_CFG_TARGET_FEATURE") + .map(|features| features.split(',').any(|feature| feature == "crt-static")) + .unwrap_or(false) +} + trait BuilderDefine { fn define(&mut self, key: &str, value: &str) -> &mut Self; /// Set a CMake-style boolean option. @@ -264,7 +270,6 @@ impl BuilderDefine for cc::Build { .file(source_root.join("src/snmalloc/override/rust.cc")) .cpp(true) .debug(debug) - .static_crt(true) } fn compiler_define(&mut self, key: &str, value: &str) -> &mut Self { @@ -295,11 +300,21 @@ impl BuilderDefine for cmake::Config { } fn configure_cpp(&mut self, debug: bool, _source_root: &Path) -> &mut Self { + let static_crt = target_uses_static_crt(); + let runtime_library = if static_crt { + "MultiThreaded" + } else { + "MultiThreadedDLL" + }; + self.define("SNMALLOC_RUST_SUPPORT", "ON") .very_verbose(true) .define("CMAKE_SH", "CMAKE_SH-NOTFOUND") .always_configure(true) - .static_crt(true) + .static_crt(static_crt) + // Keep the CRT flavor aligned with Rust without enabling the + // Debug CRT for snmalloc's Debug profile. + .define("CMAKE_MSVC_RUNTIME_LIBRARY", runtime_library) .profile(if debug { "Debug" } else { "Release" }) } @@ -584,9 +599,8 @@ fn configure_linking(config: &BuildConfig) { println!("cargo:rustc-link-lib=userenv"); println!("cargo:rustc-link-lib=bcrypt"); println!("cargo:rustc-link-lib=ntdll"); - if config.debug { - println!("cargo:rustc-link-lib=msvcrtd"); - } else { + if !target_uses_static_crt() { + // Rust's MSVC target uses the release CRT for every profile. println!("cargo:rustc-link-lib=msvcrt"); } }