KMP AGP 9.0.0 - Android Application to Library Migration

Upgrading New KMP Project to AGP 9.0

This guide will take you through the process step-by-step.

It's designed to be verbose and also image heavy so newer programmers can easily follow everything and ensure they are doing all the steps correctly.

There are full listings for all the changes.

I used the PL Coding Video as a reference to help with this and strongly recommend taking a look. There is a GitHub repo linked under the video as well that you can inspect. My libs.toml file contains different entries so these are not directly compatible. I tried to follow the conventions from the default wizards and made as few changes as possible.

Note: Unfortunately, the longer code sections will look terrible on mobile. Formatting everything for mobile makes it look bad on a monitor. Please use a bigger screen if you need to read the longer code sections. You should be fine to read and understand everything without needing to see the code listings.

Start New Project

For the purpose of this guide, we will test everything on a new project.

Start a new KMP project in Android Studio via the Wizard or using the JetBrains KMP Template Download. This guide may help.

If you are very new or struggle, you may want to do everything exactly the same so your project perfectly matches my screenshots, use the following project details:


Experienced Android developers should be comfortable working with different project and package names.

Important Note: I believe the Android Studio wizard was updated in the last day or so as it now produces the same result as the JetBrains template. Previously, as referenced in the PL Coding Tutorial, the app would not launch after upgrading to AGP 9.0.0. Now, we can follow the automated upgrade process and everything launches and runs, but it produces a bunch of warning we need to take care of.

While testing this tutorial, I'm using a new project from the wizard with Android, iOS, Desktop, and Web. I'm also including tests (which can't be seen on the image below).

Upgrade to AGP 9.0.0

Use the inbuilt wizard to upgrade to the AGP 9.0.0


You can upgrade directly from 8.11.2 to 9.0.0 from the Dropdown:

You'll get a success message with the following recommendation:

Sync succeeded
The upgraded project successfully synced with the IDE. You should test that the upgraded project builds and passes its tests successfully before making further changes.
The upgrade consisted of the following steps:
  • Upgrade AGP dependency from 8.11.2 to 9.0.0
  • Upgrade Gradle version to 9.1.0
  • Enable resValues build feature
  • Disable targetSdk defaults to compileSdk
  • Disable App Compile-Time R Class
  • Continue to allow   in the main manifest
  • Allow non-unique package names
  • Enable Dependency Constraints
  • Disable R8 Strict Mode for Keep Rules
  • Disable R8 Optimized Resource Shrinking
  • Disable built-in Kotlin support
  • Preserve the old (internal) AGP Dsl APIs

Upgrade Details

Opening your gradle.properties (project properties), you should see a lot of these steps are taken care of for you. I believe this was the change that was made to the built in wizard as I think these setting allow everything to run without moving the Android content into its own module.

#Kotlin
kotlin.code.style=official
kotlin.daemon.jvmargs=-Xmx3072M

#Gradle
org.gradle.jvmargs=-Xmx4096M -Dfile.encoding=UTF-8
org.gradle.configuration-cache=true
org.gradle.caching=true

#Android
android.nonTransitiveRClass=true
android.useAndroidX=true
android.defaults.buildfeatures.resvalues=true
android.sdk.defaultTargetSdkToCompileSdkIfUnset=false
android.enableAppCompileTimeRClass=false
android.usesSdkInManifest.disallowed=false
android.uniquePackageNames=false
android.dependency.useConstraints=true
android.r8.strictFullModeForKeepRules=false
android.r8.optimizedResourceShrinking=false
android.builtInKotlin=false
android.newDsl=false

Your gradle-wrapper.properties should also have been updated:

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

I will put other full content here as well in case you want to compare for any reason, but you should be able to safely ignore these. We will need to make changes to these later for the App -> Library Android migration.

build.gradle.kts (Module: composeApp) - Click to reveal
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidApplication)
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler)
alias(libs.plugins.composeHotReload)
}

kotlin {
androidTarget {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11)
}
}

listOf(
iosArm64(),
iosSimulatorArm64()
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "ComposeApp"
isStatic = true
}
}

jvm()

js {
browser()
binaries.executable()
}

@OptIn(ExperimentalWasmDsl::class)
wasmJs {
browser()
binaries.executable()
}

