fix(natives): static-link win32 MSVC CRT so addon needs no VC++ redist
The shipped win32-x64 pi_natives addon linked the dynamic MSVC CRT (/MD)
and imported VCRUNTIME140.dll from the Visual C++ Redistributable, which
is absent on a clean Windows install. LoadLibrary of the extracted .node
then failed with error 126 ("The specified module could not be found"),
so omp could not start after a fresh `irm install.ps1 | iex`.
Static-link the CRT for the win32 addon: +crt-static for rustc (crate
BUILD select) plus the static_link_msvcrt cc feature enabled for win32 in
the native_addon transition, so its C deps (opus/cmake, tree-sitter,
blake3, ring) compile /MT in lock-step. The rebuilt .node imports only
core Windows system DLLs -- no VCRUNTIME140.dll, no api-ms-win-crt-*.
Fixes #8439
This commit is contained in:
+14
-1
@@ -16,19 +16,32 @@ _ADDON_RUSTC_FLAGS = [
|
||||
]
|
||||
|
||||
def _addon_transition_impl(settings, attr):
|
||||
# Statically link the MSVC CRT for the shipped win32 addon: rustc gets
|
||||
# +crt-static via the crate's rustc_flags select, and the C dependencies
|
||||
# (opus/cmake, tree-sitter, blake3, ring) must move to /MT in lock-step so
|
||||
# the final .node imports no VCRUNTIME140.dll from the Visual C++
|
||||
# Redistributable (absent on a clean Windows install -> dlopen error 126).
|
||||
# The static_link_msvcrt cc feature flips the toolchain compile flags that
|
||||
# rules_rust forwards to cc-rs/cmake as CFLAGS/CXXFLAGS; it is inert for the
|
||||
# zig/darwin toolchains, so scoping it to win32 is belt-and-suspenders.
|
||||
features = list(settings["//command_line_option:features"])
|
||||
if "win32" in str(attr.platform):
|
||||
features = features + ["static_link_msvcrt"]
|
||||
return {
|
||||
"//command_line_option:platforms": str(attr.platform),
|
||||
"//command_line_option:compilation_mode": "opt",
|
||||
"//command_line_option:features": features,
|
||||
"@rules_rust//rust/settings:lto": "thin",
|
||||
"@rules_rust//rust/settings:extra_rustc_flags": _ADDON_RUSTC_FLAGS,
|
||||
}
|
||||
|
||||
_addon_transition = transition(
|
||||
implementation = _addon_transition_impl,
|
||||
inputs = [],
|
||||
inputs = ["//command_line_option:features"],
|
||||
outputs = [
|
||||
"//command_line_option:platforms",
|
||||
"//command_line_option:compilation_mode",
|
||||
"//command_line_option:features",
|
||||
"@rules_rust//rust/settings:lto",
|
||||
"@rules_rust//rust/settings:extra_rustc_flags",
|
||||
],
|
||||
|
||||
@@ -22,9 +22,16 @@ exec hosts. Replaces cargo-xwin.
|
||||
work from Bazel actions (cwd = execroot) *and* from build scripts, where
|
||||
rules_rust `${pwd}`-expands `CC`/`AR` to absolute paths and cc-rs/cmake spawn
|
||||
tools from other cwds.
|
||||
- **CRT: dynamic `/MD`** (rules_cc's msvc branch default outside `dbg` without
|
||||
the `static_link_msvcrt` feature) — matches what napi/cc-rs produced under
|
||||
cargo-xwin (rust msvc targets default to dynamic CRT without `+crt-static`).
|
||||
- **CRT: static `/MT` for the shipped addon.** The toolchain *default* is
|
||||
dynamic `/MD` (rules_cc's msvc branch default outside `dbg` without the
|
||||
`static_link_msvcrt` feature), matching what napi/cc-rs produced under
|
||||
cargo-xwin. But `//:natives-win32-x64-baseline` overrides to static CRT:
|
||||
`-Ctarget-feature=+crt-static` for rustc (crate BUILD select) plus the
|
||||
`static_link_msvcrt` cc feature (enabled for win32 in the `native_addon`
|
||||
transition, `bazel/defs.bzl`) so the C deps compile `/MT` in lock-step.
|
||||
Without this the `.node` imports `VCRUNTIME140.dll` from the Visual C++
|
||||
Redistributable, which is absent on a clean Windows install and makes the
|
||||
loader's dlopen fail with error 126 (issue #8439).
|
||||
- **SSE floor in the wrapper, not annotations**: `-msse4.1 -msse4.2` live in the
|
||||
clang-cl wrapper, which only ever targets win32-x64 (baseline = x86-64-v2 ⊇
|
||||
SSE4.2). This is the old build-native.ts CFLAGS hack, windows-only by
|
||||
@@ -103,8 +110,9 @@ exec hosts. Replaces cargo-xwin.
|
||||
## What to verify on can.internal (linux-x64)
|
||||
|
||||
1. `bazel build //:natives-win32-x64-baseline` end-to-end link; check the
|
||||
produced `pi_natives.win32-x64-baseline.node` imports (dumpbin/llvm-readobj:
|
||||
expect VCRUNTIME140/api-ms-win-crt-* → `/MD`, no static CRT).
|
||||
produced `pi_natives.win32-x64-baseline.node` imports (dumpbin/llvm-readobj):
|
||||
expect **no** `VCRUNTIME140.dll` and **no** `api-ms-win-crt-*` (static CRT);
|
||||
only core Windows system DLLs (kernel32, ntdll, advapi32, …) should remain.
|
||||
2. LLVM 20.1.7 Linux-X64 binaries are built on a newish Ubuntu: confirm the
|
||||
kata runner image's glibc is ≥ 2.35-ish and has `libtinfo6`/`libstdc++6`
|
||||
(usual LLVM release-binary runtime deps).
|
||||
|
||||
@@ -40,6 +40,13 @@ rust_shared_library(
|
||||
# cdylib at all; napi musl addons have always linked the dynamic CRT.
|
||||
"//bazel/triples:x86_64-unknown-linux-musl": ["-Ctarget-feature=-crt-static"],
|
||||
"//bazel/triples:aarch64-unknown-linux-musl": ["-Ctarget-feature=-crt-static"],
|
||||
# Statically link the MSVC CRT so the shipped .node does not import
|
||||
# VCRUNTIME140.dll from the Visual C++ Redistributable, which is absent
|
||||
# on a clean Windows install and makes the loader's dlopen fail with
|
||||
# "The specified module could not be found" (error 126). The C deps are
|
||||
# switched to /MT in lock-step via the static_link_msvcrt cc feature in
|
||||
# the native_addon transition (bazel/defs.bzl).
|
||||
"//bazel/triples:x86_64-pc-windows-msvc": ["-Ctarget-feature=+crt-static"],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
version = "17.1.5",
|
||||
|
||||
@@ -64,7 +64,7 @@ Notes:
|
||||
|
||||
This mirrors the old cargo `ci` profile. Because the profile lives **in the transition**, a bare `bazel build //:natives-<t>` is always release-grade regardless of `-c`, and every addon shares one cache entry per (platform, source) pair. The rule then symlinks the produced shared library to the loader's canonical `pi_natives.<platform>-<arch>[-<variant>].node` name, scoped under the rule name (`bazel-bin/natives-<t>/…`) so gnu/musl outputs with identical basenames cannot collide at the package level.
|
||||
|
||||
Per-target codegen that is not part of the transition lives in `crates/pi-natives/BUILD.bazel` `rustc_flags` selects: `-Ctarget-cpu=x86-64-v2` (baseline) / `x86-64-v3` (modern) via `//bazel/variants`, the napi link args (`-Wl,-undefined,dynamic_lookup` on macOS, `-Wl,-z,nodelete` on linux — `build.rs`/`napi_build::setup()` is deliberately not wired in), and `-Ctarget-feature=-crt-static` for musl.
|
||||
Per-target codegen that is not part of the transition lives in `crates/pi-natives/BUILD.bazel` `rustc_flags` selects: `-Ctarget-cpu=x86-64-v2` (baseline) / `x86-64-v3` (modern) via `//bazel/variants`, the napi link args (`-Wl,-undefined,dynamic_lookup` on macOS, `-Wl,-z,nodelete` on linux — `build.rs`/`napi_build::setup()` is deliberately not wired in), `-Ctarget-feature=-crt-static` for musl, and `-Ctarget-feature=+crt-static` for win32-x64 msvc (paired with the `static_link_msvcrt` cc feature enabled in the `native_addon` transition so the C deps compile `/MT` in lock-step — the shipped `.node` then imports no `VCRUNTIME140.dll` from the VC++ Redistributable).
|
||||
|
||||
### 3) Platforms and toolchains
|
||||
|
||||
@@ -73,7 +73,7 @@ Per-target codegen that is not part of the transition lives in `crates/pi-native
|
||||
| linux gnu (x64/arm64) | `@zig_sdk//libc_aware/toolchain:linux_*_gnu.2.17` (hermetic zig cc) | glibc **2.17** portability floor — same floor the previous cross builds used |
|
||||
| linux musl (x64/arm64) | `@zig_sdk//libc_aware/toolchain:linux_*_musl` | dynamic CRT (`-Ctarget-feature=-crt-static` in the crate BUILD) |
|
||||
| darwin (x64/arm64) | host Xcode toolchain | Apple frameworks aren't redistributable; darwin addons build on mac hosts only |
|
||||
| win32-x64 msvc | `//bazel/toolchains/msvc` (`@msvc_cc`): clang-cl + lld-link + xwin CRT/SDK | hermetic cross-link from linux-x64 CI pods and darwin dev hosts; see `bazel/toolchains/msvc/NOTES.md` |
|
||||
| win32-x64 msvc | `//bazel/toolchains/msvc` (`@msvc_cc`): clang-cl + lld-link + xwin CRT/SDK | hermetic cross-link from linux-x64 CI pods and darwin dev hosts; **static CRT** (`+crt-static` + `static_link_msvcrt`) so the addon needs no VC++ Redistributable; see `bazel/toolchains/msvc/NOTES.md` |
|
||||
|
||||
Rust toolchains are nightly (pinned in `MODULE.bazel`), with repo-local musl re-registrations in `//bazel/toolchains` carrying an explicit `@zig_sdk//libc:musl` constraint (rules_rust's generated gnu and musl toolchains otherwise share (os, cpu) constraints).
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed `omp` failing to start on a clean Windows install with `Failed to load pi_natives native addon for win32-x64 ... The specified module could not be found` (LoadLibrary error 126). The shipped win32-x64 addon linked the dynamic MSVC CRT (`/MD`) and imported `VCRUNTIME140.dll` from the Visual C++ Redistributable, which is absent on a fresh Windows install. The addon now statically links the CRT (`+crt-static` for rustc plus the `static_link_msvcrt` cc feature for its C dependencies), so the `.node` imports only core Windows system DLLs ([#8439](https://github.com/can1357/oh-my-pi/issues/8439)).
|
||||
|
||||
## [17.3.0] - 2026-08-13
|
||||
|
||||
### Fixed
|
||||
|
||||
Reference in New Issue
Block a user