From 32e45c266db703f124c5d4e121d163665921ef8e Mon Sep 17 00:00:00 2001 From: Arnie Date: Fri, 12 Jun 2026 19:05:03 +0200 Subject: [PATCH] Fix gradle aapt2 linking --- .envrc | 2 ++ CLAUDE.md | 13 ++++++++----- flake.nix | 29 ++++++++++++++++++----------- gradle.properties | 4 +--- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/.envrc b/.envrc index a5dbbcb..f037719 100644 --- a/.envrc +++ b/.envrc @@ -1 +1,3 @@ use flake . + +export TV_IP=10.127.255.225 diff --git a/CLAUDE.md b/CLAUDE.md index 048bcc3..f703e28 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -20,11 +20,14 @@ This is a lab project (`lab` skill conventions apply) EXCEPT: ## NixOS aapt2 workaround AGP cannot run the Maven-downloaded aapt2 on NixOS (dynamically linked -generic Linux binary). The nix shellHook rewrites the -`android.aapt2FromMavenOverride` line in `gradle.properties` to point at -the SDK's nix-patched aapt2 on every `nix develop`. The sentinel value -`__NIX_SHELLHOOK_SETS_THIS__` is what's tracked in git; the shellHook -replaces it before any gradle command runs. +generic Linux binary). The flake's dev shell ships a wrapped `gradle` that +always passes `-Dorg.gradle.project.android.aapt2FromMavenOverride=` on the command line; Gradle turns `org.gradle.project.*` system +props into project properties, which is what AGP reads. It must be a CLI +arg: the nixpkgs-25.11 gradle wrapper ignores `GRADLE_OPTS` (fixed +post-25.11, nixpkgs PR #449037 — the flake wrapper can be dropped once +the pin moves past 25.11). No file rewriting; `gradle.properties` stays +untouched. ## Commands (user-run, from repo root) diff --git a/flake.nix b/flake.nix index ab493c2..92f492d 100644 --- a/flake.nix +++ b/flake.nix @@ -43,30 +43,37 @@ sdkRoot = "${androidSdk}/libexec/android-sdk"; fonts = with pkgs; [ noto-fonts dejavu_fonts freefont_ttf ]; + + # NixOS gotcha: AGP downloads a dynamically-linked aapt2 from Maven + # that can't run on NixOS. android.aapt2FromMavenOverride is a Gradle + # *project* property; `-Dorg.gradle.project.` on the command line + # sets one. It must be a CLI arg, not GRADLE_OPTS: the gradle package + # in nixpkgs 25.11 is a raw `exec java ... GradleMain "$@"` wrapper + # that ignores GRADLE_OPTS (fixed post-25.11 in nixpkgs PR #449037 — + # once we're past 25.11, plain GRADLE_OPTS works and this wrapper can go). + gradle = pkgs.symlinkJoin { + name = "gradle-nixos-aapt2"; + paths = [ pkgs.gradle ]; + nativeBuildInputs = [ pkgs.makeWrapper ]; + postBuild = '' + wrapProgram $out/bin/gradle \ + --add-flags "-Dorg.gradle.project.android.aapt2FromMavenOverride=${sdkRoot}/build-tools/${buildToolsVersion}/aapt2" + ''; + }; in { devShells.default = pkgs.mkShell { packages = [ androidSdk pkgs.jdk17 - pkgs.gradle + gradle # wrapped, see above pkgs.imagemagick # banner/icon generation pkgs.android-tools # adb for sideloading ] ++ fonts; - ANDROID_HOME = sdkRoot; ANDROID_SDK_ROOT = sdkRoot; FONTCONFIG_FILE = pkgs.makeFontsConf { fontDirectories = fonts; }; - - # NixOS gotcha: AGP downloads a dynamically-linked aapt2 from Maven - # that can't run on NixOS. AGP reads the override from gradle.properties - # as a project property (not a JVM system property), so GRADLE_OPTS -D - # flags don't work. The shellHook writes the correct nix store path - # directly into gradle.properties so providers.gradleProperty() finds it. - shellHook = '' - sed -i "s|android.aapt2FromMavenOverride=.*|android.aapt2FromMavenOverride=${sdkRoot}/build-tools/${buildToolsVersion}/aapt2|" gradle.properties - ''; }; } ); diff --git a/gradle.properties b/gradle.properties index d95c162..9fecc38 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,3 @@ org.gradle.jvmargs=-Xmx2g android.useAndroidX=true -# NixOS: AGP cannot run the Maven-downloaded aapt2 (dynamically linked generic Linux binary). -# Value is rewritten by the nix shellHook on every `nix develop` — do not edit manually. -android.aapt2FromMavenOverride=__NIX_SHELLHOOK_SETS_THIS__ +# NixOS aapt2 override is injected by the wrapped gradle in the nix dev shell — see flake.nix.