sourceSets {
androidMain.dependencies {
implementation(libs.compose.uiToolingPreview)
implementation(libs.androidx.activity.compose)
}
commonMain.dependencies {
implementation(libs.compose.runtime)
implementation(libs.compose.foundation)
implementation(libs.compose.material3)
implementation(libs.compose.ui)
implementation(libs.compose.components.resources)
implementation(libs.compose.uiToolingPreview)
implementation(libs.androidx.lifecycle.viewmodelCompose)
implementation(libs.androidx.lifecycle.runtimeCompose)
}
commonTest.dependencies {
implementation(libs.kotlin.test)
}
jvmMain.dependencies {
implementation(compose.desktop.currentOs)
implementation(libs.kotlinx.coroutinesSwing)
}
}
}

android {
namespace = "com.github.d9l9.tests.kmpnewprojecttoagp9"
compileSdk = libs.versions.android.compileSdk.get().toInt()

defaultConfig {
applicationId = "com.github.d9l9.tests.kmpnewprojecttoagp9"
minSdk = libs.versions.android.minSdk.get().toInt()
targetSdk = libs.versions.android.targetSdk.get().toInt()
versionCode = 1
versionName = "1.0"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}

dependencies {
debugImplementation(libs.compose.uiTooling)
}

compose.desktop {
application {
mainClass = "com.github.d9l9.tests.kmpnewprojecttoagp9.MainKt"

nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "com.github.d9l9.tests.kmpnewprojecttoagp9"
packageVersion = "1.0.0"
}
}
}
build.gradle.kts (Project: ProjectName) - Click to reveal
plugins {
// this is necessary to avoid the plugins to be loaded multiple times
// in each subproject's classloader
alias(libs.plugins.androidApplication) apply false
alias(libs.plugins.androidLibrary) apply false
alias(libs.plugins.composeHotReload) apply false
alias(libs.plugins.composeMultiplatform) apply false
alias(libs.plugins.composeCompiler) apply false
alias(libs.plugins.kotlinMultiplatform) apply false
}

libs.versions.toml - Click to reveal
[versions]
agp = "9.0.0"
android-compileSdk = "36"
android-minSdk = "24"
android-targetSdk = "36"
androidx-activity = "1.12.2"
androidx-appcompat = "1.7.1"
androidx-core = "1.17.0"
androidx-espresso = "3.7.0"
androidx-lifecycle = "2.9.6"
androidx-testExt = "1.3.0"
composeHotReload = "1.0.0"
composeMultiplatform = "1.10.0"
junit = "4.13.2"
kotlin = "2.3.0"
kotlinx-coroutines = "1.10.2"
material3 = "1.10.0-alpha05"

[libraries]
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotlin-testJunit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" }
junit = { module = "junit:junit", version.ref = "junit" }
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core" }
androidx-testExt-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-testExt" }
androidx-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-espresso" }
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }
compose-uiTooling = { module = "org.jetbrains.compose.ui:ui-tooling", version.ref = "composeMultiplatform" }
androidx-lifecycle-viewmodelCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" }
androidx-lifecycle-runtimeCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" }
compose-runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "composeMultiplatform" }
compose-foundation = { module = "org.jetbrains.compose.foundation:foundation", version.ref = "composeMultiplatform" }
compose-material3 = { module = "org.jetbrains.compose.material3:material3", version.ref = "material3" }
compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "composeMultiplatform" }
compose-components-resources = { module = "org.jetbrains.compose.components:components-resources", version.ref = "composeMultiplatform" }
compose-uiToolingPreview = { module = "org.jetbrains.compose.ui:ui-tooling-preview", version.ref = "composeMultiplatform" }
kotlinx-coroutinesSwing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" }

[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
androidLibrary = { id = "com.android.library", version.ref = "agp" }
composeHotReload = { id = "org.jetbrains.compose.hot-reload", version.ref = "composeHotReload" }
composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "composeMultiplatform" }
composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }

Run!

Now we've upgraded, we can safely run the project. 

As well as Android, I'm also testing the JS, JVM, and wasmJs builds just to be safe. They all work, but I do get a lot of warnings with the JS and wasmJs builds (which are both also extremely slow). I'm running Windows on an Intel PC and so cannot test the iOS build locally. I can only assume it works.

