-
Notifications
You must be signed in to change notification settings - Fork 242
updated: AGP 9 project migration guide #530
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
| <toc-element toc-title="Basic project structure" topic="multiplatform-discover-project.md"/> | ||
| <toc-element toc-title="Advanced project structure" topic="multiplatform-advanced-project-structure.md"/> | ||
| <toc-element toc-title="Project configuration options" topic="multiplatform-project-configuration.md"/> | ||
| <toc-element toc-title="Project configuration options" topic="multiplatform-project-agp-9-migration.md"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong toc-title
| You can remove old run configurations associated with the `composeApp` module. | ||
| 2. In the `gradle/libs.versions.toml` file, update the AGP version to a 9.* version, for example: | ||
| ```txt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"CDE016: Unknown language is specified for a code block"
Let's try toml or text
| // ... | ||
| } | ||
| ``` | ||
| 4. In the `kotlin {}` block, specify the targets that the common module should support in this example: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous step is for the root build.gradle.kts file, specify the file with the kotlin {} block
| > To do that, in the `gradle.properties` file of your project add this property: | ||
| > `android.enableLegacyVariantApi=true`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| > To do that, in the `gradle.properties` file of your project add this property: | |
| > `android.enableLegacyVariantApi=true`. | |
| > To do this, add the following property to the `gradle.properties` file: | |
| > `android.enableLegacyVariantApi=true`. |
| Before actually creating a module, you need to decide on what is business logic, which code is both UI- and | ||
| platform-independent. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Before actually creating a module, you need to decide on what is business logic, which code is both UI- and | |
| platform-independent. | |
| Before creating a module, you need to identify the code for business logic that is both UI- and platform-independent. |
| ### Update the iOS integration | ||
| Since the iOS app entry point is not built as a separate Gradle module, you can embed the source code into any module. | ||
| In this example, `sharedUi` makes most sense: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| In this example, `sharedUi` makes most sense: | |
| In this example, `sharedUi` makes the most sense: |
| ### Remove `composeApp` and update the Android Gradle plugin version | ||
| When all code is working from correct new modules: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| When all code is working from correct new modules: | |
| Once all code works correctly from the new modules: |
| 1. Remove the old module completely: | ||
| 1. Remove the `composeApp` dependency from the `settings.gradle.kts` file (the line `include(":composeApp")`). | ||
| 2. Remove the `composeApp` directory entirely. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 2. Remove the `composeApp` directory entirely. | |
| 2. Delete the `composeApp` directory entirely. |
| 4. That your apps build and run with the new AGP. | ||
| Congratulations, you modernized and optimized the structure of your project! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
| Congratulations, you modernized and optimized the structure of your project! | |
| Congratulations! You have modernized and optimized the structure of your project. |
| kotlin { | ||
| // ... | ||
| androidLibrary { | ||
| namespace = "com.jetbrains.greeting.demo.sharedLogic" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be sharedUi?
|
The guide is long and intimidating, with repetitive steps for each platform. What do you think about adding a section with general steps for creating a module? This would help identify common patterns upfront and allow us to make repetitive steps collapsible. |
| <toc-element toc-title="Basic project structure" topic="multiplatform-discover-project.md"/> | ||
| <toc-element toc-title="Advanced project structure" topic="multiplatform-advanced-project-structure.md"/> | ||
| <toc-element toc-title="Project configuration options" topic="multiplatform-project-configuration.md"/> | ||
| <toc-element toc-title="Project configuration options" topic="multiplatform-project-agp-9-migration.md"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I'm not sure if this guide will be discoverable under "Explore project structure"
| ```kotlin | ||
| fun currentTimeAt(location: String): String? { | ||
| @OptIn(ExperimentalTime::class) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we add opt-in on a project level?
| Kotlin Multiplatform projects with Android targets which were created using the Android Gradle plugin version earlier | ||
| than 9.0 | ||
| need to be restructured to upgrade to AGP 9.0. | ||
| Several APIs needed for KMP configuration are hidden in AGP 9.0 and eventually are going to be removed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it publicly communicated/documented? It would be nice to provide a link to outline a rough timeline
| than 9.0 | ||
| need to be restructured to upgrade to AGP 9.0. | ||
| Several APIs needed for KMP configuration are hidden in AGP 9.0 and eventually are going to be removed. | ||
| To solve this in the long term, we recommend updating your project structure to isolate AGP usage to an Android module. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, it's not entirely correct. Library-AGP is still going to be used in a shared module, but Application-AGP will be isolated in an Android module. I'm not sure if there's established terminology for distinguishing between these two types of AGPs
| The example project is a Compose Multiplatform app that is the result of the [](compose-multiplatform-new-project.md) | ||
| tutorial. | ||
| You can check out the initial state of the project in | ||
| the [update_october_2025 branch](https://github.com/kotlin-hands-on/get-started-with-cm/tree/update_october_2025) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a temporary branch that I was planning to delete 😅 should we create a new one with more meaningful name?
| * Isolate the Android module (that uses the `androidApplication` Gradle plugin) from KMP modules (that use the | ||
| `androidLibrary` | ||
| Gradle plugin). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we explicitly state somewhere at the beginning that the goal for this migration is to not use com.android.application and org.jetbrains.kotlin.multiplatform in the same module? Maybe even before describing workaround with android.enableLegacyVariantApi=true, so people would know if they even need to migrate
| You have isolated the shared logic in a separate module and successfully used it cross-platform. | ||
| Next step, creating a shared UI module. | ||
|
|
||
| <!-- TODO Platform.kt may be a good example of migrating expect-actuals, but are they still there in the sample we're using? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, it's not used in the sample app. We either need to come up with a better example for expect/actual usage in this particular sample or just keep it more generic without mentioning Platform class and related methods
| sourceSets { | ||
| commonMain.dependencies { | ||
| implementation(projects.sharedLogic) | ||
| implementation(compose.runtime) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're going to get rid of dependency aliases in CMP, so this block will change by the time of release. I'll let you know what it's going to look like
No description provided.