我正在尝试将Mapbox的框架集成到我的Kotlin多平台库中。但是我在cinterop部分遇到了编译错误。
第一个问题是MapboxMobileEvents框架的编译步骤。 MapboxMobileEvents.h
的导入语句引用了不存在的MapboxMobileEvents
目录。我创建了一个符号链接来解决这个问题。
那之后,我从clang收到一个错误。
Exception in thread "main" java.lang.IllegalStateException: clang_parseTranslationUnit2 failed with CXError_ASTReadError;
sourceFile = /var/folders/vj/mvxq9qtn1r9_8x2c7zyx04_m0000gn/T/tmp6661284981682757951tmp8536987580934998728.m
arguments = -fmodules -isystem /Users/mkrussel/.konan/dependencies/clang-llvm-apple-8.0.0-darwin-macos/lib/clang/8.0.0/include -B/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin -fno-stack-protector -stdlib=libc++ -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.5.sdk -miphoneos-version-min=9.0 -O2 -I/Users/mkrussel/pangea/mapbox-native/pangea-mapbox/frameworks/MapboxMobileEvents.framework/Headers -fobjc-arc -include-pch /var/folders/vj/mvxq9qtn1r9_8x2c7zyx04_m0000gn/T/tmp1085765932502683439.pch -Werror=implicit-function-declaration -ferror-limit=0
tmp6661284981682757951tmp8536987580934998728.m
名称在每次构建时都会更改,但是文件始终为空,这是我认为引起问题的原因。
我不知道是什么导致文件为空。
我是否将cinterop配置错误?
Kotlin插件是否损坏?
Mapbox框架与Kotlin本机不兼容吗?
我的gradle文件看起来像
iOSTarget("ios") {
compilations {
@Suppress("UNUSED_VARIABLE")
val main by getting {
kotlinOptions.freeCompilerArgs = listOf("-Xobjc-generics")
val frameworksDir = "$projectDir/frameworks"
cinterops(Action {
val mapboxEvents by creating {
defFile("$frameworksDir/mapbox-events.def")
includeDirs.allHeaders("$frameworksDir/MapboxMobileEvents.framework/Headers")
}
})
cinterops(Action {
val mapbox by creating {
defFile("$frameworksDir/mapbox.def")
includeDirs.allHeaders("$frameworksDir/Mapbox.framework/Headers")
}
})
}
}
}
mapbox-events.def
package = framework.mapbox.events
language = Objective-C
headers = MapboxMobileEvents.h
headersFilter = **
compilerOpts = -F/Users/mkrussel/pangea/mapbox-native/pangea-mapbox/frameworks -framework MapboxMobileEvents -fmodules
linkerOpts = -F/Users/mkrussel/pangea/mapbox-native/pangea-mapbox/frameworks -framework MapboxMobileEvents
mapbox.def
package = framework.mapbox
language = Objective-C
headers = Mapbox.h
headersFilter = **
compilerOpts = -F/Users/mkrussel/pangea/mapbox-native/pangea-mapbox/frameworks -framework Mapbox -fmodules
linkerOpts = -F/Users/mkrussel/pangea/mapbox-native/pangea-mapbox/frameworks -framework Mapbox
在.def
文件中使用完整路径名,以确保没有相对路径问题。
尝试仅使用mapbox.def
或mapbox-events.def
文件之一仍然会产生相同的错误。
使用:
也尝试过此方法,但同样失败。
iOSTarget("ios") {
val frameworksDir = "$projectDir/frameworks"
compilations {
@Suppress("UNUSED_VARIABLE")
val main by getting {
kotlinOptions.freeCompilerArgs = listOf("-Xobjc-generics")
cinterops(Action {
val mapboxEvents by creating {
defFile("$frameworksDir/mapbox-events.def")
packageName("com.mapbox.events")
header("$frameworksDir/MapboxMobileEvents.framework/Headers/MapboxMobileEvents.h")
compilerOpts("-fmodules")
includeDirs.allHeaders("$frameworksDir/MapboxMobileEvents.framework/Headers")
}
})
cinterops(Action {
val mapbox by creating {
defFile("$frameworksDir/mapbox.def")
packageName("com.mapbox")
header("$frameworksDir/Mapbox.framework/Headers/Mapbox.h")
compilerOpts("-fmodules")
includeDirs.allHeaders("$frameworksDir/Mapbox.framework/Headers")
}
})
}
}
binaries {
executable {
linkerOpts = mutableListOf("-F$frameworksDir", "-framework", "Mapbox", "-framework", "MapboxMobileEvents")
}
}
}
mapbox-event.def
language = Objective-C
mapbox.def
language = Objective-C
答案 0 :(得分:1)
我最终使它起作用。
mapbox.def
language = Objective-C
modules = Mapbox
linkerOpts = -framework Mapbox
在build.gradle.kts中
kotlin {
ios {
val frameworkLocation = File(rootDir, "native/TestApp/Pods/Mapbox-iOS-SDK/dynamic/").absolutePath
val frameworks = "-F$frameworkLocation"
compilations {
@Suppress("UNUSED_VARIABLE")
val main by getting {
cinterops {
val mapbox by creating {
defFile = File("$projectDir/libs/mapbox.def")
packageName("com.mapbox")
compilerOpts(frameworks)
}
}
}
}
binaries.matching { it is org.jetbrains.kotlin.gradle.plugin.mpp.Framework }
.configureEach {
val framework = this as org.jetbrains.kotlin.gradle.plugin.mpp.Framework
framework.linkerOpts(frameworks)
}
}
}
好像我缺少的一大块东西是模块行
答案 1 :(得分:0)
我已经在那些框架上玩了一些,这里就是我所发现的。
您不需要compilerOpts
文件中的那些.def
。此选项用于cinterop工具,而不是最终的二进制编译。您在此处设置的选项可能应该转到Gradle脚本的kotlin.binaries.framework
块。可以在documentation中找到更多信息。
UPD:此建议并不完全正确,因为它仅解决了Mapbox框架的绑定生成问题。问题是cinterop
工具的-fmodules
编译器标志存在问题。该标志对于MapboxMobileEvents框架非常重要,因为它在使用Foundation和CoreFoundation框架时依赖于@import
语法。
请订阅YouTrack问题here。修复后,我将在这里进行更新。