From 4924146075d680ed59b56cb2b44e6372a4f0d637 Mon Sep 17 00:00:00 2001 From: rzuasti Date: Tue, 2 Jun 2026 20:49:28 -0400 Subject: [PATCH] Pin Android SDK components and aapt2 override for Flutter builds The Android SDK lives in the read-only Nix store, so the Gradle build cannot auto-install missing components. Pin everything the Flutter Android build needs in the dev shell's composeAndroidPackages: platforms 33-36 (app targets 36; plugins pin 34 and 35), build-tools 35.0.0 (AGP 8.11.1), NDK 28.2.13676358 (flutter.ndkVersion), and cmake 3.22.1 (plugin native builds). Also redirect the Android Gradle Plugin to the Nix-patched aapt2 from the SDK via android.aapt2FromMavenOverride, written to the user-global ~/.gradle/gradle.properties on shell entry (the project's tracked gradle.properties must not contain a machine-specific store path). AGP's Maven-downloaded aapt2 cannot run on NixOS. Ignore the generated frontend/android/build/ directory. Co-Authored-By: Claude Opus 4.8 --- flake.nix | 24 +++++++++++++++++++++++- frontend/android/.gitignore | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 32240bb..f9639cd 100644 --- a/flake.nix +++ b/flake.nix @@ -39,11 +39,17 @@ # available and reproducible across machines, instead of relying on the # contents of the default androidPkgs bundle (which can drift over time). androidComposition = pkgsBySystem.${system}.androidenv.composeAndroidPackages { - platformVersions = ["36"]; # matches Flutter 3.41 compileSdk/targetSdk + # 36 = Flutter 3.41 app compileSdk/targetSdk; 33-35 cover plugin subprojects + # which each pin their own compileSdk (e.g. package_info_plus -> 34, jni -> 35). + platformVersions = ["33" "34" "35" "36"]; + buildToolsVersions = ["35.0.0"]; # required by Android Gradle Plugin 8.11.1 includeEmulator = true; includeSystemImages = true; systemImageTypes = ["google_apis"]; abiVersions = ["x86_64"]; + includeNDK = true; + ndkVersions = ["28.2.13676358"]; # matches Flutter 3.41 flutter.ndkVersion + cmakeVersions = ["3.22.1"]; # required by plugin native (externalNativeBuild) tasks }; in { default = pkgsBySystem.${system}.mkShell rec { @@ -87,6 +93,22 @@ || echo " WARNING: failed to create Android emulator '$ANDROID_AVD_NAME'." fi + # Point the Android Gradle Plugin at the Nix-patched aapt2 shipped in + # the SDK build-tools. AGP otherwise downloads a prebuilt aapt2 from + # Maven that cannot run on NixOS (its ELF interpreter is missing). + # We write this to the user-global Gradle properties because the + # project's android/gradle.properties is version-controlled and must + # not contain a machine-specific Nix store path. The managed block is + # rewritten on every entry so it tracks the pinned SDK store path. + aapt2Bin="$(ls "$ANDROID_SDK_ROOT"/build-tools/*/aapt2 2>/dev/null | sort | tail -n1)" + if [ -n "$aapt2Bin" ]; then + mkdir -p "$HOME/.gradle" + gradleProps="$HOME/.gradle/gradle.properties" + touch "$gradleProps" + sed -i '/# >>> oott-nix >>>/,/# <<< oott-nix <<>> oott-nix >>>\nandroid.aapt2FromMavenOverride=%s\n# <<< oott-nix <<<\n' "$aapt2Bin" >> "$gradleProps" + fi + DEV_SHELL=oott exec fish ''; }; diff --git a/frontend/android/.gitignore b/frontend/android/.gitignore index be3943c..73b6f93 100644 --- a/frontend/android/.gitignore +++ b/frontend/android/.gitignore @@ -1,5 +1,6 @@ gradle-wrapper.jar /.gradle +/build/ /captures/ /gradlew /gradlew.bat