先日 Kotlin Multiplatform 製モバイルアプリ向けの ライブラリを作って公開した ので、その時にちょっとつまづいた部分について。
org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.31
com.android.tools.build:gradle:3.3.2
Kotlin Multiplatform ProjectはGradleを用いて(Kotlin Gradle Pluginを用いて)ビルドされ、それらの依存関係はMavenリポジトリから取得されます。
すなわちKotlin MPP向けにライブラリを公開する際はMavenリポジトリへ公開する必要があり、またGradleでの依存性解決が前提とされています。
settings.gradle
に以下の1行を記述します:
enableFeaturePreview('GRADLE_METADATA')
Kotlin MPP向けのライブラリは、Gradle Module Metadataを用いて依存関係を解決します。具体的には こういったファイル を出力します。
これがあると何が嬉しいかというと、依存関係としてたったこの1行だけでiOSやAndroid向けのバイナリをよしなに読み込ませることができます:
kotlin { ... sourceSets { commonMain { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.31" implementation "com.example:your-published-library:1.0.0" // ^ これだけ } } iosMain { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.31" // なにか参照しなくても、commonで記述した内容でiOS向けバイナリが取ってこれる } } androidMain { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.31" // こっちも同様 } } } }
平易な表現にしようとして厳密さを失っていますが、これはiOSやAndroidなどのプラットフォーム特有の問題を解決するためのものです。
iOS向けアプリ開発では、開発時にはSimulatorを用いる場合が多々あります。
流通しているiOSデバイス実機はARM64アーキテクチャなのに対し、このSimulatorはx64アーキテクチャで動きます。
そのため、ビルドするアーキテクチャとして2通り分(必要ならそれ以上) の記述が必要です:
kotlin { def ios64 = iosArm64('iosArm64') def iosSim = iosX64('iosX64') sourceSets { ... iosMain { ... } ios64.compilations.main.defaultSourceSet { dependsOn iosMain } iosSim.compilations.main.defaultSourceSet { dependsOn iosMain } } }
現行のGradle Module Metadataの都合上、各variant向けの出力を設定しておく必要があります:
kotlin { android { publishLibraryVariants('debug', 'release') } ... }
Kotlin Gradle Pluginは親切なので、maven-publish
プラグインが適切に有効化されていれば MavenPublication
を自動的に設定してくれます。
よって必要な設定は以下です:
plugins { id 'maven-publish' // apply plugin: 'maven-publish' } ... group = 'com.example.your.artifact.group' version = '0.0.1-SNAPSHOT-YOUR-VERSION'
ローカルリポジトリであれば以下のコマンドでOKです:
./gradlew publishToMavenLocal
実行すると、たとえばiOS, Android向けにここまでの内容を参考に設定していた場合は 以下の成果物が得られます:
com.example:your-published-library:1.0.0
com.example:your-published-library-metadata:1.0.0
com.example:your-published-library-android:1.0.0
com.example:your-published-library-android-debug:1.0.0
com.example:your-published-library-iosarm64:1.0.0
com.example:your-published-library-iosx64:1.0.0
先頭のサフィックスが無いパッケージは .pom
と .module
ファイルしか持ちません。ここを起点に各プラットフォーム向けの依存性を解決する役割のみを持ちます。
-metadata
はcommon
で記述された公開I/Fの定義を持ちます。
残るモジュールは、各プラットフォームやABI向けのバイナリです。
公開したライブラリの参照方法は Gradle Module Metadataを有効にする
のセクションの通りで、サフィックスの無いモジュールを依存関係に加えるのみです。
ただし、Gradle Module Metadataを有効にしていないアプリの場合、各モジュールの参照が必要になる模様です。
こうして開発したライブラリは Kotlin MPP, Kotlin/Native, Pure Androidプロジェクト(Kotlinが有効なもの)で共通して利用することができました。