mcpField
K
kotlin-tooling-agp9-migration

kotlin-tooling-agp9-migration

github.com/kotlin開発1.1k2.2k 回インストール7 週間前に更新
リポジトリ

kotlin-tooling-agp9-migration について

Kotlin Multiplatform プロジェクトを Android Gradle Plugin 9.0 に対応させる移行スキルです。モジュールを分析し、ライブラリ移行、アプリ分割、マルチプラットフォーム構成の再編を案内します。

主な機能

  1. 01Gradle モジュールと設定の分析
  2. 02KMP Android ライブラリ移行の案内
  3. 03Android アプリと共有モジュールの分割
  4. 04マルチプラットフォームのエントリーポイント再編
  5. 05AGP 9.0 プラグイン互換性の確認

活用シーン

  1. 01KMP プロジェクトの AGP 9.0 対応
  2. 02共有コードからの Android アプリ分離
  3. 03Android ライブラリモジュールの移行
  4. 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.md
references/
DSL-REFERENCE.md
KNOWN-ISSUES.md
MIGRATION-APP-SPLIT.md
MIGRATION-FULL-RESTRUCTURE.md
MIGRATION-LIBRARY.md
PLUGIN-COMPATIBILITY.md
VERSION-MATRIX.md
scripts/
analyze-project.sh

詳細

KMP AGP 9.0 への移行

Android Gradle Plugin 9.0 では、同じモジュール内で Android アプリケーションプラグインおよびライブラリプラグインと Kotlin Multiplatform プラグインを併用できなくなります。このスキルでは、移行の手順を説明します。

Step 0: プロジェクトを分析する

変更を加える前に、プロジェクトの構成を把握してください。

  1. settings.gradle.kts(または .gradle)を読み、すべてのモジュールを確認します
  2. 各モジュールの build.gradle.kts を読み、適用されているプラグインを特定します
  3. プロジェクトで Gradle バージョンカタログ(gradle/libs.versions.toml)を使用しているか確認します。存在する場合は、現在の AGP/Gradle/Kotlin のバージョンを確認するために読みます。ない場合は、build.gradle.kts ファイル(通常はルートの buildscript {} または plugins {} ブロック)でバージョンを直接確認します。このガイドの例はすべて、状況に応じて変更してください — バージョンカタログの例では alias(libs.plugins.xxx) を使用し、直接指定する場合は id("plugin.id") version "x.y.z" を使用します
  4. gradle/wrapper/gradle-wrapper.properties を読み、Gradle のバージョンを確認します
  5. gradle.properties を確認し、既存の回避策(android.enableLegacyVariantApi)がないか調べます
  6. org.jetbrains.kotlin.android プラグインの使用状況を確認します — AGP 9.0 には Kotlin が組み込まれているため、このプラグインを削除する必要があります
  7. org.jetbrains.kotlin.kapt プラグインの使用状況を確認します — 組み込み Kotlin とは互換性がないため、KSP または com.android.legacy-kapt に移行する必要があります
  8. 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 を参照してください。

