Multiplatform multiple native targets, same source code


#1

Say I have 2 expected declarations in my common module:

  • the first one relies on K/N stdlib (kotlin.system.getTimeMillis for example)
  • the other one relies on specific target os/arch stuff.

Is there a clever way to not write again the common stuff? Maybe something like:

common
   |
   |-native-common
      |
      |-native-A
      |-native-B


#2

AFAIK in upcoming 1.3.20 this way works in Gradle, but not supported in IDEA.


#3

Yeah but which target should I pick? There is no “common-native” target or similar.


#4

Something like this:

sourceSets {
    nativeCommon
    nativeA {
        dependsOn nativeCommon
    }
    nativeB {
        dependsOn nativeCommon
    }
}

But as I said - it works from Gradle, but not from IDEA.


#5

Using Kotlin DSL of plugin 1.3.20-eap?


#6

Yes, tried in eap-100 and Kotlin DSL.


#7
plugins {
    id("kotlin-multiplatform") version "1.3.20-eap-100"
    id("maven-publish")
}
repositories {
    maven(url = "https://dl.bintray.com/kotlin/kotlin-eap")
    mavenCentral()
}
...
kotlin {
    jvm()
    js()
    nativeCommon() // <-- error here!
}
...

Auto-completion does not suggest anything with the name correlated to commonNative


#8

It’s not target, it’s source set.
Something like this:

kotlin {
    sourceSets.create("nativeCommon")
    sourceSets["nativeA"].apply {
        dependsOn(sourceSets["nativeCommon"])
    }
    sourceSets["nativeB"].apply {
        dependsOn(sourceSets["nativeCommon"])
    }
}

#9

Wow it works like a breeze! Thank you so much!
I assume that this code sharing based on sourceSets works on every Kotlin project (maybe Java as well).
Would it be possible to set nativeCommon source sets to a Kotlin/Native module? Even by hand every rebuild. That would at least remove some of the red warnings in those sources.


#10

I do not know, and as it does not work in IDEA still use old trick:

        sourceSets["macosxMain"].apply {
            kotlin.srcDir("src/nativeMain/kotlin")
        }
        sourceSets["linuxMain"].apply {
            kotlin.srcDir("src/nativeMain/kotlin")
        }