Skip to content

Support AGP 9 built-in Kotlin and the KMP android library plugin#543

Merged
andrewparmet merged 4 commits into
open-toast:mainfrom
andrewparmet:agp9-built-in-kotlin
Jul 7, 2026
Merged

Support AGP 9 built-in Kotlin and the KMP android library plugin#543
andrewparmet merged 4 commits into
open-toast:mainfrom
andrewparmet:agp9-built-in-kotlin

Conversation

@andrewparmet

@andrewparmet andrewparmet commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

AGP 9 enables built-in Kotlin by default and fails the build if org.jetbrains.kotlin.android is applied. That plugin id was protokt's only Android trigger, so on AGP 9 protokt configured nothing.

Single-platform Android

  • Also react to com.android.base when the built-in kotlin extension is present and the KGP android plugin is not (avoiding double configuration on AGP 8).
  • Change testApi to testImplementation since AGP 9 removed testApi.
  • optimal() codec detection selects protobuf-javalite for these projects, matching kotlin("android") behavior.

KMP android target (com.android.kotlin.multiplatform.library)

Previously failed at apply time. Protokt now wires it like other source-set-less KMP targets, with source sets mapping exactly to compilations:

  • src/main/protoandroidMain; src/test/protoandroidHostTest when host tests are enabled. Device tests are not wired.
  • ArtProfile tasks are ordered after generateProto: AGP derives baselineProfiles directories as siblings of Kotlin source directories, which lands inside generateProto's output and otherwise trips Gradle's implicit-dependency validation. Bit of an annoyance.

Tests and CI

  • -Dandroid-integration.version overrides AGP in the integration suite; android-test-fixtures covers the legacy path on AGP 8 and built-in Kotlin on 9.
  • New multiplatform-android module (AGP 9+ only) exercises the KMP android target, including host tests.
  • New integration-agp9 CI job runs the suite with AGP 9.2.1 on all three OSes, with and without the configuration cache. Separate job because AGP 9 forces KGP 2.2.10+ onto the buildscript classpath, which would invalidate the older-Kotlin matrix rows.
  • android-test-fixtures compileSdk bumped 31 → 36; platform 31 is not preinstalled on runners and its download corrupts intermittently.

AGP 9 enables built-in Kotlin by default and rejects
org.jetbrains.kotlin.android, so the plugin never saw its only Android
trigger and silently configured nothing on AGP 9 projects.

- React to com.android.base when the built-in `kotlin` extension is
  present, in addition to org.jetbrains.kotlin.android; a flag prevents
  double configuration on AGP 8 where both fire
- Fall back to testImplementation when testApi does not exist (AGP 9
  removed it)
- Codec auto-detection selects protobuf-javalite for Android projects
  detected via com.android.base, not just via the KGP android plugin
- Tolerate a missing <target>Test KotlinSourceSet: the AGP KMP android
  target (com.android.kotlin.multiplatform.library) has
  androidHostTest/androidDeviceTest instead of androidTest
- Fall back to the base generateProto/generateTestProto tasks for JVM-like
  KMP targets whose Gradle source sets don't exist (the AGP KMP android
  target creates none)
- Order ArtProfile tasks after generateProto: AGP derives
  baselineProfiles directories as siblings of Kotlin source directories,
  which lands inside generateProto's output and otherwise trips Gradle's
  implicit-dependency validation
- Integration tests: AGP version is overridable via
  -Dandroid-integration.version; android-test-fixtures applies the KGP
  android plugin only on AGP < 9; new multiplatform-android module
  exercises the KMP android target and is included only on AGP 9+
- CI: new integration-agp9 job runs the integration suite with AGP 9.2.1
  on all three OSes, with and without the configuration cache
Replaces the source-set-srcDir approach for
com.android.kotlin.multiplatform.library with the variant API. Generated
sources are registered per component with addGeneratedSourceDirectory
via a sync task, so source sets correspond exactly to compilations:
androidMain gets main protos, androidHostTest gets test protos when host
tests are enabled. Device tests are not wired.

- New AndroidKmpLibrary object handles the target; ProtoktBuild
  dispatches to it and no longer needs the generateProto task-name
  fallback or optional test source sets
- protokt-gradle-plugin adds a compileOnly dependency on
  com.android.tools.build:gradle-api; runtime classes load only when the
  AGP KMP library plugin is present
- ArtProfile ordering constraint kept: commonMain's generated srcDir
  still participates in the android compilation, so AGP still derives a
  baselineProfiles sibling inside generateProto's output
- multiplatform-android integration module enables host tests and
  exercises main and test protos in them
addGeneratedSourceDirectory relocates the wired DirectoryProperty into
an AGP-managed location, which forced a sync task to copy generateProto
output. Add the generated directories to the androidMain and
androidHostTest Kotlin source sets directly, with explicit compile-task
dependencies, matching how every other source-set-less KMP target is
wired. Drops the sync task and the compileOnly dependency on
com.android.tools.build:gradle-api.
- Replace the androidConfigured flag with a hasPlugin check: the
  com.android.base callback runs after the plugins block, so checking
  for org.jetbrains.kotlin.android there is race-free on AGP 8
- Use the<KotlinMultiplatformExtension>() in AndroidKmpLibrary
- Construct messages directly in multiplatform-android tests instead of
  through a commonMain factory
- android-test-fixtures: compileSdk 31 -> 36. Platform 31 is not
  preinstalled on GitHub runners and its on-demand download corrupts
  intermittently, failing random integration matrix rows
@andrewparmet andrewparmet marked this pull request as ready for review July 7, 2026 01:52
@andrewparmet andrewparmet requested a review from ogolberg July 7, 2026 01:53
@andrewparmet andrewparmet merged commit abb2bea into open-toast:main Jul 7, 2026
28 checks passed
@andrewparmet andrewparmet deleted the agp9-built-in-kotlin branch July 7, 2026 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants