The rexglue codegen tool segfaults/aborts during static teardown AFTER writing its output (cvar registry SIOF + heap corruption at exit). The generated source is complete and valid, so generate-skate3/generate-eawebkit now wrap the invocation with bash -c that verifies the written output files instead of the exit code - a genuine failure (unresolved calls without the Title Update package) produces no output and is still caught. Fixes the release build on toolchains that hit the teardown bug (also applies to CI). release.sh: glob the actual rexglue runtime lib name (librexruntimerd.so for relwithdebinfo vs librexruntime.so for release) so packaging ships the lib the binary links.
156 lines
No EOL
6.4 KiB
Bash
Executable file
156 lines
No EOL
6.4 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
|
|
|
|
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"
|
|
fi
|
|
|
|
echo "==> Release $TAG ($EXT) preset=$PRESET game=$GAME_ROOT"
|
|
echo "==> Configure (extra args: ${CMAKE_ARGS:-none})"
|
|
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"
|
|
zip -r "$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\"}" \
|
|
| python3 -c "import sys,json
|
|
try: print(json.load(sys.stdin).get('id',''))
|
|
except Exception: print('')")"
|
|
|
|
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('')")"
|
|
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" \
|
|
| python3 -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)"
|
|
echo "==> Done: https://git.mithraic.cloud/$REPO_FULL/releases/tag/$TAG"
|
|
fi |