Hey everyone, I'm creating a KMP library and want ...
# multiplatform
h
Hey everyone, I'm creating a KMP library and want to publish it to my local Maven repository to add this library as a dependency on an Android project. Here is the structure I'm using:
Copy code
.
└── Library/
    ├── shared/
    │   ├── featureA (module)/
    │   │   └── build.gradle.kts
    │   ├── featureB (module)/
    │   │   └── build.gradle.kts
    │   └── src/commonMain/kotlin/com/example/library/
    │       └── Library.kt
    └── build.gradle.kts
The
shared/src/build.gradle.kts
depends on both
featureA
and
featureB
, and it also contains the publishing configurations, like below:
Copy code
plugins {
    // Other plugins
    id("maven-publish")
}

group = "com.example"
version = "1.0"

publishing {
    repositories {
        mavenLocal()
    }
}

kotlin {
    androidTarget {
        // Other configs
        publishLibraryVariants("release")
    }
    // Other configs
    sourceSets {
        commonMain.dependencies {
            api(projects.shared.featureA)
            api(projects.shared.featureB)
        }
    }
}
After running the
publishAndroidReleasePublicationToMavenLocalRepository
gradle task, the artefacts are properly created, and I can add this dependency to my Android project, like below:
Copy code
implementation("com.example:shared-android:1.0")
However, I can only access the classes that are inside
shared/src
and not the ones in
featureA
or
featureB
. Unless I also publish them as a separate library and import them into the Android project. What I expect is to publish a single artefact where I can access all the exposed classes/interfaces that are declared as
api
dependencies in the
shared/src/build.gradle.kts
Does anyone know if this is feasible?
p
That's the way Android and java works. I am not aware of a KMP build task to achieve this. In plain java you can play with Uber jars and embedded jars but in Android you need to publish independently. I might be outdated
h
Thank you for your response, Pablichenko. 🙏 I wonder how Ktor achieve this because to use the Ktor client, you have to add only two dependencies:
ktor-client-core
and
ktor-client-cio
. These modules depend on several others, but you don't have to import them into your project; for example, the
ktor-client-cio
gradle file depends on: • ktor-client-core • ktor-http-cio • ktor-shared:ktor-websockets • ktor-network:ktor-network-tls Maybe I do have to publish all of them, and then Gradle will resolve their dependency? 🤔
Ok, I just tested here, and this is exactly the case. I have to publish all the modules as artefacts to the repository, but in the Android project, I only have to add the dependency to the main module. But one trick is that I have to use the
publishToMavenLocal
to publish all the defined target artefacts, and in the Android project, I can use
shared:1.0
instead of
shared-android:1.0
. But I guess that if I just need the Android library, I can use only the
publishAndroidReleasePublication
and
publishKotlinMultiplatformPublication
tasks to generate the artefacts I need.
p
What I described is traditional Android lib development. But perhaps KMP improved some stuff in this regards with the klibs.
I know there is an open ticket in the Android issue tracker asking for this. But it has been sitting there for years.
When you add a dependency as a maven coordinate. Gradle reads the pom.xml file associated with this dependency, then pull them into the build process. This is imported as a transitive dependency
When you publish your library, you have to ensure the pom.xml includes your dependencies. Otherwise, may lead to build errors sometimes runtime errors.
👍 1
h
Yes, I didn't know about this, thanks for the help! 🙏
👍 1
a
Hi @heitorcolangelo I’m facing the same issue. Is there any other way apart from publishing all sub modules as separate artefacts ?
p
I don't think it is possible tbh, this is the official issue, give it a star for support: https://issuetracker.google.com/issues/62121508?pli=1
a
Yeah. I finally published everything as separate artifacts. Thanks @Pablichjenkov
🎉 1
p
Great, one thing to notice, in iOS achieving what you want is totally possible. Depending how you setup the build dynamic or static. Static it will include all the dependent modules in the published library. And, using export, you can expose the dependent modules public API too, from your library.
a
Yes. I’m using KMMBridge for that.
🔥 1