概要
プラグインKotlin Multiplatform Mobile
を利用してプロジェクトを作った際、実機ビルドができないとなった時の対応。
エラー内容としては下記。
${Path}/iosApp.xcodeproj Building for iOS Simulator, but the linked and embedded framework 'shared.framework' was built for iOS.
原因
AndroidとiOS側で共有されている'shared.framework'がiOS Simulator用にビルドされていて、実機では使えないという話。
FWは以下のような処理を経て生成される。
具体的にはConfigurationを基に各ターゲット向けに生成されたFWをコピーし、xcode-frameworks
という名前にしている。
val packForXcode by tasks.creating(Sync::class) {
group = "build"
val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
val sdkName = System.getenv("SDK_NAME") ?: "iphonesimulator"
val targetName = "ios" + if (sdkName.startsWith("iphoneos")) "Arm64" else "X64"
val framework = kotlin.targets.getByName<KotlinNativeTarget>(targetName).binaries.getFramework(mode)
inputs.property("mode", mode)
dependsOn(framework.linkTask)
val targetDir = File(buildDir, "xcode-frameworks")
from({ framework.outputDirectory })
into(targetDir)
}
Gradleタスクを呼び出しは、iOSのBuild Phaseで行われている。
問題があるのはここ。
cd "$SRCROOT/.."
./gradlew :shared:packForXCode -PXCODE_CONFIGURATION=${CONFIGURATION}
Xcode10で最適化のため新しいbuild systemに移行された。
その際build phaseでの設定方法やその処理内容に変更が入り、ファイルに変更がなければbuild phaseのスクリプトも実行されなくなった。
詳しい変更内容は下記で確認。
そのため、shared:packForXCode
においても一度Simlulator向けにビルドすると、FWは存在しているので実行されなくなる。
xcode-frameworks
を削除すれば、実機向けにもビルドできるが逆も然りで、この場合Simlulator向けにビルドできなくなる
${Path}/iosApp.xcodeproj Building for iOS Simulator, but the linked and embedded framework 'shared.framework' was built for iOS.
対応
Build Phaseではなく、SchemaのPre-ActionsでpackForXCode
を実行する。
注意が必要なのは Provided build settings from
も変更しておくこと。