0.3.3-0-pre.3
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/development/006-ANDROID_RUST_NATIVE_BUILD.md -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 4 -->
|
||||
|
||||
# Build Rust Android natif
|
||||
|
||||
@@ -12,95 +12,95 @@ Le crate Rust `game-android-entrypoint` est un `cdylib`. Il est compilé avec ex
|
||||
- `reflex` ;
|
||||
- `snake`.
|
||||
|
||||
Le même nom de bibliothèque native peut être utilisé dans les deux APK puisque chaque module Android possède son propre répertoire `jniLibs`.
|
||||
Le même nom de bibliothèque native peut être utilisé dans les deux APK puisque chaque module Android possède son propre ensemble de `jniLibs` générés.
|
||||
|
||||
## SDL3 AAR et Prefab
|
||||
|
||||
L'AAR officiel SDL3 expose ses bibliothèques natives avec Prefab.
|
||||
|
||||
Pour `arm64-v8a`, la structure attendue est notamment :
|
||||
L'AAR officiel SDL3 expose ses bibliothèques natives avec Prefab. Pour chaque ABI, la logique Gradle commune cherche d'abord :
|
||||
|
||||
```text
|
||||
prefab/modules/SDL3/libs/android.arm64-v8a/libSDL3.so
|
||||
prefab/modules/SDL3/libs/android.<abi>/libSDL3.so
|
||||
```
|
||||
|
||||
Le script `scripts/build_android_rust.py` accepte cette structure officielle et conserve un fallback `jni/<abi>/libSDL3.so` pour compatibilité.
|
||||
Elle accepte aussi `jni/<abi>/libSDL3.so`, puis un fallback Prefab univoque. Pour chaque ABI elle :
|
||||
|
||||
Pour chaque application, le script :
|
||||
1. extrait `libSDL3.so` depuis l'AAR dans un répertoire temporaire de linkage ;
|
||||
2. stage `libSDL3.so` dans les `jniLibs` générés du variant ;
|
||||
3. lance `cargo ndk` avec exactement une feature jeu ;
|
||||
4. stage `libgame_android_entrypoint.so` dans le même arbre généré ;
|
||||
5. vérifie la présence des deux bibliothèques avant de rendre l'output au variant AGP.
|
||||
|
||||
1. extrait `libSDL3.so` depuis l'AAR ;
|
||||
2. l'utilise comme bibliothèque de liaison pour le build Rust ;
|
||||
3. copie `libSDL3.so` dans le `jniLibs/<abi>/` du module Android ;
|
||||
4. lance `cargo ndk` ;
|
||||
5. vérifie la présence de `libgame_android_entrypoint.so`.
|
||||
|
||||
Ainsi, `SDLActivity` dispose au runtime de `libSDL3.so` et de la bibliothèque Rust applicative.
|
||||
Les `jniLibs` générés sont déclarés à la Variant API via `variant.sources.jniLibs.addGeneratedSourceDirectory`. Gradle possède ainsi la dépendance entre le packaging Android et le build natif au lieu d'exiger une commande préalable séparée.
|
||||
|
||||
## Toolchain
|
||||
|
||||
SDL Android requiert actuellement SDK 35 ou ultérieur, NDK r28c ou ultérieur et API minimale 21. La baseline projet conserve `compileSdk 36`, `minSdk 21` et l'AAR SDL3 3.4.16.
|
||||
|
||||
Installer au minimum :
|
||||
|
||||
```bash
|
||||
rustup target add aarch64-linux-android
|
||||
cargo install cargo-ndk
|
||||
```
|
||||
|
||||
NDK de référence :
|
||||
Le contrat projet utilise :
|
||||
|
||||
```text
|
||||
r28c = 28.2.13676358
|
||||
AGP 9.4.0
|
||||
Gradle minimum 9.6.0
|
||||
JDK runtime >= 17, fourni par l'environnement
|
||||
Java source/target 17
|
||||
compileSdk 36
|
||||
minSdk 21
|
||||
NDK 28.2.13676358 / r28c
|
||||
SDL3 AAR 3.4.16
|
||||
cargo-ndk requis côté développeur
|
||||
```
|
||||
|
||||
Avec le SDK manager :
|
||||
`Android/settings.gradle` compare `GradleVersion.current()` au minimum projet `9.6.0`. Le projet n'épingle donc pas une distribution Gradle : un Gradle local plus récent est accepté tant qu'il satisfait le minimum.
|
||||
|
||||
```bash
|
||||
"${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "ndk;28.2.13676358" "platform-tools"
|
||||
Le projet Android natif n'impose pas `JAVA_HOME`. Le JDK courant du shell/IDE exécute Gradle ; `java -version` et `gradle --version` sont relevés pendant les gates. Le niveau de bytecode/source Java de la glue reste explicitement `17`, indépendamment du JDK de build.
|
||||
|
||||
`cargo-ndk` détecte le NDK désigné pour le sous-processus via `ANDROID_NDK_HOME`. La tâche Gradle résout cette valeur à partir de `ANDROID_HOME` ou `ANDROID_SDK_ROOT` et de `androidNdkVersion`; aucun `ANDROID_NDK_HOME` global n'est requis.
|
||||
|
||||
## État 0.3.3-0-pre.3
|
||||
|
||||
La preuve mono-ABI de `0-pre.2` a validé que `assembleDebug` déclenche correctement le build Rust/SDL3 ARM64 sans orchestrateur Python préalable.
|
||||
|
||||
`0-pre.3` élargit ce même graphe à :
|
||||
|
||||
```text
|
||||
arm64-v8a
|
||||
x86_64
|
||||
```
|
||||
|
||||
`cargo-ndk` détecte un NDK installé par Android Studio ou utilise `ANDROID_NDK_HOME` lorsqu'il est défini.
|
||||
pour Snake et Reflex :
|
||||
|
||||
Pour utiliser directement `adb` :
|
||||
|
||||
```bash
|
||||
export PATH="${ANDROID_HOME}/platform-tools:${PATH}"
|
||||
```text
|
||||
:<game>:assembleDebug
|
||||
-> buildDebugSasedevRustArm64V8a
|
||||
-> buildDebugSasedevRustX8664
|
||||
-> deux sources jniLibs générées
|
||||
-> APK Debug universal
|
||||
```
|
||||
|
||||
Cet export peut être ajouté au fichier de configuration shell local de la machine.
|
||||
Chaque arbre ABI contient :
|
||||
|
||||
## Build
|
||||
```text
|
||||
build/generated/sasedevNative/debug/<abi>/jniLibs/<abi>/
|
||||
├── libSDL3.so
|
||||
└── libgame_android_entrypoint.so
|
||||
```
|
||||
|
||||
Depuis la racine :
|
||||
|
||||
```bash
|
||||
python3 scripts/build_android_rust.py reflex
|
||||
python3 scripts/build_android_rust.py snake
|
||||
java -version
|
||||
(cd Android && gradle --version)
|
||||
(cd Android && gradle :game-snake-poc:assembleDebug)
|
||||
(cd Android && gradle :game-reflex-poc:assembleDebug)
|
||||
```
|
||||
|
||||
Puis :
|
||||
Il ne faut pas appeler `scripts/build_android_rust.py` avant ces tâches. Le script Python historique reste temporairement versionné jusqu'à la fermeture complète du chemin natif en `0-pre.4`.
|
||||
|
||||
```bash
|
||||
cd Android
|
||||
gradle :game-reflex-poc:assembleDebug
|
||||
gradle :game-snake-poc:assembleDebug
|
||||
cd ..
|
||||
```
|
||||
|
||||
Les bibliothèques générées sous `Android/*/src/main/jniLibs/` sont des artefacts de build et ne sont pas versionnées.
|
||||
Les outputs natifs restent sous `Android/<module>/build/` et ne sont jamais versionnés.
|
||||
|
||||
## Smoke appareil
|
||||
|
||||
Préflight :
|
||||
Le premier APK universal doit être inspecté mécaniquement avant installation. Il doit contenir exactement les couples attendus pour `arm64-v8a` et `x86_64`, sans dépendre de `armeabi-v7a` ou `x86`.
|
||||
|
||||
```bash
|
||||
adb version
|
||||
adb devices
|
||||
```
|
||||
|
||||
Puis installation/lancement des APK si un appareil ou émulateur est disponible.
|
||||
|
||||
L'absence de `adb` ou d'appareil n'est pas un défaut fonctionnel du projet ; elle bloque uniquement le smoke appareil.
|
||||
Le plan prévoit ensuite un smoke sur l'AVD x86_64 disponible et sur l'appareil ARM64 réel. Ces smokes attestent le packaging multi-ABI ; ils ne changent pas le `minSdk`, qui reste un axe séparé et sera consolidé avec l'AAB/compatibilité dans `0-pre.4`.
|
||||
|
||||
## Exception FFI Rust
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/003-V0_3_3_ANDROID_NATIVE_MULTI_ABI_PLAN.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Plan 0.3.3 — Android SDL3 natif multi-ABI et packaging Gradle
|
||||
|
||||
@@ -36,8 +36,8 @@ Les décisions de cadrage `0-pre.1` sont :
|
||||
|
||||
```text
|
||||
AGP 9.4.0
|
||||
Gradle 9.6.0 à épingler par wrapper lors de l'implémentation
|
||||
JDK 17
|
||||
Gradle >= 9.6.0, version système acceptée si supérieure
|
||||
JDK >= 17, fourni par l'environnement ; JDK 25 candidat validable
|
||||
compileSdk 36
|
||||
targetSdk 36
|
||||
minSdk candidat 21
|
||||
@@ -52,6 +52,16 @@ splits ABI hors chemin par défaut
|
||||
|
||||
Le `minSdk 21` est fondé sur le plancher Android actuellement documenté par SDL3, pas sur la seule valeur historique du dépôt. Le `targetSdk 36` est maintenu pour la politique Google Play actuelle.
|
||||
|
||||
### Révision de toolchain après `0-pre.2`
|
||||
|
||||
La preuve mono-ABI a réussi avec le wrapper Gradle `9.6.0` et JDK 17. Après cette validation, la décision projet est de ne pas transformer ces valeurs de preuve en versions exactes imposées au chemin SDL3 natif :
|
||||
|
||||
- AGP `9.4.0` conserve Gradle `9.6.0` comme minimum ;
|
||||
- un Gradle système plus récent est autorisé et doit être affiché dans la gate ;
|
||||
- le JDK runtime doit satisfaire Gradle/AGP (`>= 17`) mais provient de l'environnement ;
|
||||
- le niveau Java de la glue Android reste `sourceCompatibility/targetCompatibility = 17` ;
|
||||
- les contraintes JDK/Gradle du POC Tauri restent locales à ce POC et ne pilotent pas Android SDL3 natif.
|
||||
|
||||
Le pipeline devra aussi vérifier la compatibilité 16 KB des bibliothèques natives finales. AGP 9.4 et NDK r28c fournissent le socle requis, mais le prébuild SDL3 doit être contrôlé dans l'APK/AAB produit.
|
||||
|
||||
## Ownership cible
|
||||
@@ -85,7 +95,7 @@ La future logique commune doit couvrir au minimum :
|
||||
11. diagnostics explicites si outil, target, AAR, NDK ou output manque ;
|
||||
12. absence de secret de signature dans le dépôt.
|
||||
|
||||
Le projet Android natif doit acquérir un Gradle Wrapper épinglé à la version compatible AGP afin que `CMD-051` devienne réellement reproductible sans dépendre d'un Gradle global.
|
||||
Le projet Android natif déclare `minimumGradleVersion=9.6.0` et refuse au chargement une version inférieure. Le Gradle réellement utilisé est celui de l'environnement ; une version plus récente que le minimum est autorisée. Le projet n'épingle pas de wrapper natif.
|
||||
|
||||
## ABI et compatibilité OS
|
||||
|
||||
@@ -134,15 +144,15 @@ Aucune réécriture Gradle productive dans cette tranche.
|
||||
|
||||
### `0-pre.2` — ownership Gradle/Cargo sur Snake mono-ABI
|
||||
|
||||
Introduire le Gradle Wrapper compatible AGP 9.4 et la logique Gradle commune minimale. Faire de `:game-snake-poc:assembleDebug` le propriétaire du build Rust `arm64-v8a`, de l'extraction/linkage SDL3 et des `jniLibs` générés, sans appel préalable au script Python.
|
||||
Introduire la logique Gradle commune minimale et prouver que `:game-snake-poc:assembleDebug` possède le build Rust `arm64-v8a`, l'extraction/linkage SDL3 et les `jniLibs` générés, sans appel préalable au script Python. Cette preuve a initialement utilisé un wrapper Gradle 9.6.0 afin d'isoler le task wiring.
|
||||
|
||||
Le delta doit rester borné à une ABI pour valider l'ordre des tâches, les inputs/outputs, le mapping de feature et les diagnostics avant de multiplier les dimensions.
|
||||
La gate utilisateur du 2026-09-21 a validé ce chemin. Après cette preuve, la politique toolchain a été révisée : le projet Android natif utilise désormais un Gradle système `>= 9.6.0` et le JDK courant de l'environnement au lieu d'épinger Gradle/JDK pour ce chemin.
|
||||
|
||||
### `0-pre.3` — multi-ABI et APK universal
|
||||
### `0-pre.3` — toolchain minimale, multi-ABI et APK universal
|
||||
|
||||
Étendre la logique commune à `arm64-v8a + x86_64`, produire un APK Debug universal Snake et vérifier mécaniquement les deux couples `libSDL3.so`/`libgame_android_entrypoint.so`.
|
||||
Retirer le wrapper natif introduit pour la preuve `0-pre.2`, déclarer et contrôler `Gradle >= 9.6.0`, ne plus imposer `JAVA_HOME`, puis étendre la logique commune à `arm64-v8a + x86_64`. Produire un APK Debug universal Snake et vérifier mécaniquement les deux couples `libSDL3.so`/`libgame_android_entrypoint.so`.
|
||||
|
||||
Ajouter Reflex comme second consommateur dans cette tranche si, et seulement si, la factorisation commune réduit son activation à une configuration de module sans nouvelle architecture.
|
||||
La factorisation commune étant réduite au mapping `module -> feature`, ajouter Reflex comme second consommateur avec les mêmes deux ABI, sans nouvelle architecture.
|
||||
|
||||
### `0-pre.4` — AAB, minSdk et fermeture du chemin historique
|
||||
|
||||
@@ -185,12 +195,11 @@ adb version
|
||||
adb devices -l
|
||||
emulator -list-avds
|
||||
(cd Android && gradle --version)
|
||||
printf 'configured NDK: '; sed -n 's/^androidNdkVersion=//p' Android/gradle.properties
|
||||
ls -ld "$ANDROID_HOME/ndk/28.2.13676358"
|
||||
printf 'configured NDK: '; sed -n 's/^androidNdkVersion=//p' ls -ld "$ANDROID_HOME/ndk/28.2.13676358"
|
||||
test -f Android/libs/SDL3-3.4.16.aar && sha256sum Android/libs/SDL3-3.4.16.aar
|
||||
```
|
||||
|
||||
L'absence du Gradle global n'est pas destinée à devenir une dépendance durable : `0-pre.2` doit introduire le wrapper. En revanche, l'inventaire demandé par le prompt `004` doit relever l'état actuel avant cette transition.
|
||||
La politique a été révisée après validation de `0-pre.2` : le projet Android natif dépend volontairement d'un Gradle fourni par l'environnement, avec minimum `9.6.0` déclaré et contrôlé par `settings.gradle`. Il n'impose plus de wrapper ni de `JAVA_HOME`; les gates consignent les versions réellement utilisées.
|
||||
|
||||
## Critères d'entrée en RC
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/RULES_COMMANDS.md -->
|
||||
<!-- version: 14 -->
|
||||
<!-- version: 15 -->
|
||||
|
||||
# Règles d'exécution des commandes
|
||||
|
||||
@@ -48,11 +48,11 @@
|
||||
|
||||
## Android et Gradle
|
||||
|
||||
- **CMD-ANDROID-001** — Les commandes Gradle Android sont exécutées depuis `Android/` ou avec un chemin explicite vers le wrapper du projet.
|
||||
- **CMD-ANDROID-002** — Les tâches ciblées par application sont préférées, par exemple `./gradlew :game-reflex-poc:assembleDebug`, lorsqu'elles existent.
|
||||
- **CMD-ANDROID-001** — Les commandes Gradle du projet Android natif sont exécutées depuis `Android/` avec le `gradle` résolu par l’environnement ; sa version doit être au moins égale à `minimumGradleVersion` déclaré par le projet.
|
||||
- **CMD-ANDROID-002** — Les tâches ciblées par application sont préférées, par exemple `gradle :game-reflex-poc:assembleDebug`, lorsqu'elles existent.
|
||||
- **CMD-ANDROID-003** — Un build Android global n'est pas exécuté si la tranche ne touche ni Android ni le contrat natif utilisé par Android.
|
||||
- **CMD-ANDROID-004** — `gradle clean` ou `./gradlew clean` reste un nettoyage Android ciblé ; il n'est pas rendu obligatoire uniquement parce qu'un `cargo clean` est planifié.
|
||||
- **CMD-ANDROID-005** — Les commandes Android réelles ne deviennent des gates qu'après introduction du wrapper Gradle, de l'AGP, du NDK, de SDL3 et des modules exécutables correspondants.
|
||||
- **CMD-ANDROID-004** — `gradle clean` reste un nettoyage Android ciblé ; il n'est pas rendu obligatoire uniquement parce qu'un `cargo clean` est planifié.
|
||||
- **CMD-ANDROID-005** — Les commandes Android réelles ne deviennent des gates qu'après déclaration d'un minimum Gradle contrôlé, de l'AGP, du NDK, de SDL3 et des modules exécutables correspondants.
|
||||
|
||||
## Web
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/RULES_VALIDATION_MATRIX.md -->
|
||||
<!-- version: 5 -->
|
||||
<!-- version: 6 -->
|
||||
|
||||
# Matrice normative des commandes et validations
|
||||
|
||||
@@ -38,7 +38,7 @@ Les commandes ciblées restent la norme pendant l'implémentation ; les gates wo
|
||||
| `CMD-046` | `(cd <tauri-app> && cargo tauri android dev)` | gates Rust/frontend applicables | smoke interactif Tauri Android | `pre`/beta |
|
||||
| `CMD-047` | `(cd <tauri-app> && cargo tauri android build)` | gates Rust/frontend applicables | packaging Tauri Android final/prefinal | beta/RC |
|
||||
| `CMD-050` | build Rust Android ABI ciblé | gates Rust applicables | Android/JNI/backend natif touché | pre/beta |
|
||||
| `CMD-051` | `(cd Android && ./gradlew :<app>:assembleDebug)` | `CMD-050` si Rust natif change | Android/app/manifest/Java touché | pre/beta |
|
||||
| `CMD-051` | `(cd Android && gradle :<app>:assembleDebug)` | `CMD-050` si Rust natif change | Android/app/manifest/Java touché | pre/beta |
|
||||
| `CMD-052` | install + smoke AVD | `CMD-051` | Android concerné | beta |
|
||||
| `CMD-053` | install + smoke appareil réel | `CMD-051` | Android concerné | beta/RC |
|
||||
| `CMD-060` | `cargo clean --dry-run --verbose` | — | contrôle disque / préparation nettoyage | maintenance |
|
||||
|
||||
Reference in New Issue
Block a user