releases: harden for Windows + one-click windows-build.cmd launcher

Addresses the known Windows build issues (see /mnt/archive/Issues.txt):
- windows-build.cmd: loads vcvarsall with a stable Windows SDK (WINSDK,
  default 10.0.26100.0) fixing kernel32.lib LNK1104; sets
  MSYS2_ARG_CONV_EXCL=* so Git Bash does not corrupt %LIB%; inits submodules
  (including the broken-pin self-heal) before building.
- release.sh: auto-detect the Title Update package (repo root or game dir);
  zip fallback to 7z or PowerShell Compress-Archive (Git Bash has no zip);
  upload JSON parsing falls back from python3/python to grep (Git Bash ships
  neither python).
This commit is contained in:
MiTHRAL 2026-08-27 14:02:24 -04:00
parent 4ec504ac6c
commit 81189576c0
3 changed files with 134 additions and 13 deletions

View file

@ -50,12 +50,37 @@ Per-platform notes:
| Platform | Build machine | Command |
|---|---|---|
| Linux | any Linux with the toolchain (README: Ubuntu 24.04 + Clang 20) | `./tools/release/release.sh` |
| Windows | a **Windows** machine (MSVC/clang-cl + Windows SDK, D3D12) | run the same script on Windows (`--os windows`) |
| macOS | an **Apple Silicon/Intel Mac** (Homebrew LLVM + MoltenVK, per README) | run the same script on macOS |
| Windows | a **Windows** machine (Visual Studio MSVC + Windows SDK, D3D12) | `tools\release\windows-build.cmd` (see below) |
| macOS | an **Apple Silicon/Intel Mac** (Homebrew LLVM + MoltenVK, per README) | `./tools/release/release.sh` |
Cross-compiling Windows/macOS from a Linux box is not practical for this
stack (D3D12 on Windows, Cocoa/MoltenVK on macOS need their native SDKs), so
each platform's release is built on that platform.
stack (D3D12 needs the Windows SDK, Cocoa/MoltenVK need a Mac), so each
platform's release is built on that platform.
### Windows build
On a Windows box, the known build issues (multiple Windows SDKs, Git Bash
`%LIB%` mangling, missing submodules) are handled by the launcher:
```bat
tools\release\windows-build.cmd --tag v2.0.2-mp1 --upload
```
It loads the MSVC environment (`vcvarsall.bat x64 <SDK>`), sets
`MSYS2_ARG_CONV_EXCL=*` so Git Bash doesn't corrupt `%LIB%`, initializes the
submodules (including the self-heal), and runs `release.sh`. Config via env:
- `VCVARSALL` — path to `vcvarsall.bat` (default: VS 18 Community x64).
- `WINSDK` — Windows SDK version (default `10.0.26100.0`; try `10.0.22621.0`
if yours differs — a broken SDK default is what causes `kernel32.lib`
`LNK1104`).
- `GITBASH` — path to Git for Windows `bash.exe`.
`release.sh` now auto-detects the Title Update package (repo root or
`game/`), falls back to PowerShell `Compress-Archive` when `zip` is missing,
and no longer requires `python3` for the upload JSON parsing. The Windows
build also needs the game dump (`game/default.xex` + `EAWebkit.xex`) and the
TU package present on that box (build-time only, never shipped).
## Option B — automated via Forgejo Actions (optional)

View file

