kazeia/kazeia-android/scripts/jnilibs.sh

86 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Gestion reproductible des jniLibs de l'app Kazeia.
#
# Les .so de app/src/main/jniLibs/arm64-v8a/ sont des ARTEFACTS (gitignorés),
# venant de 5 chaînes de build différentes (kazeia-engine, ExecuTorch, QNN SDK,
# Genie, TTS pipeline). La SOURCE DE VÉRITÉ versionnée est le manifest sha256 :
# kazeia-android/scripts/jnilibs.MANIFEST.sha256
#
# Usage :
# ./jnilibs.sh verify # compare jniLibs au manifest (CI/Gradle l'appelle)
# ./jnilibs.sh sync-engine # rafraîchit le sous-ensemble kazeia-engine depuis /opt/Kazeia-engine/dist
# ./jnilibs.sh update-manifest # re-fige le manifest sur l'état courant (à committer !)
# ./jnilibs.sh export # tarball des jniLibs (transfert vers une autre machine)
# ./jnilibs.sh import <tar.gz> # restaure les jniLibs depuis un export, puis verify
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
LIBS="$HERE/../app/src/main/jniLibs/arm64-v8a"
MANIFEST="$HERE/jnilibs.MANIFEST.sha256"
ENGINE_DIST="/opt/Kazeia-engine/dist"
verify() {
[ -f "$MANIFEST" ] || { echo "ERREUR: manifest absent ($MANIFEST)"; exit 1; }
local fail=0
# 1) tous les fichiers du manifest présents et conformes
while read -r sum path; do
[ -z "$sum" ] && continue; case "$sum" in \#*) continue;; esac
local f="$LIBS/$path"
if [ ! -f "$f" ]; then echo " MANQUANT $path"; fail=1
elif [ "$(sha256sum "$f" | cut -d' ' -f1)" != "$sum" ]; then echo " MODIFIÉ $path"; fail=1
fi
done < "$MANIFEST"
# 2) pas de .so non déclaré (un intrus = build non reproductible ailleurs)
for f in "$LIBS"/*.so; do
local b; b="$(basename "$f")"
grep -q " $b\$" "$MANIFEST" || { echo " NON DÉCLARÉ $b (update-manifest ?)"; fail=1; }
done
if [ $fail -eq 0 ]; then echo "jniLibs OK ($(grep -cv '^#' "$MANIFEST" | cat) libs conformes au manifest)";
else echo ""; echo "jniLibs NON conformes. Corriger puis './jnilibs.sh update-manifest' si le changement est voulu."; exit 1; fi
}
sync_engine() {
# Sous-ensemble possédé par kazeia-engine (build CPU-only, cf RAG_INTEGRATION.md engine)
[ -d "$ENGINE_DIST" ] || { echo "ERREUR: $ENGINE_DIST absent (machine sans le dépôt engine — utiliser import)"; exit 1; }
for f in lib-cpu/libllama.so lib-cpu/libggml.so lib-cpu/libggml-base.so lib-cpu/libggml-cpu.so \
b-jni-cpu/libkazeia_engine.so b-jni-cpu/libkazeia_tts.so; do
cp -v "$ENGINE_DIST/$f" "$LIBS/" || true
done
echo "→ vérifier l'app sur device, puis './jnilibs.sh update-manifest' + commit."
}
update_manifest() {
{
echo "# jniLibs MANIFEST — état attendu de app/src/main/jniLibs/arm64-v8a/"
echo "# Régénéré par scripts/jnilibs.sh update-manifest le $(date +%F)."
echo "# Provenances : kazeia-engine dist (libllama/libggml*/libkazeia_*),"
echo "# ExecuTorch build local (libexecutorch*, libqnn_executorch_backend, libfbjni),"
echo "# QNN SDK 2.42 (libQnn*), Genie (libGenie), TTS pipeline (libtts_pipeline), libomp."
echo "# Les binaires ne sont PAS dans git ; ce manifest fait foi (verify en preBuild)."
( cd "$LIBS" && sha256sum *.so | sort -k2 )
} > "$MANIFEST"
echo "manifest re-figé : $MANIFEST ($(grep -cv '^#' "$MANIFEST") libs) — À COMMITTER."
}
export_tar() {
local out="/opt/Kazeia/_archives/kazeia-jnilibs-$(date +%Y%m%d).tar.gz"
mkdir -p /opt/Kazeia/_archives
tar czf "$out" -C "$LIBS/.." arm64-v8a
echo "export : $out ($(du -h "$out" | cut -f1)) — à déposer sur box.kazeia.com (dossier privé) pour les autres machines."
}
import_tar() {
[ -f "${1:-}" ] || { echo "usage: jnilibs.sh import <tar.gz>"; exit 1; }
tar xzf "$1" -C "$LIBS/.."
verify
}
case "${1:-}" in
verify) verify;;
sync-engine) sync_engine;;
update-manifest) update_manifest;;
export) export_tar;;
import) import_tar "${2:-}";;
*) grep '^#' "$0" | head -14; exit 1;;
esac