build: reproductibilité des jniLibs — manifest sha256 + script + garde release
Les 23 .so de app/src/main/jniLibs/ (474 Mo, 5 chaînes de build : kazeia-engine, ExecuTorch, QNN SDK 2.42, Genie, TTS pipeline) sont des artefacts gitignorés posés à la main — « ça ne buildait que sur cette machine ». On ne les versionne pas (l'historique gonflerait de ~500 Mo par update engine) ; on versionne leur DÉFINITION : - scripts/jnilibs.MANIFEST.sha256 : état attendu (sha256 + provenances). - scripts/jnilibs.sh : verify (CI/Gradle) | sync-engine (rafraîchit le sous-ensemble kazeia-engine depuis /opt/Kazeia-engine/dist) | update-manifest (re-fige, à committer) | export/import (tarball pour autre machine). - Garde Gradle : preReleaseBuild dépend de verifyJniLibs → un build RELEASE avec des libs manquantes/modifiées/non déclarées ÉCHOUE. Debug reste libre. Validé : release passe avec libs conformes ; échoue sur lib altérée (MODIFIÉ libomp.so) ; verify OK après restauration. Ménage au passage : 3 .bak morts (~293 Mo) sortis de jniLibs vers _jnilibs_backup_baks/. Nouvelle machine : git clone + ./scripts/jnilibs.sh import <tarball> (export déposé sur box.kazeia.com privé) → build garanti conforme. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
e5b48e4e0f
commit
9c6f4e8838
|
|
@ -108,6 +108,16 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reproductibilité des jniLibs : les .so (gitignorés, 5 chaînes de build) doivent
|
||||||
|
// correspondre au manifest versionné. Un build RELEASE avec des libs divergentes
|
||||||
|
// échoue ; le debug reste libre (itération engine). Cf scripts/jnilibs.sh.
|
||||||
|
val verifyJniLibs = tasks.register<Exec>("verifyJniLibs") {
|
||||||
|
commandLine("bash", rootProject.file("scripts/jnilibs.sh").absolutePath, "verify")
|
||||||
|
}
|
||||||
|
tasks.matching { it.name == "preReleaseBuild" }.configureEach {
|
||||||
|
dependsOn(verifyJniLibs)
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// Tests unitaires JVM (src/test/) — logique pure : CrisisGuard, VectorIndex, Chunker.
|
// Tests unitaires JVM (src/test/) — logique pure : CrisisGuard, VectorIndex, Chunker.
|
||||||
// Lancer : ./gradlew :app:testDebugUnitTest
|
// Lancer : ./gradlew :app:testDebugUnitTest
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
# jniLibs MANIFEST — état attendu de app/src/main/jniLibs/arm64-v8a/
|
||||||
|
# Régénéré par scripts/jnilibs.sh update-manifest le 2026-06-11.
|
||||||
|
# Provenances : kazeia-engine dist (libllama/libggml*/libkazeia_*),
|
||||||
|
# ExecuTorch build local (libexecutorch*, libqnn_executorch_backend, libfbjni),
|
||||||
|
# QNN SDK 2.42 (libQnn*), Genie (libGenie), TTS pipeline (libtts_pipeline), libomp.
|
||||||
|
# Les binaires ne sont PAS dans git ; ce manifest fait foi (verify en preBuild).
|
||||||
|
dd0506873aeb45e103ef0023678a7f14938a0f147f2348d1efc366f1dce40863 libexecutorch_jni.so
|
||||||
|
0b6f86e114f0cf9f2940194797f06ded576e6b3272a5ffbb2c4b8cdc02850ef8 libexecutorch.so
|
||||||
|
34a0af206f660461e3da687f64172830cc61a32a93732fd7e984c43996d6fd91 libfbjni.so
|
||||||
|
d49b53137f478b7b4ccbd58b9166d83e832c299b681609c70628291c61ae7204 libGenie.so
|
||||||
|
616fa830f6fd3396ea7f0ca92f348c2146efb0b1154ab6ed2e6709655905ead3 libggml-base.so
|
||||||
|
66ea0c948385d8060a7296285d7a85738c21318a88ef767986444a3d9683aeea libggml-cpu.so
|
||||||
|
7aeb209ec5c1da8857779b8f3b4c3e7519ed69c6211491948d3c87349dbced57 libggml.so
|
||||||
|
daf3695e82debf425e4a53b73e96fcb9e9e01ab2fe8513bf6db8f53b09450a34 libkazeia_engine.so
|
||||||
|
fdd730af3daf132d0819b3fc99abd8aae79800aab7a9aad371e117c16bd3a3aa libkazeia_stt.so
|
||||||
|
114795bf0256c380dc87971598707e9e0b745a7fc868f3d1fb460e94cecdd69c libkazeia_tts.so
|
||||||
|
349ba592462113c6e871b9c3ee508727a9e5f154a33905f946bda97535eff586 libllama-common.so
|
||||||
|
2ca77a28421fc0c680e0a5ddf0208a9471268370893f8dd4eba2a10a8aacb4ac libllama.so
|
||||||
|
a207169a2696e8f0f7639090c2882152c734368b5696246a514d63b3ce0769c1 libomp.so
|
||||||
|
d1e8fc79e47fe04ed00aa9bbcc5ccb84d187f0160b1d77ae5bd012aedea9c938 libqnn_executorch_backend.so
|
||||||
|
414794639e2897120143cff80aaf73e830e305357b6c1aa8343de380c89b8c36 libQnnGpuNetRunExtensions.so
|
||||||
|
26f13b297d375e9629eb997b7adb05a4ce9e1c17d306baaefe905563fee43eb8 libQnnGpuProfilingReader.so
|
||||||
|
b5b52b66f3fc5567429024409dcedb006ca6a9115f271689810589b7d79af430 libQnnGpu.so
|
||||||
|
2daafb376fe6904aa325e29810480e3d76dc392991d1367ae6ea3508db2b60ac libQnnHtpPrepare.so
|
||||||
|
10eb1923b34ac9a726e4a446b395d5eee2ea5388487917778aaf954e8bfb2d92 libQnnHtp.so
|
||||||
|
7ee72b438c97c13ceb96d18fe255d1f156afbdc4c43669752f349dd5a56e62a3 libQnnHtpV79Skel.so
|
||||||
|
a08fb34747345125fd3cef3fc10046c663465dd60fddbac9cc37436b3d2e68a9 libQnnHtpV79Stub.so
|
||||||
|
a69cfc4350c16b226bcaa19c657234820bb93e3ff6116cf3845ae77557f1f7c3 libQnnSystem.so
|
||||||
|
d35a02f70cb63ec60c8ae78011f5e93aecbb31396d5395a4a82cb1bc71803956 libtts_pipeline.so
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
#!/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
|
||||||
Loading…
Reference in New Issue