Skip to content

fix: make X11/Wayland backends Linux-only so GOOS=windows builds clean - #5

Merged
tannevaled merged 1 commit into
mainfrom
fix/windows-cross-build
Aug 9, 2026
Merged

fix: make X11/Wayland backends Linux-only so GOOS=windows builds clean#5
tannevaled merged 1 commit into
mainfrom
fix/windows-cross-build

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Problem

The module did not compile for GOOS=windows (or any non-unix GOOS). internal/x11 and internal/wayland used unix-only syscalls that were not build-guarded, so go build ./... compiled them everywhere and failed:

# github.com/go-widgets/window/internal/wayland
internal/wayland/transport.go:31:23: undefined: syscall.CmsgSpace
internal/wayland/seat.go:298:18:     undefined: syscall.Mmap
internal/wayland/shm.go:89:24:       undefined: syscall.Mmap
# github.com/go-widgets/window/internal/x11
internal/x11/conn.go:232:17:         undefined: syscall.UnixRights
internal/x11/shmbuf.go:63:18:        undefined: syscall.Mmap
internal/x11/shmbuf.go:53:9:         cannot use fd (uintptr syscall.Handle) as int ...

The top-level window package already stubbed non-Linux (open_linux.go / open_other.goErrUnsupported), but the internal backends leaked unix syscalls into the windows build.

Fix

Extract only the OS-specific primitives into build-tagged files, keeping every protocol/codec type and all transport-agnostic logic cross-platform (so their unit tests still build/run on every GOOS — the design already described in open_other.go):

  • internal/x11: syscalls_{linux,other}.go (anon file + mmap/munmap/close), conn_linux.go (unixRW SCM_RIGHTS fd passing)
  • internal/wayland: syscalls_{linux,other}.go (anon file + shm mmap + keymap mmap), transport_linux.go (unixTransport SCM_RIGHTS), conn_linux.go (New over *net.UnixConn)

Shared-memory syscalls now sit behind package-var indirection: real on Linux, ErrUnsupported stubs off Linux. No live Linux behavior changes. Test harnesses needing a real socketpair/mmap are tagged //go:build linux (wayland helpers split into helpers_test.go + helpers_linux_test.go); socket-free codec/protocol tests stay cross-platform.

CI

  • Coverage gate is now Linux-only (the backends are Linux-only).
  • macOS lane proves the codec + ErrUnsupported stub build/vet/test off Linux.
  • New cross-build matrix compiles windows/amd64, darwin/{arm64,amd64} and all six 64-bit Linux arches — the regression guard.

Verification (run, not asserted)

  • go build ./... clean: windows/amd64, darwin/{arm64,amd64}, linux/{amd64,arm64,riscv64,loong64,ppc64le,s390x}
  • CGO_ENABLED=0 go test ./... green on real linux/arm64 (Debian VM)
  • 100.0% coverage on internal/x11 and internal/wayland
  • go vet ./... clean on windows, darwin and linux (incl. -tags=integration)

🤖 Generated with Claude Code

The internal/x11 and internal/wayland backend packages leaked unix-only
syscalls (syscall.UnixRights, unix.CmsgSpace, Mmap/Munmap, socket/memfd/shm
calls) into every build. With `go build ./...` compiling all packages,
GOOS=windows failed:

  internal/wayland/transport.go:31: undefined: syscall.CmsgSpace
  internal/wayland/seat.go:298:    undefined: syscall.Mmap
  internal/x11/conn.go:232:        undefined: syscall.UnixRights
  internal/x11/shmbuf.go:63:       undefined: syscall.Mmap
  ... (cannot use fd int as syscall.Handle, etc.)

The top-level `window` package already stubbed non-Linux via
open_linux.go/open_other.go, but the internal backends were unguarded.

Fix: extract only the OS-specific primitives into build-tagged files,
keeping every protocol/codec type and all transport-agnostic logic
cross-platform (so their unit tests still build and run on every GOOS,
mirroring the design described in open_other.go):

  - internal/x11:     syscalls_{linux,other}.go (anon file, mmap/munmap/close),
                      conn_linux.go (unixRW SCM_RIGHTS fd passing)
  - internal/wayland: syscalls_{linux,other}.go (anon file, mmap, keymap mmap),
                      transport_linux.go (unixTransport SCM_RIGHTS),
                      conn_linux.go (New over *net.UnixConn)

The shared-memory syscalls now sit behind package-var indirection (real on
Linux, ErrUnsupported stubs off Linux); no live Linux behavior changes.
Test harnesses that need a real socketpair/mmap are tagged //go:build linux
(wayland helpers split into helpers_test.go + helpers_linux_test.go); the
socket-free codec/protocol tests stay cross-platform.

CI: coverage gate is now Linux-only (backends are Linux-only); macOS lane
proves the codec + ErrUnsupported stub build/pass off Linux; new cross-build
matrix compiles windows/amd64, darwin/{arm64,amd64} and all six 64-bit Linux
arches so this can't regress.

Verified: `go build ./...` clean on windows/amd64, darwin/{arm64,amd64} and
linux/{amd64,arm64,riscv64,loong64,ppc64le,s390x}; `go test ./...` green on
linux with 100.0% coverage on internal/x11 and internal/wayland.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit 53aad71 into main Aug 9, 2026
19 checks passed
@tannevaled
tannevaled deleted the fix/windows-cross-build branch August 9, 2026 10:23
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