Not able to add iOS custom framework to a KMM (Kotlin Multi Platform) module (cinteropXXXIosArm64 FAILED module not found)

不想你离开。 提交于 2020-12-30 03:36:10

问题


I'm developing an iOS app, which makes use of a Kotlin Native share module. This Kotlin Native shared module, makes use of a self-developed iOS framework.

This had worked very well in the past, but now I'm trying to upgrade my project for the last release of Kotlin Native (1.4.10 at this moment), Android Studio, and so on, and I'm not able to import my custom iOS framework dependency.

The folder structure of the iOS framework is the following:

Following the guide at https://kotlinlang.org/docs/mobile/add-dependencies.html, I added a .def file to my shared code project with the following content:

language = Objective-C
modules = SlicerUtils
package = com.xxxx.customframework

The build.gradle.kts file is the standard file generated with the template for KMM projects available in the last release of Android Studio (4.2.idontremember). Then I added the iosX64 and iosArm64 sections as explained in the link above:

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

plugins {
    id("com.android.library")
    kotlin("multiplatform")
    kotlin("plugin.serialization") version "1.4.10"



    id("kotlin-android-extensions")

}
group = "con.xxxx.customframework"
version = "1.0"

repositories {
    gradlePluginPortal()
    google()
    jcenter()
    mavenCentral()
}
kotlin {
    android()
    ios {
        binaries {
            framework {
                baseName = "shared"
            }
        }
    }





    //////////////////////////

    val iosFrameworkBaseDir = "${projectDir}/../../ios-frameworks"
    val slicerUtilsDir = file("$iosFrameworkBaseDir/SlicerUtils/SlicerUtils").absolutePath


    val slicerUtilsBaseFrameworkDirX64 = file("$slicerUtilsDir/DerivedData/SlicerUtils/Build/Products/Debug-iphonesimulator/SlicerUtils.framework").absolutePath
    val slicerUtilsBaseBuildDirArm64 = file("$slicerUtilsDir/DerivedData/SlicerUtils/Build/Products/Debug-iphoneos/SlicerUtils.framework").absolutePath

    iosX64() {
        compilations.getByName("main") {
            val slicerUtils  by cinterops.creating {

                defFile("SwiftSlicerUtils.def")

               compilerOpts("-framework", "SlicerUtils", "-F${slicerUtilsDir}")
               

            }

        }

        binaries.all {
            // Linker options required to link to the library.
            linkerOpts("-L$slicerUtilsBaseFrameworkDirX64", "-lSlicerUtils")
        
        }
    }

    iosArm64() {
        compilations.getByName("main") {
            val slicerUtils by cinterops.creating {

                defFile("SwiftSlicerUtils.def")

                compilerOpts("-framework", "SlicerUtils", "-F${slicerUtilsDir}")
                

            }

        }

        binaries.all {
            // Linker options required to link to the library.
              linkerOpts("-L$slicerUtilsBaseBuildDirArm64", "-lSlicerUtils")
        }
    }
    /////////////////////////


    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.0.1")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1")
            }
        }
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test-common"))
                implementation(kotlin("test-annotations-common"))


            }
        }
        val androidMain by getting {
            dependencies {

                implementation("org.jetbrains.kotlin:kotlin-stdlib")
                implementation("org.jsoup:jsoup:1.13.1")
            }
        }
        val androidTest by getting {
            dependencies {
                implementation(kotlin("test-junit"))
                implementation("junit:junit:4.13")
            }
        }
        val iosMain by getting
        val iosTest by getting
    }
}
android {
    compileSdkVersion(29)
    sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
    defaultConfig {
        minSdkVersion(23)
        targetSdkVersion(29)
        versionCode = 1
        versionName = "1.0"
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
        }
    }
}
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)
}
tasks.getByName("build").dependsOn(packForXcode)

The error I'm receiving is the following:

> Task :shared:cinteropSlicerUtilsIosArm64 FAILED
Exception in thread "main" java.lang.Error: /var/folders/xd/ts3w2yyj66732_54xj7nhrtr0000gn/T/tmp3537373282020062433.m:1:9: fatal error: module 'SlicerUtils' not found
    at org.jetbrains.kotlin.native.interop.indexer.UtilsKt.ensureNoCompileErrors(Utils.kt:152)
    at org.jetbrains.kotlin.native.interop.indexer.ModuleSupportKt.getModulesASTFiles(ModuleSupport.kt:67)
    at org.jetbrains.kotlin.native.interop.indexer.ModuleSupportKt.getModulesInfo(ModuleSupport.kt:13)
    at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.buildNativeLibrary(main.kt:499)
    at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.processCLib(main.kt:264)
    at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.interop(main.kt:72)
    at org.jetbrains.kotlin.cli.utilities.InteropCompilerKt.invokeInterop(InteropCompiler.kt:45)
    at org.jetbrains.kotlin.cli.utilities.MainKt.mainImpl(main.kt:19)
    at org.jetbrains.kotlin.cli.utilities.MainKt.main(main.kt:37)

FAILURE: Build failed with an exception.

I tried pretty much all the combinations existent from paths to the framework folder without success, but in the example pasted, I'm providing the path to the root folder of the framework with the compileropts command, and the path to build folder of each architecture with the linkeropts command. As said I tried this and other combinations, without success.

As a general question, when the official documentation says:

Pass the framework name to the compiler and linker using the -framework option. Pass the path to the framework sources and binaries to the compiler and linker using the -F option.

  • What is the module name of the error?
  • What is the framework name? The name of the project in xCode?
  • The path to the framework sources is the path to the swift files of this framework, or to the root folder of the framework or what?
  • And where is the binary of a framework stored? I suppose that the binary is the following file, but I'm not sure:

Maybe you can point me out what I'm doing wrong. Thank you in advance!

来源:https://stackoverflow.com/questions/64864812/not-able-to-add-ios-custom-framework-to-a-kmm-kotlin-multi-platform-module-ci

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!