Share cached PE imports and architecture with Windows packaging

This commit is contained in:
evgeny committed 2026-10-30 10:59:04 +01:00
1 parent 8617405464
commit 0bee366d6b
2 files changed
+40 -20

No files matched your search

+3 -11
View File
@@ -79,16 +79,8 @@ test ${PIPESTATUS[0]} -eq 0 || { log "Build FAILED"; exit 1; }
log ""
log "[3/4] Deploying runtime DLLs..."
DEPLOY_STARTED=$SECONDS
RUNTIME_CACHE="$BUILD_DIR/.runtime-cache"
RUNTIME_COPIED=0 RUNTIME_CURRENT=0 RUNTIME_SCANNED=0 RUNTIME_HITS=0
declare -A RUNTIME_SOURCES=() RUNTIME_STAMPS=()
source "$SRC_DIR/runtime_cache.sh"
OBJDUMP="objdump"; [ -n "${MSYSTEM_PREFIX:-}" ] && OBJDUMP="$MSYSTEM_PREFIX/bin/objdump"
OBJDUMP=$(command -v "$OBJDUMP") || { log " ERROR: objdump not found"; exit 1; }
CACHE_POLICY=$(sha256sum "$SRC_DIR/build.sh" "$SRC_DIR/runtime_cache.sh" "$SRC_DIR/compiler_runtime.sh" | sha256sum) || {
log " ERROR: cannot fingerprint deployment scripts"; exit 1;
}
CACHE_POLICY+="|$(stat -Lc '%n|%s|%y|%z' -- "$OBJDUMP")" || { log " ERROR: cannot stat $OBJDUMP"; exit 1; }
runtime_cache_init
IMPORT_DUMP=$(mktemp) || { log " ERROR: cannot create temporary import dump"; exit 1; }
trap 'rm -f -- "$IMPORT_DUMP" || log " WARN: cannot remove temporary import dump: $IMPORT_DUMP"' EXIT
# Повторная сборка восстанавливает DLL, даже если EXE не перелинковывался.
@@ -132,7 +124,7 @@ done
[ "$DLLS_PRESENT" -ne 1 ] || log " Main runtime DLLs present; verifying their dependencies"
# Проверяем зависимости на каждом запуске: основные DLL не гарантируют полный комплект.
{
runtime_imports "$BUILD_DIR/vibechat.exe"
runtime_inspect "$BUILD_DIR/vibechat.exe"
EXE_IMPORTS="$import_list"
QT_SOURCES=()
declare -A QT_PLUGIN_SOURCES=()
@@ -237,7 +229,7 @@ done
continue
fi
fi
runtime_imports "$src" || { MISSING=$((MISSING + 1)); continue; }
runtime_inspect "$src" || { MISSING=$((MISSING + 1)); continue; }
fi
while read -r dep; do
[ -z "$dep" ] && continue
+37 -9
View File
@@ -1,7 +1,21 @@
#!/bin/bash
# Кеш раскладки Windows DLL: метаданные копий и PE-импорты. Подключается из build.sh.
# Общий кеш build.sh/package_win.sh: метаданные копий, формат PE и импорты.
# CACHE_POLICY меняется при изменении скриптов/objdump; ошибки не публикуют готовую запись.
# Обоим скриптам нужны одинаковые objdump и версия кеша. IMPORT_DUMP задаёт вызывающий код.
runtime_cache_init() {
RUNTIME_CACHE="$BUILD_DIR/.runtime-cache"
RUNTIME_COPIED=0 RUNTIME_CURRENT=0 RUNTIME_SCANNED=0 RUNTIME_HITS=0
declare -gA RUNTIME_SOURCES=() RUNTIME_STAMPS=()
OBJDUMP="${MSYSTEM_PREFIX:+$MSYSTEM_PREFIX/bin/}objdump"
OBJDUMP=$(command -v "$OBJDUMP") || { log " ERROR: objdump not found"; return 1; }
CACHE_POLICY=$(sha256sum "$SRC_DIR/build.sh" "$SRC_DIR/package_win.sh" "$SRC_DIR/runtime_cache.sh" \
"$SRC_DIR/compiler_runtime.sh" | sha256sum) || {
log " ERROR: cannot fingerprint runtime scripts"; return 1;
}
CACHE_POLICY+="|$(stat -Lc '%n|%s|%y|%z' -- "$OBJDUMP")" || { log " ERROR: cannot stat $OBJDUMP"; return 1; }
}
runtime_cache_write() {
local cache_file="$1" cache_data="$2"
if ! mkdir -p "${cache_file%/*}" || ! printf '%s\n' "$cache_data" > "$cache_file.tmp" ||
@@ -50,10 +64,10 @@ runtime_copy() {
log " Updated: ${copy_dst#"$BUILD_DIR/"} (from $copy_src)"
}
# Возвращает список через import_list; вызывать без subshell, чтобы сохранить счётчики.
# Возвращает binary_format, binary_stamp и import_list; вызывать без subshell, чтобы сохранить счётчики.
# Завершающая строка отличает полноценную запись с пустыми импортами от оборванной.
runtime_imports() {
local import_src="$1" import_stamp import_cached="" import_header import_started=$SECONDS import_rc
runtime_inspect() {
local import_src="$1" import_stamp import_cached="" import_header import_started=$SECONDS import_rc inspection
local import_cache="$RUNTIME_CACHE/imports/${1#"$BUILD_DIR/"}"
# runtime_copy уже проверил метаданные этой копии; не запускаем stat второй раз.
import_stamp=${RUNTIME_STAMPS[${import_src,,}]:-}
@@ -62,10 +76,13 @@ runtime_imports() {
log " ERROR: cannot stat PE file: $import_src"; return 1;
}
fi
binary_stamp="$import_stamp"
import_header="$CACHE_POLICY|$import_stamp"
[ ! -f "$import_cache" ] || import_cached=$(< "$import_cache")
if [[ "$import_cached" == "$import_header"$'\n'*$'\nEND' ]]; then
import_list=${import_cached#*$'\n'}
if [[ "$import_cached" == "$import_header"$'\nFORMAT '*$'\n'*$'\nEND' ]]; then
inspection=${import_cached#*$'\nFORMAT '}
binary_format=${inspection%%$'\n'*}
import_list=${inspection#*$'\n'}
import_list=${import_list%$'\nEND'}
RUNTIME_HITS=$((RUNTIME_HITS + 1))
return 0
@@ -75,9 +92,20 @@ runtime_imports() {
log " ERROR: cannot inspect $import_src (exit=$import_rc, elapsed=$((SECONDS - import_started))s): $(cat "$IMPORT_DUMP")"
return 1
}
import_list=$(awk '/DLL Name:/ {print $3}' "$IMPORT_DUMP") || {
log " ERROR: cannot parse PE imports: $import_src"; return 1;
# objdump -p уже выводит file format; отдельный objdump -f не нужен.
inspection=$(awk '{sub(/\r$/, "")} /file format/ {format=$NF} /DLL Name:/ {imports=imports $3 "\n"}
END {if (format == "") exit 1; printf "%s\n%s", format, imports}' "$IMPORT_DUMP") || {
log " ERROR: cannot parse PE format/imports: $import_src"; return 1;
}
runtime_cache_write "$import_cache" "$import_header"$'\n'"$import_list"$'\nEND' || return 1
binary_format=${inspection%%$'\n'*}
import_list=""
[[ "$inspection" != *$'\n'* ]] || import_list=${inspection#*$'\n'}
import_stamp=$(stat -Lc '%n|%s|%y|%z' -- "$import_src") || {
log " ERROR: cannot stat inspected PE file: $import_src"; return 1;
}
if [ "$binary_stamp" != "$import_stamp" ]; then
log " ERROR: PE file changed during inspection: $import_src; rebuild and retry"; return 1;
fi
runtime_cache_write "$import_cache" "$import_header"$'\nFORMAT '"$binary_format"$'\n'"$import_list"$'\nEND' || return 1
RUNTIME_SCANNED=$((RUNTIME_SCANNED + 1))
}