ultimate-media-tracker/build-windows.sh
Tronax 83a26ef0cf
build: fix Windows packaging to produce the NSIS installer
The bundling loop ran under set -euo pipefail; once no new /mingw64 deps
remained, grep exited 1 and aborted the script before makensis ran, so no
Setup.exe was produced. Disable strict mode in that subshell and collect
deps before copying. Anchor all installer source paths to the script dir
via ${__FILEDIR__} and switch the File glob to "\*" so extensionless files
and plugin subfolders are included.

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

102 lines
3.2 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"
# Disable strict mode here: once everything is copied, grep finds no new
# /mingw64 deps and returns 1, which would otherwise abort the whole script.
set +e +o pipefail
for _ in $(seq 1 6); do
deps="$(find . \( -name '*.exe' -o -name '*.dll' \) -print0 \
| xargs -0 -I{} ldd "{}" 2>/dev/null \
| grep -io '/mingw64/bin/[^ ]*\.dll' \
| sort -u)"
for f in $deps; 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/"