首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iOS Arm64二进制框架(.xcframework)和cinterop的KMM

iOS Arm64二进制框架(.xcframework)和cinterop的KMM
EN

Stack Overflow用户
提问于 2021-09-14 12:10:48
回答 1查看 892关注 0票数 4

我在这里遵循指南,尝试在一个新的KMM项目中使用没有iOS的CocoaPods框架:

https://kotlinlang.org/docs/kmm-add-dependencies.html#without-cocoapods

我有一个现有的、正在工作的.xcframework,它是我在shared/src下添加到项目中的。我在src/nativeInterop/cinterop/中添加了一个src/nativeInterop/cinterop/文件,并在相同的共享dir中更新了build.gradle.kts文件:

MyKit.def看起来就像

代码语言:javascript
复制
language = Objective-C
modules = MyKit
package = MyKit

build.gradle.kts

代码语言:javascript
复制
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和二进制本身的dir,还是只指向Framework。提亚

EN

回答 1

Stack Overflow用户

发布于 2022-10-25 16:42:57

假设您拥有默认的KMM项目结构以及框架和def文件,如下所示:

代码语言:javascript
复制
- androidApp
- iosApp
  - MyFramework.framework
- shared
  - src
    - nativeInterop
      - cinterop
        - MyFramework.def

这就是您需要在build.gradle文件中添加的内容:

代码语言:javascript
复制
    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)
        }
    }

不幸的是,正如所述的这里一样,相对路径不能正确地作为编译器参数工作,所以您可以做的是使用projectDir值,从那个点到您的框架所在的位置。

注意:您需要指向框架所在的父文件夹(在示例中,我指向iosApp/,它是MyFramework.framework的父文件夹)。

另一个注意事项:如果您有一个.framework,afaik,您需要为iosX64iosArm64iosSimulatorArm64等复制这段代码,以使导入在iosMain中正确工作。

如果您有一个.xcframework,那么路径需要指向.xcframework中的正确变体,例如ios-arm64_armv7ios-arm64_i386_x86_64-simulator等等。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69177531

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档