Migrating Android to a Library

So here's the complicated (or troublesome) part. We need to move the Android code out of composeApp and into a library module.

1. Locate Android Section

First, let's find the code we need to move.

From the Android view, look for the blue. We have the manifest and Kotlin folder. These are the Android versions.

2. Create Module

Next, let's create our androidApp module.

New->New Module / Android Library

Name the module. The package name should automatically update.

It'll take a minute or two for Gradle to sync, but you should see this when it finishes:

3. Move Content

We next need to move our Android content out into the module.

Warning: This will break the build. You will not be able to run everything until we complete these steps and fix the dependencies. I would strongly recommend setting a Git restore point before doing this so you can back again in case you mess things up. I personally hate it when things don't build and run so I  try to get the build up and running again as quickly as possible.

We're going to move AndroidManifest.xml, MainActivity.kt, and our resources into our module.

Unfortunately, if you try to move the AndroidManifest from the Android view, it looks like it works but it doesn't. Instead, you need to switch to the Project view (then composeApp/src/androidMain/kotlin/package).


From the project view, drag the composeApp manifest and the res folder into androidApp main. You will get a refactor prompt followed by an overwrite prompt.

Overwrite and verify the file has been moved correctly.

Next we just need to move our MainActivity into androidApp / package / androidapp.

This is slightly easier from the project view as it's not so far to drag. Here are screenshots after the move from both views:


Make sure the package name is retained (the Package should not be empty). If the package is empty, just select it from the dropdown. This is caused by dragging it into main and not into the package.

You will get a refactor prompt and a confirmation so go ahead and Refactor Anyway.

4. Fix Dependencies

Next we need to work through our dependency fixes. I prefer working from the Android view for this as all the files we need are in one place under Gradle Scripts.

I would strongly recommend making a Git commit here so you can revert back to this point if you need to start again.

I'll explain the changes then post full versions of the files. There's quite a lot happening so it's easy to mess this up. If it does go wrong.

Nothing is being removed from these files as I have commented everything out instead. This makes it easier to spot the changes from your own version. Of course, you should remove these lines when everything is working as expected.

A) libs.versions.toml

We just need to add the KMP Library:
[plugins]
...
#Added
androidKmpLibrary = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" }
I've also commented out Sdk references in the full version below as these are not used. I've spaced out some of the entries to make things a little easier to read below.
Final libs.versions.toml - Click to reveal
[versions]
agp = "9.0.0"

#android-compileSdk = "36"
#android-minSdk = "24"
#android-targetSdk = "36"

androidx-activity = "1.12.2"
androidx-appcompat = "1.7.1"

androidx-core = "1.17.0"
androidx-espresso = "3.7.0"
androidx-lifecycle = "2.9.6"
androidx-testExt = "1.3.0"

composeHotReload = "1.0.0"
composeMultiplatform = "1.10.0"

junit = "4.13.2"

kotlin = "2.3.0"
kotlinx-coroutines = "1.10.2"
material3 = "1.10.0-alpha05"
material = "1.13.0"

[libraries]
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotlin-testJunit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" }
junit = { module = "junit:junit", version.ref = "junit" }

androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core" }

androidx-testExt-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-testExt" }
androidx-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "androidx-espresso" }

androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }

compose-uiTooling = { module = "org.jetbrains.compose.ui:ui-tooling", version.ref = "composeMultiplatform" }

androidx-lifecycle-viewmodelCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" }
androidx-lifecycle-runtimeCompose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" }

compose-runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "composeMultiplatform" }
compose-foundation = { module = "org.jetbrains.compose.foundation:foundation", version.ref = "composeMultiplatform" }
compose-material3 = { module = "org.jetbrains.compose.material3:material3", version.ref = "material3" }
compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "composeMultiplatform" }
compose-components-resources = { module = "org.jetbrains.compose.components:components-resources", version.ref = "composeMultiplatform" }
compose-uiToolingPreview = { module = "org.jetbrains.compose.ui:ui-tooling-preview", version.ref = "composeMultiplatform" }

kotlinx-coroutinesSwing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }

