Skip to content

new(winehq.org): headless wine for Windows-binary CI testing#12986

Draft
tannevaled wants to merge 8 commits into
pkgxdev:mainfrom
tannevaled:new/winehq.org
Draft

new(winehq.org): headless wine for Windows-binary CI testing#12986
tannevaled wants to merge 8 commits into
pkgxdev:mainfrom
tannevaled:new/winehq.org

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Closes #12985.

What

Adds a winehq.org recipe — a minimal headless build of Wine sufficient to run console-only Windows binaries on a Linux host. Pilot scope: linux/x86-64 only.

Why

Unblocks #12984 (llvm.org/mingw-w64) — that recipe's test step is already wired with a soft-dep on winehq.org, so once this lands the cross-compile pilot upgrades from "PE magic-byte check" to "actually run the .exe and assert stdout". More broadly: any future Windows-targeting pantry recipe gets real runtime tests in the existing Linux CI infra (no GitHub Windows runners needed).

Architecture context: pkgxdev/brewkit#346 RFC.

Build configuration

Stripped down to the minimum needed for CLI tool execution:

Flag Why
--enable-archs=x86_64 64-bit only — halves build, sufficient for our use
--disable-tests skip wine's massive internal test suite
--without-x no X11 in CI
--without-opengl --without-osmesa --without-vulkan no 3D
--without-alsa --without-pulse --without-oss no audio
--without-sdl --without-gstreamer no multimedia
--without-cups --without-gphoto --without-usb --without-v4l2 --without-sane --without-udev --without-pcap no peripherals
--without-fontconfig --without-krb5 --without-capi --without-cms other unneeded subsystems

Build deps from pantry: gnu.org/bison, github.com/westes/flex, perl.org, gnu.org/gettext, freetype.org, gnutls.org, zlib.net, plus the toolchain (gnu.org/{make,gcc,binutils}).

Test

wine64 --version   # expects "wine-X.Y"

That's all. Anything more substantive belongs in consumer recipes (e.g., llvm-mingw runs hello.exe through wine).

