https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
o

Orhan Tozan

02/28/2020, 1:59 PM
Hi guys, I already have several modules that have no reference to android/ios. So really pure Kotlin modules, business logic etc. The idea is the following three following repo's: • core • android implementations • ios implementations So I don't want to use the expect, actual mechanism, but just the interface/implementation mechanism. How do I set something like this up?
k

Kris Wong

02/28/2020, 2:08 PM
you could do 3 separate repos, or 3 modules in the same repo
o

Orhan Tozan

02/28/2020, 2:10 PM
Yes, 3 repos is what I want. Which multiplatform module project setup do I need to chose in intellij idea for the Core repo? Core repo consists of multiple modules. In the android/ios default setup I get android/ios folders created what I not want. I want the core repo to be pure, not having any mention of any platform.
@Kris Wong
Do I need to choose Multiplatform Library?
k

Kris Wong

02/28/2020, 2:15 PM
that sounds closest to what you want
r

russhwolf

02/28/2020, 2:17 PM
Even if all your code is common, the core module still needs to declare what platforms it builds for. So those templates will generate source folders for the platforms but you can delete the ones you don't have any code in. But you'll still have them declared in gradle.
o

Orhan Tozan

02/28/2020, 2:21 PM
Allright thanks. I have two more questions: Question 1: Right now my Core modules have the `
Copy code
apply plugin: 'java-library'
apply plugin: 'kotlin'
in there build.gradle. Will this be replaced now with
Copy code
plugins {
    id 'org.jetbrains.kotlin.multiplatform' version '1.3.61'
}
? Question 2:
The generated gradles are in default groovy I see (build.gradle). Is it recommended to switch to the newer kotlin dsl gradle files? (build.gradle.kts) ?
r

russhwolf

02/28/2020, 2:27 PM
yes on 1. For 2, opinions vary. Long-term I think kts is the way to go and I use it for my own projects, but IDE support can be inconsistent. There should be a checkbox on the templates though to generate kts scripts if you want.
o

Orhan Tozan

02/28/2020, 2:29 PM
I didn't see a checkbox for generating kts scripts. Im using intellij idea 2019.3.3
r

russhwolf

02/28/2020, 2:32 PM
Oh. It's in the gradle kotlin templates but not the kotlin ones
There's also samples online you can look at, eg https://github.com/touchlab/KaMPKit
k

Kris Wong

02/28/2020, 2:47 PM
Kotlin DSL is much easier to work with
o

Orhan Tozan

02/28/2020, 5:22 PM
Thanks guys, you've been helpful. Assuming we have this 3 repo setup, how is building meant? Am I supposed to open the core repo in intellij idea and open the android repo in Android studio? How is building and running done.
Should I publish the Core to maven and make the android repo just use it as a external dependency? How would the flow of that go, debuggin etc.
k

Kris Wong

02/28/2020, 5:25 PM
that's up to you. either include it as an inline subproject, or publish it to Maven. it depends on your work flows and how you want to run module releases
o

Orhan Tozan

02/28/2020, 5:28 PM
If you go down the publish to Maven path, does that mean that, for example I am trying to fix a bug in Core, and in order to test if it works on Android, I have to first publish it to maven with a new release 1.0.x+1? Which makes the release track polluted for just some trial and error
Or am I missing somethign
k

Kris Wong

02/28/2020, 5:39 PM
that's correct
it's also not too complicated to define a flag in a local properties file that will allow each developer to switch between inline project, and artifact repo (default)
o

Orhan Tozan

02/28/2020, 5:41 PM
So that makes the publishing to Maven thing really not an option, since trial and error developing isn't possible with that. Publishing Core to maven is only meant for teams were the core repo and android repo are really separate islands I guess.
k

Kris Wong

02/28/2020, 5:42 PM
but for iOS, ultimately you need a framework file. and if have multiple MPPs, you'll need one umbrella framework
i'd say that's correct
it's really to everyone's benefit if you have a unit test for every use case in your MPP
o

Orhan Tozan

02/28/2020, 5:45 PM
I understand
I should to delete all of those sourceSets except commonMain and commonTest, right?
I see that every module has is own build.gradle with mpp and sourceset definitions. What is the use of the root build.gradle (yellow one)?
k

Kris Wong

02/28/2020, 5:47 PM
you can try, but it may not build the target if you delete it's source set
it's for project level configuration
o

Orhan Tozan

02/28/2020, 5:49 PM
My source was this:
Russell Wolf
Even if all your code is common, the core module still needs to declare what platforms it builds for. So those templates will generate source folders for the platforms but you can delete the ones you don't have any code in. But you'll still have them declared in gradle.
Previously in the thread
k

Kris Wong

02/28/2020, 5:49 PM
give it a try
o

Orhan Tozan

02/28/2020, 5:50 PM
So should I put all those sourcesets into the single root build.gradle file, making the seperate module gradle's redundant?
k

Kris Wong

02/28/2020, 5:50 PM
no
you should only put things in the root that apply to every module
o

Orhan Tozan

02/28/2020, 5:52 PM
The similarity between all modules is that they only have commonMain and commonTest sourcesets. The difference ofcourse is that each module will have different dependencies.
So with this situation, I guess the root build.gradle doesn't have anything to add that it can apply for every module, making the root build.gradle redundant/useless? Is it better for me to delete the root build.gradle?
k

Kris Wong

02/28/2020, 6:06 PM
i suspect you will apply the KMP plugin at that level
i actually haven't tried a multi-module setup for KMP
o

Orhan Tozan

02/28/2020, 6:09 PM
What about the target declaration
Can I just declare this (everything in the red square) once in the root build.gradle, and not mention it again in the individual module build.gradle's ?
k

Kris Wong

02/28/2020, 6:12 PM
i doubt it, you'll have to experiment i think
o

Orhan Tozan

02/28/2020, 6:13 PM
Ok
Can I just put this code in every module build.gradle, and delete the root build.gradle completely?
r

russhwolf

02/28/2020, 6:44 PM
You can omit the root level gradle file if you want. I usually have a small one with common repositories and some other simple config declared in an
allprojects{}
block I don't think you can share target definitions there but try it if you're curious. One way you can share some of that logic is using
buildSrc
. For example I have a bunch of helper logic here in Multiplatform Settings so I can just call
standardConfiguration()
at the module level. https://github.com/russhwolf/multiplatform-settings/blob/master/buildSrc/src/main/kotlin/BuildHelpers.kt
o

Orhan Tozan

02/28/2020, 6:56 PM
Thanks, gradle was always a black box, magic place for me
But now I learn slowly how it actually works
How do I specify plugins for every module in the root gradle?
This doesn't work
Gives me a build error
r

russhwolf

02/28/2020, 7:08 PM
Yeah you can't do everything from there. Plugins block has to be at the top.
o

Orhan Tozan

02/28/2020, 7:09 PM
But then it says
Plugin [id: 'com.android.library'] was not found in any of the following sources:
Taken from the KampKit github sample @Kris Wong, I assume this is necessary for every module even tho it has no android code?
Is it even required for my domain code module to specify the above?
r

russhwolf

02/28/2020, 7:19 PM
You need an
android
block with at least a
compileSdkVersion
for any module with one of the Android plugins applied. If you use
jvm
for the Android side you don't need it
k

Kris Wong

02/28/2020, 7:20 PM
if you are not using Android SDK APIs, then you don't need the android plugin
change your target to JVM
otherwise, you will need android config block, AndroidManifest.xml, etc...
o

Orhan Tozan

02/28/2020, 7:21 PM
Ah ok I get it, because jvm() target also works seamlessly on Android side ofcourse, right?
k

Kris Wong

02/28/2020, 7:28 PM
correct
o

Orhan Tozan

03/04/2020, 10:09 PM
Hey @Kris Wong, you were saying that there two options to use a mpp repo with a standalone android repo. The Publish to maven way and the other way. How should my Android repo reference the mpp repo this other way?
k

Kris Wong

03/04/2020, 10:11 PM
will there be frequent or infrequent changes in the KMP module?
o

Orhan Tozan

03/04/2020, 10:17 PM
Hmm, not sure yet. What would the difference be in setup?
k

Kris Wong

03/04/2020, 10:18 PM
well, if it were frequent, then I would add it as a subproject
otherwise I'd drop the artifact in libs
o

Orhan Tozan

03/04/2020, 10:20 PM
Frequent changes in the KMP module, as in constantly trial and error debugging?
How do I add the kmp project as a subproject?
And an artifact is something like a generated .jar of the project but then in kotlin mpp form?
k

Kris Wong

03/04/2020, 10:25 PM
it would work the same as any other subproject in gradle
o

Orhan Tozan

03/04/2020, 10:29 PM
But if I add it as a subproject to my android project, won't the files be duplicated? Or is there a way I can make my android project add the mpp project as a subproject, without affecting the on-disk structure?
k

Kris Wong

03/04/2020, 10:29 PM
i would use git submodules
o

Orhan Tozan

03/04/2020, 10:30 PM
Hmm, is it hard to use?
Also, why would the link the artifact of the mpp to android not work for frequent changes?
k

Kris Wong

03/04/2020, 10:37 PM
i don't understand your question
o

Orhan Tozan

03/04/2020, 10:41 PM
You were suggesting me to drop the artifact in the libs folder, when the mpp has infrequent changes. Why shouldn't this be applied when it has frequently changes?
k

Kris Wong

03/04/2020, 10:44 PM
you really want to be manually copying artifacts around on every change, and not know which version of the artifact is actually in your libs folder?
o

Orhan Tozan

03/04/2020, 11:22 PM
I get it
So we are talking about the artifacts in the.idea/artifacts/ folder right?
@Kris Wong I set up the git submodules in the android repo. It looks something like this now:
Copy code
android-repo/
    build.gradle
    settings.gradle.kts
    (..android-modules)
    core (git submodule) /
        (..mpp-modules)
        build.gradle
        settings.gradle.kts
How should my android modules build.gradles reference the mpp modules as a dependency?
k

Kris Wong

03/09/2020, 1:25 PM
include
it in settings.gradle, and add it as a
project
dependency in whatever project consumes it
o

Orhan Tozan

03/09/2020, 1:28 PM
Thanks for the quick response Kris, you're really helpful. Given a module_a in the core folder, does that mean the android-repo settings.gradle.kts should look like the following?:
Copy code
include(..other, ":module_a")
k

Kris Wong

03/09/2020, 1:41 PM
yes. you just need to tell it where to find each project, since they are not in the source root
o

Orhan Tozan

03/09/2020, 11:02 PM
@Kris Wong Ok, this is how my settings.gradle.kts looks now. It works I think. The only issue I get now is the following build error:
Caused by: org.gradle.plugin.management.internal.InvalidPluginRequestException: Plugin request for plugin already on the classpath must not include a version
k

Kris Wong

03/10/2020, 1:04 PM
you have multiple projects that are using the same gradle plugin. you need to resolve it in the settings file, and remove the version from the build file
o

Orhan Tozan

03/10/2020, 5:32 PM
Ok, just for clarification, If I change this:
Copy code
plugins {
    kotlin("multiplatform") version "1.3.70"
}
to this:
Copy code
plugins {
    kotlin("multiplatform")
}
will that make gradle automatically use the latest version of the kotlin multiplatform plugin?
k

Kris Wong

03/10/2020, 5:40 PM
no
o

Orhan Tozan

03/10/2020, 5:58 PM
Which version would be used then?
k

Kris Wong

03/10/2020, 6:00 PM
try it and find out
o

Orhan Tozan

03/10/2020, 6:12 PM
I did, now getting the following error:
Plugin [id: 'org.jetbrains.kotlin.multiplatform'] was not found in any of the following sources:
. Looks like omitting the plugin version number isn't an option?
k

Kris Wong

03/10/2020, 6:21 PM
are you resolving it in the settings file?
o

Orhan Tozan

03/10/2020, 6:23 PM
No I didn't, because frankly I don't know how to. I found this: Do you mean something like this?:
k

Kris Wong

03/10/2020, 6:26 PM
yes
o

Orhan Tozan

03/10/2020, 6:26 PM
Ok, interesting, thanks
Is there any reason why the KaMPKit github doesn't have this?
k

Kris Wong

03/10/2020, 6:44 PM
i am going to assume app is including the version
o

Orhan Tozan

03/10/2020, 7:19 PM
o

Orhan Tozan

03/10/2020, 7:47 PM
I see
Whats the difference between useModule and classpath?
k

Kris Wong

03/10/2020, 7:53 PM
the project is using
buildSrc
, which is a nice concept, but adds slight complication
o

Orhan Tozan

03/10/2020, 7:59 PM
I get it
So I should just stick to the settings.gradle.kts example earlier in the conversation right
I managed to make it work by resolving it in the root build.gradle.kts. Thanks for the help Kris!
🍻 1