@ -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 " -n e 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 ""