Skip to content

Commit

Permalink
Use KotlinHierarchyTemplate for structuring source sets
Browse files Browse the repository at this point in the history
KotlinHierarchyTemplate allows writing KMP source set structures with less code
and without explicit dependsOn relations.

There is one downside is that all source sets are created now if at least
one of the target is declared. i.e. for example if JS target is declared
but wasm is not. Then jsAndWasmSharedMain source set will be created anyway.

It also fixes the issue with Kotlin 2.0 KT-68212
In :ktor-network jvmAndNixTest has an expect that in K1 was actualized in iosTest
there was no direct or transitive dependsOn relation from iosTest to jvmAndNixTest
and thus in K2 such actualization was prohibited. In this commit Source Set
structure is sanitized and now dependsOn relations are in good order.

^KT-68212 Fixed
  • Loading branch information
antohaby authored and tbogdanova committed May 23, 2024
1 parent 1e85bb7 commit f12b139
Showing 1 changed file with 40 additions and 218 deletions.
258 changes: 40 additions & 218 deletions buildSrc/src/main/kotlin/TargetsConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import org.gradle.api.*
import org.gradle.kotlin.dsl.*
import org.jetbrains.kotlin.gradle.*
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.targets.js.dsl.*
import java.io.*
Expand Down Expand Up @@ -52,31 +53,52 @@ fun Project.configureTargets() {

if (hasPosix || hasLinux || hasDarwin || hasWindows) extra.set("hasNative", true)

sourceSets {
if (hasJsAndWasmShared) {
val commonMain by getting {}
val jsAndWasmSharedMain by creating {
dependsOn(commonMain)
}
val commonTest by getting {}
val jsAndWasmSharedTest by creating {
dependsOn(commonTest)
if (hasJvmAndNix) { jvm(); nixTargets(); }
if (hasPosix) { posixTargets() }
if (hasDesktop) { desktopTargets() }
if (hasNix) { nixTargets() }
if (hasLinux) { linuxTargets() }
if (hasDarwin) { darwinTargets() }
if (hasWindows) { windowsTargets() }

@OptIn(ExperimentalKotlinGradlePluginApi::class)
applyHierarchyTemplate {
common {
group("nix") {
group("darwin") {
group("macos") { withMacos() }
group("ios") { withIos() }
group("tvos") { withTvos() }
group("watchos") { withWatchos() }
}
group("linux") { withLinux() }
}

jsMain {
dependsOn(jsAndWasmSharedMain)
}
jsTest {
dependsOn(jsAndWasmSharedTest)
withJvm()

group("jsAndWasmShared") {
withJs()
withWasm()
}
wasmJsMain {
dependsOn(jsAndWasmSharedMain)

group("posix") {
group("nix")
group("windows") { withMingw() }
group("desktop") {
group("macos")
group("linux")
group("windows")
}
}
wasmJsTest {
dependsOn(jsAndWasmSharedTest)

group("jvmAndNix") {
group("nix")
withJvm()
}
}
}

sourceSets {
val commonMain by getting {
dependencies {
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
Expand All @@ -89,206 +111,6 @@ fun Project.configureTargets() {
}
}

if (hasPosix) {
val posixMain by creating
val posixTest by creating
}

if (hasNix) {
val nixMain by creating
val nixTest by creating
}

if (hasDarwin) {
val darwinMain by creating
val darwinTest by creating {
dependencies {
implementation(kotlin("test"))
}
}

val macosMain by creating
val macosTest by creating

val watchosMain by creating
val watchosTest by creating

val tvosMain by creating
val tvosTest by creating

val iosMain by creating
val iosTest by creating
}

if (hasDesktop) {
val desktopMain by creating
val desktopTest by creating {
dependencies {
implementation(kotlin("test"))
}
}
}

if (hasLinux) {
val linuxMain by creating
val linuxTest by creating
}

if (hasWindows) {
val windowsMain by creating
val windowsTest by creating
}

if (hasJvmAndNix) {
val jvmAndNixMain by creating {
findByName("commonMain")?.let { dependsOn(it) }
}

val jvmAndNixTest by creating {
findByName("commonTest")?.let { dependsOn(it) }
}
}

if (hasJvm) {
val jvmMain by getting {
findByName("jvmAndNixMain")?.let { dependsOn(it) }
}

val jvmTest by getting {
findByName("jvmAndNixTest")?.let { dependsOn(it) }
}
}

if (hasPosix) {
val posixMain by getting {
findByName("commonMain")?.let { dependsOn(it) }
}

val posixTest by getting {
findByName("commonTest")?.let { dependsOn(it) }

dependencies {
implementation(kotlin("test"))
}
}

posixTargets().forEach {
getByName("${it}Main").dependsOn(posixMain)
getByName("${it}Test").dependsOn(posixTest)
}
}

if (hasNix) {
val nixMain by getting {
findByName("posixMain")?.let { dependsOn(it) }
findByName("jvmAndNixMain")?.let { dependsOn(it) }
}

val nixTest by getting {
findByName("posixTest")?.let { dependsOn(it) }
findByName("jvmAndNixTest")?.let { dependsOn(it) }
}

nixTargets().forEach {
getByName("${it}Main").dependsOn(nixMain)
getByName("${it}Test").dependsOn(nixTest)
}
}

if (hasDarwin) {
val nixMain: KotlinSourceSet? = findByName("nixMain")
val darwinMain by getting
val darwinTest by getting
val macosMain by getting
val macosTest by getting
val iosMain by getting
val iosTest by getting
val watchosMain by getting
val watchosTest by getting
val tvosMain by getting
val tvosTest by getting

nixMain?.let { darwinMain.dependsOn(it) }
macosMain.dependsOn(darwinMain)
tvosMain.dependsOn(darwinMain)
iosMain.dependsOn(darwinMain)
watchosMain.dependsOn(darwinMain)

macosTargets().forEach {
getByName("${it}Main").dependsOn(macosMain)
getByName("${it}Test").dependsOn(macosTest)
}

iosTargets().forEach {
getByName("${it}Main").dependsOn(iosMain)
getByName("${it}Test").dependsOn(iosTest)
}

watchosTargets().forEach {
getByName("${it}Main").dependsOn(watchosMain)
getByName("${it}Test").dependsOn(watchosTest)
}

tvosTargets().forEach {
getByName("${it}Main").dependsOn(tvosMain)
getByName("${it}Test").dependsOn(tvosTest)
}

darwinTargets().forEach {
getByName("${it}Main").dependsOn(darwinMain)
getByName("${it}Test").dependsOn(darwinTest)
}
}

if (hasLinux) {
val linuxMain by getting {
findByName("nixMain")?.let { dependsOn(it) }
}

val linuxTest by getting {
findByName("nixTest")?.let { dependsOn(it) }

dependencies {
implementation(kotlin("test"))
}
}

linuxTargets().forEach {
getByName("${it}Main").dependsOn(linuxMain)
getByName("${it}Test").dependsOn(linuxTest)
}
}

if (hasDesktop) {
val desktopMain by getting {
findByName("posixMain")?.let { dependsOn(it) }
}

val desktopTest by getting

desktopTargets().forEach {
getByName("${it}Main").dependsOn(desktopMain)
getByName("${it}Test").dependsOn(desktopTest)
}
}

if (hasWindows) {
val windowsMain by getting {
findByName("posixMain")?.let { dependsOn(it) }
}

val windowsTest by getting {
dependencies {
implementation(kotlin("test"))
}
}

windowsTargets().forEach {
getByName("${it}Main").dependsOn(windowsMain)
getByName("${it}Test").dependsOn(windowsTest)
}
}

if (hasNative) {
tasks.findByName("linkDebugTestLinuxX64")?.onlyIf { HOST_NAME == "linux" }
tasks.findByName("linkDebugTestLinuxArm64")?.onlyIf { HOST_NAME == "linux" }
Expand Down

0 comments on commit f12b139

Please sign in to comment.