@ -78,14 +78,46 @@ if [ ! -f "$GAME_ROOT/default.xex" ]; then
exit 1
fi
# ---- helpers (Windows Git Bash lacks zip/python; provide fallbacks) ---------
json_id() { # read JSON on stdin, print the value of "id"
if command -v python3 >/dev/null 2>&1; then
python3 -c "import sys,json
try: print(json.load(sys.stdin).get('id',''))
except Exception: print('')"
elif command -v python >/dev/null 2>&1; then
python -c "import sys,json
try: print(json.load(sys.stdin).get('id',''))
except Exception: print('')"
else
grep -o '"id":[0-9]*' | head -1 | cut -d: -f2
fi
}
make_zip() { # make_zip <zipname> <dir>
if command -v zip >/dev/null 2>&1; then
(cd "$(dirname "$2")" && zip -r "$(basename "$1")" "$(basename "$2")")
elif command -v 7z >/dev/null 2>&1; then
7z a -tzip "$1" "$2" >/dev/null
elif command -v powershell >/dev/null 2>&1; then
powershell -NoProfile -Command "Compress-Archive -Path '$2' -DestinationPath '$1' -Force"
else
echo "ERROR: no zip tool found (install zip, 7z, or use PowerShell)"; exit 1
fi
}
# ---- build ------------------------------------------------------------------
TU_ARGS=""
if [ -n "$TU" ]; then
if [ ! -f "$TU" ]; then echo "ERROR: title update package not found: $TU"; exit 1; fi
TU_ARGS="-DSKATE3_TITLE_UPDATE_PACKAGE=$TU"
elif [ -n "$(ls "$REPO"/TU_12K2276_* "$GAME_ROOT"/TU_12K2276_* 2>/dev/null | head -1)" ]; then
TU="$(ls "$REPO"/TU_12K2276_* "$GAME_ROOT"/TU_12K2276_* 2>/dev/null | head -1)"
echo "==> Using title update package: $TU"
TU_ARGS="-DSKATE3_TITLE_UPDATE_PACKAGE=$TU"
fi
echo "==> Release $TAG ($EXT) preset=$PRESET game=$GAME_ROOT"
echo "==> Configure (extra args: ${CMAKE_ARGS:-none})"
echo "==> Configure"
cmake --preset "$PRESET" -DSKATE3_GAME_DATA_ROOT="$GAME_ROOT" $TU_ARGS $CMAKE_ARGS
echo "==> Generate recompiled code"
cmake --build --preset "$PRESET" --target generate-all --parallel
@ -116,7 +148,7 @@ if [ -f "$OUT/game/default.xexp" ]; then
fi
cp README.md "$STAGE/"
rm -f "$NAME.zip"
zip -r "$NAME.zip" "$STAGE"
make_zip "$NAME.zip" "$STAGE"
rm -rf "$STAGE"
echo "==> Packaged: $NAME.zip ($(du -h "$NAME.zip" | cut -f1))"
sha256sum "$NAME.zip"
@ -132,15 +164,11 @@ if [ "$UPLOAD" = 1 ]; then
RELEASE_ID="$(curl -s -X POST "$INSTANCE/api/v1/repos/$REPO_FULL/releases" \
-H "$AUTH" -H "Content-Type: application/json" \
-d "{\"tag_name\":\"$TAG\",\"name\":\"Skate 3 Recomp $TAG\",\"target_commitish\":\"main\"}" \
| python3 -c "import sys,json
try: print(json.load(sys.stdin).get('id',''))
except Exception: print('')")"
| json_id)"
if [ -z "$RELEASE_ID" ]; then
RELEASE_ID="$(curl -s "$INSTANCE/api/v1/repos/$REPO_FULL/releases/tags/$TAG" -H "$AUTH" \
| python3 -c "import sys,json
try: print(json.load(sys.stdin).get('id',''))
except Exception: print('')")"
| json_id)"
fi
if [ -z "$RELEASE_ID" ]; then
echo "ERROR: could not create/find release '$TAG'"; exit 1
@ -148,9 +176,14 @@ except Exception: print('')")"
curl -s -X POST "$INSTANCE/api/v1/repos/$REPO_FULL/releases/$RELEASE_ID/assets" \
-H "$AUTH" -F "attachment=@$NAME.zip" -F "name=$NAME.zip" \
| python3 -c "import sys,json
| if command -v python3 >/dev/null 2>&1 || command -v python >/dev/null 2>&1; then
PY=python3; command -v python3 >/dev/null 2>&1 || PY=python
"$PY" -c "import sys,json
try:
a=json.load(sys.stdin); print('Uploaded asset', a.get('name'), a.get('size'), 'bytes')
except Exception as e: print('upload response parse failed:', e)"
else
echo "Upload request sent (no python to parse the response)"
fi
echo "==> Done: https://git.mithraic.cloud/$REPO_FULL/releases/tag/$TAG"
fi

View file

@ -0,0 +1,63 @@
@echo off
rem One-click Windows release build for skate3recomp-multiplayer.
rem
rem Fixes the known Windows build issues documented in /mnt/archive/Issues.txt
rem (and mirrored in docs/releases.md):
rem 1. stable Windows SDK so kernel32.lib resolves (vcvarsall with an SDK
rem version instead of the broken default),
rem 2. Git Bash %LIB% mangling (MSYS2_ARG_CONV_EXCL=*),
rem 3. missing rexglue submodules (git submodule update --init + self-heal).
rem
rem Usage (from a normal cmd.exe / PowerShell prompt):
rem tools\release\windows-build.cmd [--tag vX.Y.Z] [--upload]
rem
rem Config via environment variables:
rem VCVARSALL path to vcvarsall.bat (default: VS 18 Community x64)
rem WINSDK Windows SDK version (default 10.0.26100.0; try 10.0.22621.0
rem if yours is different)
rem GITBASH path to Git for Windows bash.exe
setlocal
if "%VCVARSALL%"=="" set "VCVARSALL=%ProgramFiles%\Microsoft Visual Studio\18\Community\VC\Auxiliary\Build\vcvarsall.bat"
if "%WINSDK%"=="" set "WINSDK=10.0.26100.0"
if "%GITBASH%"=="" set "GITBASH=%ProgramFiles%\Git\bin\bash.exe"
if not exist "%VCVARSALL%" (
echo [ERROR] vcvarsall.bat not found: %VCVARSALL%
echo Set VCVARSALL to your Visual Studio install, e.g.
echo "%%ProgramFiles%%\Microsoft Visual Studio\17\Community\VC\Auxiliary\Build\vcvarsall.bat"
exit /b 1
)
if not exist "%GITBASH%" (
echo [ERROR] Git Bash not found: %GITBASH%
echo Install Git for Windows or set GITBASH.
exit /b 1
)
echo [1/3] Loading MSVC environment (x64, SDK %WINSDK%)
call "%VCVARSALL%" x64 %WINSDK%
if errorlevel 1 (
echo [ERROR] vcvarsall failed. Try a different WINSDK, e.g.
echo set WINSDK=10.0.22621.0
exit /b 1
)
rem Prevent Git Bash from converting/corrupting %LIB% and semicolon paths.
set "MSYS2_ARG_CONV_EXCL=*"
rem Convert the repo path to forward slashes for Git Bash (%~dp0 is
rem tools\release\ with a trailing backslash; ..\.. reaches the repo root).
set "REPO=%~dp0..\.."
set "REPO=%REPO:\=/%"
echo [2/3] Initializing submodules (rexglue SDK + nested)
"%GITBASH%" --login -c "cd '%REPO%' && git submodule update --init --jobs 4 && bash tools/ci/init-submodules.sh"
if errorlevel 1 (
echo [ERROR] submodule init failed.
exit /b 1
)
echo [3/3] Building release
"%GITBASH%" --login -c "cd '%REPO%' && bash tools/release/release.sh %*"
exit /b %errorlevel%
endlocal