#!/usr/bin/env bash # # Build + package Ultimate Media Tracker for Windows. # Run from the project root inside the MSYS2 *MINGW64* shell. # # Usage: # ./build-windows.sh configure + build + bundle (+ installer) # ./build-windows.sh clean wipe build/dist first # # Produces: # dist/ portable build (zip & ship this folder) # UltimateMediaTracker-Setup.exe NSIS installer (if makensis is installed) # set -euo pipefail cd "$(dirname "$0")" BUILD_DIR="build-win" DIST_DIR="dist" EXE="umt.exe" BUILD_TYPE="${BUILD_TYPE:-Release}" # Must run in the MINGW64 environment so CMake finds Qt under /mingw64. if [[ "${MSYSTEM:-}" != "MINGW64" ]]; then echo "ERROR: run this from the MSYS2 MINGW64 shell (MSYSTEM=MINGW64)." >&2 exit 1 fi WINDEPLOY="$(command -v windeployqt6 || command -v windeployqt || true)" if [[ -z "$WINDEPLOY" ]]; then echo "ERROR: windeployqt not found. Install with:" >&2 echo " pacman -S mingw-w64-x86_64-qt6-tools" >&2 exit 1 fi if [[ "${1:-}" == "clean" ]]; then echo "==> Removing $BUILD_DIR and $DIST_DIR" rm -rf "$BUILD_DIR" "$DIST_DIR" fi echo "==> Configuring ($BUILD_TYPE)" # Set the generator only on a fresh dir; reusing one with -G errors out. GEN=() if [[ ! -f "$BUILD_DIR/CMakeCache.txt" ]]; then GEN=(-G Ninja) fi cmake -S . -B "$BUILD_DIR" "${GEN[@]}" -DCMAKE_BUILD_TYPE="$BUILD_TYPE" echo "==> Building" cmake --build "$BUILD_DIR" -j echo "==> Assembling $DIST_DIR" rm -rf "$DIST_DIR" mkdir -p "$DIST_DIR" cp "$BUILD_DIR/$EXE" "$DIST_DIR/" echo "==> Running windeployqt" "$WINDEPLOY" --release --no-translations "$DIST_DIR/$EXE" echo "==> Bundling MinGW runtime + transitive dependencies" # windeployqt does not copy third-party MinGW DLLs (harfbuzz, freetype, png, # pcre2, zlib, glib, libgcc/libstdc++/winpthread ...). Resolve them via ldd and # repeat a few passes so transitive deps (incl. those of the deployed plugins) # are all picked up. ( cd "$DIST_DIR" for _ in $(seq 1 6); do find . \( -name '*.exe' -o -name '*.dll' \) -print0 \ | xargs -0 -I{} ldd "{}" 2>/dev/null \ | grep -io '/mingw64/bin/[^ ]*\.dll' \ | sort -u \ | while read -r f; do [ -e "./$(basename "$f")" ] || cp "$f" . done done ) echo "==> Verifying dependencies" if command -v ntldd >/dev/null 2>&1; then missing="$(cd "$DIST_DIR" && ntldd -R "$EXE" 2>/dev/null | grep -i 'not found' || true)" if [[ -n "$missing" ]]; then echo "WARNING: unresolved dependencies remain:" >&2 echo "$missing" >&2 else echo " all dependencies resolved." fi else echo " (install mingw-w64-x86_64-ntldd to auto-verify)" fi if command -v makensis >/dev/null 2>&1; then echo "==> Building NSIS installer" makensis installer.nsi echo "==> Installer: UltimateMediaTracker-Setup.exe" else echo "NOTE: makensis not found; skipping installer." echo " Install it with: pacman -S mingw-w64-x86_64-nsis" fi echo echo "==> Done. Portable build in: $DIST_DIR/"