From b2aa757af277b6d3cf231ddbe6a109bbc713c047 Mon Sep 17 00:00:00 2001 From: Yogthos Date: Thu, 2 Jul 2026 14:04:29 -0400 Subject: [PATCH] Windows release binaries (x86_64) via MSYS2/MinGW Adds a windows-latest job to the release matrix: MSYS2/MinGW-w64 toolchain, Chez 10.4.1 built from source (ta6nt), the same build-joltc flow, packaged as a zip of joltc.exe. The whole job runs in the msys2 shell so cc/xxd/paths behave; the produced binary is a plain Windows executable. Platform seams: bld-nt? with the winsock/COM/registry link set, no -rdynamic under MinGW, GetModuleFileName as the launcher's self-path on _WIN32, and built binaries (joltc itself and jolt-build outputs) normalize to a .exe suffix. workflow_dispatch added so the matrix can be dry-run without tagging; the release upload step only fires on tags. For #205. --- .github/workflows/release.yml | 73 +++++++++++++++++++++++++++++++++-- host/chez/build-joltc.ss | 2 +- host/chez/build.ss | 32 ++++++++++----- host/chez/stub/launcher.c | 6 +++ 4 files changed, 99 insertions(+), 14 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 732fbb0..6ecfd66 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,6 +12,7 @@ on: push: tags: - 'v*' + workflow_dispatch: {} # dry-run the build matrix without tagging permissions: contents: write # create/update the GitHub Release and upload assets @@ -26,10 +27,18 @@ jobs: include: - os: ubuntu-latest target: x86_64-linux + shell: bash # No x86_64-macos: GitHub is retiring the macos-13 Intel runner (jobs # queue forever). Intel Macs build from source. macos-14 is arm64. - os: macos-14 target: aarch64-macos + shell: bash + - os: windows-latest + target: x86_64-windows + shell: msys2 {0} + defaults: + run: + shell: ${{ matrix.shell }} steps: - uses: actions/checkout@v5 with: @@ -78,6 +87,54 @@ jobs: if: runner.os == 'macOS' run: brew install chezscheme lz4 + # --- Windows: MSYS2/MinGW-w64 toolchain + Chez built from source (ta6nt). + # The whole job runs in the msys2 shell so cc/xxd/paths behave; the + # produced joltc.exe is a plain Windows binary (no MSYS runtime dep). --- + - name: Set up MSYS2 (Windows) + if: runner.os == 'Windows' + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: false + install: >- + git make vim unzip zip + mingw-w64-x86_64-gcc + mingw-w64-x86_64-lz4 + mingw-w64-x86_64-zlib + + - name: Cache Chez Scheme (Windows) + if: runner.os == 'Windows' + id: cache-chez-win + uses: actions/cache@v4 + with: + path: chez-install + key: chez-${{ runner.os }}-v10.4.1-mingw64 + + - name: Build Chez Scheme from source (Windows) + if: runner.os == 'Windows' && steps.cache-chez-win.outputs.cache-hit != 'true' + run: | + git clone --depth 1 --branch v10.4.1 https://github.com/cisco/ChezScheme.git /tmp/chez-src + cd /tmp/chez-src + ./configure --threads --installprefix="$GITHUB_WORKSPACE/chez-install" + make -j"$(nproc)" + make install + + - name: Put chez on PATH (Windows) + if: runner.os == 'Windows' + run: | + printf '#!/bin/sh +exec "%s/chez-install/bin/scheme" "$@" +' "$GITHUB_WORKSPACE" > "$GITHUB_WORKSPACE/chez-install/bin/chez" + chmod +x "$GITHUB_WORKSPACE/chez-install/bin/chez" + echo "$GITHUB_WORKSPACE/chez-install/bin" >> "$GITHUB_PATH" + # cc is the build's compiler name; alias it to mingw gcc + printf '#!/bin/sh +exec gcc "$@" +' > /usr/local/bin/cc || printf '#!/bin/sh +exec gcc "$@" +' > "$GITHUB_WORKSPACE/chez-install/bin/cc" + chmod +x /usr/local/bin/cc 2>/dev/null || chmod +x "$GITHUB_WORKSPACE/chez-install/bin/cc" + - name: Show Chez version run: chez --version @@ -132,16 +189,24 @@ jobs: ver="${GITHUB_REF_NAME}" name="joltc-${ver}-${{ matrix.target }}" mkdir -p "dist/${name}" - cp target/release/joltc "dist/${name}/joltc" cp README.md LICENSE "dist/${name}/" - tar -C dist -czf "dist/${name}.tar.gz" "${name}" - ( cd dist && shasum -a 256 "${name}.tar.gz" > "${name}.tar.gz.sha256" ) + if [ "${{ runner.os }}" = "Windows" ]; then + cp target/release/joltc.exe "dist/${name}/joltc.exe" + ( cd dist && zip -r "${name}.zip" "${name}" && sha256sum "${name}.zip" > "${name}.zip.sha256" ) + else + cp target/release/joltc "dist/${name}/joltc" + tar -C dist -czf "dist/${name}.tar.gz" "${name}" + ( cd dist && shasum -a 256 "${name}.tar.gz" > "${name}.tar.gz.sha256" ) + fi ls -la dist - name: Upload to the GitHub Release + if: startsWith(github.ref, 'refs/tags/') uses: softprops/action-gh-release@v2 with: files: | dist/*.tar.gz dist/*.tar.gz.sha256 - fail_on_unmatched_files: true + dist/*.zip + dist/*.zip.sha256 + fail_on_unmatched_files: false diff --git a/host/chez/build-joltc.ss b/host/chez/build-joltc.ss index b2ab8bb..6151e22 100644 --- a/host/chez/build-joltc.ss +++ b/host/chez/build-joltc.ss @@ -245,6 +245,6 @@ ;; table so `build` can foreign-entry them to spill the bundled Chez boots. On ;; Linux dlsym can't see executable symbols otherwise (macOS exports them anyway). (bld-system (string-append - "cc -O2 -rdynamic -I'" bld-csv-dir "' -I'" jb-build "' '" jb-main-c "' '" + "cc -O2 " (if bld-nt? "" "-rdynamic ") "-I'" bld-csv-dir "' -I'" jb-build "' '" jb-main-c "' '" bld-csv-dir "/libkernel.a' -o '" jb-out "' " (bld-link-libs))) (display (string-append "build-joltc: wrote " jb-out "\n")) diff --git a/host/chez/build.ss b/host/chez/build.ss index e7f9816..1ca0847 100644 --- a/host/chez/build.ss +++ b/host/chez/build.ss @@ -57,6 +57,7 @@ ;; --- toolchain discovery ---------------------------------------------------- (define bld-machine (symbol->string (machine-type))) (define bld-osx? (bld-contains? bld-machine "osx")) +(define bld-nt? (bld-contains? bld-machine "nt")) ;; The Chez executable, for the isolated compile pass (see build-binary step 4). (define bld-chez @@ -94,14 +95,19 @@ ;; Link flags. macOS Homebrew layout for the kernel's lz4/zlib/ncurses deps. (define (bld-link-libs) - (if bld-osx? - (let ((lz4 (bld-sh-capture "brew --prefix lz4 2>/dev/null"))) - (string-append - (if (> (string-length lz4) 0) (string-append "-L" lz4 "/lib ") "") - "-llz4 -lz -lncurses -framework Foundation -liconv -lm")) - ;; Linux: the Chez kernel pulls in compression (lz4/z), the expression - ;; editor (ncurses + terminfo), threads, dlopen, libuuid, and clock_gettime. - "-llz4 -lz -lncurses -ltinfo -ldl -lm -lpthread -luuid -lrt")) + (cond + (bld-osx? + (let ((lz4 (bld-sh-capture "brew --prefix lz4 2>/dev/null"))) + (string-append + (if (> (string-length lz4) 0) (string-append "-L" lz4 "/lib ") "") + "-llz4 -lz -lncurses -framework Foundation -liconv -lm"))) + ;; Windows (ta6nt, MinGW-w64 under MSYS2): the Chez kernel pulls in + ;; compression, winsock, COM/UUID, and the registry. + (bld-nt? + "-llz4 -lz -lws2_32 -lrpcrt4 -lole32 -ladvapi32 -luser32 -lshell32 -lm") + ;; Linux: the Chez kernel pulls in compression (lz4/z), the expression + ;; editor (ncurses + terminfo), threads, dlopen, libuuid, and clock_gettime. + (else "-llz4 -lz -lncurses -ltinfo -ldl -lm -lpthread -luuid -lrt"))) ;; --- runtime manifest (mirrors host/chez/cli.ss's load order) --------------- ;; A line is either literal Scheme text to inline, or a tag whose emission the build @@ -411,7 +417,15 @@ ;; direct-link?: opt-in closed-world direct-linking (app->app calls bind directly, ;; no runtime redefinition). Off by default in every mode — release stays ;; dynamically linked. +(define (bld-suffix? s suf) + (let ((n (string-length s)) (m (string-length suf))) + (and (>= n m) (string=? (substring s (- n m) n) suf)))) (define (build-binary entry-ns out-path mode natives embed-dirs ext-roots direct-link? tree-shake?) + ;; Windows executables carry .exe; normalize here so the append-payload and + ;; cc paths agree and the shell can run the result. + (let ((out-path (if (and bld-nt? (not (bld-suffix? out-path ".exe"))) + (string-append out-path ".exe") + out-path))) ;; The self-contained path (jolt-embedded-bytes "stub/launcher") needs no csv ;; kernel files, no Chez, no cc — only the legacy cc path does. (unless (jolt-embedded-bytes "stub/launcher") (bld-check-toolchain)) @@ -558,7 +572,7 @@ (build-self-contained entry-ns out-path mode builddir flat-ss flat-so boot (bld-native-link-flags natives)) (build-with-cc entry-ns out-path mode builddir flat-ss flat-so boot boot-h main-c - (bld-native-link-flags natives)))))))) + (bld-native-link-flags natives))))))))) ;; --- self-contained link (in-process compile + append the boot to the stub) --- ;; compile-file runs against the DEFAULT interaction environment, so the boot's diff --git a/host/chez/stub/launcher.c b/host/chez/stub/launcher.c index 0cc7cee..29a270e 100644 --- a/host/chez/stub/launcher.c +++ b/host/chez/stub/launcher.c @@ -26,6 +26,12 @@ static int self_path(char *buf, uint32_t size) { /* _NSGetExecutablePath fills buf and reports the needed size on overflow. */ return _NSGetExecutablePath(buf, &size); } +#elif defined(_WIN32) +#include +static int self_path(char *buf, uint32_t size) { + DWORD n = GetModuleFileNameA(NULL, buf, size); + return (n == 0 || n >= size) ? -1 : 0; +} #else #include static int self_path(char *buf, uint32_t size) {