fix: support native builds on Windows via MinGW-w64 (clang) and zig's bundled sysroot - #202
Open
techfreaque wants to merge 1 commit into
Open
fix: support native builds on Windows via MinGW-w64 (clang) and zig's bundled sysroot#202techfreaque wants to merge 1 commit into
techfreaque wants to merge 1 commit into
Conversation
… own bundled sysroot
scriptc had no working native (non-cross-compiled) Windows build path
at all: `nativePlatformArgs()` only had a `linux` branch, falling
through to empty flags on win32 for both host-native drivers
`resolveCc` can select (bare clang and `zig cc`) - which need OPPOSITE
handling on this platform.
**Bare clang**: its own default target on Windows is the MSVC ABI,
which has none of the POSIX compatibility headers (dirent.h,
unistd.h) or types (ssize_t) this project's runtime C sources need.
Fixed by auto-discovering a MinGW-w64 install (SCRIPTC_MINGW_ROOT env
var, else the common MSYS2/mingw-w64 install locations) and pointing
clang at it via --target=x86_64-w64-mingw32, plus the include/lib/gcc-
runtime/winpthread flags that target needs to actually link.
**zig cc**: already bundles its own mingw-w64 headers/CRT for its
`x86_64-windows-gnu` target (see this file's own module doc comment)
and needs no external MinGW at all - `--target=x86_64-w64-mingw32`
isn't even a valid zig target-query spelling and hard-errors
("UnknownOperatingSystem") if fed to it. `nativePlatformArgs` takes a
`viaZig` flag so the MinGW-discovery branch only applies to the bare-
clang path; zig's host-native branch gets empty targetArgs/linkArgs,
matching how `zig cc` already works standalone. `resolveCc` also
computes these lazily (only at the two host-native return sites),
so every zig-cc cross-compile target (iOS, Android, Linux, wasm, ...)
- which builds its own explicit targetArgs/linkArgs and never touches
this - keeps working on a Windows host with no local MinGW at all.
Verified on a real Windows machine with MSYS2/MinGW-w64 and zig 0.16
installed:
- `resolveCc({}, "win32")` (bare clang) -> MinGW target/include/link
flags; a minimal probe compiles AND links a real ~2MB native .exe.
- `resolveCc({SCRIPTC_CC: "zigcc"}, "win32")` -> empty targetArgs/
linkArgs; `zig cc hi.c -o hi.exe` with no extra flags compiles and
links a working ~780KB native .exe standalone (confirming the empty
flags are correct, not just "did not crash").
- Confirmed `--target=x86_64-w64-mingw32` actively breaks `zig cc`
before this fix (hard target-parse error), not just redundant.
- cc-driver.test.ts's cross-compile-target tests (linux host flags,
SCRIPTC_TARGET-without-zigcc rejection, x86_64-windows-gnu cross,
musl, regex, --dynamic engine archive) all pass unchanged.
- Could not execute the compiled native binaries end-to-end on this
particular machine (a Windows Defender Exploit Guard / Attack
Surface Reduction policy blocks running freshly-compiled unsigned
binaries here) - a local security policy, unrelated to the compiler
itself; the compile+link step (what this fix changes) completes and
produces a correct binary either way.
Contributor
|
@techfreaque is attempting to deploy a commit to the Vercel Labs Team on Vercel. A member of the Team first needs to authorize it. |
techfreaque
added a commit
to techfreaque/scriptc
that referenced
this pull request
Aug 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
scriptc build --dynamic(and any native, non-cross-compiled build) had no working path on Windows at all.nativePlatformArgs()only had alinuxbranch and fell through to empty flags forwin32, for both host-native driversresolveCccan select:dirent.h,unistd.h) or types (ssize_t) this project's runtime C sources need. Fails deep in a compile step with a cryptic missing-header error, no guidance toward the actual cause.zig cc(host-native, noSCRIPTC_TARGET) — already bundles its own mingw-w64 headers/CRT for itsx86_64-windows-gnutarget (per this file's own module doc comment), so it needs no external toolchain — this path just happened to also fall through to the same empty-flags branch, which is actually correct for it (nothing to add).Fix
nativePlatformArgs()gets awin32branch, gated by a newviaZigparameter so the two drivers get opposite treatment:SCRIPTC_MINGW_ROOTenv var, else the common MSYS2/mingw-w64 install locations) and targets it via--target=x86_64-w64-mingw32plus the include/lib/gcc-runtime/winpthread flags that target needs to actually link (MinGW's ownlibgcc.a/libgcc_eh.a, versioned and auto-discovered;-lwinpthreadforclock_gettime/nanosleep).zig cc: gets emptytargetArgs/linkArgs— matching how it already works standalone. This matters because--target=x86_64-w64-mingw32isn't even a valid zig target-query spelling; feeding it tozig cchard-errors (unable to parse target query 'x86_64-w64-mingw32': UnknownOperatingSystem), confirmed against a real zig 0.16 install.resolveCcalso computesnativePlatformArgslazily, only at the two host-native return sites — every zig-cc cross-compile target (iOS, Android, Linux, wasm, ...) builds its own explicittargetArgs/linkArgsand never touches this, so none of them require a local MinGW install on a Windows host either.Verification
On a real Windows machine with MSYS2/MinGW-w64 and zig 0.16 installed:
resolveCc({}, "win32")(bare clang) → MinGW target/include/link flags; a minimal probe compiles and links a real ~2MB native.exe.resolveCc({SCRIPTC_CC: "zigcc"}, "win32")→ emptytargetArgs/linkArgs;zig cc hi.c -o hi.exewith no extra flags compiles and links a working ~780KB native.exestandalone, confirming the empty flags are correct (not just "didn't crash").--target=x86_64-w64-mingw32actively breakszig cc(hard target-parse error) before this fix — this was a real regression risk, not just redundant flags.cc-driver.test.ts's cross-compile-target tests (linux host flags,SCRIPTC_TARGET-without-zigccrejection,x86_64-windows-gnucross, musl, regex,--dynamicengine archive) all pass unchanged.