[英]KMM with iOS Arm64 Binary Framework (.xcframework) and cinterop
我正在按照此處的指南嘗試在新的 KMM 項目中使用不帶 CocoaPods 的 iOS 框架:
https://kotlinlang.org/docs/kmm-add-dependencies.html#without-cocoapods
我有一個現有的 working.xcframework,我將其添加到shared/src
下的項目中。 我在src/nativeInterop/cinterop/
中添加了一個MyKit.def
文件,並在同一共享目錄中更新了build.gradle.kts
文件:
MyKit.def 看起來像
language = Objective-C
modules = MyKit
package = MyKit
build.gradle.kts
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
plugins {
kotlin("multiplatform")
id("com.android.library")
}
kotlin {
android()
val iosTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
::iosArm64
else
::iosX64
iosTarget("ios") {
binaries {
framework {
baseName = "shared"
}
}
}
sourceSets {
val commonMain by getting
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val androidMain by getting
val androidTest by getting {
dependencies {
implementation(kotlin("test-junit"))
implementation("junit:junit:4.13.2")
}
}
val iosMain by getting
val iosTest by getting
}
iosArm64() {
compilations.getByName("main") {
val MyKit by cinterops.creating {
// Path to .def file
defFile("src/nativeInterop/cinterop/MyKit.def")
compilerOpts("-framework", "MyKit", "-F/src/MyKit.framework")
}
}
binaries.all {
// Linker options required to link to the library -- the framework binary is located under src/MyKit.framework/ios-arm64/MyKit.framework/
linkerOpts("-framework", "MyKit", "-F/src/MyKit.framework/ios-arm64/MyKit.framework/")
}
}
}
android {
compileSdkVersion(31)
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
defaultConfig {
minSdkVersion(26)
targetSdkVersion(31)
}
}
將import MyKit.*
添加到我的 MainActivity 后,我得到了unknown reference
錯誤。
是否支持 iOS 二進制框架? 他們有一個.
文件名中的分隔符,所以這可能是個問題。 我的-F
路徑有問題嗎?? 我不清楚路徑是否應該一直到帶有Headers
和二進制文件本身的目錄,或者只是到框架根目錄。 TIA
假設您具有默認的 KMM 項目結構以及框架和 def 文件,如下所示:
- androidApp
- iosApp
- MyFramework.framework
- shared
- src
- nativeInterop
- cinterop
- MyFramework.def
這是您需要在build.gradle
文件中添加的內容:
val myFrameworkDefFilePath = "src/nativeInterop/cinterop/MyFramework.def"
val myFrameworkCompilerLinkerOpts = listOf("-framework", "MyFramework", "-F${projectDir}/../iosApp/")
iosArm64 {
compilations.getByName("main") {
val MyFramework by cinterops.creating {
// Path to .def file
defFile(myFrameworkDefFilePath)
compilerOpts(myFrameworkCompilerLinkerOpts)
}
}
binaries.all {
// Tell the linker where the framework is located.
linkerOpts(myFrameworkCompilerLinkerOpts)
}
}
不幸的是,如此處所述,相對路徑無法像編譯器 arguments 一樣正常工作,因此您可以使用projectDir
值,並從該點到您的框架所在的位置。
注意:您需要指向框架所在的父文件夾(在示例中,我指向iosApp/
,它是MyFramework.framework
的父文件夾)。
另一個注意事項:如果您有.framework
,afaik,您需要為iosX64
、 iosArm64
、 iosSimulatorArm64
等復制此代碼,以使導入在iosMain
中正常工作。
如果您有.xcframework
路徑需要指向.xcframework
內的正確變體,例如ios-arm64_armv7
、 ios-arm64_i386_x86_64-simulator
等等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.