#!/bin/bash set -eo pipefail LOG_FILE="build_win.log" > "$LOG_FILE" log() { echo "$1"; echo "$1" >> "$LOG_FILE"; } log "================================" log "ChatGUI Build Script (MSYS2 UCRT64)" log "================================" log "" SRC_DIR="$(cd "$(dirname "$0")" && pwd)" BUILD_DIR="$SRC_DIR/build" log "Source: $SRC_DIR" log "Build: $BUILD_DIR" log "" if [ -f "$BUILD_DIR/CMakeCache.txt" ]; then OLD_GEN=$(grep 'CMAKE_GENERATOR:' "$BUILD_DIR/CMakeCache.txt" 2>/dev/null | cut -d= -f2) if [ "$OLD_GEN" != "Ninja" ]; then log "Generator changed ($OLD_GEN -> Ninja), cleaning build dir..." rm -rf "$BUILD_DIR" fi fi log "[1/4] Configuring CMake (generator: Ninja)..." cmake -S "$SRC_DIR" -B "$BUILD_DIR" -G Ninja 2>&1 | tee -a "$LOG_FILE" test ${PIPESTATUS[0]} -eq 0 || { log "CMake configure FAILED"; exit 1; } log "" JOBS=$(nproc 2>/dev/null || echo 4) log "[2/4] Building (parallel: $JOBS jobs)..." cmake --build "$BUILD_DIR" -j"$JOBS" 2>&1 | tee -a "$LOG_FILE" test ${PIPESTATUS[0]} -eq 0 || { log "Build FAILED"; exit 1; } log "" log "[3/4] Deploying runtime DLLs..." WINDEPLOYQT="/ucrt64/bin/windeployqt" if [ -x "$WINDEPLOYQT" ]; then log " Running $WINDEPLOYQT..." "$WINDEPLOYQT" --no-translations --no-compiler-runtime "$BUILD_DIR/vibechat.exe" 2>&1 | tee -a "$LOG_FILE" RC=${PIPESTATUS[0]} if [ $RC -eq 0 ]; then log " OK: windeployqt completed" else log " WARN: windeployqt failed (exit $RC)" fi else log " WARN: $WINDEPLOYQT not found (install: pacman -S mingw-w64-ucrt-x86_64-qt5-tools)" log " Resolving dependencies recursively..." todo="$BUILD_DIR/vibechat.exe" while [ -n "$todo" ]; do next_todo="" for src in $todo; do for dep in $(objdump -p "$src" 2>/dev/null | grep "DLL Name:" | awk '{print $3}'); do case "$dep" in KERNEL32.dll|msvcrt.dll|USER32.dll|GDI32.dll|SHELL32.dll|ADVAPI32.dll|\ WS2_32.dll|ole32.dll|OLEAUT32.dll|IPHLPAPI.DLL|BCRYPT.dll|dbghelp.dll|\ api-ms-win-*) continue ;; esac [ -f "$BUILD_DIR/$dep" ] && continue if cp "/ucrt64/bin/$dep" "$BUILD_DIR/" 2>/dev/null; then log " OK: $dep"; next_todo="$next_todo $BUILD_DIR/$dep" elif cp "/mingw64/bin/$dep" "$BUILD_DIR/" 2>/dev/null; then log " OK: $dep (mingw64)"; next_todo="$next_todo $BUILD_DIR/$dep" fi done done todo="$next_todo" done fi # Qt platform plugin (loaded dynamically, not in import table) mkdir -p "$BUILD_DIR/platforms" for d in /ucrt64/share/qt5/plugins /ucrt64/lib/qt5/plugins; do cp "$d/platforms/qwindows.dll" "$BUILD_DIR/platforms/" 2>/dev/null && break done cp "$SRC_DIR/rlottie_build/librlottie.dll" "$BUILD_DIR/" 2>/dev/null && log " OK: librlottie.dll" || log " WARN: librlottie.dll not found" cp "$SRC_DIR/setup_firewall.bat" "$BUILD_DIR/" 2>/dev/null && log " OK: setup_firewall.bat" || log " WARN: setup_firewall.bat not found" log "" log "[4/4] Verifying..." EXE="$BUILD_DIR/vibechat.exe" if [ -f "$EXE" ]; then SIZE=$(du -h "$EXE" | cut -f1) log " OK: vibechat.exe ($SIZE)" log "" log "================================" log "Build SUCCESS" log "================================" log "Executable: $EXE" else log " FAIL: vibechat.exe not found" exit 1 fi