ultimate-media-tracker/build-windows.sh
Tronax 7a4f3f312b
build: add Linux and Windows build scripts with NSIS installer
build-linux.sh configures and builds via CMake. build-windows.sh builds
in MSYS2/MINGW64, bundles Qt and transitive MinGW DLLs via windeployqt
plus an ldd pass, and produces an NSIS installer (installer.nsi). Ignore
the dist/ output and generated Setup.exe.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-15 02:37:19 +02:00

99 lines
3 KiB
Bash
Executable file

#!/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/"