#!/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)" fi # Резолвим НЕ-Qt зависимости (FFmpeg, mingw-runtime) всегда: windeployqt копирует только Qt. # FFmpeg ищем ПЕРВЫМ в $FFMPEG_BIN: exe линкован именно под кастомный билд, # а pacman-ffmpeg той же мажорной версии в /ucrt64/bin дал бы неверный набор кодеков. FFMPEG_BIN="$SRC_DIR/ffmpeg/ffmpeg_build/install/bin" OBJDUMP="objdump"; [ -n "${MSYSTEM_PREFIX:-}" ] && OBJDUMP="$MSYSTEM_PREFIX/bin/objdump" shopt -s nocasematch log " Resolving non-Qt 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|msvcp140.dll|vcruntime140.dll|ucrtbase.dll|\ user32.dll|gdi32.dll|gdi32full.dll|shell32.dll|shlwapi.dll|advapi32.dll|\ ole32.dll|oleaut32.dll|comdlg32.dll|comctl32.dll|ws2_32.dll|wsock32.dll|\ iphlpapi.dll|netapi32.dll|dnsapi.dll|winmm.dll|imm32.dll|version.dll|\ setupapi.dll|crypt32.dll|bcrypt.dll|ncrypt.dll|dbghelp.dll|kernelbase.dll|\ rpcrt4.dll|psapi.dll|powrprof.dll|cfgmgr32.dll|userenv.dll|secur32.dll|\ uxtheme.dll|dwmapi.dll|d3d11.dll|dxgi.dll|opengl32.dll|glu32.dll|\ wtsapi32.dll|mpr.dll|api-ms-win-*) continue ;; esac [ -f "$BUILD_DIR/$dep" ] && continue if [ -d "$FFMPEG_BIN" ] && cp "$FFMPEG_BIN/$dep" "$BUILD_DIR/" 2>/dev/null; then log " OK: $dep (ffmpeg)"; next_todo="$next_todo $BUILD_DIR/$dep" elif 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 shopt -u nocasematch # 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" # Проверяем, что все ожидаемые не-Qt DLL на месте (FFmpeg + mingw-runtime + rlottie + zlib + OpenSSL) log " Verifying required non-Qt DLLs..." MISSING=0 if [ -d "$FFMPEG_BIN" ]; then for d in avcodec-*.dll avformat-*.dll avutil-*.dll swscale-*.dll swresample-*.dll; do if ls "$BUILD_DIR/$d" >/dev/null 2>&1; then log " OK: $d" else log " WARN: $d MISSING in build dir"; MISSING=1 fi done else log " SKIP: FFmpeg not built — no FFmpeg DLLs expected" fi for d in libstdc++-6.dll libgcc_s_*.dll libwinpthread-1.dll librlottie.dll zlib1.dll libcrypto-*.dll; do if ls "$BUILD_DIR/$d" >/dev/null 2>&1; then log " OK: $d" else log " WARN: $d MISSING in build dir"; MISSING=1 fi done [ "$MISSING" -eq 1 ] && log " WARN: some required non-Qt DLLs missing — app may not start" 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