问题
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