Allows you to toggle between Kotlin JVM Plugin -> Kotlin Multiplatform with a Gradle Property kmp4free=true
.
This Gradle Plugin was built to support gradual adoption of Kotlin Multiplatform. It's called kmp4free
because you are able to take a normal Kotlin JVM module, and with a single line change, enable or disable the Kotlin Multiplatform Plugin.
There is always a risk of adding something new, especially with a large project. The introduction of a technology that is not at a stable version yet can block the adoption of a new technology. The goal of this plugin is to reduce risk to a single line change.
Add the Snapshot Repo in your project's settings.gradle.kts
pluginManagement {
repositories {
// ...
maven { url = "https://s01.oss.sonatype.org/content/repositories/snapshots/" }
}
}
Add the Plugin on your project's build.gradle.kts
plugins {
id("com.handstandsam.kmp4free") version "${latest_version}"
}
Just replace kotlin("jvm")
with id("com.handstandsam.kmp4free")
in the plugins
block of your module's build.gradle.kts
file.
You can set kmp4free=true
in your gradle.properties
or send it in as a command-line parameter to gradle with -Pkmp4free=true
.
This enables property the Kotlin Multiplatform Plugin, along with the additional changes required to support seamless switching between the Kotlin JVM Plugin.
Any code in the main
sourceSet needs to be commonMain
compatible when multiplatform
is enabled, otherwise the build will fail about not being able to resolve JVM dependencies. This isn't a bad thing though, as you will then be able to identify what you need to change to make your code multiplatform compatible.
src/main
➡️src/commonMain
src/test
➡️src/jvmTest
implementation
➡️commonMainImplementation
api
➡️commonMainApi
testImplementation
➡️jvmTestImplementation
testApi
➡️jvmTestApi
When tests are already written with JVM Libraries like JUnit and Google's Truth library, it would be a lot of work to migrate those tests over to commonTest
, so these tests will only run on the JVM with kmp4free
. Additionally, this task alias means that your scripts that run Gradle Tasks do not have to update either when the plugin is enabled, since the test
task will be available.
:module:test
➡️:module:jvmTest
This uses the Kotlin JVM Plugin, and bypasses Kotlin Multiplatform entirely.
src/commonMain
➡️src/main
src/jvmMain
➡️src/main
src/commonTest
➡️src/test
src/jvmTest
➡️src/test
commonMainImplementation
➡️implementation
commonMainApi
➡️api
commonTestImplementation
➡️testImplementation
commonTestApi
➡️testApi
jvmTestImplementation
➡️testImplementation
jvmTestApi
➡️testApi
You can set the following properties in your gradle.properties
Droidcon SF Presentation: Embracing commonMain
for Android Development
You may typically see source sets defined like val commonMain by getting
. Because with kmp4free
we toggle the multiplatform plugin on/off, that Source Set will be sometimes be already there, and other times may not be. Therefore we use maybeCreate("commonMain")
to avoid the error.
- api
- implementation
- compileOnly
- runtimeOnly
- apiDependenciesMetadata
- implementationDependenciesMetadata
- compileOnlyDependenciesMetadata
- runtimeOnlyDependenciesMetadata
No. kmp4free
is a step in the journey of migrating a kotlin("jvm")
module to kotlin("multiplatform")
with a commonMain
SourceSet without adding any plugin changes when disabled.
The reason why you can't is because a kotlin("jvm")
module means you cannot have resources in the res
directory, an AndroidManifest.xml
and not use Android APIs. You may find that your Android Library doesn't have any of those. If that's true, just convert it to a kotlin("jvm")
module, and then you can use the plugin!
See Issue #6 for more discussion on this topic.
You are able to use jvm
or multiplatform
style configuration. Note: will want to use the maybeCreate("commonMain")
call instead of val commonMain by getting
when accessing Source Sets.
That is because sometimes the configuration is there when enabled, but off when disabled. When you are ready, you can migrate away from the kmp4free
plugin and start using the standard kotlin("jvm")
project with just a jvm()
target.
You can only apply your configuration IF the kotlin("multiplatform")
plugin has been added. That is because this plugin allows it to be on & off.
Look up the KotlinMultiplatformExtension
, and if not null (Checked by the ?.
operator), you can supply your configuration like this:
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
project.extensions.findByType(KotlinMultiplatformExtension::class.java)?.apply {
ios()
}
You can find more information in Issue #2. I'm thinking this would be a lambda in the plugin configuration block for each target.