概要:

  1. プラグインを置き換える:com.android.library → com.android.kotlin.multiplatform.library
  2. org.jetbrains.kotlin.android プラグインがある場合は削除する(AGP 9.0 には Kotlin サポートが組み込まれています)
  3. DSL を移行する:トップレベルの android {} ブロックから kotlin { android {} } に設定を移動します。
    kotlin {
        android {
            namespace = "com.example.lib"
            compileSdk = 35
            minSdk = 24
        }
    }
    
  4. ソースディレクトリの名前を変更する(モジュールが KMP レイアウトではなく従来の Android レイアウトを使用している場合のみ):
    • src/main → src/androidMain
    • src/test → src/androidHostTest
    • src/androidTest → src/androidDeviceTest
    • モジュールがすでに src/androidMain/ を使用している場合、ディレクトリ名の変更は不要です
  5. 依存関係を移動する:トップレベルの dependencies {} から sourceSets に移動します。
    kotlin {
        sourceSets {
            androidMain.dependencies {
                implementation("androidx.appcompat:appcompat:1.7.0")
            }
        }
    }
    
  6. モジュールが Android または Compose Multiplatform のリソースを使用している場合は、リソースを明示的に有効にします。
    kotlin {
        android {
            androidResources { enable = true }
        }
    }
    
  7. モジュールに .java ソースファイルがある場合は、Java のコンパイルを有効にします。
    kotlin {
        android {
            withJava()
        }
    }
    
  8. モジュールにユニットテストまたはインストルメンテーションテストがある場合は、テストを明示的に有効にします。
    kotlin {
        android {
            withHostTest { isIncludeAndroidResources = true }
            withDeviceTest {
                instrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
            }
        }
    }
    
  9. Compose ツール依存関係を更新します。
    // Old: 
    debugImplementation(libs.androidx.compose.ui.tooling)
    // New:
    androidRuntimeClasspath(libs.androidx.compose.ui.tooling)
    
  10. 該当する場合は、コンシューマー向け ProGuard ルールを明示的に公開します:
    kotlin {
        android {
            consumerProguardFiles.add(file("consumer-rules.pro"))
        }
    }
    
  11. サブ依存関係のバリアント(プロダクトフレーバー/ビルドタイプ)を解決する: 新しい 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 を参照してください。

概要:

  1. 独自の 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)
    }
    
  2. Android のエントリーポイントコードを src/androidMain/ から androidApp/src/main/ に移動します:
    • MainActivity.kt(およびその他の Activity/Fragment)
    • AndroidManifest.xml(<application> とランチャー <activity> を含むアプリレベルのマニフェスト)— <activity> の android:name に、新しい場所での完全修飾クラス名が指定されていることを確認します
    • Android Application クラスがある場合はそれも移動します
    • アプリレベルのリソース(ランチャーアイコン、テーマなど)
  3. settings.gradle.kts に追加します:include(":androidApp")
  4. ルートの build.gradle.kts に追加します:apply false を指定したプラグイン宣言
  5. 元のモジュールをアプリケーションからライブラリに変換します(パス A の手順を使用)
  6. 異なる名前空間を設定します:アプリモジュールとライブラリモジュールには、それぞれ異なる名前空間が必要です
  7. 共有モジュールから削除します:applicationId、targetSdk、versionCode、versionName
  8. 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)
└── ...
手順
  1. まず Path B を適用します — androidApp を抽出します(AGP 9.0 では必須です)
  2. desktopApp を抽出します(デスクトップターゲットがある場合):
    • org.jetbrains.compose と application {} プラグインを使用してモジュールを作成します
    • main() 関数を desktopMain から desktopApp/src/main/kotlin/ に移動します
    • compose.desktop { application { ... } } の設定を desktopApp/build.gradle.kts に移動します
    • shared モジュールへの依存関係を追加します
  3. webApp を抽出します(wasmJs/js ターゲットがある場合):
    • 適切な Kotlin/JS または Kotlin/Wasm の設定を使用してモジュールを作成します
    • Web のエントリーポイントを wasmJsMain/jsMain から webApp/src/wasmJsMain/kotlin/ に移動します
    • ブラウザー/配布の設定を webApp/build.gradle.kts に移動します
    • shared モジュールへの依存関係を追加します
  4. iOS — 通常はすでに独立した iosApp ディレクトリにあります。次を確認します:
    • フレームワークのエクスポート設定(binaries.framework)が shared モジュールに残っていること
    • Xcode プロジェクトが正しいフレームワークのパスを参照していること
  5. モジュール名を composeApp から shared に変更します:
    • ディレクトリ名を変更します
    • settings.gradle.kts の include を更新します
    • すべてのモジュールの依存関係参照を更新します
  6. shared モジュールを整理します:プラットフォームアプリのモジュールに移動した、すべてのプラットフォームのエントリーポイントコードとアプリ固有の設定を削除します
バリエーション:ネイティブ UI

一部のプラットフォームでネイティブ UI(iOS の SwiftUI など)を使用する場合は、shared を次のように分割します:

  • sharedLogic — すべてのプラットフォームで使用されるビジネスロジック
  • sharedUI — 共有 UI を使用するプラットフォームだけで使用される Compose Multiplatform UI
