Use Gradle sub-projects with Kotlin multiplatform
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:
- Every 'normal' (common) module has one platform module for each platform.
- For common module
alpha
, the javascript platform module must be calledalpha-js
(similar for-jvm
). - If there is no platform specific code, this module can be just a gradle file in a directory.
- The platform modules can be conveniently placed inside of the common module directory (so
alpha:alpha-js
). - The common module should not refer to the platform modules; the platform modules have a dependency
expectedBy project(":the_common_module")
. If module
alpha
depends onbeta
, thenalpha
must havedependencies { compile project(":beta") }
alpha-js
must havedependencies { compile project(":beta:beta-js") }
(in addition toexpectedBy
)alpha-jvm
must havedependencies { compile project(":beta:beta-jvm") }
(in addition toexpectedBy
) etc
Only the top module has
settings.gradle
, which includes ALL submodules (including platform ones).- Make sure to get the names right, as incorrect ones don't cause an error, they just fail silently. (It seems ridiculous but I guess there is a reason.)
- Do NOT put all the output into a single, shared build directory - this results in several weird non-deterministic errors.
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.