怠慢プログラマーの備忘録

怠慢でナマケモノなプログラマーの備忘録です。

【Kotlin Multiplatform Mobile】build.gradle経由でXCFrameworkを作成する(備忘録)

前回の記事でiOS向けのframeworkを生成してiOS AppにEmbedするところまでいきました。

yutaabe200.hatenablog.com

しかしarm64とx64のアーキテクチャそれぞれのframeworkを生成するので現実的ではありません。 そこでそれぞれのアーキテクチャのframeworkを内包したxcframeworkをbuild.gradle経由で作成する方法が下記になります。

なおXCFrameworksのサポートはKotlin 1.5.30でサポートされています。

kotlinlang.org

build.gradle.kts

import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget

plugins {
    kotlin("multiplatform")
    id("com.android.library")
}

kotlin {
    android()

    val xcf = XCFramework("SharedModule")
    val iosTargets = listOf(
        iosArm64(),
        iosX64("ios")
    )
    iosTargets.forEach {
        it.binaries {
            framework {
                baseName = "SharedModule"
                xcf.add(this)
            }
        }
    }

    sourceSets {
        val commonMain by getting
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test-common"))
                implementation(kotlin("test-annotations-common"))
            }
        }
        val iosMain by getting
        val iosArm64Main by getting {
            dependsOn(iosMain)
        }
        val iosTest by getting
    }
}

android {
    compileSdkVersion(31)
    sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
    defaultConfig {
        minSdkVersion(24)
        targetSdkVersion(31)
    }
}

tasks.getByName("preBuild").dependsOn(tasks.getByName("compileKotlinIos"))

task("createXCFramework") {
    dependsOn(tasks.getByName("assembleSharedModuleXCFramework"))
    doLast {
        val buildDir = tasks.getByName("assembleSharedModuleXCFramework").project.buildDir.absolutePath
        val outputFile = File("$buildDir/XCFrameworks/debug/SharedModule.xcframework")
        val targetFile = File("$buildDir/build/xcframeworks/SharedModule.xcframework")
        outputFile.copyRecursively(target = targetFile)
    }
}

XCFrameworkを宣言した時点でassembleXCFrameworkassembleDebugXCFrameworkassembleReleaseXCFrameworkのタスクが登録されます。 タスクの命名assemble + val xcf = XCFramework("SharedModule")で指定した名前 + XCFrameworkになります。