SIGN IN SIGN UP
oven-sh / bun UNCLAIMED

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one

0 0 150 Rust

ci: build the Windows artifacts by cross-compiling from Linux (#31431)

Replaces the native Windows build lanes with cross-compiled ones — the
same model macOS uses since #31303. Follow-up to #31300, which added the
toolchain support and ran the cross builds as soft-fail validation lanes
alongside the native ones.

### What changes

- The three `windows` entries in `buildPlatforms` become `crossCompile:
true` (amazonlinux docker images), so they go through the regular
`build-cpp` / `build-rust` / `build-bun` split with the **same step
keys, labels, and artifact names** as before — just on the Linux fleet.
These are now the Windows artifacts the tests consume and the release
ships.
- The soft-fail `windows-cross` validation lanes are deleted (they're
the real lanes now).
- The windows **rust** step runs on the same amazonlinux image as the
cpp/link steps (configure provides the xwin sysroot + clang-cl env that
`cc`-crate build scripts need), instead of a native Windows VM.
- Stays on native Windows machines, consuming the cross-built artifacts:
the test shards, `windows-sign` (smctl is Windows-only), and the
x64-baseline `verify-baseline` step (Intel SDE).

### Consequences

- **All three windows lanes ship non-LTO for now.** The x64 cross
toolchain fully supports ThinLTO + cross-language LTO (`--lto=on`), but
LLVM's thin backends miscompile JSC on x86-64 at -O1+ (verified via the
experiment PRs: cross-language off changes nothing, backends at -O0 are
clean), so LTO is no longer the windows default — same situation that
keeps linux on full LTO. Windows LTO returns as a follow-up (full-LTO
COFF configuration or an upstream fix). The size wins (SAFEICF, filtered
+ zstd ICU) are LTO-independent and stay.
- No Azure Windows build VMs anymore — Windows machines are only used
where Windows is actually required (tests / signing / SDE).

### Risk / what this PR's CI proves

The cross-built **WebKit** artifacts (JSC/WTF/ICU incl. the
lazily-decompressed zstd data table) already went through the full
Windows test matrix in #31300 — the native lanes there linked against
them. The cross-built **bun.exe itself** has only had build-only
validation until now; this PR's CI run is the first time the Windows
test suites execute a fully cross-compiled bun.exe, which is exactly the
gate it needs to pass before merging. The
`ci-cpp-only`/`ci-rust-only`/`ci-link-only` split for a Windows target
on a Linux host is also exercised end-to-end here for the first time
(the validation lanes used the single-step full build).



### windows-aarch64 heap corruption: root-caused and fixed (in this PR)

The first full runs of the cross-built **windows-aarch64** binary died
with `STATUS_HEAP_CORRUPTION` (0xC0000374) on every cold `bun install`.
Crash dumps (procdump on the ARM64 fleet, symbolicated against the PDB)
showed segment-heap corruption in the small-block region holding
BoringSSL's parsed certificate/ASN.1 allocations, with the failing heap
calls coming from the TLS/cert path and from libarchive's
charset-converter setup on extraction workers. Two changes in this PR
address it (also proposed standalone as #31461):

- **Bind BoringSSL's mimalloc allocator hooks on Windows**
(`/INCLUDE:OPENSSL_memory_alloc/free/get_size`): the hooks are
referenced only as COFF weak externals, which never pull the defining
archive member, so they have silently never been active on Windows and
every BoringSSL allocation landed on the CRT's NT heap.
- **Cache libarchive's codepage lookup** (vendored patch):
`get_current_codepage()/get_current_oemcp()` queried
`setlocale(LC_CTYPE, NULL)` once per created charset converter — one per
extracted archive across many concurrent worker threads.

With the fix, the corruption is gone across all arm64 shards (zero
`0xC0000374` exits in two full runs). x64 and x64-baseline pass 8/8.

### windows-aarch64 DNS failures: root-caused and fixed (in this PR)

After the heap fix, the arm64 shards still failed c-ares-backed DNS
(`dns.resolve*`, `lookupService`, mongodb SRV) with ECONNREFUSED — the
resolver discovered no DNS servers and fell back to localhost, while the
natively built binary on the same machines was fine. Instrumented c-ares
+ binary diffing traced it to the **Universal CRT payload in the VS
manifest (what xwin downloads, any xwin version) shipping an ancient
arm64 UCRT** whose `__stdio_common_vsprintf` mis-formats on ARM64: every
discovered DNS server formatted as garbage, so the list parsed to
nothing — and every printf-family call in the cross arm64 binary was
suspect.

Fix (also proposed standalone as #31492): fetch the *serviced* UCRT
static libs from the official `Microsoft.Windows.SDK.CPP.<arch>` NuGet
(pinned `10.0.26100.8249`, the same libs a real Visual Studio install
has) into a cache overlay and add it as `/libpath:` ahead of
`/winsysroot`; plus bump xwin to 0.9.0 with `--sdk-version 10.0.26100` /
`--crt-version 14.44.17.14` pinned so manifest refreshes can't drift the
toolchain. Same SDK, same headers, same minimum supported Windows — only
the lib binaries are newer.

Validated on the arm64 fleet: DNS discovery now returns the real
resolver and all `dns.*` queries pass, and **all 24 windows test shards
(x64, x64-baseline, aarch64) are green** on the validation build.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
J
Jarred Sumner committed
f472981ecb9d614e5aa7d26035a6d04ef20406a5
Parent: 79a4029
Committed by GitHub <noreply@github.com> on 5/28/2026, 8:17:40 PM