Browse Source

Verify runtime dependencies and deploy matching Qt plugins every build

master
evgeny 5 days ago
parent
commit
c4217a8aa6
  1. 45
      tools/chatgui/build.sh

45
tools/chatgui/build.sh

@ -13,6 +13,7 @@ log ""
SRC_DIR="$(cd "$(dirname "$0")" && pwd)"
BUILD_DIR="$SRC_DIR/build"
RUNTIME_PREFIX="${MSYSTEM_PREFIX:-/ucrt64}"
log "Source: $SRC_DIR"
log "Build: $BUILD_DIR"
@ -29,7 +30,7 @@ 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"
chatgui_refresh_compiler_runtime "$BUILD_DIR" "$RUNTIME_PREFIX/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" || {
@ -69,7 +70,8 @@ case "$QT_PACKAGE" in
esac
log " Runtime package: $QT_PACKAGE"
MAIN_DLLS=(
"Qt${QT_MAJOR}Core.dll" "Qt${QT_MAJOR}Gui.dll" "Qt${QT_MAJOR}Network.dll" "Qt${QT_MAJOR}Widgets.dll" "platforms/qwindows.dll"
"Qt${QT_MAJOR}Core.dll" "Qt${QT_MAJOR}Gui.dll" "Qt${QT_MAJOR}Network.dll" "Qt${QT_MAJOR}Widgets.dll"
"platforms/qwindows.dll" "imageformats/qjpeg.dll"
"libstdc++-6.dll" "libgcc_s_*.dll" "libwinpthread-1.dll" "librlottie.dll" "zlib1.dll" "libcrypto-*.dll"
)
if [ -d "$FFMPEG_BIN" ]; then
@ -83,11 +85,11 @@ for d in "${MAIN_DLLS[@]}"; do
break
fi
done
if [ "$DLLS_PRESENT" -eq 1 ]; then
log " SKIP: main runtime DLLs already present; recursive dependency scan skipped"
else
[ "$DLLS_PRESENT" -ne 1 ] || log " Main runtime DLLs present; verifying their dependencies"
# Проверяем зависимости на каждом запуске: основные DLL не гарантируют полный комплект.
{
WINDEPLOYQT=""
for candidate in "/ucrt64/bin/windeployqt${QT_MAJOR}.exe" "/ucrt64/bin/windeployqt-qt${QT_MAJOR}.exe" /ucrt64/bin/windeployqt.exe; do
for candidate in "$RUNTIME_PREFIX/bin/windeployqt${QT_MAJOR}.exe" "$RUNTIME_PREFIX/bin/windeployqt-qt${QT_MAJOR}.exe" "$RUNTIME_PREFIX/bin/windeployqt.exe"; do
[ -x "$candidate" ] || continue
tool_version=$("$candidate" --version 2>&1) || { log " WARN: cannot query $candidate: $tool_version"; continue; }
if [[ "$tool_version" =~ (^|[[:space:]])${QT_MAJOR}\.[0-9]+ ]]; then WINDEPLOYQT="$candidate"; break; fi
@ -106,6 +108,22 @@ else
log " WARN: matching $QT_PACKAGE windeployqt not found; copying dependencies directly"
fi
# Основные Qt DLL и динамические плагины всегда берём из выбранного комплекта.
for component in Core Gui Network Widgets; do
qt_dll="Qt${QT_MAJOR}${component}.dll"
cp "$RUNTIME_PREFIX/bin/$qt_dll" "$BUILD_DIR/" || { log " ERROR: cannot deploy $qt_dll from $RUNTIME_PREFIX/bin"; exit 1; }
done
for plugin in platforms/qwindows.dll imageformats/qjpeg.dll; do
plugin_source=""
for dir in "$RUNTIME_PREFIX/share/qt${QT_MAJOR}/plugins" "$RUNTIME_PREFIX/lib/qt${QT_MAJOR}/plugins"; do
[ -f "$dir/$plugin" ] && { plugin_source="$dir/$plugin"; break; }
done
[ -n "$plugin_source" ] || { log " ERROR: $QT_PACKAGE plugin missing: $plugin"; exit 1; }
mkdir -p "$BUILD_DIR/${plugin%/*}"
cp "$plugin_source" "$BUILD_DIR/$plugin" || { log " ERROR: cannot deploy $plugin_source"; exit 1; }
log " OK: $plugin (from $plugin_source)"
done
# Резолвим НЕ-Qt зависимости (FFmpeg, mingw-runtime): windeployqt копирует только Qt.
# FFmpeg ищем ПЕРВЫМ в $FFMPEG_BIN: exe линкован именно под кастомный билд,
# а pacman-ffmpeg той же мажорной версии в /ucrt64/bin дал бы неверный набор кодеков.
@ -116,14 +134,14 @@ else
for src in "$FFMPEG_BIN/"*.dll; do
# Общий runtime берём из установленного UCRT64, а кодеки — из собственной сборки FFmpeg.
if chatgui_is_compiler_runtime_dll "${src##*/}"; then
src="/ucrt64/bin/${src##*/}"
src="$RUNTIME_PREFIX/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)
todo=("$BUILD_DIR/vibechat.exe" "$BUILD_DIR/"*.dll "$BUILD_DIR/platforms/"*.dll "$BUILD_DIR/imageformats/"*.dll)
declare -A scanned=()
MISSING=0
# Большой вывод objdump передаём через файл, чтобы не зависеть от here-string и pipe в MSYS2.
@ -167,9 +185,9 @@ else
esac
if [ ! -f "$BUILD_DIR/$dep" ]; then
dep_src=""
dep_dirs=("$FFMPEG_BIN" /ucrt64/bin "$SRC_DIR/rlottie_build")
dep_dirs=("$FFMPEG_BIN" "$RUNTIME_PREFIX/bin" "$SRC_DIR/rlottie_build")
if chatgui_is_compiler_runtime_dll "$dep"; then
dep_dirs=(/ucrt64/bin)
dep_dirs=("$RUNTIME_PREFIX/bin")
fi
for dir in "${dep_dirs[@]}"; do
if [ -f "$dir/$dep" ]; then
@ -190,11 +208,6 @@ else
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/qt${QT_MAJOR}/plugins" "/ucrt64/lib/qt${QT_MAJOR}/plugins"; do
cp "$d/platforms/qwindows.dll" "$BUILD_DIR/platforms/" 2>/dev/null && break
done
# Проверяем тот же основной комплект после копирования.
log " Verifying main runtime DLLs..."
MISSING=0
@ -206,7 +219,7 @@ else
if [ "$MISSING" -eq 1 ]; then
log " ERROR: required runtime DLLs missing"; exit 1
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 ""

Loading…
Cancel
Save