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

andylamax

08/05/2020, 9:19 PM
I have found something so wiered and it goes as follows. I have a multiplatform lib called
theme-core
which at the moment, targets
js
jvm
and
android
. I also have a pure js library
theme-react
which depends on
theme core
.
theme-react
being a purely
js
lib. It has it's sources located at
src/main/kotlin
while
theme-core
sources for targeting js are at
src/jsMain/kotlin
I am trying to use
theme-react
and ultimately
theme-core
as a dependency to a pure js react ui library called
enteprise-react
. as always sources are located at
src/main/kotlin
Idea is able to resolve
theme-react
sources but can't resolve
theme-core
sources. After being bugged by this for a while, I tried changing my
build.gradle.kts
like so
Copy code
sourceSets {
    val jsMain by creating {
        dependencies {
            api(project(":theme-core"))
            api(project(":theme-react"))
        }
    }

    val main by getting {
        dependsOn(jsMain)
        dependencies {
            api(kotlin("stdlib-js"))
            api("org.jetbrains.kotlinx:kotlinx-react:${versions.kotlinjs.react}")
            api("org.jetbrains:kotlin-styled:${versions.kotlinjs.styled}")
            api("org.jetbrains:kotlin-css-js:${versions.kotlinjs.css}")
        }
    }
}
so now
enterprise-react
has two sourceSets.
jsMain
and
main
. If I put my sources in
jsMain
all pure js libraries (including
kotlin-react
and
kotlin-styled
) aren't resolved by IDEA. If I put my sources in
main
IDEA failes to resolve all dependencies build from the sources of the subprojects at
jsMain
(i.e.
theme-core
) and all other mpp supprojects. I tried seperating my sources, no luck. as there is a moment I need resources from both
theme-core
and
kotlin-react
. Has anyone experienced this issue at all? any workaround suggestions please . . . Thank you in advance
s

Skolson5903

08/07/2020, 5:37 PM
Sorry for the long-winded response, I spent a lot of time battling what you seem to also be battling, starting with 1.4-M3 and now in 1.4.0-rc. I can't help with JS issues, but hopefully stuff below will help. I also have seen sourceset weirdness in an MP project with three MP modules set up as android libraries, one android app module and one ios app module. I used the 1.4-M3 new project wizard in Intellij to generate the initial setup, using the kotlin gradle DSL (not groovy). Later I upgraded to 1.4.0-rc when that came out. The Intellij new project wizard sets up commonMain, commonTest, iosMain, iosTest, androidMain, androidTest directories. I also added a buildSrc to the owning project structure that the wizard doesn't have an option for, but worked fine with gradle. Anyway in this setup, when I started adding source I had similar troubles to yours, and gradle complained about androidMain when I tried to use it. So I used this snippet in the kotlin block to list the current sourcesets present. Again this is only useful if you have MP modules not using the default name "shared":
Copy code
kotlin {
   ...
    //list all kotlin sourcesets and their sourceDirectories
    sourceSets.forEach {
        println("$moduleName kotlin sourceSet ${it.name}")
        it.kotlin.sourceDirectories.forEach{println("  srcDir: ${it.absolutePath}")}
    }

}
And this snippet to explore the android block sourcesets: //list all android sourcesets and their directories
Copy code
sourceSets.forEach {
        println("$moduleName android sourceSet ${it.name}")
        it.java.srcDirs.forEach{println("   srcDir: ${it.absolutePath}")}
    }
On yours, pay close attention to the sourcseset names, in my environment the module name gets pre-pended on most of them and I didn't tried to fight that. The lists produced in the gradle console by the snippets above showed me the mismatches I was getting burned by. For example, given a module name of "ioCommon" instead of shared, I got these sourcesets in the kotlin block:
Copy code
commonMain - MP source goes here
commonTest - MP unit tests go here. I doen't use this, I do Kotest under JUnit. So see ioCommonMain below.  If you need MP tests, beware of open issue I filed: Kotlin Issue Tracker KT-40571
ioCommonMain - basically this acts like androidMain, but if you look in the default srcdirs for this they point to src/main/kotlin, not src/androidMain/kotlin
ioCommonTest - Kotest and kotlin.tests unit tests using JUnit5 work fine here, you just need Kotest 4.20 snapshot and Kotest 1.1.0 snapshot plugins until the ones for 1.4.0 are published the 
iosMain - looks fine but I have only let generated actual classe go here, all unimplemented so far.
iosTest - looks fine but I haven't used it yet
The link above got messed up: Kotlin Issue Tracker in the android block with the above setup, kotlin unit tests don't get recognized, because android didn't look in the right kotlin dirs. I had to add this snippet to make Android Studio and gradle happy with my desired "kotlin" subdirectory:
Copy code
android {
	...
    sourceSets {
        getByName("test").java.srcDirs("src\\test\\kotlin")
    }
}
finally, looking at the souredirs for both the kotlin sourceSets and the android sourceSets, the path of least resistance for me was to make src/main/kotlin and src/test/kotlin dirs
Copy code
ioCommon\src\main\kotlin - contains the java-specific "actual" classes that match to the MP "expect" classes
   ioCommon\src\androidTest\kotlin - contains instrumented unit tests
   ioCommon\src\test\kotlin - had to create this directory, contains java unit tests, not android instrumented ones
After I did all this in all three of the build.gradle.kts files, one for each MP module, everything started mostly working :-) It looks to me like once you have MPP modules not using the default name of "shared", sourceset strangeness happens. Kotlin sourcesets do not coordinate well with the android sourcesets in this scenario. In my setup, the workarounds are working, but there are likely better ways to get this right. I like androidMain better than main in the modules long-term, but since I have this working, decided to wait and rearrange sourcesets later, after I get some other stuff done :-). Once you get the sourcesets right, dependsOn and other dependencies stuff seems to work fine. I have also tried all of the above on gradle, 6.3, 6.4, and am currently using 6.5.1 no problem. I don't know who to report this sort of thing to. I don't know if its a defect or WAD, but it sure seems to me that it could be cleaner than it is :-) If anyone out there works with the related gradle plugins and new project wizard and wants to dig into this more, I'm motivated and I have time :-)
a

andylamax

08/08/2020, 5:07 AM
That is one long-winded response. Let me go with your approach for now. Thanx
s

Skolson5903

08/09/2020, 4:52 PM
🙂 🙂 🙂
2 Views