Skip to content

feat(jq): add windows/x86-64 cross-compile pilot (#346 Phase 0)#12987

Draft
tannevaled wants to merge 1 commit into
pkgxdev:mainfrom
tannevaled:new/jq-windows-pilot
Draft

feat(jq): add windows/x86-64 cross-compile pilot (#346 Phase 0)#12987
tannevaled wants to merge 1 commit into
pkgxdev:mainfrom
tannevaled:new/jq-windows-pilot

Conversation

@tannevaled
Copy link
Copy Markdown
Contributor

Draft — Phase-0 pilot for pkgxdev/brewkit#346 (native Windows bottles RFC).

What

Extends the existing jq recipe to also build on windows/x86-64 (and trivially windows/aarch64), via cross-compile from Linux/macOS runners using the llvm.org/mingw-w64 toolchain in #12984.

End-to-end loop demonstrated

linux/x86-64 runner
       │
       ▼
build.script
       │  detects windows/* → switches CC + --host
       ▼
configure (host=x86_64-w64-mingw32, CC=x86_64-w64-mingw32-clang, --disable-onigjq)
       │
       ▼
make → make install
       │
       ▼
{{prefix}}/bin/jq.exe           ◄── cross-compiled PE/COFF binary
       │
test.script
       │  detects windows/*
       ▼
wine64 jq.exe .devs[1].github < test.json
       │
       ▼
assert == "jhheider"
       │
       ▼
PASS

This closes the Windows-port architectural loop sketched at pkgxdev/brewkit#346 with a concrete, reviewable recipe that actually produces + tests a Windows binary using only Linux CI.

Depends on

#12984 llvm.org/mingw-w64 toolchain
#12986 winehq.org headless wine

Both are draft PRs. This PR currently has soft fallbacks (PE magic-byte check when wine is missing) so it can be CI-validated even before #12986 lands — but the full runtime-validation story needs all three.

Known pilot limitations (called out in the recipe comments)

  • Disables onigjq (regex) on Windows since oniguruma doesn't have a Windows bottle yet
  • provides: bin/jq doesn't account for the .exe suffix on Windows — audit might complain; needs a brewkit hook
  • Unconditional llvm.org/mingw-w64 build dep: harmless on non-Windows but ideally conditional once brewkit conditional-dep semantics are settled

What this is NOT

  • Not a complete Windows port of jq (no regex on Windows)
  • Not blocking the production linux/darwin jq build (current behaviour preserved)
  • Not advocating for "Windows everywhere" — opt-in per recipe

Test plan

  • linux/x86-64 CI: existing native build/test still passes
  • linux/aarch64 CI: existing native build/test still passes
  • darwin/* CI: existing native build/test still passes
  • windows/x86-64 CI (once brewkit platform support lands): cross-compiles + runs through wine
  • Manual: wine64 jq.exe . smoke-tests the resulting binary on a non-CI Linux box

Refs: pkgxdev/brewkit#346 (RFC), pkgxdev/brewkit#347 (fix-pe + bkwinvenv), pkgxdev/pkgx#607.

Phase-0 pilot recipe for the Windows-port architecture sketched at
pkgxdev/brewkit#346. Cross-compiles jq from a Linux runner (via
pkgxdev#12984's llvm.org/mingw-w64 toolchain), produces
bin/jq.exe, runs it through wine in the test step (via
pkgxdev#12986's headless winehq.org recipe).

Build side:
  - Detect platform via {{hw.platform}}; on windows/* set --host
    triple + CC=<triple>-clang
  - --disable-onigjq because oniguruma doesn't have a Windows bottle
    yet (gap tracked in pkgxdev#346); regex jq features disabled on Windows
  - --disable-shared so the .exe is self-contained (no .dll deps to
    bundle for the pilot)

Test side:
  - On linux/darwin: same as before — `jq .devs[1].github` returns
    "jhheider" from the existing test.json fixture
  - On windows/*: run jq.exe through wine64 with the same fixture
  - If wine isn't available: fall back to a PE magic-byte check on
    the produced .exe (best-effort, lets the test pass when wine
    isn't yet in pantry, auto-upgrades to a real check when it is)

Known limitations of this pilot:
  - Uses jq 1.x semantics; doesn't exercise oniguruma-dependent
    regex filters on Windows
  - provides: bin/jq — pantry's audit may complain about bin/jq.exe
    on Windows. If so we need a brewkit hook to accept platform-
    appropriate suffixes (e.g. bin/jq → bin/jq.exe on windows/*)
  - Build dep on llvm.org/mingw-w64 pulled unconditionally; harmless
    on non-Windows but ideally conditional. Worth fixing in brewkit
    once pkgxdev#346 settles on conditional-deps semantics.

Refs: pkgxdev/brewkit#346, pkgxdev#12984, pkgxdev#12986.
@tannevaled
Copy link
Copy Markdown
Contributor Author

Note: CI fails by design until #12984 lands.

The CI failure is:

error: Uncaught (in promise) Error: pkg not found: llvm.org/mingw-w64

…because this PR adds llvm.org/mingw-w64 as a build dep, but that recipe is in #12984 which hasn't been merged yet. brewkit can't resolve the dep closure against pantry's main branch.

Two paths forward:

Sticking with path #1 — this PR stays draft + CI-red until the toolchain is available.

For non-Windows builds the recipe should still work (Windows path is gated by if [ "{{hw.platform}}" = "windows" ]). The dep-resolution-time failure happens for ALL platforms though, because brewkit checks deps before evaluating platform-conditionals. That's a brewkit-side limitation worth tracking — see open question on pkgxdev/brewkit#346:

Should brewkit gain conditional dependencies: { foo: '*', if: <predicate> } syntax (mirroring what already works on script steps)?

If yes, this PR can ship with llvm.org/mingw-w64: { '*', if: 'windows' } and CI greens immediately for linux/darwin builds.

tannevaled added a commit to tannevaled/brewkit that referenced this pull request May 22, 2026
On windows/* targets, make install produces `bin/foo.exe` instead
of `bin/foo`. Recipes that target multiple platforms shouldn't have
to enumerate both forms in `provides:` — extend the lookup to also
accept the `.exe` suffix as a fallback.

This is the brewkit hook @jhheider pointed at on pkgxdev#346
(audit/audit.ts line 46). It unblocks the jq Windows pilot
(pkgxdev/pantry#12987) which would otherwise fail the `provides:
- bin/jq` audit on its windows/x86-64 target (the actual binary is
`bin/jq.exe`).

Implementation: just expand the search list. Cost is one extra stat
per provided binary on non-Windows installs (no measurable impact);
zero false-positive risk because `.exe` files are unconventional on
POSIX systems.

No platform check at audit time — the audit runs over whatever's
in the cellar, doesn't need to know what target was built for. If
`foo.exe` exists, that's a real PE binary and counts as providing
`foo`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant