kotlin-tooling-agp9-migration について
Kotlin Multiplatform プロジェクトを Android Gradle Plugin 9.0 に対応させる移行スキルです。モジュールを分析し、ライブラリ移行、アプリ分割、マルチプラットフォーム構成の再編を案内します。
主な機能
- 01Gradle モジュールと設定の分析
- 02KMP Android ライブラリ移行の案内
- 03Android アプリと共有モジュールの分割
- 04マルチプラットフォームのエントリーポイント再編
- 05AGP 9.0 プラグイン互換性の確認
活用シーン
- 01KMP プロジェクトの AGP 9.0 対応
- 02共有コードからの Android アプリ分離
- 03Android ライブラリモジュールの移行
- 04マルチプラットフォーム Compose プロジェクトの再編
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ kotlin/ kotlin-agent-skills --skill kotlin-tooling-agp9-migrationインストール後、Claude Code で/kotlin-tooling-agp9-migrationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/checklist.mdreferences/DSL-REFERENCE.mdKNOWN-ISSUES.mdMIGRATION-APP-SPLIT.mdMIGRATION-FULL-RESTRUCTURE.mdMIGRATION-LIBRARY.mdPLUGIN-COMPATIBILITY.mdVERSION-MATRIX.mdscripts/analyze-project.sh詳細
KMP AGP 9.0 への移行
Android Gradle Plugin 9.0 では、同じモジュール内で Android アプリケーションプラグインおよびライブラリプラグインと Kotlin Multiplatform プラグインを併用できなくなります。このスキルでは、移行の手順を説明します。
Step 0: プロジェクトを分析する
変更を加える前に、プロジェクトの構成を把握してください。
settings.gradle.kts(または.gradle)を読み、すべてのモジュールを確認します- 各モジュールの
build.gradle.ktsを読み、適用されているプラグインを特定します - プロジェクトで Gradle バージョンカタログ(
gradle/libs.versions.toml)を使用しているか確認します。存在する場合は、現在の AGP/Gradle/Kotlin のバージョンを確認するために読みます。ない場合は、build.gradle.ktsファイル(通常はルートのbuildscript {}またはplugins {}ブロック)でバージョンを直接確認します。このガイドの例はすべて、状況に応じて変更してください — バージョンカタログの例ではalias(libs.plugins.xxx)を使用し、直接指定する場合はid("plugin.id") version "x.y.z"を使用します gradle/wrapper/gradle-wrapper.propertiesを読み、Gradle のバージョンを確認しますgradle.propertiesを確認し、既存の回避策(android.enableLegacyVariantApi)がないか調べますorg.jetbrains.kotlin.androidプラグインの使用状況を確認します — AGP 9.0 には Kotlin が組み込まれているため、このプラグインを削除する必要がありますorg.jetbrains.kotlin.kaptプラグインの使用状況を確認します — 組み込み Kotlin とは互換性がないため、KSP またはcom.android.legacy-kaptに移行する必要があります- AGP 9.0 と互換性がない可能性のあるサードパーティ製プラグインを確認します(下記の「プラグインの互換性」セクションを参照)
Bash を利用できる場合は、このスキルのディレクトリから scripts/analyze-project.sh を実行すると、構造化された概要を取得できます。
各モジュールを分類する
各モジュールについて、種類を特定します。
| 現在のプラグイン | 移行パス |
|---|---|
kotlin.multiplatform + com.android.library | パス A — ライブラリプラグインの切り替え |
kotlin.multiplatform + com.android.application | パス B — Android の分割が必須 |
1 つのモジュールに複数のプラットフォームのエントリポイントがある kotlin.multiplatform | パス C — 全面的な再構成(推奨) |
com.android.application または com.android.library(KMP なし) | 下記の「純粋な Android のヒント」を参照 |
対象範囲を決める
- KMP と Android アプリケーションプラグインを併用しているすべてのモジュールでは、パス B が必須です
- 複数のプラットフォーム(Android、Desktop、Web)のエントリポイントを含むモノリシックな
composeApp(または類似の)モジュールがある場合は、パス C を推奨します。これは、各プラットフォームに専用のアプリモジュールを設ける JetBrains の新しいデフォルトのプロジェクト構成に沿ったものです。 - パス B のみ(最低限必要な移行)にするか、パス C(推奨される全面的な再構成)にするか、ユーザーに確認してください
パス A:ライブラリモジュールの移行
モジュールに kotlin.multiplatform と com.android.library が適用されている場合に使用します。
変更前と変更後のコード全体については、references/MIGRATION-LIBRARY.md を参照してください。
概要:
- プラグインを置き換える:
com.android.library→com.android.kotlin.multiplatform.library org.jetbrains.kotlin.androidプラグインがある場合は削除する(AGP 9.0 には Kotlin サポートが組み込まれています)- DSL を移行する:トップレベルの
android {}ブロックからkotlin { android {} }に設定を移動します。kotlin { android { namespace = "com.example.lib" compileSdk = 35 minSdk = 24 } } - ソースディレクトリの名前を変更する(モジュールが KMP レイアウトではなく従来の Android レイアウトを使用している場合のみ):
src/main→src/androidMainsrc/test→src/androidHostTestsrc/androidTest→src/androidDeviceTest- モジュールがすでに
src/androidMain/を使用している場合、ディレクトリ名の変更は不要です
- 依存関係を移動する:トップレベルの
dependencies {}からsourceSetsに移動します。kotlin { sourceSets { androidMain.dependencies { implementation("androidx.appcompat:appcompat:1.7.0") } } } - モジュールが Android または Compose Multiplatform のリソースを使用している場合は、リソースを明示的に有効にします。
kotlin { android { androidResources { enable = true } } } - モジュールに
.javaソースファイルがある場合は、Java のコンパイルを有効にします。kotlin { android { withJava() } } - モジュールにユニットテストまたはインストルメンテーションテストがある場合は、テストを明示的に有効にします。
kotlin { android { withHostTest { isIncludeAndroidResources = true } withDeviceTest { instrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } } } - Compose ツール依存関係を更新します。
// Old: debugImplementation(libs.androidx.compose.ui.tooling) // New: androidRuntimeClasspath(libs.androidx.compose.ui.tooling) - 該当する場合は、コンシューマー向け ProGuard ルールを明示的に公開します:
kotlin { android { consumerProguardFiles.add(file("consumer-rules.pro")) } } - サブ依存関係のバリアント(プロダクトフレーバー/ビルドタイプ)を解決する:
新しい KMP Android ライブラリプラグインは単一バリアントのアーキテクチャを適用するため、複数のバリアント(
debug/releaseビルドタイプや、free/paidなどのプロダクトフレーバー)を公開する依存関係の解決方法を標準では認識しません。localDependencySelectionを使ってフォールバック動作を設定します:kotlin { android { localDependencySelection { // Android ライブラリ依存関係から使用するビルドタイプを、優先順位順に指定します selectBuildTypeFrom.set(listOf("debug", "release")) // 依存関係に 'tier' ディメンションがある場合は、'free' フレーバーを選択します productFlavorDimension("tier") { selectFrom.set(listOf("free")) } } } }
パス B:Android アプリと共有モジュールの分割
モジュールに kotlin.multiplatform と com.android.application が適用されている場合に使用します。AGP 9.0 との互換性のために必須です。
ガイド全体については、references/MIGRATION-APP-SPLIT.md を参照してください。
概要:
- 独自の
build.gradle.ktsを持つandroidAppモジュールを作成します:plugins { alias(libs.plugins.androidApplication) // Do NOT apply kotlin-android — AGP 9.0 includes Kotlin support alias(libs.plugins.composeMultiplatform) // if using Compose alias(libs.plugins.composeCompiler) // if using Compose } android { namespace = "com.example.app" compileSdk = 35 defaultConfig { applicationId = "com.example.app" minSdk = 24 targetSdk = 35 versionCode = 1 versionName = "1.0" } buildFeatures { compose = true } } dependencies { implementation(projects.shared) // or whatever the shared module is named implementation(libs.androidx.activity.compose) } - Android のエントリーポイントコードを
src/androidMain/からandroidApp/src/main/に移動します:MainActivity.kt(およびその他の Activity/Fragment)AndroidManifest.xml(<application>とランチャー<activity>を含むアプリレベルのマニフェスト)—<activity>のandroid:nameに、新しい場所での完全修飾クラス名が指定されていることを確認します- Android Application クラスがある場合はそれも移動します
- アプリレベルのリソース(ランチャーアイコン、テーマなど)
settings.gradle.ktsに追加します:include(":androidApp")- ルートの
build.gradle.ktsに追加します:apply falseを指定したプラグイン宣言 - 元のモジュールをアプリケーションからライブラリに変換します(パス A の手順を使用)
- 異なる名前空間を設定します:アプリモジュールとライブラリモジュールには、それぞれ異なる名前空間が必要です
- 共有モジュールから削除します:
applicationId、targetSdk、versionCode、versionName - IDE の実行構成を更新します:モジュールを古いモジュールから
androidAppに変更します
パス C:全体の再構成(推奨)
複数のプラットフォームのエントリーポイントを含むモノリシックなモジュール(通常は composeApp)があるプロジェクトで使用します。これは任意ですが、新しい JetBrains のデフォルトに沿った構成です。
ガイド全体については、references/MIGRATION-FULL-RESTRUCTURE.md を参照してください。
目標の構成
project/
├── shared/ ← KMP library (was composeApp), pure shared code
├── androidApp/ ← Android entry point only
├── desktopApp/ ← Desktop entry point only (if desktop target exists)
├── webApp/ ← Wasm/JS entry point only (if web target exists)
├── iosApp/ ← iOS Xcode project (usually already separate)
└── ...
手順
- まず Path B を適用します —
androidAppを抽出します(AGP 9.0 では必須です) desktopAppを抽出します(デスクトップターゲットがある場合):org.jetbrains.composeとapplication {}プラグインを使用してモジュールを作成しますmain()関数をdesktopMainからdesktopApp/src/main/kotlin/に移動しますcompose.desktop { application { ... } }の設定をdesktopApp/build.gradle.ktsに移動しますsharedモジュールへの依存関係を追加します
webAppを抽出します(wasmJs/js ターゲットがある場合):- 適切な Kotlin/JS または Kotlin/Wasm の設定を使用してモジュールを作成します
- Web のエントリーポイントを
wasmJsMain/jsMainからwebApp/src/wasmJsMain/kotlin/に移動します - ブラウザー/配布の設定を
webApp/build.gradle.ktsに移動します sharedモジュールへの依存関係を追加します
- iOS — 通常はすでに独立した
iosAppディレクトリにあります。次を確認します:- フレームワークのエクスポート設定(
binaries.framework)がsharedモジュールに残っていること - Xcode プロジェクトが正しいフレームワークのパスを参照していること
- フレームワークのエクスポート設定(
- モジュール名を
composeAppからsharedに変更します:- ディレクトリ名を変更します
settings.gradle.ktsの include を更新します- すべてのモジュールの依存関係参照を更新します
- shared モジュールを整理します:プラットフォームアプリのモジュールに移動した、すべてのプラットフォームのエントリーポイントコードとアプリ固有の設定を削除します
バリエーション:ネイティブ UI
一部のプラットフォームでネイティブ UI(iOS の SwiftUI など)を使用する場合は、shared を次のように分割します:
sharedLogic— すべてのプラットフォームで使用されるビジネスロジックsharedUI— 共有 UI を使用するプラットフォームだけで使用される Compose Multiplatform UI
バリエーション:サーバー
プロジェクトにサーバーターゲットが含まれている場合:
- ルートに
serverモジュールを追加します - すべてのクライアントモジュールを
app/ディレクトリの下に移動します - サーバーとクライアントで共有するコード(モデル、バリデーション)のために
coreモジュールを追加します
バージョンの更新
移行パスにかかわらず、以下の対応が必要です:
-
Gradle wrapper — 9.1.0 以降に更新します:
# gradle/wrapper/gradle-wrapper.properties distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip -
AGP のバージョン — 9.0.0 以降に更新し、KMP ライブラリプラグインを追加します。
バージョンカタログを使用する場合(
gradle/libs.versions.toml):[versions] agp = "9.0.1" [plugins] android-kotlin-multiplatform-library = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" }バージョンカタログを使用しない場合 —
com.android.*プラグインのバージョンを更新し、ルートのbuild.gradle.ktsに追加します:plugins { id("com.android.application") version "9.0.1" apply false id("com.android.kotlin.multiplatform.library") version "9.0.1" apply false } -
JDK — JDK 17 以降が使用されていることを確認します(AGP 9.0 で必須です)
-
SDK Build Tools — 36.0.0 に更新します:
Install via SDK Manager or configure in android { buildToolsVersion = "36.0.0" } -
gradle.properties を確認します — エラーの原因となるプロパティを削除し、変更されたデフォルト値を確認します(「Gradle Properties Default Changes」セクションを参照してください)
Kotlin の組み込みサポートへの移行
AGP 9.0 では、すべての com.android.application および com.android.library モジュールで Kotlin の組み込みサポートがデフォルトで有効になります。org.jetbrains.kotlin.android プラグインは不要になり、適用すると競合します。
重要: 組み込みの Kotlin サポートは KMP サポートを置き換えるものではありません。KMP ライブラリモジュールでは、引き続き
org.jetbrains.kotlin.multiplatform と com.android.kotlin.multiplatform.library が必要です。
ステップ 1:kotlin-android プラグインを削除する
すべてのモジュールレベルおよびルートレベルのビルドファイルから削除します:
// Remove from module build.gradle.kts
plugins {
// REMOVE: alias(libs.plugins.kotlin.android)
// REMOVE: id("org.jetbrains.kotlin.android")
}
// Remove from root build.gradle.kts
plugins {
// REMOVE: alias(libs.plugins.kotlin.android) apply false
}
バージョンカタログ(gradle/libs.versions.toml)から削除します:
[plugins]
# REMOVE: kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
ステップ 2:kapt を KSP または legacy-kapt に移行する
org.jetbrains.kotlin.kapt プラグインは、組み込みの Kotlin サポートと互換性がありません。
推奨:KSP に移行する — 各アノテーションプロセッサーの KSP 移行ガイドを参照してください。
代替策:com.android.legacy-kapt を使用する(AGP と同じバージョン):
# gradle/libs.versions.toml
[plugins]
legacy-kapt = { id = "com.android.legacy-kapt", version.ref = "agp" }
// Module build.gradle.kts — replace kotlin-kapt with legacy-kapt
plugins {
// REMOVE: alias(libs.plugins.kotlin.kapt)
alias(libs.plugins.legacy.kapt)
}
ステップ 3:kotlinOptions を compilerOptions に移行する
純粋な Android モジュール(KMP ではない)の場合は、android.kotlinOptions {} をトップレベルの
kotlin.compilerOptions {} に移行します:
// Old
android {
kotlinOptions {
jvmTarget = "11"
languageVersion = "2.0"
freeCompilerArgs += listOf("-Xopt-in=kotlin.RequiresOptIn")
}
}
// New
kotlin {
compilerOptions {
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11)
languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
optIn.add("kotlin.RequiresOptIn")
}
}
注: 組み込みの Kotlin サポートでは、jvmTarget のデフォルト値は android.compileOptions.targetCompatibility です。そのため、すでに compileOptions を設定している場合は、省略できることがあります。
ステップ 4:kotlin.sourceSets を android.sourceSets に移行する
組み込みの Kotlin サポートでは、kotlin セットを含む android.sourceSets {} のみがサポートされます:
// NOT SUPPORTED with built-in Kotlin:
kotlin.sourceSets.named("main") {
kotlin.srcDir("additionalSourceDirectory/kotlin")
}
// Correct:
android.sourceSets.named("main") {
kotlin.directories += "additionalSourceDirectory/kotlin"
}
生成されたソースには、Variant API を使用します:
androidComponents.onVariants { variant ->
variant.sources.kotlin!!.addStaticSourceDirectory("additionalSourceDirectory/kotlin")
}
モジュールごとの移行戦略
大規模なプロジェクトでは、モジュールごとに移行してください。
- 全体で無効にします。
gradle.propertiesにandroid.builtInKotlin=falseを設定します。 - オプトインプラグインを適用して、移行済みのモジュールごとに有効にします。
plugins { id("com.android.built-in-kotlin") version "AGP_VERSION" } - そのモジュールについて手順 1〜4 に従います。
- すべてのモジュールの移行が完了したら、
android.builtInKotlin=falseとすべてのcom.android.built-in-kotlinプラグインを削除します。
オプション:Kotlin を使用しないモジュールで無効にする
Kotlin ソースが含まれないモジュールでは、ビルド時間を短縮するために組み込み Kotlin を無効にします。
android {
enableKotlin = false
}
オプトアウト(一時的な措置)
プラグインの互換性問題で移行が妨げられる場合は、一時的にオプトアウトします。
# gradle.properties
android.builtInKotlin=false
android.newDsl=false # also required if using new DSL opt-out
警告: オプトアウトするかどうかをユーザーに確認し、オプトアウトする場合は一時的な措置であることを伝えてください。
プラグインの互換性
既知の互換バージョン、オプトアウトフラグによる回避策、動作しないプラグインを含む互換性一覧については、references/PLUGIN-COMPATIBILITY.md を参照してください。
移行の前に、プロジェクト内のすべてのプラグインを一覧にし、それぞれをこの表で確認してください。回避策のない動作しないプラグインがある場合は、ユーザーに伝えてください。プラグインにオプトアウトフラグが必要な場合は、それらをgradle.propertiesに追加し、一時的な回避策として記載してください。
Gradle プロパティのデフォルト値の変更
AGP 9.0 では、多くの Gradle プロパティのデフォルト値が変更されます。gradle.properties を確認し、明示的に設定されていて、現在のデフォルト値と競合する可能性のある値がないか調べてください。
主な変更点:
| プロパティ | 以前のデフォルト値 | 新しいデフォルト値 | 対応 |
|---|---|---|---|
android.uniquePackageNames | false | true | 各ライブラリに一意の名前空間があることを確認する |
android.enableAppCompileTimeRClass | false | true | R フィールドに対する switch を if/else にリファクタリングする |
android.defaults.buildfeatures.resvalues | true | false | 必要な箇所で resValues = true を有効にする |
android.defaults.buildfeatures.shaders | true | false | 必要な箇所でシェーダーを有効にする |
android.r8.optimizedResourceShrinking | false | true | R8 の keep ルールを確認する |
android.r8.strictFullModeForKeepRules | false | true | keep ルールを明示的にする |
android.proguard.failOnMissingFiles | false | true | 無効な ProGuard ファイル参照を削除する |
android.r8.proguardAndroidTxt.disallowed | false | true | proguard-android-optimize.txt のみを使用する |
android.r8.globalOptionsInConsumerRules.disallowed | false | true | ライブラリのコンシューマールールからグローバルオプションを削除する |
android.sourceset.disallowProvider | false | true | androidComponents で Sources API を使用する |
android.sdk.defaultTargetSdkToCompileSdkIfUnset | false | true | targetSdk を明示的に指定する |
android.onlyEnableUnitTestForTheTestedBuildType | false | true | デフォルト以外のビルドタイプをテストする場合のみ |
エラーの原因となるようになったプロパティを確認して削除してください。
android.r8.integratedResourceShrinking— 削除済みで、常に有効ですandroid.enableNewResourceShrinker.preciseShrinking— 削除済みで、常に有効です
純粋な Android のヒント
KMP 以外の Android モジュールを AGP 9.0 にアップグレードする場合は、上記の「組み込み Kotlin の移行」の手順に従ってから、「Gradle プロパティのデフォルト値の変更」の表を確認してください。その他の変更点は次のとおりです。
- 新しい DSL インターフェースを確認する —
BaseExtensionは削除されています。CommonExtensionまたは特定の拡張型を使用してください。 - Java のデフォルト値が Java 8 から Java 11 に変更されました —
compileOptionsに反映されていることを確認してください。
検証
移行後、チェックリストに沿って検証してください。主な確認項目:
./gradlew buildがエラーなしで成功する- すべてのプラットフォームターゲットのビルドが成功する(Android、
xcodebuildを使った iOS、Desktop、JS/Wasm) ./gradlew :shared:allTestsと Android のユニットテストが成功する- KMP モジュールに
com.android.libraryまたはcom.android.applicationがない - AGP 9.0 モジュールに
org.jetbrains.kotlin.androidがない - ソースセットに正しい名前(
androidMain、androidHostTest、androidDeviceTest)が使われている - バリアント API または DSL に関する非推奨警告がない
よくある問題
詳細は参考資料を参照してください。主な注意点:
KMP ライブラリプラグインの問題
- ライブラリモジュールでは BuildConfig を使用できません — DI/
AppConfigurationインターフェースを使うか、コンパイル時定数には BuildKonfig または gradle-buildconfig-plugin を使用してください - ビルドバリアントはありません — 単一バリアントのアーキテクチャです。コンパイル時定数には BuildKonfig/gradle-buildconfig-plugin のフレーバーを使用できますが、バリアント固有の依存関係/リソース/署名はアプリモジュールに移す必要があります
- 新しいプラグインでは NDK/JNI はサポートされません — 別の
com.android.libraryモジュールに切り出してください androidResources { enable = true }がないと Compose リソースでクラッシュします- コンシューマー向け ProGuard ルールは、新しい DSL で
consumerProguardFiles.add(file(...))に移行しないと、通知なく無視されます - KSP には AGP 9.0 との互換性のため、バージョン 2.3.1 以降が必要です
AGP 9.0 の一般的な問題
- BaseExtension は削除されました — 古い DSL 型を使う規約プラグインは、
CommonExtensionを使うように書き換える必要があります - バリアント API は削除されました —
applicationVariants、libraryVariants、variantFilterはandroidComponentsに置き換えられました - 規約プラグインにはリファクタリングが必要です — 古い
android {}拡張ヘルパーは使用できません
参考ファイル
- DSL リファレンス — 旧 DSL から新 DSL への対応を並べて説明
- バージョン対応表 — AGP/Gradle/KGP/Compose/IDE の互換性
- プラグイン互換性 — サードパーティ製プラグインの状況と回避策