From f638979507aa467269ecc445e55f748911f93ef0 Mon Sep 17 00:00:00 2001 From: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com> Date: Mon, 9 Nov 2026 23:43:10 -0500 Subject: [PATCH] perf(lab): compile with the Kotlin daemon, since in-process Kotlin compiles always redo the whole app --- docs/lab-builds.md | 4 +++- tools/agent/dd-lab-build | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/docs/lab-builds.md b/docs/lab-builds.md index ef0a40d98..64d2d2d0a 100644 --- a/docs/lab-builds.md +++ b/docs/lab-builds.md @@ -52,7 +52,9 @@ tools/agent/setup It installs Claude Code, git, gh and loopback adb, plus the build toolchain: JDK 17, the Android SDK platform, and Google's x86-64 `aapt2` run under `qemu-user`. The first Lab build compiles the -whole app and takes about 20 minutes on a Snapdragon 865; later ones are incremental. Setup +whole app and takes about 8 minutes on a Snapdragon 865; later ones compile only what changed. +That needs the Kotlin daemon: Kotlin's in-process compiles always redo the whole app. BuildConfig +is given the installed commit, so committing a change does not change it. Setup does that first build ahead of time with `dd-lab-build --prepare`, which compiles the installed commit without making a Lab build. `~/.cache/dd-lab-build.json` reports the stage, the current task, progress in thousandths and the diff --git a/tools/agent/dd-lab-build b/tools/agent/dd-lab-build index 387b93840..e53bdbb7b 100755 --- a/tools/agent/dd-lab-build +++ b/tools/agent/dd-lab-build @@ -96,15 +96,24 @@ if [ ! -d "$ANDROID_HOME/platforms/android-34" ]; then "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" "platforms;android-34" "build-tools;35.0.0" >/dev/null fi -# A full Kotlin compile of the app needs about 3 GB of heap; smaller devices get what they can spare. +# A full Kotlin compile of the app needs about 2.5 GB of heap and Gradle about 1 GB; smaller devices get +# what they can spare. Both daemons end with this script's process when the build is done. total_mb=$(awk '/^MemTotal:/ {print int($2 / 1024)}' /proc/meminfo) -heap=$(( total_mb * 2 / 5 )); [ $heap -gt 3072 ] && heap=3072; [ $heap -lt 1536 ] && heap=1536 +heap=$(( total_mb / 2 )); [ $heap -gt 4096 ] && heap=4096; [ $heap -lt 2048 ] && heap=2048 heap=${DD_LAB_HEAP_MB:-$heap} +kotlin_heap=$(( heap * 2 / 3 )); gradle_heap=$(( heap - kotlin_heap )) + +# Only the Kotlin daemon compiles incrementally; in-process compiles always redo the whole app, and the +# caches they leave behind make the daemon's first incremental compile fail. +if [ "$(cat "$cache/dd-lab-build-strategy" 2>/dev/null)" != daemon ]; then + rm -rf app/build/kotlin/compileReleaseKotlin + echo daemon > "$cache/dd-lab-build-strategy" +fi # Google publishes aapt2 for x86-64 Linux only; setup wraps it in qemu-user at ~/aapt2/aapt2. gradle=(./gradlew :app:processReleaseResources :app:mergeDexRelease --max-workers=2 -PskipRust=true -x buildVkBridgeServer - -Pandroid.aapt2FromMavenOverride=$HOME/aapt2/aapt2 -Pkotlin.compiler.execution.strategy=in-process - -Dorg.gradle.jvmargs=-Xmx${heap}m --console=plain) + -Pandroid.aapt2FromMavenOverride=$HOME/aapt2/aapt2 -Pkotlin.compiler.execution.strategy=daemon + -Pkotlin.daemon.jvmargs=-Xmx${kotlin_heap}m -Dorg.gradle.jvmargs=-Xmx${gradle_heap}m --console=plain) progress planning mapfile -t plan < <("${gradle[@]}" --dry-run -q 2>/dev/null | awk '/^:/ {print $1}' || true) total=${#plan[@]}