[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
androidLibrary = { id = "com.android.library", version.ref = "agp" }

composeHotReload = { id = "org.jetbrains.compose.hot-reload", version.ref = "composeHotReload" }
composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "composeMultiplatform" }

composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }

#Added
androidKmpLibrary = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" }
B) Optional - gradle-wrapper.properties

You don't need to adjust the Gradle wrapper, but I pushed my version up to 9.3.0.

Final gradle-wrapper.properties - Click to reveal
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
C) gradle.properties (project properties)

We just need to remove the following:


#android.defaults.buildfeatures.resvalues=true
#android.sdk.defaultTargetSdkToCompileSdkIfUnset=false
#android.enableAppCompileTimeRClass=false
#android.usesSdkInManifest.disallowed=false
#android.uniquePackageNames=false
#android.dependency.useConstraints=true
#android.r8.strictFullModeForKeepRules=false
#android.r8.optimizedResourceShrinking=false
#android.builtInKotlin=false
#android.newDsl=false

I believe those options are what allowed project to run when upgrading to AGP 9 without moving the Android code into a library.

Final gradle.properties (project properties) - Click to reveal
#Kotlin
kotlin.code.style=official
kotlin.daemon.jvmargs=-Xmx3072M

#Gradle
org.gradle.jvmargs=-Xmx4096M -Dfile.encoding=UTF-8
org.gradle.configuration-cache=true
org.gradle.caching=true

#Android
android.nonTransitiveRClass=true
android.useAndroidX=true

#android.defaults.buildfeatures.resvalues=true
#android.sdk.defaultTargetSdkToCompileSdkIfUnset=false
#android.enableAppCompileTimeRClass=false
#android.usesSdkInManifest.disallowed=false
#android.uniquePackageNames=false
#android.dependency.useConstraints=true
#android.r8.strictFullModeForKeepRules=false
#android.r8.optimizedResourceShrinking=false
#android.builtInKotlin=false
#android.newDsl=false
D) build.gradle.kts (Module: composeApp)

Now we need to make some big changes to the project build file. 

We should remove the jvmTargetandroidApplication pluginandroidTarget, android section, and dependencies section.

We need to add androidKmpLibrary and an androidLibrary section. You'll need to make sure your package name is correct for that (you can copy it from your composeApp).

We also need to add enableAndroidResources to androidLibrary or we get a new exciting crash when we click the button. Unfortunately, this is not caught at compile time and will only show up when your Android app accesses resources. I imagine this will be quickly patched out.

org.jetbrains.compose.resources.MissingResourceException: Missing resource with path: composeResources/kmpnewprojecttoagp9.composeapp.generated.resources/drawable/compose-multiplatform.xml

Rather than show these changes, please refer to the full listing.

Final build.gradle.kts (Module: composeApp) - Click to reveal
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl

//import org.jetbrains.kotlin.gradle.dsl.JvmTarget

plugins {
alias(libs.plugins.kotlinMultiplatform)
// alias(libs.plugins.androidApplication)
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler)
alias(libs.plugins.composeHotReload)

// Added
alias(libs.plugins.androidKmpLibrary)
}

kotlin {
// androidTarget {
// compilerOptions {
// jvmTarget.set(JvmTarget.JVM_11)
// }
// }

// Added
androidLibrary {
compileSdk = 36
minSdk = 24
namespace = "com.github.d9l9.tests.composeApp"
// // org.jetbrains.compose.resources.MissingResourceException: Missing resource with path: composeResources/gradeagp9updatetestarea.composeapp.generated.resources/drawable/compose-multiplatform.xml
// experimentalProperties["android.experimental.kmp.enableAndroidResources"] = true // Withiout this, Android app will crash with
}

listOf(
iosArm64(),
iosSimulatorArm64()
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "ComposeApp"
isStatic = true
}
}

jvm()

js {
browser()
binaries.executable()
}

