I have a library that depends solely on the Kotlin stdlib, and I’d like to make it a multiplatform project. The wizard in IntelliJ creates an MPP with JVM, JS and native source sets, but since I don’t have any platform-specific code, I don’t need these.
Can I simply remove these source sets and the jvm()
js()
etc. calls from my build?
Yes, you can do that, but please bear in mind that the current architecture of multiplatform projects requires that all expect declarations are provided with actual implementations within the same module, and no actual implementations can be added by a library consumer.
2 Likes
Thanks, so since I do not currently have any expect
/actual
declarations, I shouldn’t have any problems with removing all implementations, since they do nothing?
Actually no, sorry, it doesn’t seem to work that way. I tried it locally. If you publish only the common
artifact of the library and then try to use it in an MPP client with a JVM target, you will get a compilation error, something like this:
> Task :compileKotlinJvm FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':compileKotlinJvm'.
> Could not resolve all files for configuration ':jvmCompileClasspath'.
> Could not resolve belkov.inner:inner-metadata:0.0.1.
Required by:
project :
> Unable to find a matching variant of belkov.inner:inner-metadata:0.0.1: Variant 'metadata-api':
- Found org.gradle.status 'release' but wasn't required.
- Required org.gradle.usage 'java-api' and found incompatible value 'kotlin-api'.
- Required org.jetbrains.kotlin.platform.type 'jvm' and found incompatible value 'common'.
So the JVM library artifact must also be published in order to consume the library with a JVM client.
1 Like
Thanks for your response; that’s unfortunate. I suppose I could just add a target for every platform currently available, but then I would have to change it if any new platforms receive Kotlin support. Are there plans for supporting common-only libraries?
There are no immediate plans, but you can follow the feature request https://youtrack.jetbrains.com/issue/KT-30088 for updates.
1 Like
The way that multiplatform works is that common modules have their common code included into the source code for the platform implementation. Due to implements/expects this does not produce conflicts with multiple declarations.
In addition, common modules provide their API as a separate artefact (a sort of IDL) that can be used by consumers of the common module (other common code).
As such common-only artefactts do not contain any code, only interface declarations. Eventually there needs to be a platform. This platform needs an implementation of the library that works with the platform. This means you will need the (empty) platform modules to allow the code to be compiled for that platform. You can remove the source folders if they are empty, but cannot remove the module from the gradle file.
1 Like