Thread
#multiplatform
    andylamax

    andylamax

    2 years ago
    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
    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

    2 years ago
    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":
    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
    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:
    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:
    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
    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 😃
    andylamax

    andylamax

    2 years ago
    That is one long-winded response. Let me go with your approach for now. Thanx
    s

    Skolson5903

    2 years ago
    🙂 🙂 🙂