@OptIn(ExperimentalWasmDsl::class)
wasmJs {
browser()
binaries.executable()
}
//
sourceSets {
androidMain.dependencies {
implementation(libs.compose.uiToolingPreview)
implementation(libs.androidx.activity.compose)
}
commonMain.dependencies {
implementation(libs.compose.runtime)
implementation(libs.compose.foundation)
implementation(libs.compose.material3)
implementation(libs.compose.ui)

implementation(libs.compose.components.resources)
implementation(libs.compose.uiToolingPreview)

implementation(libs.androidx.lifecycle.viewmodelCompose)
implementation(libs.androidx.lifecycle.runtimeCompose)
}
commonTest.dependencies {
implementation(libs.kotlin.test)
}
jvmMain.dependencies {
implementation(compose.desktop.currentOs)
implementation(libs.kotlinx.coroutinesSwing)
}
}
}

//android {
// namespace = "com.github.d9l9.tests.kmpnewprojecttoagp9"
// compileSdk = libs.versions.android.compileSdk.get().toInt()
//
// defaultConfig {
// applicationId = "com.github.d9l9.tests.kmpnewprojecttoagp9"
// minSdk = libs.versions.android.minSdk.get().toInt()
// targetSdk = libs.versions.android.targetSdk.get().toInt()
// versionCode = 1
// versionName = "1.0"
// }
// packaging {
// resources {
// excludes += "/META-INF/{AL2.0,LGPL2.1}"
// }
// }
// buildTypes {
// getByName("release") {
// isMinifyEnabled = false
// }
// }
// compileOptions {
// sourceCompatibility = JavaVersion.VERSION_11
// targetCompatibility = JavaVersion.VERSION_11
// }
//}
//
//dependencies {
// debugImplementation(libs.compose.uiTooling)
//}

compose.desktop {
application {
mainClass = "com.github.d9l9.tests.kmpnewprojecttoagp9.MainKt"

nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "com.github.d9l9.tests.kmpnewprojecttoagp9"
packageVersion = "1.0.0"
}
}
}
E) build.gradle.kts (Module: androidApp)

This is a lot easier than the previous file.

We need to remove androidLibrary plugin and consumerProguardFiles("consumer-rules.pro"). We should add androidApplication and composeCompiler plugins.

plugins {
// alias(libs.plugins.androidLibrary)

// Added
alias(libs.plugins.androidApplication)
alias(libs.plugins.composeCompiler)
}
    defaultConfig {
minSdk = 24

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
// consumerProguardFiles("consumer-rules.pro")
}

The compileOptions section can also be safely removed; our jvmToolchain takes care of all this.

//    compileOptions {
// sourceCompatibility = JavaVersion.VERSION_11
// targetCompatibility = JavaVersion.VERSION_11
// }
Final build.gradle.kts (Module: androidApp) - Click to reveal
plugins {
// alias(libs.plugins.androidLibrary)

// Added
alias(libs.plugins.androidApplication)
alias(libs.plugins.composeCompiler)
}

android {
namespace = "com.github.d9l9.tests.androidapp"
compileSdk {
version = release(36)
}

defaultConfig {
minSdk = 24

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
// consumerProguardFiles("consumer-rules.pro")
}


buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
// compileOptions {
// sourceCompatibility = JavaVersion.VERSION_11
// targetCompatibility = JavaVersion.VERSION_11
// }
}

dependencies {
// Added
implementation(projects.composeApp)
implementation(libs.compose.uiToolingPreview)
implementation(libs.androidx.activity.compose)

implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.testExt.junit)
androidTestImplementation(libs.androidx.espresso.core)
}
F) build.gradle.kts (Project: ProjectName)

The easiest; we just need to add androidKmpLibrary.

plugins {
...
// Added
alias(libs.plugins.androidKmpLibrary) apply false
}
Final build.gradle.kts (Project: ProjectName) - Click to reveal
plugins {
// this is necessary to avoid the plugins to be loaded multiple times
// in each subproject's classloader
alias(libs.plugins.androidApplication) apply false
alias(libs.plugins.androidLibrary) apply false

alias(libs.plugins.composeHotReload) apply false
alias(libs.plugins.composeMultiplatform) apply false
alias(libs.plugins.composeCompiler) apply false
alias(libs.plugins.kotlinMultiplatform) apply false

// Added
alias(libs.plugins.androidKmpLibrary) apply false
}
Mission Complete
Everything is done!

I hope you found this guide useful. The file listings may be a good reference point if you every have problems with upgrading any existing projects.

Happy coding, KMPers!

Comments

Popular Posts