Files
utun2/tools/chatgui/build.sh
T

213 lines
9.3 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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
# Старые DLL приложения в build могут мешать запуску cc1/cc1plus после обновления MSYS2.
source "$SRC_DIR/compiler_runtime.sh"
if [ "${MSYSTEM:-}" = UCRT64 ]; then
chatgui_refresh_compiler_runtime "$BUILD_DIR" /ucrt64/bin 2>&1 | tee -a "$LOG_FILE"
log "Preparing bundled rlottie..."
cmake -S "$SRC_DIR/rlottie_src" -B "$SRC_DIR/rlottie_build" -G Ninja \
-DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON 2>&1 | tee -a "$LOG_FILE" || {
log " ERROR: bundled rlottie configure failed"; exit 1;
}
cmake --build "$SRC_DIR/rlottie_build" --target rlottie --parallel 4 2>&1 | tee -a "$LOG_FILE" || {
log " ERROR: bundled rlottie build failed"; exit 1;
}
log " OK: bundled rlottie ready in $SRC_DIR/rlottie_build"
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..."
RLOTTIE_DLL="$SRC_DIR/rlottie_build/librlottie.dll"
[ -f "$RLOTTIE_DLL" ] || { log " ERROR: librlottie.dll not found: $RLOTTIE_DLL"; exit 1; }
cp "$RLOTTIE_DLL" "$BUILD_DIR/librlottie.dll" || {
log " ERROR: cannot copy $RLOTTIE_DLL -> $BUILD_DIR/librlottie.dll"; exit 1;
}
log " OK: librlottie.dll (from $RLOTTIE_DLL; copied to $BUILD_DIR/librlottie.dll)"
FFMPEG_BIN="$SRC_DIR/ffmpeg/ffmpeg_build/install/bin"
MAIN_DLLS=(
"Qt[56]Core.dll" "Qt[56]Gui.dll" "Qt[56]Network.dll" "Qt[56]Widgets.dll" "platforms/qwindows.dll"
"libstdc++-6.dll" "libgcc_s_*.dll" "libwinpthread-1.dll" "librlottie.dll" "zlib1.dll" "libcrypto-*.dll"
)
if [ -d "$FFMPEG_BIN" ]; then
MAIN_DLLS+=("avcodec-*.dll" "avformat-*.dll" "avutil-*.dll" "swscale-*.dll" "swresample-*.dll")
fi
DLLS_PRESENT=1
for d in "${MAIN_DLLS[@]}"; do
if ! compgen -G "$BUILD_DIR/$d" >/dev/null; then
log " Main DLL missing: $d; deploying runtime DLLs"
DLLS_PRESENT=0
break
fi
done
if [ "$DLLS_PRESENT" -eq 1 ]; then
log " SKIP: main runtime DLLs already present; recursive dependency scan skipped"
else
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 дал бы неверный набор кодеков.
OBJDUMP="objdump"; [ -n "${MSYSTEM_PREFIX:-}" ] && OBJDUMP="$MSYSTEM_PREFIX/bin/objdump"
command -v "$OBJDUMP" >/dev/null 2>&1 || { log " ERROR: $OBJDUMP not found"; exit 1; }
shopt -s nocasematch nullglob
# Обновляем весь комплект FFmpeg, включая DLL, не импортируемые напрямую приложением.
for src in "$FFMPEG_BIN/"*.dll; do
# Общий runtime берём из установленного UCRT64, а кодеки — из собственной сборки FFmpeg.
if chatgui_is_compiler_runtime_dll "${src##*/}"; then
src="/ucrt64/bin/${src##*/}"
fi
cp "$src" "$BUILD_DIR/" || { log " ERROR: failed to copy $src"; exit 1; }
log " OK: $(basename "$src") (from $src)"
done
log " Resolving non-Qt dependencies recursively..."
# Проверяем также уже скопированные DLL: наличие файла не гарантирует наличие его зависимостей.
todo=("$BUILD_DIR/vibechat.exe" "$BUILD_DIR/"*.dll)
declare -A scanned=()
MISSING=0
# Большой вывод objdump передаём через файл, чтобы не зависеть от here-string и pipe в MSYS2.
IMPORT_DUMP=$(mktemp) || {
log " ERROR: cannot create temporary file for DLL inspection"
exit 1
}
trap 'rm -f -- "$IMPORT_DUMP" || log " WARN: cannot remove temporary import dump: $IMPORT_DUMP"' EXIT
for ((i = 0; i < ${#todo[@]}; i++)); do
src="${todo[i]}"
key="${src,,}"
[ -n "${scanned[$key]:-}" ] && continue
scanned[$key]=1
CHECK_STARTED=$SECONDS
"$OBJDUMP" -p "$src" > "$IMPORT_DUMP" 2>&1 || {
RC=$?
log " ERROR: cannot inspect $src (exit=$RC, elapsed=$((SECONDS - CHECK_STARTED))s): $(cat "$IMPORT_DUMP")"
MISSING=$((MISSING + 1))
continue
}
PARSE_STARTED=$SECONDS
import_list=$(awk '/DLL Name:/ {print $3}' "$IMPORT_DUMP" 2>&1) || {
RC=$?
log " ERROR: cannot parse imports for $src (exit=$RC, elapsed=$((SECONDS - PARSE_STARTED))s): $import_list"
MISSING=$((MISSING + 1))
continue
}
while read -r dep; do
[ -z "$dep" ] && continue
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|bcryptprimitives.dll|ncrypt.dll|dbghelp.dll|imagehlp.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|ntdll.dll|avicap32.dll|msimg32.dll|wldap32.dll|gdiplus.dll|usp10.dll|\
dwrite.dll|winspool.drv|api-ms-win-*)
continue ;;
esac
if [ ! -f "$BUILD_DIR/$dep" ]; then
dep_src=""
dep_dirs=("$FFMPEG_BIN" /ucrt64/bin "$SRC_DIR/rlottie_build")
if chatgui_is_compiler_runtime_dll "$dep"; then
dep_dirs=(/ucrt64/bin)
fi
for dir in "${dep_dirs[@]}"; do
if [ -f "$dir/$dep" ]; then
dep_src="$dir/$dep"
break
fi
done
if [ -z "$dep_src" ]; then
log " ERROR: $src requires $dep; not found in FFmpeg, UCRT64 or rlottie directories"
MISSING=$((MISSING + 1))
continue
fi
cp "$dep_src" "$BUILD_DIR/" || { log " ERROR: failed to copy $dep_src"; exit 1; }
log " OK: $dep (from $dep_src; required by $src)"
fi
todo+=("$BUILD_DIR/$dep")
done <<< "$import_list"
done
shopt -u nocasematch nullglob
[ "$MISSING" -eq 0 ] || { log " ERROR: runtime DLL deployment incomplete"; exit 1; }
# 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
# Проверяем тот же основной комплект после копирования.
log " Verifying main runtime DLLs..."
MISSING=0
for d in "${MAIN_DLLS[@]}"; do
if ! compgen -G "$BUILD_DIR/$d" >/dev/null; then
log " WARN: $d MISSING in build dir"; MISSING=1
fi
done
if [ "$MISSING" -eq 1 ]; then
log " WARN: some main runtime DLLs missing — app may not start"
fi
fi
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