mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-23 15:52:42 +02:00
bundle-linux.sh now copies the exact libSDL2 the exe was linked against next
to it and sets the rpath to $ORIGIN via patchelf, with an ldd assertion that
the bundled copy is the one resolved. zlib/libGL remain system deps
(preinstalled on desktop distros and SteamOS). CI installs patchelf; the
generated in-bundle README gains a Steam Deck sideload note and the SDL2
zlib-license copyright file is carried when the distro ships one.
Also refreshes the release-facing docs that ship with / describe the cut:
- .github/release-notes.md: v0.1.0-alpha body -> <version> pre-release body
(what's new + known issues incl. D243/D230/D245/D246/D197/D75, the D251
4K ghost row, and 'not yet verified on real Deck hardware')
- tools_pc/dist/README.md.in: alpha claims (no audio / black sky / US-only)
-> pre-release status; ROM table now lists all three regions (the asset
step auto-detects by SHA-1)
124 lines
6.1 KiB
Bash
Executable File
124 lines
6.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
#
|
||
# Package a Linux GoldenEye 007 PC port build for distribution.
|
||
#
|
||
# Run from anywhere, AFTER building (./build-pc.sh or a cmake --build):
|
||
#
|
||
# tools_pc/bundle-linux.sh [VERSION]
|
||
#
|
||
# Produces, under dist/ :
|
||
# goldeneye-pc-port-<VERSION>-linux-x86_64/ the unpacked bundle
|
||
# goldeneye-pc-port-<VERSION>-linux-x86_64.tar.gz + .tar.gz.sha256
|
||
#
|
||
# The bundle contains ONLY: the engine executable, its SDL2 library, a README,
|
||
# license texts, and the prepare-assets/ tool. It contains NO ROM and NO game
|
||
# assets. SDL2 is bundled (copied next to the exe, whose rpath is set to
|
||
# $ORIGIN) so the tarball runs as-is on any distro — including a sideloaded
|
||
# Steam Deck — with nothing installed; zlib and libGL are expected from the
|
||
# system (preinstalled everywhere that matters, incl. SteamOS). The script
|
||
# hard-fails if patchelf is missing or if a ROM image / oversized blob ends up
|
||
# inside the bundle.
|
||
#
|
||
set -euo pipefail
|
||
|
||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||
cd "$REPO_ROOT"
|
||
|
||
VERSION="${1:-$(git describe --tags --always --dirty 2>/dev/null || echo 0.0.0-dev)}"
|
||
VERSION="${VERSION#v}" # strip a leading "v"
|
||
NAME="goldeneye-pc-port-${VERSION}-linux-x86_64"
|
||
OUT="dist/${NAME}"
|
||
|
||
# Accept a build from either the CI Linux tree or a local build-pc/ tree.
|
||
EXE=""
|
||
for cand in build-linux/ge007.x86_64 build-pc/ge007.x86_64 build-linux/ge007* build-pc/ge007*; do
|
||
if [ -f "$cand" ] && [ -x "$cand" ] && [[ "$cand" != *.exe ]]; then EXE="$cand"; break; fi
|
||
done
|
||
[ -n "$EXE" ] || { echo "error: no Linux ge007 binary found in build-linux/ or build-pc/ — build first" >&2; exit 1; }
|
||
|
||
echo "==> Bundling $EXE -> $NAME"
|
||
rm -rf "$OUT"
|
||
mkdir -p "$OUT/licenses"
|
||
cp "$EXE" "$OUT/"
|
||
chmod +x "$OUT/$(basename "$EXE")"
|
||
EXE_NAME="$(basename "$EXE")"
|
||
|
||
# --- bundle SDL2 (turnkey on any distro / Steam Deck) ------------------
|
||
# SDL2 is the engine's only non-universal runtime dep. Copy the exact file
|
||
# this exe was linked against next to it and point the rpath at $ORIGIN so
|
||
# the bundled copy wins over whatever the target system has.
|
||
command -v patchelf >/dev/null 2>&1 || {
|
||
echo "error: patchelf is required to bundle SDL2 (apt install patchelf / pacman -S patchelf)" >&2; exit 1; }
|
||
SDL2_LIB="$(ldd "$EXE" | awk '/libSDL2/ {print $3; exit}')"
|
||
[ -n "$SDL2_LIB" ] && [ -f "$SDL2_LIB" ] || {
|
||
echo "error: cannot locate libSDL2 for $EXE (unexpected ldd output)" >&2; exit 1; }
|
||
cp -L "$SDL2_LIB" "$OUT/"
|
||
chmod 644 "$OUT/$(basename "$SDL2_LIB")"
|
||
patchelf --set-rpath '$ORIGIN' "$OUT/$EXE_NAME"
|
||
RESOLVED="$(ldd "$OUT/$EXE_NAME" | awk '/libSDL2/ {print $3; exit}')"
|
||
case "$RESOLVED" in
|
||
"$OUT"/*) echo " + $(basename "$SDL2_LIB") (bundled; rpath \$ORIGIN)" ;;
|
||
*) echo "error: bundled libSDL2 is not picked up via \$ORIGIN (ldd -> ${RESOLVED:-nothing})" >&2; exit 1 ;;
|
||
esac
|
||
|
||
# --- report the remaining dynamic-library needs (system-provided) ------
|
||
if command -v ldd >/dev/null 2>&1; then
|
||
echo " remaining system dependencies (zlib / libGL / libc — preinstalled on desktop distros and SteamOS):"
|
||
ldd "$OUT/$EXE_NAME" | grep -v "\$OUT/" | sed 's/^/ /' || true
|
||
fi
|
||
|
||
# --- docs + licenses --------------------------------------------------
|
||
DEPS_BLOCK=$'## 1a. Runtime libraries\n\nSDL2 is bundled in this folder and found automatically (the executable\npoints at its own directory first). zlib and OpenGL come from your system —\npreinstalled on every desktop distro and on SteamOS / Steam Deck.\n\n**Steam Deck:** sideload this folder (USB or a file manager), do steps 2–4\nbelow, then add `@EXE@` to Games → *Add Game* as a non-Steam game.\n'
|
||
sed -e "s|@VERSION@|${VERSION}|g" \
|
||
-e "s|@PLATFORM@|Linux x86-64|g" \
|
||
-e "s|@EXE@|${EXE_NAME}|g" \
|
||
-e "s|@LICENSE_EXTRA@||g" \
|
||
tools_pc/dist/README.md.in > "$OUT/README.md.tmp"
|
||
# @DEPS@ is a multi-line block — substitute it via awk, not sed.
|
||
awk -v repl="$DEPS_BLOCK" '{ if ($0 == "@DEPS@") print repl; else print }' \
|
||
"$OUT/README.md.tmp" > "$OUT/README.md"
|
||
rm -f "$OUT/README.md.tmp"
|
||
|
||
cp NOTICE "$OUT/licenses/NOTICE"
|
||
cp LICENSE "$OUT/licenses/LICENSE-port-MIT.txt"
|
||
[ -f port/fast3d/LICENSE.txt ] && cp port/fast3d/LICENSE.txt "$OUT/licenses/LICENSE-fast3d.txt"
|
||
# SDL2 ships under the zlib license; carry the distro's copyright file when
|
||
# it exists (Debian/Ubuntu), skip silently elsewhere.
|
||
SDL2_LIC="$(dpkg -L libsdl2-2.0-0 2>/dev/null | grep -m1 '/copyright$' || true)"
|
||
[ -n "$SDL2_LIC" ] && [ -f "$SDL2_LIC" ] && cp "$SDL2_LIC" "$OUT/licenses/SDL2.txt"
|
||
|
||
# --- asset-prep tool (identical assembly to bundle-win.sh) -----------
|
||
PREP="$OUT/prepare-assets"
|
||
mkdir -p "$PREP/vendor/scripts" "$PREP/vendor/assets/obseg"
|
||
cp tools_pc/dist/prepare-assets/prepare-assets.py "$PREP/"
|
||
cp tools_pc/d43_emit.py tools_pc/d69_emit.py "$PREP/"
|
||
cp tools_pc/d88_emit.py tools_pc/d88_propdefs.py "$PREP/"
|
||
cp scripts/filelist.u.csv "$PREP/vendor/scripts/"
|
||
cp assets/obseg/file_resource_table.inc.c "$PREP/vendor/assets/obseg/"
|
||
find assets -iname 'modelfileheader.inc.c' -print0 \
|
||
| xargs -0 -I{} cp --parents {} "$PREP/vendor/"
|
||
nmh="$(find "$PREP/vendor/assets" -iname 'modelfileheader.inc.c' | wc -l)"
|
||
echo " + prepare-assets/ (emit scripts + $nmh model headers)"
|
||
[ "$nmh" -gt 400 ] || { echo "error: prepare-assets vendored only $nmh model headers — expected ~512" >&2; exit 1; }
|
||
|
||
# --- guard: no ROM / game data snuck in ------------------------------
|
||
if find "$OUT" -type f \( -iname '*.z64' -o -iname '*.n64' -o -iname '*.v64' \) | grep -q .; then
|
||
echo "error: bundle contains a ROM image — aborting" >&2
|
||
exit 1
|
||
fi
|
||
BYTES="$(du -sb "$OUT" | cut -f1)"
|
||
LIMIT=$((60 * 1024 * 1024))
|
||
if [ "$BYTES" -gt "$LIMIT" ]; then
|
||
echo "error: bundle is $BYTES bytes (> 60 MB) — likely contains game data, aborting" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# --- tarball + checksum ---------------------------------------------
|
||
( cd dist && rm -f "${NAME}.tar.gz" "${NAME}.tar.gz.sha256" \
|
||
&& tar -czf "${NAME}.tar.gz" "$NAME" \
|
||
&& sha256sum "${NAME}.tar.gz" > "${NAME}.tar.gz.sha256" )
|
||
|
||
echo "==> dist/${NAME}.tar.gz ($(du -h "dist/${NAME}.tar.gz" | cut -f1))"
|
||
cat "dist/${NAME}.tar.gz.sha256"
|
||
find "$OUT" -type f | sed "s#^dist/##" | sort
|