Kotlin Multiplatform Mobile не может найти пакет klib

Я прочитал эти сообщения SO 1, 2, 3, столкнувшиеся с аналогичной проблемой. Я пытаюсь использовать .klib в своем проекте KMM Android. Klib построен из заголовка library.h C. Вот что я сделал:

Я построил библиотеку Котлина

Используя следующий блок Gradle в проекте KMM shared:

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() // https://kotlinlang.org/docs/mpp-build-native-binaries.html#declare-binaries
        }
    }
}

с mylib.def файлом

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

При сборке .klib и папка сборки появляются в каталоге classes общего проекта, как показано ниже:

введите описание изображения здесь

Красная линия под Platform указывает на ошибку:

Ожидаемый класс Platform не имеет фактического объявления в модуле MyApplication.shared.androidNativeArm64Main для Native

но, очевидно, это может быть просто системный сбой (не уверен - Alt + Введите решение для создания фактического класса ... похоже, ничего не делает). Если это не проблема, я продолжаю ...

Проверяю .klib подробности

Запуск .konan/.../bin/klib info mylib.klib Я получаю не c.mylib в качестве имени пакета, а com.example.myapplication:shared-cinterop-mylib (см. Ниже). Я могу жить с этим (хотя не уверен, почему это не то, что я указал в 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

Я пробовал включить пакет в свой androidApp Gradle

Я хочу получить доступ к .klib внутри моего androidApp проекта. Я пробовал оба пакета 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 :. Требуется: project: androidApp Возможное решение:

Я не уверен, что подсказка решит проблему, но я все равно попытался добавить файл в блок androidApp Gradle repositories { ... }, используя, например,

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

но я не уверен, что это правильный способ добавить файл в репозиторий.

Вопрос

Может ли кто-нибудь помочь мне распознать пакет в androidApp? Я буду продолжать попытки.


person Pixel    schedule 29.03.2021    source источник


Ответы (1)


person    schedule
comment
Спасибо за ответ рассмотрю дальше. Я хотел скомпилировать свою библиотеку C / C ++ в единую библиотеку Kotlin и использовать этот единый API в проектах iOS и Android без необходимости использовать JNI в Android или другие оболочки в iOS. Я думал, что KMM может позволить мне скомпилировать мой код C ++ в библиотеку Kotlin и использовать эту библиотеку как в Android, так и в iOS. Но ваше последнее замечание заставляет меня думать, что это невозможно? - person Pixel; 02.04.2021
comment
Да, сейчас это не вариант. KMM использует компилятор Kotlin / Native, который позволяет вам использовать библиотеки C (пока нет взаимодействия с C ++, но некоторые заголовки типа C также будут работать) из кода Kotlin и связать полученный двоичный файл с этими библиотеками. Или он позволяет вам создать собственную библиотеку и использовать ее из C / C ++. - person Artyom Degtyarev; 07.04.2021
comment
Привет, Артём. Твоя последняя фраза заставила меня перевернуть мои мысли. Вы хотите сказать, что я могу создать общий shared Kotlin API, содержащий expected и actual функции (фактические функции, реализованные в соответствующих подпроектах iOS и Android), а затем скомпилировать и построить этот API Kotlin и передать его двум копиям моего ядра C / C ++ код, каждый из которых находится в подпроектах iOS и Android? Если это возможно, я думаю, это решит мою проблему, и, возможно, я неправильно думал о KMM. - person Pixel; 07.04.2021
comment
Да, если вы используете цель Kotlin / Native (см. здесь, для android для этого потребуется androidNative один), вы можете настроить проект для создания статической или динамической библиотеки (см. этот документ). Результат будет доступен из кода C / C ++ так же, как библиотека, созданная из исходных кодов C. Этот подход не так популярен, поэтому я могу сослаться только на это старое руководство. . Вы всегда можете спросить совета у людей здесь или в kotlinlang Slack. - person Artyom Degtyarev; 07.04.2021