Создайте смесь библиотеки Github из jvm и мультиплатформы Kotlin - PullRequest
1 голос
/ 12 апреля 2020

Я пытаюсь создать библиотеку Android, и у меня есть следующее:

  • Github Repo для библиотеки
    • Библиотека 1: Kotlin собственный / мультиплатформенный код, который может компилироваться в Android и iOS
    • Библиотека 2: код Kotlin / JVM зависит от библиотеки 1
    • Пример приложения: приложение с использованием библиотеки 2 и библиотеки 1
  • Личный Android Проект
    • Зависит от библиотеки Github выше

В моем личном проекте у меня есть только:

implementation 'com.github.username:myrepo:0.5'

Проблемы

  1. Частный проект Android загружает android библиотеку (Библиотека 2), но мультиплатформенные kotlin модели и функции (Библиотека 1) недоступны.

    Обратите внимание, что пример приложения библиотеки работает нормально. Я подозреваю, что jitpack.io неправильно публикует артефакты. Есть идеи, как решить эту проблему? Что-нибудь нужно сделать с файлами Gradle, чтобы решить проблему?

  2. Я бы хотел опубликовать многоплатформенную библиотеку в одиночку. Я попытался получить к нему доступ из мультиплатформенного модуля Kotlin, но получаю сообщение "Невозможно разрешить зависимости". Вот что я пытался:

    implementation 'com.github.username.myrepo:library1_moduleName:0.1'


Мультиплатформа Gradle для библиотеки 1:

plugins {
    kotlin("multiplatform")
}

kotlin {
    //select iOS target platform depending on the Xcode environment variables
    val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
        if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
            ::iosArm64
        else
            ::iosX64

    iOSTarget("ios") {
        binaries {
            framework {
                baseName = "library1"
                freeCompilerArgs.add("-Xobjc-generics")

            }
        }
    }

    jvm("android")

    sourceSets["commonMain"].dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
    }

    sourceSets["androidMain"].dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib")
    }
}

val packForXcode by tasks.creating(Sync::class) {
    val targetDir = File(buildDir, "xcode-frameworks")

    /// selecting the right configuration for the iOS
    /// framework depending on the environment
    /// variables set by Xcode build
    val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
    val framework = kotlin.targets
        .getByName<KotlinNativeTarget>("ios")
        .binaries.getFramework(mode)
    inputs.property("mode", mode)
    dependsOn(framework.linkTask)

    from({ framework.outputDirectory })
    into(targetDir)

    /// generate a helpful ./gradlew wrapper with embedded Java path
    doLast {
        val gradlew = File(targetDir, "gradlew")
        gradlew.writeText(
            "#!/bin/bash\n"
                    + "export 'JAVA_HOME=${System.getProperty("java.home")}'\n"
                    + "cd '${rootProject.rootDir}'\n"
                    + "./gradlew \$@\n"
        )
        gradlew.setExecutable(true)
    }
}

tasks.getByName("build").dependsOn(packForXcode)

Gradle для библиотеки 2

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {

    repositories {
        google()
        jcenter()
        maven { url 'https://jitpack.io' }
    }

    compileSdkVersion 29
    buildToolsVersion "29.0.0"


    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 29

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles 'consumer-rules.pro'
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    api project(":library1")
}

Ответы [ 2 ]

2 голосов
/ 14 апреля 2020

Я предлагаю вам изменить build.gradle конфигурацию для таргетинга на Android / Измените ее на

plugins {
    kotlin("multiplatform")
    id("com.android.library")
    id("maven-publish")
}

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.0"

    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 29
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

kotlin {
    //select iOS target platform depending on the Xcode environment variables
    val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
        if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
            ::iosArm64
        else
            ::iosX64

    iOSTarget("ios") {
        binaries {
            framework {
                baseName = "library1"
                freeCompilerArgs.add("-Xobjc-generics")

            }
        }
    }

    // jvm("android")
    android {
        publishLibraryVariants("release")
    }

    sourceSets["commonMain"].dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
    }

    sourceSets["androidMain"].dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib")
    }
}

val packForXcode by tasks.creating(Sync::class) {
    val targetDir = File(buildDir, "xcode-frameworks")

    /// selecting the right configuration for the iOS
    /// framework depending on the environment
    /// variables set by Xcode build
    val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
    val framework = kotlin.targets
        .getByName<KotlinNativeTarget>("ios")
        .binaries.getFramework(mode)
    inputs.property("mode", mode)
    dependsOn(framework.linkTask)

    from({ framework.outputDirectory })
    into(targetDir)

    /// generate a helpful ./gradlew wrapper with embedded Java path
    doLast {
        val gradlew = File(targetDir, "gradlew")
        gradlew.writeText(
            "#!/bin/bash\n"
                    + "export 'JAVA_HOME=${System.getProperty("java.home")}'\n"
                    + "cd '${rootProject.rootDir}'\n"
                    + "./gradlew \$@\n"
        )
        gradlew.setExecutable(true)
    }
}

tasks.getByName("build").dependsOn(packForXcode)

, создайте файл AndroidManifest.xml для библиотеки1 в разделе src/main/AndroidManifest.xml

<manifest package="library1"/>

вы Теперь вы можете добавить sh ваш проект в github, создать тег и подождать, пока jitpack выполнит свои магические действия c

Если вы хотите использовать его в library2, в разделе dependencies просто добавьте

implementation 'com.github.username.myrepo:library1-android:0.1' //for android
1 голос
/ 13 апреля 2020

Возможно, вам понадобится включить метаданные для многоплатформенной библиотеки ; в settings.gradle:

enableFeaturePreview('GRADLE_METADATA')

А также при настройке библиотеки для Maven (неясно, как вы публикуете sh в GitHub, поскольку build.gradle не включает в себя все это в качестве автоматизации) , Даже при публикации его в GitHub вместо mavenLocal() ему, вероятно, потребуется предоставить какие-то метаданные ... на что может указывать «Невозможно разрешить зависимости», если предположить, что он существует под именем указанного пакета.

apply plugin: 'maven-publish'
group 'com.github.username'
version '1.0.0'

Конфигурация api хороша только для зависимостей, на которые ссылаются несколько модулей; все остальное (любое единственное вхождение) должно быть implementation. Я имею в виду, я нахожу библиотеку 2 build.gradle сбивающей с толку, потому что сверху она читает maven { url 'https://jitpack.io' } (без фактической ссылки на удаленную зависимость), а затем позже она читает api project(":library1") (что определенно является локальной зависимостью).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...