Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No matching variant of Kotlin Multiplatrom Mobile library found

I have a Kotlin Multiplatform Mobile library that I published to Maven Central. I am also trying to use this library in a non-KMM Android app. When I declare the dependency in the android app I get this error

Execution failed for task ':app:checkDebugAarMetadata'.
> Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
   > Could not resolve io.github.tyczj:tweedle-android:0.3.0.
     Required by:
         project :app
      > No matching variant of io.github.tyczj:tweedle-android:0.3.0 was found. The consumer was configured to find a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but:
          - Variant 'commonMainMetadataElements-published' capability io.github.tyczj:tweedle-android:0.3.0:
              - Incompatible because this component declares a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed a runtime of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm'
              - Other compatible attribute:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')
          - Variant 'metadataApiElements-published' capability io.github.tyczj:tweedle-android:0.3.0:
              - Incompatible because this component declares a usage of 'kotlin-metadata' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed a runtime of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm'
              - Other compatible attribute:
                  - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')
          - Variant 'releaseApiElements-published' capability io.github.tyczj:tweedle-android:0.3.0 declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
              - Incompatible because this component declares an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug'
          - Variant 'releaseRuntimeElements-published' capability io.github.tyczj:tweedle-android:0.3.0 declares a runtime of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
              - Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug'

I assume something is wrong with my configuration but I dont really know what that error is telling me, this is my first time creating a KMM library.

Here is my build.gradle.kts

import org.gradle.api.tasks.bundling.Jar

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

repositories {
    gradlePluginPortal()
    google()
    mavenCentral()
}

val javadocJar by tasks.registering(Jar::class) {
    archiveClassifier.set("javadoc")
}

group = "io.github.tyczj"
version = "0.3.0"

kotlin {
    android{
        publishLibraryVariants("release")
    }
    ios {
        binaries {
            framework {
                baseName = "tweedle"
            }
        }
    }
    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-core:1.5.1")
                implementation("io.ktor:ktor-client-json:1.5.1")
                implementation("io.ktor:ktor-client-serialization:1.5.1")
                implementation("io.ktor:ktor-client-logging:1.5.1")
                implementation("ch.qos.logback:logback-classic:1.2.3")
//                implementation("com.squareup.okio:okio:2.10.0")
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2-native-mt"){
                    version {
                        strictly("1.4.2-native-mt")
                    }
                }
            }
        }
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test-common"))
                implementation(kotlin("test-annotations-common"))
            }
        }
        val androidMain by getting {
            dependencies {
                implementation("androidx.core:core-ktx:1.3.2")
                implementation("io.ktor:ktor-client-android:1.5.1")
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2-native-mt")
                implementation("com.github.scribejava:scribejava-apis:8.3.0")
            }
        }
        val androidTest by getting {
            dependencies {
                implementation(kotlin("test-junit"))
                implementation("junit:junit:4.12")
            }
        }
        val iosMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-ios:1.5.1")
            }
        }
//        val iosTest by getting
    }
}

android {
    compileSdkVersion(30)
    sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
    defaultConfig {
        minSdkVersion(26)
        targetSdkVersion(30)
        versionCode = 1
        versionName = "1.0"
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
        }
    }

    packagingOptions {
        excludes.add("META-INF/*.kotlin_module")
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().all {
        kotlinOptions {
            jvmTarget = "1.8"
        }
    }
}

afterEvaluate {
    publishing {
        repositories {
            maven {
                name = "sonatype"
                url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")
                credentials {
                    username = rootProject.ext["ossrhUsername"]?.toString()
                    password = rootProject.ext["ossrhPassword"]?.toString()
                }
            }
        }

        publications.withType<MavenPublication> {

            artifact(javadocJar.get())

            pom{
                name.set("Tweedle")
                description.set("Tweedle is an Android library built around the Twitter v2 API built fully in Kotlin using Kotlin Coroutines")
                url.set("https://github.com/tyczj/Tweedle")
                licenses {
                    license {
                        name.set("MIT")
                        url.set("https://opensource.org/licenses/MIT")
                    }
                }
                developers {
                    developer {
                        id.set("tyczj")
                        name.set("Jeff Tycz")
                        email.set("[email protected]")
                    }
                }
                scm {
                    url.set("https://github.com/tyczj/Tweedle")
                }
            }
        }
    }
}

val packForXcode by tasks.creating(Sync::class) {
    group = "build"
    val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
    val sdkName = System.getenv("SDK_NAME") ?: "iphonesimulator"
    val targetName = "ios" + if (sdkName.startsWith("iphoneos")) "Arm64" else "X64"
    val framework =
        kotlin.targets.getByName<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget>(
            targetName
        ).binaries.getFramework(mode)
    inputs.property("mode", mode)
    dependsOn(framework.linkTask)
    val targetDir = File(buildDir, "xcode-frameworks")
    from({ framework.outputDirectory })
    into(targetDir)
}
tasks.getByName("build").dependsOn(packForXcode)

ext["signing.keyId"] = rootProject.ext["signing.keyId"]?.toString()
ext["signing.password"] = rootProject.ext["signing.password"]?.toString()
ext["signing.secretKeyRingFile"] = rootProject.ext["signing.secretKeyRingFile"]?.toString()

signing {
    sign(publishing.publications)
}

What do I need to do to be able to use the android dependency (io.github.tyczj:tweedle-android) in a non-KMM android app?

Update

I tried adding "debug" to android library variants

android{
    publishLibraryVariants("release", "debug")
}

as well as adding fallbacks

buildTypes {
    getByName("release") {
        isMinifyEnabled = false
    }
    val staging by creating{
        setMatchingFallbacks(listOf("release", "debug"))
    }
}

and that didnt do anything

If I create a new KMM project and just try to add the dependency I get somewhat of a different error saying

Failed building KotlinMPPGradleModel
org.gradle.internal.resolve.ArtifactNotFoundException: Could not find tweedle-android-0.3.1-samplessources.jar (io.github.tyczj:tweedle-android:0.3.1).
like image 633
tyczj Avatar asked May 16 '21 01:05

tyczj


People also ask

How do I publish a kotlin multiplatform library?

Publishing multiplatform libraries You can publish a multiplatform library to a Maven repository with the maven-publish Gradle plugin. Specify the group, version, and the repositories where the library should be published. The plugin creates publications automatically.

How do I set up kotlin multiplatform?

In Android Studio, select Settings/Preferences | Plugins, search Marketplace for Kotlin Multiplatform Mobile, and then install it. The Kotlin plugin should be compatible with the Kotlin Multiplatform Mobile plugin.

What is KMM in Kotlin?

Kotlin Multiplatform Mobile (KMM) is an SDK designed to simplify the development of cross-platform mobile applications. You can share common code between iOS and Android apps and write platform-specific code only where it's necessary.


1 Answers

The error message referencing "samplessources" comes up when you include a dependency that's not built for the correct platforms. There's some discussion in this youtrack issue, as well as this other issue around emitting a better error message in this case.

In your case, it's presumably being triggered by implementation("ch.qos.logback:logback-classic:1.2.3") in your common dependencies. This is a JVM library, but you have an iOS target so it won't work in your common dependencies. Move it to your Android dependencies instead.

like image 117
RussHWolf Avatar answered Nov 11 '22 12:11

RussHWolf