Skip to content

ci(windows): Windows build in CI, and portable zips for x86_64 and aarch64 - #331

Merged
joske merged 11 commits into
masterfrom
feat/windows-release
Nov 4, 2026
Merged

joske merged 11 commits into
masterfrom
feat/windows-release

Conversation

@joske

@joske joske commented Nov 4, 2026

Copy link
Copy Markdown
Owner

CI now builds yserver on Windows, and produces portable zips for x86_64 and aarch64 (Windows on ARM).

  • The zip: yserver-<version>-windows-<arch>.zip, about 5 MB. Unzip it anywhere and run start-yserver.cmd.
    • The launcher creates a cookie in %LOCALAPPDATA%\yserver\Xauthority if there isn't one, then starts yserver. The mode comes from Settings.
    • README.txt explains DISPLAY and XAUTHORITY for WSL and remote machines, and the software-rendering fallback.
  • Nothing to install:
    • The C runtime, libxkbcommon and freetype are linked statically. The exe imports only Windows system DLLs, and the packaging script fails if a runtime DLL import comes back.
    • Vulkan comes with every GPU driver.
    • The XKB data ships in xkb\, built from xkeyboard-config 2.48 with its checksum verified. yserver finds it next to the exe when XKB_CONFIG_ROOT isn't set.
  • No Vulkan device: yserver now explains the likely cause (no GPU driver, Microsoft Basic Display Adapter, an older Intel GPU, or a VM), and points to lavapipe (mesa-dist-win) with VK_DRIVER_FILES as the software fallback.
  • Licenses: included for everything statically linked: libxkbcommon, freetype, zlib, libpng, bzip2, brotli, xkeyboard-config, and the Rust crates.
  • CI: a windows job on windows-latest and windows-11-arm runs clippy, builds the zip and uploads it as an artifact. Both run in parallel with the existing jobs and finish before the BSD ones.
    • vcpkg is pinned to 2026.10.16 and its build output is cached. glslc comes from the pinned, checksum-verified Vulkan SDK.
    • A local overlay of libxkbcommon's vcpkg port drops X11 support, which we don't use. Without it, vcpkg built libX11 and libxcb through MSYS2, which takes over 85 minutes on the ARM runner.
    • ci.yml can now also be started by hand (workflow_dispatch). Releases build the zips through it but don't attach them yet.

Verification:

  • CI: both Windows jobs pass, from scratch and with the cache, building the C libraries plus glslc in under 2 minutes on x86_64 and about 4 on arm64. dumpbin /dependents on both zips' exes shows only system DLLs.
  • In a Windows 11 VM:
    • The x86_64 zip, unzipped fresh, starts from start-yserver.cmd and uses the bundled XKB data.
    • An xterm connects from Linux over TCP.
    • Settings' mode can be changed, and Explorer shows the yserver icon.
  • Not tested yet: the aarch64 zip on real Snapdragon hardware.

Refs #27

🤖 Generated with Claude Code

joske and others added 11 commits November 4, 2026 18:05
…er.exe

Without XKB_CONFIG_ROOT, libxkbcommon looks in the vcpkg prefix it was
built in, so the server could not start anywhere else. An include path,
not a set_var: libxkbcommon reads the variable with the CRT's getenv,
which does not see SetEnvironmentVariableW. The root used is logged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"required Vulkan extension VK_KHR_surface is not available" was all a
machine without a Vulkan driver got. Now the error says what the loader
found (no loader, no driver, or the devices and their Vulkan versions)
and points at lavapipe from mesa-dist-win as the fallback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tools/windows/package.ps1 builds yserver-<version>-windows-<arch>.zip for
x86_64 or aarch64: yserver.exe linked against vcpkg's static libraries on
the DLL CRT (dumpbin-checked for non-system imports), the XKB data, a
launcher that makes a cookie and starts rootless, a README, and the
licenses of yserver, the C libraries and the Rust crates.
tools/windows/build-xkb-data.sh builds the XKB data from the
xkeyboard-config 2.48 release tarball, sha256-pinned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Linux job builds the XKB data once; a matrix over windows-latest and
windows-11-arm installs the vcpkg ports (with a binary cache), runs
clippy and uploads the zip. workflow_dispatch so a branch can run it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The xkbcommon crate's #[link] is dylib-kind, so its calls go through
__imp_ pointers that vcpkg's static library does not define: 73
unresolved externals. A static -l in RUSTFLAGS overrides that kind.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
actions/cache saves at job end only when the job succeeds, so a failure
after the vcpkg step threw away a 20-minute shaderc build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A cold vcpkg install built shaderc and, through the libxkbcommon port,
libx11 and libxcb with autotools under MSYS2 for both the target and
the host triplet; on ARM64 MSYS2 runs emulated and took over 85 minutes.
glslc now comes from the pinned, sha256-checked Vulkan SDK installer,
libxkbcommon from an overlay port without xkbcommon-x11, and the host
triplet is the release-only target triplet. vcpkg-env.ps1 is now
build-env.ps1. Cold vcpkg install on an x64 VM: 56 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…++ redistributable

Rust builds with +crt-static (build-env.ps1's RUSTFLAGS) and the vcpkg
libraries with the static-CRT x64/arm64 release triplets. The packaging
check now refuses vcruntime140.dll and the api-ms-win-crt-* imports.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rootless is the default now, and --rootless would fix the mode and lock
it in the Settings dialog. README.txt says where the mode is chosen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@joske
joske merged commit 94d879a into master Nov 4, 2026
10 of 11 checks passed
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