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).
189 lines
No EOL
7.8 KiB
Bash
Executable file
189 lines
No EOL
7.8 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Build a Skate 3 recomp release from this checkout and optionally publish it
|
|
# to a Forgejo/Gitea Release.
|
|
#
|
|
# IMPORTANT: the release zip contains ONLY the recompiled binaries
|
|
# (skate3 + librexruntime.so + ghost_relay + README) - NO game files. Players
|
|
# bring their own ISO and the in-app installer extracts it. The game dump
|
|
# (default.xex + data/webkit/EAWebkit.xex) is required at BUILD TIME only,
|
|
# because codegen translates the actual Xbox 360 binary into C++ source; it
|
|
# is never included in, or uploaded with, the release.
|
|
#
|
|
# Usage:
|
|
# ./tools/release/release.sh # build this platform, no upload
|
|
# ./tools/release/release.sh --tag v1.0.0 --upload # build + publish
|
|
# ./tools/release/release.sh --game-root /path/to/game --tu /path/to/TU_12K2276_...
|
|
#
|
|
# Options:
|
|
# --tag TAG release tag/version (default: last git tag or 'dev')
|
|
# --game-root DIR extracted game dump (default: $REPO/game)
|
|
# --tu FILE optional Title Update STFS package for codegen
|
|
# --os linux|windows|macos override platform (default: host OS)
|
|
# --cmake-args "..." extra flags appended to every cmake configure
|
|
# call (e.g. -DCMAKE_C_COMPILER=clang-22
|
|
# -DCMAKE_CXX_COMPILER=clang++-22
|
|
# -DCMAKE_LINKER=ld.lld on distros without clang-20)
|
|
# --upload publish the zip to a Forgejo Release
|
|
#
|
|
# Env for --upload:
|
|
# GITEA_TOKEN Forgejo token with write:repository (release) scope
|
|
# FORGEJO_REPO default "ad3laid3/skate3recomp-multiplayer"
|
|
# FORGEJO_INSTANCE default "https://git.mithraic.cloud"
|
|
|
|
set -euo pipefail
|
|
|
|
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
cd "$REPO"
|
|
|
|
UPLOAD=0
|
|
TAG=""
|
|
GAME_ROOT="${SKATE3_GAME_DATA_ROOT:-$REPO/game}"
|
|
TU="${SKATE3_TITLE_UPDATE_PACKAGE:-}"
|
|
OS_ARG=""
|
|
CMAKE_ARGS=""
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--tag) TAG="${2:?--tag needs a value}"; shift 2;;
|
|
--game-root) GAME_ROOT="$2"; shift 2;;
|
|
--tu) TU="$2"; shift 2;;
|
|
--os) OS_ARG="$2"; shift 2;;
|
|
--cmake-args) CMAKE_ARGS="$2"; shift 2;;
|
|
--upload) UPLOAD=1; shift;;
|
|
-h|--help)
|
|
sed -n '2,32p' "$0"; exit 0;;
|
|
*) echo "unknown argument: $1"; exit 2;;
|
|
esac
|
|
done
|
|
|
|
# ---- platform ---------------------------------------------------------------
|
|
UNAME_S="$(uname -s 2>/dev/null || echo Windows)"
|
|
case "${OS_ARG:-$UNAME_S}" in
|
|
linux|Linux) PRESET="linux-relwithdebinfo"; BIN="skate3"; LIB="librexruntime.so"; EXT="Linux";;
|
|
windows|Windows|MINGW*|MSYS*|CYGWIN*)
|
|
PRESET="relwithdebinfo"; BIN="skate3.exe"; LIB="librexruntime.dll"; EXT="Windows";;
|
|
macos|macOS|Darwin) PRESET="macos-relwithdebinfo"; BIN="skate3"; LIB="librexruntime.dylib"; EXT="macOS";;
|
|
*) echo "unsupported platform: ${OS_ARG:-$UNAME_S} (set --os linux|windows|macos)"; exit 2;;
|
|
esac
|
|
|
|
if [ -z "$TAG" ]; then
|
|
TAG="$(git describe --tags --always 2>/dev/null || echo dev)"
|
|
fi
|
|
VER="${TAG#v}"
|
|
NAME="Skate3Recomp-$EXT-$VER"
|
|
|
|
if [ ! -f "$GAME_ROOT/default.xex" ]; then
|
|
echo "ERROR: game dump not found at $GAME_ROOT (need default.xex + data/webkit/EAWebkit.xex)"
|
|
echo " It is required for codegen; it is NOT shipped in the release."
|
|
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"
|
|
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
|
|
echo "==> Reconfigure (generated sources)"
|
|
cmake --preset "$PRESET" -DSKATE3_GAME_DATA_ROOT="$GAME_ROOT" $TU_ARGS $CMAKE_ARGS
|
|
echo "==> Build"
|
|
cmake --build --preset "$PRESET" --parallel
|
|
|
|
# ---- package ---------------------------------------------------------------
|
|
OUT="out/build/$PRESET"
|
|
STAGE="$NAME"
|
|
rm -rf "$STAGE"; mkdir -p "$STAGE"
|
|
cp "$OUT/$BIN" "$STAGE/"
|
|
# The rexglue runtime lib carries a config suffix (librexruntimerd.so for
|
|
# relwithdebinfo, librexruntime.so for release); the binary links whichever
|
|
# was built, so ship it under its real name.
|
|
RUNTIME="$(ls "$OUT"/librexruntime*.so "$OUT"/librexruntime*.dll "$OUT"/librexruntime*.dylib 2>/dev/null | head -1 || true)"
|
|
if [ -n "$RUNTIME" ]; then
|
|
cp "$RUNTIME" "$STAGE/"
|
|
fi
|
|
cp "$OUT/ghost_relay" "$STAGE/" 2>/dev/null || true
|
|
cp "$OUT/ghost_relay.exe" "$STAGE/" 2>/dev/null || true
|
|
# Title-update patches staged next to the binary when the build used the TU
|
|
if [ -f "$OUT/game/default.xexp" ]; then
|
|
mkdir -p "$STAGE/game/data/webkit"
|
|
cp "$OUT/game/default.xexp" "$STAGE/game/"
|
|
cp "$OUT/game/data/webkit/EAWebkit.xexp" "$STAGE/game/data/webkit/" 2>/dev/null || true
|
|
fi
|
|
cp README.md "$STAGE/"
|
|
rm -f "$NAME.zip"
|
|
make_zip "$NAME.zip" "$STAGE"
|
|
rm -rf "$STAGE"
|
|
echo "==> Packaged: $NAME.zip ($(du -h "$NAME.zip" | cut -f1))"
|
|
sha256sum "$NAME.zip"
|
|
|
|
# ---- publish ----------------------------------------------------------------
|
|
if [ "$UPLOAD" = 1 ]; then
|
|
: "${GITEA_TOKEN:?--upload needs GITEA_TOKEN}"
|
|
REPO_FULL="${FORGEJO_REPO:-ad3laid3/skate3recomp-multiplayer}"
|
|
INSTANCE="${FORGEJO_INSTANCE:-https://git.mithraic.cloud}"
|
|
AUTH="Authorization: token $GITEA_TOKEN"
|
|
echo "==> Publishing $NAME.zip to $INSTANCE/$REPO_FULL release '$TAG'"
|
|
|
|
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\"}" \
|
|
| json_id)"
|
|
|
|
if [ -z "$RELEASE_ID" ]; then
|
|
RELEASE_ID="$(curl -s "$INSTANCE/api/v1/repos/$REPO_FULL/releases/tags/$TAG" -H "$AUTH" \
|
|
| json_id)"
|
|
fi
|
|
if [ -z "$RELEASE_ID" ]; then
|
|
echo "ERROR: could not create/find release '$TAG'"; exit 1
|
|
fi
|
|
|
|
curl -s -X POST "$INSTANCE/api/v1/repos/$REPO_FULL/releases/$RELEASE_ID/assets" \
|
|
-H "$AUTH" -F "attachment=@$NAME.zip" -F "name=$NAME.zip" \
|
|
| 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 |