簡體   English   中英

帶有 iOS Arm64 二進制框架 (.xcframework) 和 cinterop 的 KMM

[英]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,您需要為iosX64iosArm64iosSimulatorArm64等復制此代碼,以使導入在iosMain中正常工作。
如果您有.xcframework路徑需要指向.xcframework內的正確變體,例如ios-arm64_armv7ios-arm64_i386_x86_64-simulator等等。

@伊曼紐爾

你好。 我有一個 iosArm64 框架,它只支持 iosArm64 arch。 該框架已互操作,我可以導入共享 kmm 庫,但是當我運行 ios 應用程序時。 它向我顯示以下錯誤消息。

體系結構 arm64 的未定義符號:“ OBJC_CLASS $_Camera”,引用自:共享(result.o)ld 中的 objc-class-ref:找不到體系結構 arm64 的符號

我已經在此處上傳了項目。 請你花點時間看看。

謝謝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM