#!/usr/bin/env bash # Builds a self-contained Windows release zip from Linux: # tools/package_windows.sh [version] -> dist/BrandlingSafari--win64.zip # # Needs: x86_64-w64-mingw32-g++ (Arch: mingw-w64-gcc), cmake, ninja, curl, zstd-capable tar, zip. # The Windows libraries (GLFW, libepoxy, SQLite, ...) come from the MSYS2 ucrt64 repository and # are cached in ~/.cache/brandling-safari/msys2-ucrt64. The engine checkout is ../Vibe-HD-2D # (or $HD2D_ENGINE_DIR). set -euo pipefail ROOT="$(cd "$(dirname "$0")/.." && pwd)" ENGINE="${HD2D_ENGINE_DIR:-$ROOT/../Vibe-HD-2D}" VERSION="${1:-$(git -C "$ROOT" describe --tags --always --dirty 2>/dev/null || echo dev)}" NAME="BrandlingSafari-$VERSION-win64" CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/brandling-safari/msys2-ucrt64" SYSROOT="$CACHE/ucrt64" BUILD="$ROOT/build_win" STAGE="$ROOT/dist/$NAME" REPO="https://repo.msys2.org/mingw/ucrt64" PACKAGES=(glfw libepoxy sqlite3 nlohmann-json glm libwinpthread) # --- 1. Windows libraries ------------------------------------------------------ mkdir -p "$CACHE" if [[ ! -f "$CACHE/.done" ]]; then echo "== downloading MSYS2 ucrt64 packages" curl -fsSL "$REPO/" -o "$CACHE/index.html" for p in "${PACKAGES[@]}"; do f=$(grep -oE "mingw-w64-ucrt-x86_64-$p-[0-9][^\"]*-any\.pkg\.tar\.zst\"" "$CACHE/index.html" | tr -d '"' | sort -V | tail -1) [[ -n "$f" ]] || { echo "package $p not found in $REPO" >&2; exit 1; } echo " $f" curl -fsSL "$REPO/$f" -o "$CACHE/$f" tar --zstd -xf "$CACHE/$f" -C "$CACHE" 2>/dev/null done touch "$CACHE/.done" fi # --- 2. Build ------------------------------------------------------------------ echo "== building" cmake -S "$ROOT" -B "$BUILD" -G Ninja -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_TOOLCHAIN_FILE="$ROOT/cmake/mingw-w64-x86_64.cmake" -DMINGW_SYSROOT="$SYSROOT" \ -DHD2D_ENGINE_DIR="$ENGINE" > /dev/null ninja -C "$BUILD" safari_client safari_server # --- 3. Stage -------------------------------------------------------------------- echo "== staging $STAGE" rm -rf "$STAGE" mkdir -p "$STAGE/assets" "$STAGE/engine/textures" "$STAGE/engine/models" cp "$BUILD/safari_client.exe" "$BUILD/safari_server.exe" "$STAGE/" x86_64-w64-mingw32-strip "$STAGE"/*.exe # Every non-system DLL the executables import (one level deep is enough: the MSYS2 DLLs # used here only import Windows system DLLs). for dll in $(x86_64-w64-mingw32-objdump -p "$STAGE"/*.exe | awk '/DLL Name/ {print $3}' | sort -u); do for dir in "$SYSROOT/bin" /usr/x86_64-w64-mingw32/bin; do if [[ -f "$dir/$dll" ]]; then cp "$dir/$dll" "$STAGE/"; break; fi done done # Game assets (no review sheets, no Blender texture sources: the .glb embeds them). cp -r "$ROOT/assets/characters" "$ROOT/assets/data" "$STAGE/assets/" mkdir -p "$STAGE/assets/creatures" "$STAGE/assets/models" cp -r "$ROOT/assets/creatures/sprites" "$ROOT/assets/creatures/roster.json" "$STAGE/assets/creatures/" cp "$ROOT/assets/models/safari.glb" "$STAGE/assets/models/" # Engine assets the game uses. cp -r "$ENGINE/assets/shaders" "$ENGINE/assets/fonts" "$STAGE/engine/" cp "$ENGINE"/assets/textures/*.png "$STAGE/engine/textures/" cp "$ENGINE/assets/models/scenery.glb" "$STAGE/engine/models/" cat > "$STAGE/README.txt" <