I'm using Kotlin multi-platform (JVM & JS), which in IDEA creates three projects: demo
, demo-js
and demo-jvm
.
I would like to split the common code into more subprojects/submodules. Let's say I add commonmod
; how do I make it compile?
The error right now, for gradle run -p demo-jvm
, is:
demo/demo-js/src/main/kotlin/demo/commonmod/example.kt: (3, 12): Actual function 'getPlatform' has no corresponding expected declaration
but I think I'm doing this fundamentally wrong, as I don't know what should depend on what (although I tried quite some iterations). If I solve this error I get other ones, and then other ones again, until I'm back to this one.
As a minimal-but-still-large example, I have:
demo/settings.gradle:
rootProject.name = 'demo'
include 'demo-jvm', 'demo-js', 'commonmod'
demo/build.gradle:
buildscript { ... }
apply plugin: 'kotlin-platform-common'
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version"
testCompile "org.jetbrains.kotlin:kotlin-test-annotations-common:$kotlin_version"
testCompile "org.jetbrains.kotlin:kotlin-test-common:$kotlin_version"
compile project(':commonmod')
}
demo/demo-jvm/settings.gradle:
rootProject.name = 'demo'
demo/demo-jvm/build.gradle:
buildscript { ... }
apply plugin: 'kotlin-platform-jvm'
apply plugin: 'application'
repositories {
mavenCentral()
}
mainClassName = "demo.MainKt"
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
expectedBy project(":")
testCompile "junit:junit:4.12"
testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
}
demo/demo-js/settings.gradle:
rootProject.name = 'demo'
demo/demo-js/build.gradle:
buildscript { ... }
apply plugin: 'kotlin-platform-js'
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
expectedBy project(":")
testCompile "org.jetbrains.kotlin:kotlin-test-js:$kotlin_version"
}
demo/commonmod/settings.gradle:
rootProject.name = 'demo'
include 'demo-jvm', 'demo-js'
demo/commonmod/build.gradle:
buildscript { ... }
apply plugin: 'kotlin-platform-common'
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version"
testCompile "org.jetbrains.kotlin:kotlin-test-annotations-common:$kotlin_version"
testCompile "org.jetbrains.kotlin:kotlin-test-common:$kotlin_version"
compile project(':demo-js')
compile project(':demo-jvm')
}
This took a crazy amount of time, so I hope this is useful for someone!
There is a functional example on Github: kotlin_multiplatform_gradle_demo
Several sources helped, but a lot of it was trial and error, so if something is bad practise, please let me know!
For the minimal example, the structure is like this:
├── alpha
│ ├── alpha-js
│ │ └── build.gradle
│ ├── alpha-jvm
│ │ └── build.gradle
│ ├── build.gradle
│ └── src
│ └── main
│ ├── kotlin
│ │ └── demo
│ │ └── alpha
│ │ └── main.kt
├── beta
│ ├── beta-js
│ │ ├── build.gradle
│ │ └── src
│ │ └── main
│ │ └── kotlin
│ │ └── demo
│ │ └── beta
│ │ └── platform.kt
│ ├── beta-jvm
│ │ ├── build.gradle
│ │ └── src
│ │ └── main
│ │ └── kotlin
│ │ └── demo
│ │ └── beta
│ │ └── platform.kt
│ ├── build.gradle
│ └── src
│ └── main
│ └── kotlin
│ └── demo
│ └── beta
│ └── platform.kt
├── build.gradle
└── settings.gradle
The common modules (alpha
and beta
) need platform modules for each platform with at least a `build.gradle``.
The settings.gradle
file imports all modules, including platform ones.
Dependencies, e.g. from alpha on beta, is declared in the common alpha module and all alpha platform modules.
Some patterns I learned:
alpha
, the javascript platform module must be called alpha-js
(similar for -jvm
).alpha:alpha-js
).expectedBy project(":the_common_module")
.If module alpha
depends on beta
, then
alpha
must have dependencies { compile project(":beta") }
alpha-js
must have dependencies { compile project(":beta:beta-js") }
(in addition to expectedBy
)alpha-jvm
must have dependencies { compile project(":beta:beta-jvm") }
(in addition to expectedBy
) etcOnly the top module has settings.gradle
, which includes ALL submodules (including platform ones).
I used to have the full config files here, but it's better to just check the code on Github because it's really long.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With