【问题标题】:How to integrate Mapbox iOS framework into Kotlin native如何将 Mapbox iOS 框架集成到 Kotlin 原生中
【发布时间】:2020-06-08 13:39:14
【问题描述】:

我正在尝试将 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.defmapbox-events.def 文件之一仍然会产生相同的错误。

使用:

  • Kotlin 版本 1.3.72
  • Xcode 版本 11.5 (11E608c)

也试过了,同样的失败。

    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

【问题讨论】:

    标签: mapbox kotlin-native


    【解决方案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)
                }
        }
    }
    

    似乎我缺少的重要部分之一是模块行

    【讨论】:

      【解决方案2】:

      我已经对这些框架进行了一些尝试,这就是我所发现的。 您不需要.def 文件中的那些compilerOpts。此选项适用于 cinterop 工具,而不是最终的二进制编译。您在此处设置的选项可能应该转到 Gradle 脚本的 kotlin.binaries.framework 块。更多信息可以在documentation找到。


      UPD:这个建议并不完全正确,因为它只修复了 Mapbox 框架的绑定生成。问题在于cinterop 工具的-fmodules 编译器标志存在问题。这个标志对于 MapboxMobileEvents 框架很重要,因为它在使用 Foundation 和 CoreFoundation 框架时依赖于 @import 语法。
      请订阅 YouTrack 问题here。修复后我会在这里更新。

      【讨论】:

      • 尝试按照建议从.def 文件中删除选项。简化了complierOpts,但我仍然遇到同样的失败。如果 cinterops 中没有“-fmodules”,我会收到有关使用 import 关键字的编译器错误
      • 感谢您使用 JetBrains 创建票证。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-27
      相关资源
      最近更新 更多