バリエーション:サーバー

プロジェクトにサーバーターゲットが含まれている場合:

  • ルートに server モジュールを追加します
  • すべてのクライアントモジュールを app/ ディレクトリの下に移動します
  • サーバーとクライアントで共有するコード(モデル、バリデーション)のために core モジュールを追加します

バージョンの更新

移行パスにかかわらず、以下の対応が必要です:

  1. Gradle wrapper — 9.1.0 以降に更新します:

    # gradle/wrapper/gradle-wrapper.properties
    distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
    
  2. 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
    }
    
  3. JDK — JDK 17 以降が使用されていることを確認します(AGP 9.0 で必須です)

  4. SDK Build Tools — 36.0.0 に更新します:

    Install via SDK Manager or configure in android { buildToolsVersion = "36.0.0" }
    
  5. 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")
}
モジュールごとの移行戦略

大規模なプロジェクトでは、モジュールごとに移行してください。

  1. 全体で無効にします。gradle.properties に android.builtInKotlin=false を設定します。
  2. オプトインプラグインを適用して、移行済みのモジュールごとに有効にします。
    plugins {
        id("com.android.built-in-kotlin") version "AGP_VERSION"
    }
    
  3. そのモジュールについて手順 1〜4 に従います。
  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.uniquePackageNamesfalsetrue各ライブラリに一意の名前空間があることを確認する
android.enableAppCompileTimeRClassfalsetrueR フィールドに対する switch を if/else にリファクタリングする
android.defaults.buildfeatures.resvaluestruefalse必要な箇所で resValues = true を有効にする
android.defaults.buildfeatures.shaderstruefalse必要な箇所でシェーダーを有効にする
android.r8.optimizedResourceShrinkingfalsetrueR8 の keep ルールを確認する
android.r8.strictFullModeForKeepRulesfalsetruekeep ルールを明示的にする
android.proguard.failOnMissingFilesfalsetrue無効な ProGuard ファイル参照を削除する
android.r8.proguardAndroidTxt.disallowedfalsetrueproguard-android-optimize.txt のみを使用する
android.r8.globalOptionsInConsumerRules.disallowedfalsetrueライブラリのコンシューマールールからグローバルオプションを削除する
android.sourceset.disallowProviderfalsetrueandroidComponents で Sources API を使用する
android.sdk.defaultTargetSdkToCompileSdkIfUnsetfalsetruetargetSdk を明示的に指定する
android.onlyEnableUnitTestForTheTestedBuildTypefalsetrueデフォルト以外のビルドタイプをテストする場合のみ

エラーの原因となるようになったプロパティを確認して削除してください。

  • android.r8.integratedResourceShrinking — 削除済みで、常に有効です
  • android.enableNewResourceShrinker.preciseShrinking — 削除済みで、常に有効です

純粋な Android のヒント

KMP 以外の Android モジュールを AGP 9.0 にアップグレードする場合は、上記の「組み込み Kotlin の移行」の手順に従ってから、「Gradle プロパティのデフォルト値の変更」の表を確認してください。その他の変更点は次のとおりです。

  • 新しい DSL インターフェースを確認する — BaseExtension は削除されています。CommonExtension または特定の拡張型を使用してください。
  • Java のデフォルト値が Java 8 から Java 11 に変更されました — compileOptions に反映されていることを確認してください。

検証

移行後、チェックリストに沿って検証してください。主な確認項目:

  1. ./gradlew build がエラーなしで成功する
  2. すべてのプラットフォームターゲットのビルドが成功する(Android、xcodebuild を使った iOS、Desktop、JS/Wasm)
  3. ./gradlew :shared:allTests と Android のユニットテストが成功する
  4. KMP モジュールに com.android.library または com.android.application がない
  5. AGP 9.0 モジュールに org.jetbrains.kotlin.android がない
  6. ソースセットに正しい名前(androidMain、androidHostTest、androidDeviceTest)が使われている
  7. バリアント 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 {} 拡張ヘルパーは使用できません

参考ファイル

コメント