From c2b38b04a7bf408789fee7415394d2c0fc1b758f Mon Sep 17 00:00:00 2001 From: bbanyai Date: Thu, 14 May 2026 11:08:30 +0200 Subject: [PATCH] chore: AGP 9.1.1 with full KMP Android library migration --- .../AndroidApplicationConventionPlugin.kt | 12 +++++- .../AndroidLibraryConventionPlugin.kt | 39 ++++++++++++++----- .../KotlinAndroidConventionPlugin.kt | 18 --------- ...tlinMultiplatformMobileConventionPlugin.kt | 8 +--- .../MavenCentralPublishConventionPlugin.kt | 9 ----- .../publicvalue/convention/config/Android.kt | 34 +++++++--------- .../convention/config/Multiplatform.kt | 12 +----- build.gradle.kts | 2 +- camerautils/build.gradle.kts | 8 +++- gradle/libs.versions.toml | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- sample-app/android-app/build.gradle.kts | 23 +++++------ .../{androidMain => main}/AndroidManifest.xml | 0 .../qrcode/sample/MainActivity.kt | 0 .../drawable-v24/ic_launcher_foreground.xml | 0 .../res/drawable/ic_launcher_background.xml | 0 .../res/mipmap-anydpi-v26/ic_launcher.xml | 0 .../mipmap-anydpi-v26/ic_launcher_round.xml | 0 .../res/values/strings.xml | 0 sample-app/shared/build.gradle.kts | 10 ++--- scanner/build.gradle.kts | 8 +++- 21 files changed, 86 insertions(+), 103 deletions(-) delete mode 100644 build-logic/convention/src/main/kotlin/org/publicvalue/convention/KotlinAndroidConventionPlugin.kt rename sample-app/android-app/src/{androidMain => main}/AndroidManifest.xml (100%) rename sample-app/android-app/src/{androidMain => main}/kotlin/org/publicvalue/multiplatform/qrcode/sample/MainActivity.kt (100%) rename sample-app/android-app/src/{androidMain => main}/res/drawable-v24/ic_launcher_foreground.xml (100%) rename sample-app/android-app/src/{androidMain => main}/res/drawable/ic_launcher_background.xml (100%) rename sample-app/android-app/src/{androidMain => main}/res/mipmap-anydpi-v26/ic_launcher.xml (100%) rename sample-app/android-app/src/{androidMain => main}/res/mipmap-anydpi-v26/ic_launcher_round.xml (100%) rename sample-app/android-app/src/{androidMain => main}/res/values/strings.xml (100%) diff --git a/build-logic/convention/src/main/kotlin/org/publicvalue/convention/AndroidApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/org/publicvalue/convention/AndroidApplicationConventionPlugin.kt index 90152ae..f035c66 100644 --- a/build-logic/convention/src/main/kotlin/org/publicvalue/convention/AndroidApplicationConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/org/publicvalue/convention/AndroidApplicationConventionPlugin.kt @@ -1,14 +1,20 @@ package org.publicvalue.convention import com.android.build.api.dsl.ApplicationExtension +import org.gradle.accessors.dm.LibrariesForLibs import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.the +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.publicvalue.convention.config.configureKotlinAndroid class AndroidApplicationConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { + val libs = the() with(pluginManager) { apply("com.android.application") } @@ -16,6 +22,10 @@ class AndroidApplicationConventionPlugin : Plugin { extensions.configure { configureKotlinAndroid(this) } + + tasks.withType().configureEach { + compilerOptions.jvmTarget.set(JvmTarget.fromTarget(libs.versions.jvmTarget.get())) + } } } -} \ No newline at end of file +} diff --git a/build-logic/convention/src/main/kotlin/org/publicvalue/convention/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/org/publicvalue/convention/AndroidLibraryConventionPlugin.kt index 688ad89..b482e7a 100644 --- a/build-logic/convention/src/main/kotlin/org/publicvalue/convention/AndroidLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/org/publicvalue/convention/AndroidLibraryConventionPlugin.kt @@ -1,22 +1,43 @@ package org.publicvalue.convention -import com.android.build.gradle.LibraryExtension -import org.publicvalue.convention.config.configureKotlinAndroid +import com.android.build.api.dsl.KotlinMultiplatformAndroidLibraryExtension +import com.android.build.api.dsl.KotlinMultiplatformAndroidLibraryTarget +import org.gradle.accessors.dm.LibrariesForLibs +import org.gradle.api.plugins.ExtensionAware import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.the +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +/** + * KMP Android library (AGP 9+). Apply [KotlinMultiplatformMobileConventionPlugin] first so + * `org.jetbrains.kotlin.multiplatform` is on the project before this plugin runs. + */ class AndroidLibraryConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { - with(pluginManager) { - apply("com.android.library") + check(pluginManager.hasPlugin("org.jetbrains.kotlin.multiplatform")) { + "Apply org.publicvalue.convention.kotlin.multiplatform.mobile before org.publicvalue.convention.android.library" } - - extensions.configure { - configureKotlinAndroid(this) - namespace = "org.publicvalue.multiplatform.easyqrscan.${project.name.replace("-", ".")}" + pluginManager.apply("com.android.kotlin.multiplatform.library") + val libs = the() + extensions.configure { + (this as ExtensionAware).extensions.configure("android") { + compileSdk = libs.versions.compileSdk.get().toInt() + minSdk = libs.versions.minSdk.get().toInt() + androidResources { + enable = true + } + } + targets.withType().configureEach { + compilerOptions { + jvmTarget.set(JvmTarget.fromTarget(libs.versions.jvmTarget.get())) + } + } } } } -} \ No newline at end of file +} diff --git a/build-logic/convention/src/main/kotlin/org/publicvalue/convention/KotlinAndroidConventionPlugin.kt b/build-logic/convention/src/main/kotlin/org/publicvalue/convention/KotlinAndroidConventionPlugin.kt deleted file mode 100644 index d3ce53d..0000000 --- a/build-logic/convention/src/main/kotlin/org/publicvalue/convention/KotlinAndroidConventionPlugin.kt +++ /dev/null @@ -1,18 +0,0 @@ -package org.publicvalue.convention - -import org.publicvalue.convention.config.configureKotlin -import org.gradle.api.Plugin -import org.gradle.api.Project - -class KotlinAndroidConventionPlugin : Plugin { - override fun apply(target: Project) { - with(target) { - with(pluginManager) { - apply("org.jetbrains.kotlin.android") - } - -// configureSpotless() - configureKotlin() - } - } -} diff --git a/build-logic/convention/src/main/kotlin/org/publicvalue/convention/KotlinMultiplatformMobileConventionPlugin.kt b/build-logic/convention/src/main/kotlin/org/publicvalue/convention/KotlinMultiplatformMobileConventionPlugin.kt index ae300bc..f318a85 100644 --- a/build-logic/convention/src/main/kotlin/org/publicvalue/convention/KotlinMultiplatformMobileConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/org/publicvalue/convention/KotlinMultiplatformMobileConventionPlugin.kt @@ -4,8 +4,6 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.configure import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension -import org.publicvalue.convention.config.configureAndroidTarget -import org.publicvalue.convention.config.configureIosTargets import org.publicvalue.convention.config.configureKotlin /** @@ -20,12 +18,8 @@ class KotlinMultiplatformMobileConventionPlugin : Plugin { extensions.configure { applyDefaultHierarchyTemplate() - - if (pluginManager.hasPlugin("com.android.library")) { - this.configureAndroidTarget() - } } configureKotlin() } } -} \ No newline at end of file +} diff --git a/build-logic/convention/src/main/kotlin/org/publicvalue/convention/MavenCentralPublishConventionPlugin.kt b/build-logic/convention/src/main/kotlin/org/publicvalue/convention/MavenCentralPublishConventionPlugin.kt index 11ffe50..5f74618 100644 --- a/build-logic/convention/src/main/kotlin/org/publicvalue/convention/MavenCentralPublishConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/org/publicvalue/convention/MavenCentralPublishConventionPlugin.kt @@ -12,7 +12,6 @@ import org.gradle.kotlin.dsl.withType import org.gradle.plugins.signing.Sign import org.gradle.plugins.signing.SigningExtension import org.jetbrains.compose.internal.utils.getLocalProperty -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension class MavenCentralPublishConventionPlugin : Plugin { override fun apply(target: Project) { @@ -23,14 +22,6 @@ class MavenCentralPublishConventionPlugin : Plugin { apply("org.jetbrains.dokka") } - extensions.configure { - if (pluginManager.hasPlugin("com.android.library")) { - androidTarget { - publishLibraryVariants("release") - } - } - } - val javadocJar = tasks.register("javadocJar", Jar::class.java) { archiveClassifier.set("javadoc") from(tasks.getByName("dokkaGeneratePublicationHtml")) diff --git a/build-logic/convention/src/main/kotlin/org/publicvalue/convention/config/Android.kt b/build-logic/convention/src/main/kotlin/org/publicvalue/convention/config/Android.kt index 7505f38..e04006f 100644 --- a/build-logic/convention/src/main/kotlin/org/publicvalue/convention/config/Android.kt +++ b/build-logic/convention/src/main/kotlin/org/publicvalue/convention/config/Android.kt @@ -2,21 +2,15 @@ package org.publicvalue.convention.config import com.android.build.api.dsl.ApplicationExtension import com.android.build.api.dsl.CommonExtension -import com.android.build.api.dsl.LibraryExtension import org.gradle.accessors.dm.LibrariesForLibs import org.gradle.api.JavaVersion import org.gradle.api.Project import org.gradle.kotlin.dsl.the -import java.io.File -fun Project.configureKotlinAndroid(extension: CommonExtension<*, *, *, *, *, *>) { +fun Project.configureKotlinAndroid(extension: CommonExtension) { val libs = the() - if (extension is LibraryExtension) { - extension.defaultConfig { - consumerProguardFiles += File("consumer-rules.pro") - } - } else if (extension is ApplicationExtension) { + if (extension is ApplicationExtension) { extension.apply { defaultConfig { targetSdk = libs.versions.targetSdk.get().toInt() @@ -24,19 +18,17 @@ fun Project.configureKotlinAndroid(extension: CommonExtension<*, *, *, *, *, *>) } } - extension.apply { - compileSdk = libs.versions.compileSdk.get().toInt() + extension.compileSdk = libs.versions.compileSdk.get().toInt() - defaultConfig { - minSdk = libs.versions.minSdk.get().toInt() - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - } + with(extension.defaultConfig) { + minSdk = libs.versions.minSdk.get().toInt() + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } - // Can remove this once https://issuetracker.google.com/issues/260059413 is fixed. - // See https://kotlinlang.org/docs/gradle-configure-project.html#gradle-java-toolchains-support - compileOptions { - sourceCompatibility = JavaVersion.toVersion(libs.versions.jvmTarget.get()) - targetCompatibility = JavaVersion.toVersion(libs.versions.jvmTarget.get()) - } + // Can remove this once https://issuetracker.google.com/issues/260059413 is fixed. + // See https://kotlinlang.org/docs/gradle-configure-project.html#gradle-java-toolchains-support + with(extension.compileOptions) { + sourceCompatibility = JavaVersion.toVersion(libs.versions.jvmTarget.get()) + targetCompatibility = JavaVersion.toVersion(libs.versions.jvmTarget.get()) } -} \ No newline at end of file +} diff --git a/build-logic/convention/src/main/kotlin/org/publicvalue/convention/config/Multiplatform.kt b/build-logic/convention/src/main/kotlin/org/publicvalue/convention/config/Multiplatform.kt index b78d459..beb245b 100644 --- a/build-logic/convention/src/main/kotlin/org/publicvalue/convention/config/Multiplatform.kt +++ b/build-logic/convention/src/main/kotlin/org/publicvalue/convention/config/Multiplatform.kt @@ -1,16 +1,6 @@ package org.publicvalue.convention.config -import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension -import org.publicvalue.convention.libs - -fun KotlinMultiplatformExtension.configureAndroidTarget() { - androidTarget { - compilerOptions { - jvmTarget.set(JvmTarget.fromTarget(project.libs.versions.jvmTarget.get())) - } - } -} fun KotlinMultiplatformExtension.configureIosTargets(baseName: String? = null) { listOf( @@ -24,4 +14,4 @@ fun KotlinMultiplatformExtension.configureIosTargets(baseName: String? = null) { isStatic = true } } -} \ No newline at end of file +} diff --git a/build.gradle.kts b/build.gradle.kts index bef807a..385a3d8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,7 @@ import java.net.URI plugins { alias(libs.plugins.android.application) apply false - alias(libs.plugins.android.library) apply false + alias(libs.plugins.android.kotlin.multiplatform.library) apply false alias(libs.plugins.composeMultiplatform) apply false alias(libs.plugins.compose.compiler) apply false alias(libs.plugins.ksp) apply false diff --git a/camerautils/build.gradle.kts b/camerautils/build.gradle.kts index c696a01..5d90d94 100644 --- a/camerautils/build.gradle.kts +++ b/camerautils/build.gradle.kts @@ -1,8 +1,8 @@ import org.publicvalue.convention.config.configureIosTargets plugins { - id("org.publicvalue.convention.android.library") id("org.publicvalue.convention.kotlin.multiplatform.mobile") + id("org.publicvalue.convention.android.library") id("org.publicvalue.convention.centralPublish") id("org.publicvalue.convention.compose.multiplatform") } @@ -10,6 +10,10 @@ plugins { description = "Compose Multiplatform Camera Utilities for Android/iOS" kotlin { + android { + namespace = "org.publicvalue.multiplatform.easyqrscan.camerautils" + } + configureIosTargets() jvm() @@ -32,4 +36,4 @@ kotlin { } } } -} \ No newline at end of file +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5105d5d..040318d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ minSdk = "23" jvmTarget = "17" # https://developer.android.com/build/releases/gradle-plugin#compatibility -agp = "8.11.2" +agp = "9.1.1" #https://github.com/JetBrains/compose-multiplatform compose-multiplatform = "1.10.1" @@ -48,7 +48,7 @@ dokka-gradlePlugin = { module = "org.jetbrains.dokka:org.jetbrains.dokka.gradle. [plugins] android-application = { id = "com.android.application", version.ref = "agp" } -android-library = { id = "com.android.library", version.ref = "agp" } +android-kotlin-multiplatform-library = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" } composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" } compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3c68ad4..473116f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Thu Aug 05 09:58:17 CEST 2021 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/sample-app/android-app/build.gradle.kts b/sample-app/android-app/build.gradle.kts index 7632a72..156d5ec 100644 --- a/sample-app/android-app/build.gradle.kts +++ b/sample-app/android-app/build.gradle.kts @@ -1,22 +1,13 @@ plugins { id("org.publicvalue.convention.android.application") - id("org.publicvalue.convention.kotlin.multiplatform.mobile") id("org.publicvalue.convention.compose.multiplatform") } -kotlin { - androidTarget() - sourceSets { - val androidMain by getting { - dependencies { - implementation(libs.androidx.activity.compose) - implementation(libs.androidx.core.ktx) - implementation(libs.androidx.appcompat) - - implementation(projects.sampleApp.shared) - } - } - } +dependencies { + implementation(projects.sampleApp.shared) + implementation(libs.androidx.activity.compose) + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.appcompat) } android { @@ -27,4 +18,8 @@ android { versionCode = 1 versionName = "1.0" } + + buildFeatures { + compose = true + } } diff --git a/sample-app/android-app/src/androidMain/AndroidManifest.xml b/sample-app/android-app/src/main/AndroidManifest.xml similarity index 100% rename from sample-app/android-app/src/androidMain/AndroidManifest.xml rename to sample-app/android-app/src/main/AndroidManifest.xml diff --git a/sample-app/android-app/src/androidMain/kotlin/org/publicvalue/multiplatform/qrcode/sample/MainActivity.kt b/sample-app/android-app/src/main/kotlin/org/publicvalue/multiplatform/qrcode/sample/MainActivity.kt similarity index 100% rename from sample-app/android-app/src/androidMain/kotlin/org/publicvalue/multiplatform/qrcode/sample/MainActivity.kt rename to sample-app/android-app/src/main/kotlin/org/publicvalue/multiplatform/qrcode/sample/MainActivity.kt diff --git a/sample-app/android-app/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml b/sample-app/android-app/src/main/res/drawable-v24/ic_launcher_foreground.xml similarity index 100% rename from sample-app/android-app/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml rename to sample-app/android-app/src/main/res/drawable-v24/ic_launcher_foreground.xml diff --git a/sample-app/android-app/src/androidMain/res/drawable/ic_launcher_background.xml b/sample-app/android-app/src/main/res/drawable/ic_launcher_background.xml similarity index 100% rename from sample-app/android-app/src/androidMain/res/drawable/ic_launcher_background.xml rename to sample-app/android-app/src/main/res/drawable/ic_launcher_background.xml diff --git a/sample-app/android-app/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml b/sample-app/android-app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml similarity index 100% rename from sample-app/android-app/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml rename to sample-app/android-app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml diff --git a/sample-app/android-app/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml b/sample-app/android-app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml similarity index 100% rename from sample-app/android-app/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml rename to sample-app/android-app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml diff --git a/sample-app/android-app/src/androidMain/res/values/strings.xml b/sample-app/android-app/src/main/res/values/strings.xml similarity index 100% rename from sample-app/android-app/src/androidMain/res/values/strings.xml rename to sample-app/android-app/src/main/res/values/strings.xml diff --git a/sample-app/shared/build.gradle.kts b/sample-app/shared/build.gradle.kts index 9495baf..9270fe4 100644 --- a/sample-app/shared/build.gradle.kts +++ b/sample-app/shared/build.gradle.kts @@ -3,12 +3,16 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.publicvalue.convention.config.configureIosTargets plugins { - id("org.publicvalue.convention.android.library") id("org.publicvalue.convention.kotlin.multiplatform.mobile") + id("org.publicvalue.convention.android.library") id("org.publicvalue.convention.compose.multiplatform") } kotlin { + android { + namespace = "org.publicvalue.multiplatform.qrcode.sample.shared" + } + configureIosTargets() sourceSets { commonMain { @@ -34,7 +38,3 @@ kotlin { } } } - -android { - namespace = "org.publicvalue.multiplatform.qrcode.sample.shared" -} diff --git a/scanner/build.gradle.kts b/scanner/build.gradle.kts index 690e604..f8c1a13 100644 --- a/scanner/build.gradle.kts +++ b/scanner/build.gradle.kts @@ -1,8 +1,8 @@ import org.publicvalue.convention.config.configureIosTargets plugins { - id("org.publicvalue.convention.android.library") id("org.publicvalue.convention.kotlin.multiplatform.mobile") + id("org.publicvalue.convention.android.library") id("org.publicvalue.convention.centralPublish") id("org.publicvalue.convention.compose.multiplatform") } @@ -10,6 +10,10 @@ plugins { description = "Compose Multiplatform QR Code Scanner for Android/iOS" kotlin { + android { + namespace = "org.publicvalue.multiplatform.easyqrscan.scanner" + } + configureIosTargets() jvm() @@ -38,4 +42,4 @@ kotlin { } } } -} \ No newline at end of file +}