Limitations / future work

  • linux/aarch64 — wine can run aarch64 Windows binaries on aarch64 Linux, but x86-64 Windows binaries need qemu-user or Hangover. Out of scope for pilot.
  • darwin — wine 11.x ships macOS support but configuration is meaningfully different (32-bit deprecation dance). Follow-up.
  • wine-staging — we pick the stable branch; staging is generally OK too but adds churn.
  • MinGW-built Wine--with-mingw produces wine with better Windows compat for the win-side DLLs, but requires a Linux-hosted mingw toolchain present at wine build time (which we now have via new(llvm.org/mingw-w64): LLVM-based mingw-w64 cross-compiler (Windows-target toolchain) #12984). Possible follow-up to unlock harder-to-emulate APIs.

Test plan

Refs: #12985 (this issue), pkgxdev/brewkit#346 (Windows port RFC), pkgxdev/pkgx#607 (platform megaticket).

Minimal headless wine build — no X11, no OpenGL, no audio, 64-bit only,
no wine tests. Aimed at the use case described in pkgxdev#12985
and the brewkit#346 RFC: run cross-compiled .exe files inside brewkit's
Linux test sandbox to validate native-Windows pantry recipes.

What it provides:
  - bin/wine, bin/wine64  (the runtime)
  - bin/winepath          (path-translation helper)
  - bin/wineserver        (the wine background service)
  - bin/winecfg           (mostly stub-useful, included for completeness)

What it does NOT support:
  - GUI apps (no X11)
  - 3D / Vulkan / OpenGL
  - Audio (ALSA, Pulse, OSS all disabled)
  - Multimedia (SDL, gstreamer disabled)
  - Peripherals (USB, CUPS, gphoto, V4L2, SANE all disabled)
  - 32-bit Win binaries (--enable-archs=x86_64 only)
  - Wine's own test suite (--disable-tests)

Pilot platform: linux/x86-64 only. linux/aarch64 + darwin/* are
follow-ups (wine-side complications: aarch64 needs qemu-user or
hangover for x86-64 Win binaries; darwin needs the macOS-32-bit dance).

Test step: `wine64 --version` returns "wine-X.Y" — proves the binary
loads + can run a basic console command. Recipes that depend on wine
(starting with pkgxdev#12984's llvm-mingw test step) get the
full runtime check for free.

Refs: pkgxdev#12985 (this issue), pkgxdev/brewkit#346 (RFC).
Brewkit's github: codepath silently ignores match:, so my previous
regex didn't filter anything — pantry picked wine-11.9 (dev release)
which lives in dl.winehq.org/source/11.x/, not /11.0/, so the URL
template 404'd.

Switch to url: mode (same shape as gnu.org/glibc):
  url: https://dl.winehq.org/wine/source/
  match: /\d{2,}\.0\//      # only stable major-version directories
  strip: /\//

Picks the latest stable (currently wine-11.0). Excludes 11.x/ dev
release dirs because match looks for an exact \d.0/ pattern.
CI surface: `configure: error: x86_64 PE cross-compiler not found`
because --enable-archs=x86_64 implicitly requires a mingw cross-
compiler on PATH (to build wine's Windows-side DLLs from source).

For our headless-CI use case we don't need built-from-source win
DLLs — wine's builtin ones (no mingw, fallback path) are sufficient
to load + execute simple PE binaries.

Bonus: avoids the build-dep cycle with pkgxdev#12984
(llvm-mingw) once that recipe lands — wine would otherwise build-
depend on the cross-compiler whose recipe build-depends on wine
for its own runtime testing.
@tannevaled

Copy link
Copy Markdown
Contributor Author

Round 3 finding: wine is also blocked on #12968.

--without-mingw doesn't fully disable the cross-compiler requirement — --enable-archs=x86_64 still triggers wine's configure to look for an x86_64 PE compiler:

configure: error: x86_64 PE cross-compiler not found.
This is an error since --enable-archs=x86_64 was requested.

That makes sense: wine MUST build its own Windows-side DLLs (kernel32, ntdll, …) for the requested target arch, because those DLLs interpose Windows API calls into Linux syscalls. There's no "ship without Windows-side DLLs" path.

So wine builds need a mingw cross-compiler. Adding llvm.org/mingw-w64 as a build dep would normally fix this — but:

pkgxdev/pantry#12968  (glibc, approved/awaiting merge)
       │
       │ (unblocks)
       ▼
pkgxdev/pantry#12984  (llvm-mingw, currently can't run clang)
       │
       │ (build dep)
       ▼
THIS PR (wine)

So this PR's full unblock chain is #12968#12984 → this.

For now: leaving the recipe with the current --enable-archs=x86_64 + --without-mingw combo. Once #12984 becomes buildable I'll add it as a build dep and the configure should pass.

(Side note: --without-mingw does prevent wine from REQUIRING mingw post-configure, but it doesn't override --enable-archs's implicit PE-compiler requirement. Wine's configure has both knobs but --enable-archs is the stronger one.)

jhheider added a commit to tannevaled/pantry that referenced this pull request Jun 12, 2026
note that this should be updated once pkgxdev#12986 is merged.
tannevaled and others added 3 commits June 13, 2026 13:09
configure aborted with `x86_64 PE cross-compiler not found`: modern Wine
builds its built-in DLLs as real PE binaries and has no ELF-builtin
fallback, so `--without-mingw` doesn't avoid the requirement — it still
needs a PE cross-compiler. Now that llvm.org/mingw-w64 is in main, add it
as a build dep (it provides x86_64-w64-mingw32-{gcc,clang}) and switch to
`--with-mingw`. No build-dep cycle: the mingw recipe only uses Wine in its
test step.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ished

Validated locally on Debian: `./configure --with-mingw --enable-archs=x86_64`
(and aarch64) detects the mingw PE cross-compiler and succeeds. The earlier
CI red likely built mingw-w64 from source inline (bottle not yet published);
re-running against the published bottle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tannevaled

Copy link
Copy Markdown
Contributor Author

Hey @jhheider — dug into the x86_64 PE cross-compiler not found failure pretty hard (reproduced wine's configure on a clean Debian + pkgx, both arm64 native and an x86_64 amd64 chroot via qemu-user with real glibc). Summary in case it saves you time:

The recipe is correct. With --with-mingw + a llvm.org/mingw-w64 build dep, ./configure --enable-archs=x86_64 --with-mingw … passes the PE-compiler probe outside brewkit:

env …supports -target x86_64-windows … --no-default-config
arm64 + pkgx (raw) ✅ yes
x86_64 + pkgx (raw) yes
x86_64 + brewkit CI ❌ no → "PE cross-compiler not found"

Ruled out as the cause of the CI no (each tested in the x86_64 chroot):

  • host arch, and missing libc6-dev (CI has it for the host gcc)
  • brewkit's linker shim (lld/lld-link → /usr/bin/$tool): llvm-mingw's clang invokes lld-link by absolute path, so the PATH shim is bypassed — fake-shimming it leaves the probe yes
  • brewkit's compiler shim (clang → ruby wrapper): llvm-mingw's clang-target-wrapper.sh resolves clang via $DIR=$(get_dir $0), also absolute → bypassed
  • brewkit's injected CFLAGS=-fPIC / CXXFLAGS=-fPIC / LDFLAGS=-pie (exported them explicitly — probe stays yes)

So the no is something specific to the brewkit build sandbox on the x86_64 runner that I can't reproduce off the actual runner. Could you grab the config.log from a failed wine run and paste the conftest block around the x86_64-w64-mingw32-gcc works… no? The exact compile/link error there should pin it. The probe command is:

x86_64-w64-mingw32-gcc -o conftest.exe -g -O2 -target x86_64-windows -fuse-ld=lld --no-default-config -Wl,-subsystem:console -Wl,-WX -Werror=unknown-warning-option -Werror=unused-command-line-argument -Werror=ignored-optimization-argument -Werror=unsupported-floating-point-opt -nostdlib -nodefaultlibs conftest.c

(Recipe fix is pushed; the rest of the CI is green.) Thanks!

@jhheider

Copy link
Copy Markdown
Contributor

Best way to get the conf log is to cat it in the build script.

include debugging cat of config.log
@jhheider

Copy link
Copy Markdown
Contributor

looks like glibc version needs; this is a good opportunity to test the libc wrapper tech.

jhheider pushed a commit to tannevaled/pantry that referenced this pull request Jun 15, 2026
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.
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.

new(winehq.org): wine in pantry — needed for Windows-binary CI testing

2 participants