Kotlin Multiplatform Mobile找不到klib软件包

编程入门 行业动态 更新时间:2024-10-19 22:25:45
本文介绍了Kotlin Multiplatform Mobile找不到klib软件包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我已阅读这些

Platform 下的红线表示错误:

预期的类'Platform'在本地模块MyApplication.shared.androidNativeArm64Main中没有实际的声明

,但显然是这可能只是系统故障(不确定-Alt + Enter解决方案创建实际的类..."似乎没有任何作用.假设这不是问题,我继续...

我检查了 .klib 详细信息

运行 .konan/.../bin/klib信息mylib.klib ,我没有得到 c.mylib 作为包名,但是却得到了 com.example.myapplication:shared-cinterop-mylib (请参见下文).我可以接受(尽管不确定为什么它不是我在Gradle中指定的)

解析为:/home/me/AndroidStudioProjects/MyApplication/shared/build/classes/kotlin/androidNativeArm64/main/shared-cinterop-mylib模块名称:< com.example.myapplication:shared-cinterop-mylib>ABI版本:1.4.1编译器版本:1.4.10库版本:null元数据版本:1.4.0红外线版本:1.0.0可用的目标:android_arm64

我尝试将软件包包含在我的 androidApp Gradle 中

我想访问我的 androidApp 项目中的 .klib .我尝试了两个软件包 c.mylib 和 com.example.myapplication:shared-cinterop-mylib .

我尝试将 implementation("com.example.myapplication:shared-cinterop-mylib")添加到我的 androidApp Gradle文件中,但出现错误:

无法确定任务':androidApp:lintVitalRelease'的依赖关系.无法解析配置':androidApp:debugCompileClasspath'的所有工件.找不到com.example.myapplication:shared-cinterop-mylib:.要求者:项目:androidApp可能的解决方案:

  • 声明提供工件的存储库,请参阅 docs.gradle上的文档/current/userguide/declaring_repositories.html

我不确定提示是否可以解决问题,但是我还是尝试使用例如将文件添加到 androidApp Gradle repositories {...} 块中

maven {url = uri("/home/me/AndroidStudioProjects/MyApplication/shared/build/classes/kotlin/androidNativeArm64/main/shared-cinterop-mylib.klib")}

但是我不确定这是将文件添加到存储库的正确方法.

问题

有人可以帮助我在 androidApp 中识别该软件包吗?我会继续尝试.

解决方案

您可能对针对不同平台的不同Kotlin版本感到困惑.请查看文档以获得详细信息,而在此我将尝试解释其基本概念.

Kotlin Multiplatform通常由三种不同的编译器组成:一种是为JVM构建的,另一种是转换为JS的,另一种是编译平台特定的本机二进制文件(可执行文件,静态或共享库)的.KMM技术是关于在两个不同的平台(iOS和Android)之间共享您的代码.

此处的重要细节是,KMM旨在使开发人员更轻松地将此共享代码包括在其现有代码库中-通常是iOS的Swift或Objective-C以及Android的Java或Kotlin/JVM.这很重要,因为此项目是使用Kotlin/Native和Kotlin/JVM构建的.在您的代码中,我看到了另一个平台声明. androidNativeArm64 ,这是Kotlin/Native目标,而不是经典的Android目标.它使用其他编译器,并因此产生一个共享库.这就是为什么

  • 您可以定义一个cinterop块,为标题创建绑定,但是
  • 这些绑定仅适用于Kotlin/Native编译的一部分.
  • 您在此处创建的

    KLIB本身不是库,而是本机库( mylib )的一组绑定.它使您能够使用Kotlin代码中的 mylib s API,该API是在 androidNativeArm64Main 源集中编写的.由于您目前没有设置这样的源,因此您的项目无法正确构建,并显示有关缺少实际声明的警告.

    总结上述所有内容.在项目的当前状态下,您可以执行以下操作:

    可以
    • 使用Kotlin/本机代码中的绑定(将文件添加到 shared/src/androidNativeArm64Main/kotlin/)
    • 使用这些绑定到共享库( .so 文件)的代码来编译代码
    • 按照Android NDK文档中的说明使用此共享库(此处)

    • 删除Kotlin/Native Android目标,并在 shared/src/androidMain/kotlin/
    • 中使用不使用C API的代码
    不能
    • 取决于Kotlin/JVM模块中的KLIB(例如,一般的 androidApp 项目或 shared 中设置的 androidMain 源)
    • 发布绑定,不关心将结果工件与C库链接
    • 使用从Kotlin/Native编译的共享库或静态库比使用C/C ++本机库要容易(抱歉,但这是您可能要避免的JNI问题)

    对于冗长而复杂的回答,我们深表歉意,如有任何问题,请与我联系.我很乐意纠正我的任何错误或不正确之处.

    I've read these SO posts 1, 2, 3 which faced a similar problem. I'm trying to use a .klib in my KMM Android project. The Klib is built from library.h C header. Here's what I did:

    I built the Kotlin Library

    Using the following Gradle block in the KMM shared project:

    kotlin { ... androidNativeArm64 { // target compilations.getByName("main") { val mylib by cinterops.creating { defFile(project.file("mylib.def")) packageName("c.mylib") // Options to be passed to compiler by cinterop tool. compilerOpts("-I/home/me/CLionProjects/mylib/") // Directories for header search (an analogue of the -I<path> compiler option). includeDirs.allHeaders("/home/me/CLionProjects/mylib/") // A shortcut for includeDirs.allHeaders. includeDirs("/home/me/CLionProjects/mylib/") } } binaries { sharedLib() // kotlinlang/docs/mpp-build-native-binaries.html#declare-binaries } } }

    with mylib.def file

    headers = /home/me/CLionProjects/mylib/library.h headerFilter = /home/me/CLionProjects/mylib/* package = c.mylib

    On building, the .klib and build folder appears in the classes directory of the shared project as shown below:

    The red line under Platform is for the error:

    Expected class 'Platform' has no actual declaration in module MyApplication.shared.androidNativeArm64Main for Native

    but apparently that may just be a system glitch (not sure - the Alt+Enter solution to "create actual class..." doesn't seem to do anything). Assuming this is not a problem I continue...

    I check the .klib details

    Running .konan/.../bin/klib info mylib.klib I don't get c.mylib as the package name but com.example.myapplication:shared-cinterop-mylib instead (see below). I can live with that (although not sure why it isn't what I specified in Gradle)

    Resolved to: /home/me/AndroidStudioProjects/MyApplication/shared/build/classes/kotlin/androidNativeArm64/main/shared-cinterop-mylib Module name: <com.example.myapplication:shared-cinterop-mylib> ABI version: 1.4.1 Compiler version: 1.4.10 Library version: null Metadata version: 1.4.0 IR version: 1.0.0 Available targets: android_arm64

    I tried including the package in my androidApp Gradle

    I want to access the .klib inside my androidApp project. I tried both packages c.mylib and com.example.myapplication:shared-cinterop-mylib.

    I tried adding implementation("com.example.myapplication:shared-cinterop-mylib") to my androidApp Gradle file, but got the error:

    Could not determine the dependencies of task ':androidApp:lintVitalRelease'. Could not resolve all artifacts for configuration ':androidApp:debugCompileClasspath'. Could not find com.example.myapplication:shared-cinterop-mylib:. Required by: project :androidApp Possible solution:

    • Declare repository providing the artifact, see the documentation at docs.gradle/current/userguide/declaring_repositories.html

    I'm not sure if the hint would solve the problem, but I tried adding the file to the androidApp Gradle repositories { ... } block anyway using e.g.

    maven { url = uri("/home/me/AndroidStudioProjects/MyApplication/shared/build/classes/kotlin/androidNativeArm64/main/shared-cinterop-mylib.klib") }

    but I'm not sure that's the right way to add a file to a repository.

    Question

    Can anyone help me to get the package recognised in androidApp ? I'll keep trying.

    解决方案

    You are probably confused about different Kotlin versions aiming for a different platform. Please check out the documentation for details, while I'll try to explain the basic concept here.

    Kotlin Multiplatform in general consists of three different compilers: one to build for the JVM, one to transpile to the JS, and one to compile platform-specific native binaries(executables, static or shared libraries). KMM technology is about sharing your code between two different platforms, iOS and Android.

    The important detail here is that KMM aims to make it easier for developers to include this shared code into their existing codebase - usually Swift or Objective-C for iOS and Java or Kotlin/JVM for Android. This is important because this project is built with Kotlin/Native and Kotlin/JVM.

    In your code, I see an additional platform declaration. The androidNativeArm64, this is a Kotlin/Native target, not a classic Android one. It uses the other compiler, and produces a shared library as a result. This is the reason why

  • You're able to define a cinterop block, creating bindings for the header, but
  • Those bindings are applicable only as a part of the Kotlin/Native compilation.
  • KLIB, which you created here, is not a library itself, but a set of bindings for the native library(mylib). It provides you an ability to use mylibs API from Kotlin code, written in the androidNativeArm64Main source set. As you don't have such a source set at this moment, your project cannot build correctly, and shows warning about missing actual declaration.

    Concluding everything described above. Here are the things you can do, and cannot do in the current state of the project:

    Can
    • Use bindings from your Kotlin/Native code(add files to shared/src/androidNativeArm64Main/kotlin/)
    • Compile the code using those bindings to a shared library(.so file)
    • Use this shared library as described in the Android NDK documentation(here)

    or

    • Delete the Kotlin/Native Android target, and code without C API usage at the shared/src/androidMain/kotlin/
    Cannot
    • Depend on a KLIB from the Kotlin/JVM modules(e.g. androidApp project in general or androidMain source set in shared)
    • Publish bindings and do not care about linking the resulting artifact with the C library
    • Use shared or static library compiled from Kotlin/Native easier than using C/C++ native library(sorry, but it will be the same JNI thing you probably try to avoid here)

    Sorry for a long and complicated answer, please contact me with any questions in the comment section below. I would be glad to correct any fo my mistakes or inaccuracies.

    更多推荐

    Kotlin Multiplatform Mobile找不到klib软件包

    本文发布于:2023-07-04 17:18:14,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1026996.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:找不到   软件包   Multiplatform   Kotlin   klib

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!