Hey, how can I test a KMM library locally without...
# multiplatform
r
Hey, how can I test a KMM library locally without publishing it to an external repo? I have a project that I can use the library in, before, we used to extract a Jar file and add it to libs, but now for KMM don’t think this the right way any ideas?
c
Do you want to do this to check the contents of the library, or to develop the library while having an example under your eyes?
r
second
I built the library and published it, but after implementing it I got errors, so. I want to implement it locally and try to fix these errors
c
You can add
Copy code
includeBuild("../path/to/the/library")
in the downstream project's
settings.gradle.kts
Reload IDEA, and it will recognize both projects together (so you can control click on a symbol of the library to get to it and edit its code)
The big benefit of this approach is that you can edit the code of the library, rerun the app, and Gradle figures out automatically that it needs to recompile the library etc, so you can iterate very easily. The downside is that a few things of the library's configuration are ignored (it's the Gradle instance of the downstream project that will build the library), so you can get Gradle or JDK problems if the two projects have very different versions, but in general that's not an issue
If you want the other way, and actually emulate a repository, but locally, you can do
Copy code
./gradlew publishToMavenLocal
and then add
Copy code
repositories {
    mavenCentral()
    mavenLocal()
}
to all modules of the downstream project, and change the version number to match whatever you published it as. However, this is exactly how an external repository would act, so each time you change the library you have to re-publish it with the same version number, etc This way is more useful to debug "why isn't that file included in the maven repository", while the
includBuild
way is more useful for "ah, there's a bug in one of my functions and I want an actual example to see how it happens"
r
Thanks a lot this is very helpful
I think last method is what I’m looking for since the issue is not in the functionality but rather in the library implementation and gradle, something is wrong with variants and attributes apparently
c
yep, that's what you want then
r
I get a very very long error log starting with this
c
If it really is an attributes/variants problem, you should probably ask in #gradle or even in the Gradle slack itself
💡 1
r
people say I have to remove
android-library
plugin from the library but I need to check
Gradle slack itself
didn’t know they have slack 👀 good to know!
c
yes, it's linked at the top of #gradle
r
cool, will try to fix the issue first with what you provided, then ask there if I still needed more help
c
does the library have
Copy code
kotlin {
    jvm()
}
or
Copy code
kotlin {
    android()
}
?
r
Copy code
kotlin {
    androidTarget {
        compilations.all {
            kotlinOptions {
                jvmTarget = "1.8"
            }
        }
    }
    iosX64()
    iosArm64()
    iosSimulatorArm64()

    cocoapods {
        summary = "Some description for the Shared Module"
        homepage = "Link to the Shared Module homepage"
        version = "1.0"
        ios.deploymentTarget = "16.0"
        framework {
            baseName = "shared"
            isStatic = true
        }
    }
    
    sourceSets {
        commonMain.dependencies {
            implementation(commonlibs.kotlinx.datetime)
        }
        commonTest.dependencies {
            implementation(libs.kotlin.test)
        }
    }
}
c
note that your error message only shows why it didn't select the first variant, but there's probably a lot more than that. You want to find the block that explains why it didn't select the variants that have
android
in their name
🤔 1
r
still requires some dependencies clean up, also cocoapods is not needed but I was still testing the whole thing first
hmm, the log is like 20 pages long, not sure what to look at exactly and how to find the useful info
c
Each line that starts with
- Variant 'SOME NAME'
is the start of a decision block. You can ignore all variants that don't have 'android' or 'jvm' in their name, since it's complaining about not finding an Android variant, so it's normal all the others fail
r
but what it mostly keep saying is
Copy code
- Doesn't say anything about com.android.build.api.attributes.AgpVersionAttr (required '8.1.0')
          - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')
          - Doesn't say anything about its target Java environment (preferred optimized for Android)
c
^ yep, that's normal for all variants that are not Android or JVM based
Hopefully there should be one (or more) variant that has 'android' or 'jvm' in their name, and then it will say something different
r
actually none of them has android or jvm
c
Well that answers that, the Android variant is not published
r
there is 198 instances of
- Variant
162 are
iosSomething
and 36 are
metadataSomething
c
198 ?? 😅
I've never seen more than ~30 or so
r
Well that answers that, the Android variant is not published
any idea why that might be the case?
198 ?? 😅
told ya, 20 pages long 😅
c
Not really, I'm not an Android guy. If you run
./gradlew publishToMavenLocal
and open
~/.m2/repository/
you should find all the binaries it produced, there should be one per module × each platform it supports. It's probably something in the config of
maven-publish
(the
publishing
block), but you're probably better off creating a new thread so other people look at it
1
r
actually its a very small library, here is the full gradle files project’s
Copy code
plugins {
    //trick: for the same plugin versions in all sub-modules
    alias(libs.plugins.androidLibrary).apply(false)
    alias(libs.plugins.kotlinMultiplatform).apply(false)
    alias(libs.plugins.kotlinCocoapods).apply(false)
    alias(libs.plugins.kotlinAndroid).apply(false)
    alias(libs.plugins.mavenPublish).apply(false)
}
shared’s build.gradle file
Copy code
plugins {
    alias(libs.plugins.kotlinMultiplatform)
    alias(libs.plugins.kotlinCocoapods)
    alias(libs.plugins.androidLibrary)
    alias(libs.plugins.mavenPublish)
}

mavenPublishing {
    publishToMavenCentral(com.vanniktech.maven.publish.SonatypeHost.S01)
    signAllPublications()
    coordinates("com.raedghazal", "kotlinx_datetime_ext", "1.0.0")

    pom {
        name.set("Kotlinx datetime ext")
        description.set("A KMM library that provides extensions and helper functions for kotlinx-datetime ")
        inceptionYear.set("2023")
        url.set("<https://github.com/RaedGhazal/kmm-kotlinx-datetime-ext>")
        developers {
            developer {
                id.set("RaedGhazal")
                name.set("Raed Ghazal")
                url.set("<https://github.com/RaedGhazal>")
            }
        }
        licenses {
            license {
                name.set("MIT License")
                url.set("<https://opensource.org/license/mit/>")
                distribution.set("<https://opensource.org/license/mit/>")
            }
        }
        scm {
            url.set("<https://github.com/RaedGhazal>")
            connection.set("scm:git:<git://github.com/RaedGhazal/kmm-kotlinx-datetime-ext.git>")
            developerConnection.set("scm:git:<ssh://git@github.com/RaedGhazal/kmm-kotlinx-datetime-ext.git>")
        }
    }
}

kotlin {
    androidTarget {
        compilations.all {
            kotlinOptions {
                jvmTarget = "1.8"
            }
        }
    }
    iosX64()
    iosArm64()
    iosSimulatorArm64()

    cocoapods {
        summary = "Some description for the Shared Module"
        homepage = "Link to the Shared Module homepage"
        version = "1.0"
        ios.deploymentTarget = "16.0"
        framework {
            baseName = "shared"
            isStatic = true
        }
    }
    
    sourceSets {
        commonMain.dependencies {
            implementation(commonlibs.kotlinx.datetime)
        }
        commonTest.dependencies {
            implementation(libs.kotlin.test)
        }
    }
}

android {
    namespace = "com.raedghazal.kotlinx_datetime_ext"
    compileSdk = 34
    defaultConfig {
        minSdk = 26
    }
}
dependencies {
    implementation(commonlibs.androidx.core.ktx)
}
it's called out there in the docs
r
yup found it and fixed it, thanks!