From 2e2bf1f3a52c6ec6be0d6dc972693e540e4093a2 Mon Sep 17 00:00:00 2001 From: roboomp Date: Thu, 13 Aug 2026 16:21:23 +0000 Subject: [PATCH] fix(natives): pin cmake opus build to static MSVC CRT (/MT) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The win32 addon static-CRT switch enabled the static_link_msvcrt cc feature, but audiopus_sys's bundled opus is built through the generated CMake toolchain, which pinned CMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL (/MD) as authoritative under CMP0091 NEW. The opus objects could then still emit /MD and pull VCRUNTIME140.dll / conflict with the static CRT the rest of the addon links, leaving the outcome dependent on compile- flag ordering. Pin CMAKE_MSVC_RUNTIME_LIBRARY to MultiThreaded (static release /MT) in the msvc toolchain.cmake so opus deterministically matches rustc's +crt-static and the static_link_msvcrt feature. Verified with a fully cold `bazel build //:natives-win32-x64-baseline` (opus recompiled): the produced .node imports no VCRUNTIME140.dll and no api-ms-win-crt-* — only core Windows system DLLs. Fixes #8439 --- bazel/toolchains/msvc/NOTES.md | 3 ++- bazel/toolchains/msvc/cc.bzl | 19 ++++++++++++------- docs/natives-build-release-debugging.md | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/bazel/toolchains/msvc/NOTES.md b/bazel/toolchains/msvc/NOTES.md index 1ba1177ab..6b1b33d15 100644 --- a/bazel/toolchains/msvc/NOTES.md +++ b/bazel/toolchains/msvc/NOTES.md @@ -102,7 +102,8 @@ exec hosts. Replaces cargo-xwin. defaults to the Debug config → `/MDd` → `msvcrtd.lib`, which the lean splat (like cargo-xwin's) does not carry; toolchain.cmake pins `CMAKE_TRY_COMPILE_CONFIGURATION=Release`, `CMAKE_POLICY_DEFAULT_CMP0091=NEW` - and `CMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL` (/MD everywhere). + and `CMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded` (static release `/MT` + everywhere, matching the addon's static-CRT policy — issue #8439). Verified on darwin: scratch `project(C)` + `add_executable` configures with "Clang 20.1.7 with MSVC-like command-line" and links a valid PE32+ exe through vs_link_exe with the wrapper rc/mt/linker. diff --git a/bazel/toolchains/msvc/cc.bzl b/bazel/toolchains/msvc/cc.bzl index 564aa0baf..627ae2906 100644 --- a/bazel/toolchains/msvc/cc.bzl +++ b/bazel/toolchains/msvc/cc.bzl @@ -124,15 +124,20 @@ set(CMAKE_CXX_COMPILER "${CMAKE_CURRENT_LIST_DIR}/bin/clang-cl") set(CMAKE_LINKER "${CMAKE_CURRENT_LIST_DIR}/bin/lld-link") set(CMAKE_RC_COMPILER "${CMAKE_CURRENT_LIST_DIR}/bin/llvm-rc") set(CMAKE_MT "${CMAKE_CURRENT_LIST_DIR}/bin/llvm-mt") -# The xwin splat carries release CRT import libs only (msvcrt.lib, no -# msvcrtd.lib — same as cargo-xwin). try_compile defaults to the Debug -# configuration, whose /MDd would demand the debug CRT; pin try_compile to -# Release and the runtime library to dynamic release /MD for every config -# (CMP0091 NEW makes CMAKE_MSVC_RUNTIME_LIBRARY authoritative even for -# projects with ancient cmake_minimum_required, e.g. bundled opus). +# The xwin splat carries release CRT import + static libs only (msvcrt.lib / +# libcmt.lib, no debug msvcrtd.lib / libcmtd.lib — same as cargo-xwin). +# try_compile defaults to the Debug configuration, whose debug CRT the splat +# lacks; pin try_compile to Release. The shipped win32 addon statically links +# the CRT (rustc +crt-static + the static_link_msvcrt cc feature; see +# bazel/defs.bzl and crates/pi-natives/BUILD.bazel), so pin the runtime library +# to the static release CRT /MT for every config as well — otherwise CMake's +# authoritative CMAKE_MSVC_RUNTIME_LIBRARY (CMP0091 NEW) would emit /MD for the +# bundled opus objects, which then import VCRUNTIME140.dll and conflict with the +# static CRT the rest of the addon links (issue #8439). Keep this in lock-step +# with the static_link_msvcrt feature: both must select the static CRT together. set(CMAKE_TRY_COMPILE_CONFIGURATION Release) set(CMAKE_POLICY_DEFAULT_CMP0091 NEW) -set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL) +set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded) """ _BUILD = """\ diff --git a/docs/natives-build-release-debugging.md b/docs/natives-build-release-debugging.md index 41985996e..02b77e1b1 100644 --- a/docs/natives-build-release-debugging.md +++ b/docs/natives-build-release-debugging.md @@ -217,7 +217,7 @@ bazelisk build --nobuild //:natives-win32-x64-baseline | rstest macro: "Cargo.toml not found" in a vendored test | rstest verifies `Cargo.toml` exists in the manifest dir | `compile_data = ["Cargo.toml"]` on the `rust_test` (see `crates/vendor/uu-tail/BUILD.bazel`) | | vendored tests fail on bare `test_data/...` paths / symlink into srcs | tests assume cargo's cwd, incompatible with runfiles execution | `tags = ["manual"]`; run via `cargo nextest` when touching the fork; hermetic sibling test covers the contract | | blake3 msvc: `ml64.exe` not found | cc-rs resolves MASM from build-script PATH on non-windows hosts | `bin/ml64.exe → llvm-ml -m64` shim in `@msvc_cc`, prepended via the `blake3` annotation PATH | -| audiopus_sys msvc: cmake demands VS generator / rc+mt tools; `try_compile` wants `msvcrtd.lib` | cross cmake on linux/mac hosts; Debug config → `/MDd` which the lean xwin splat lacks | `CMAKE_GENERATOR_x86_64_pc_windows_msvc=Ninja` + `@msvc_cc`'s `toolchain.cmake` (`CMAKE_TOOLCHAIN_FILE_x86_64_pc_windows_msvc`) pinning wrappers + Release try-compile + `/MD` | +| audiopus_sys msvc: cmake demands VS generator / rc+mt tools; `try_compile` wants `msvcrtd.lib` | cross cmake on linux/mac hosts; Debug config → `/MDd` which the lean xwin splat lacks | `CMAKE_GENERATOR_x86_64_pc_windows_msvc=Ninja` + `@msvc_cc`'s `toolchain.cmake` (`CMAKE_TOOLCHAIN_FILE_x86_64_pc_windows_msvc`) pinning wrappers + Release try-compile + `/MT` (static CRT, matches the addon policy) | | win32 link oddities generally | — | read `bazel/toolchains/msvc/NOTES.md` first: wrapper self-location, `lld-link` flavor/driver-link behavior, `LIB`, `/MD` CRT choice, xwin splat caveats | | `rust_test(crate = ...)` "can't find crate" at macro expansion | rmeta-only pipelined deps break macro_rules re-export harness compiles | rust pipelined_compilation stays OFF (`.bazelrc` note) | | build script can't find cmake/ninja | `--incompatible_strict_action_env` — no host env leaks | explicit `PATH` in the crate annotation (`MODULE.bazel`), not host env |