Skip to content

Commit

Permalink
Move targets setup into buildSrc
Browse files Browse the repository at this point in the history
* mpp, library and test configuration in convention plugin
* targets configuration using shortcuts in place
* add ability to run tests with both release and debug native binaries
* setup js jarn lock store
  • Loading branch information
olme04 committed Jan 12, 2022
1 parent 55b5e1b commit e76d8f5
Show file tree
Hide file tree
Showing 20 changed files with 2,188 additions and 184 deletions.
3 changes: 1 addition & 2 deletions benchmarks/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ import org.gradle.kotlin.dsl.benchmark
import org.jetbrains.kotlin.gradle.plugin.mpp.*

plugins {
kotlin("multiplatform")
id("kotlinx-atomicfu")
rsocket.multiplatform

alias(libs.plugins.kotlin.allopen)
alias(libs.plugins.kotlinx.benchmark)
Expand Down
141 changes: 2 additions & 139 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@
* limitations under the License.
*/

import groovy.util.*
import org.gradle.api.publish.maven.internal.artifact.*
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.plugin.mpp.*

buildscript {
repositories {
mavenCentral()
Expand All @@ -34,146 +29,14 @@ plugins {
alias(libs.plugins.versionUpdates)
}

configureYarn()

subprojects {
tasks.whenTaskAdded {
if (name.endsWith("test", ignoreCase = true)) onlyIf { !rootProject.hasProperty("skipTests") }
if (name.startsWith("link", ignoreCase = true)) onlyIf { !rootProject.hasProperty("skipLink") }
}

plugins.withId("org.jetbrains.kotlin.multiplatform") {
//targets configuration
extensions.configure<KotlinMultiplatformExtension> {
val isAutoConfigurable = project.name.startsWith("rsocket") //manual config of others
val jvmOnly =
project.name == "rsocket-transport-ktor-server" || //server is jvm only
project.name == "rsocket-test-server"
//windows target isn't supported by ktor-network
val supportMingw =
project.name != "rsocket-transport-ktor" &&
project.name != "rsocket-transport-ktor-client"

val jsOnly = project.name == "rsocket-transport-nodejs-tcp"
val nodejsOnly = project.name == "rsocket-transport-nodejs-tcp"

if (!isAutoConfigurable) return@configure

if (!jsOnly) jvm {
testRuns.all {
executionTask.configure {
// ActiveProcessorCount is used here, to make sure local setup is similar as on CI
// Github Actions linux runners have 2 cores
jvmArgs("-Xmx4g", "-XX:+UseParallelGC", "-XX:ActiveProcessorCount=2")
}
}
}

if (jvmOnly) return@configure

js {
useCommonJs()
//configure running tests for JS
nodejs {
testTask {
useMocha {
timeout = "600s"
}
}
}
if (!nodejsOnly) browser {
testTask {
useKarma {
useConfigDirectory(rootDir.resolve("js").resolve("karma.config.d"))
useChromeHeadless()
}
}
}
}

if (jsOnly) return@configure

//native targets configuration
val linuxTargets = listOf(linuxX64())
val mingwTargets = if (supportMingw) listOf(mingwX64()) else emptyList()
val macosTargets = listOf(macosX64(), macosArm64())
val iosTargets = listOf(iosArm32(), iosArm64(), iosX64(), iosSimulatorArm64())
val tvosTargets = listOf(tvosArm64(), tvosX64(), tvosSimulatorArm64())
val watchosTargets =
listOf(watchosArm32(), watchosArm64(), watchosX86(), watchosX64(), watchosSimulatorArm64())
val darwinTargets = macosTargets + iosTargets + tvosTargets + watchosTargets
val nativeTargets = darwinTargets + linuxTargets + mingwTargets

val nativeMain by sourceSets.creating {
dependsOn(sourceSets["commonMain"])
}
val nativeTest by sourceSets.creating {
dependsOn(sourceSets["commonTest"])
}

nativeTargets.forEach {
sourceSets["${it.name}Main"].dependsOn(nativeMain)
sourceSets["${it.name}Test"].dependsOn(nativeTest)
}

//run tests on release + mimalloc to reduce tests execution time
//compilation is slower in that mode, but work with buffers is much faster
if (System.getenv("CI") == "true") {
targets.all {
if (this is KotlinNativeTargetWithTests<*>) {
binaries.test(listOf(RELEASE))
testRuns.all { setExecutionSourceFrom(binaries.getTest(RELEASE)) }
compilations.all {
kotlinOptions.freeCompilerArgs += "-Xallocator=mimalloc"
}
}
}
}
}

//common configuration
extensions.configure<KotlinMultiplatformExtension> {
val isTestProject = project.name == "rsocket-test" || project.name == "rsocket-test-server"
val isLibProject = project.name.startsWith("rsocket")

sourceSets.all {
languageSettings.apply {
progressiveMode = true

optIn("kotlin.RequiresOptIn")

//TODO: kludge, this is needed now, as ktor isn't fully supports kotlin 1.5.3x opt-in changes
// will be not needed in future with ktor 2.0.0
optIn("io.ktor.utils.io.core.ExperimentalIoApi")

if (name.contains("test", ignoreCase = true) || isTestProject) {
optIn("kotlin.time.ExperimentalTime")
optIn("kotlin.ExperimentalStdlibApi")

optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
optIn("kotlinx.coroutines.InternalCoroutinesApi")
optIn("kotlinx.coroutines.ObsoleteCoroutinesApi")
optIn("kotlinx.coroutines.FlowPreview")
optIn("kotlinx.coroutines.DelicateCoroutinesApi")

optIn("io.ktor.util.InternalAPI")
optIn("io.ktor.utils.io.core.internal.DangerousInternalIoApi")

optIn("io.rsocket.kotlin.TransportApi")
optIn("io.rsocket.kotlin.ExperimentalMetadataApi")
optIn("io.rsocket.kotlin.ExperimentalStreamsApi")
optIn("io.rsocket.kotlin.RSocketLoggingApi")
}
}
}

if (isLibProject && !isTestProject) {
explicitApi()
sourceSets["commonTest"].dependencies {
implementation(projects.rsocketTest)
}
}
}
}

//workaround for https://youtrack.jetbrains.com/issue/KT-44884
configurations.matching { !it.name.startsWith("kotlinCompilerPluginClasspath") }.all {
resolutionStrategy.eachDependency {
Expand Down
20 changes: 20 additions & 0 deletions buildSrc/src/main/kotlin/TargetBuilder.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import org.gradle.api.*
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.plugin.*

class TargetBuilder internal constructor(
private val sourceSets: NamedDomainObjectContainer<KotlinSourceSet>,
private val name: String
) {
fun main(block: KotlinSourceSet.() -> Unit) {
sourceSets.getByName("${name}Main").block()
}

fun test(block: KotlinSourceSet.() -> Unit) {
sourceSets.getByName("${name}Test").block()
}
}

fun KotlinMultiplatformExtension.configureCommon(block: TargetBuilder.() -> Unit) {
TargetBuilder(sourceSets, "common").block()
}
21 changes: 21 additions & 0 deletions buildSrc/src/main/kotlin/TestOptIn.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import org.jetbrains.kotlin.gradle.plugin.*

//TODO may be remove part of annotations
fun LanguageSettingsBuilder.optInForTest() {
optIn("kotlin.time.ExperimentalTime")
optIn("kotlin.ExperimentalStdlibApi")

optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
optIn("kotlinx.coroutines.InternalCoroutinesApi")
optIn("kotlinx.coroutines.ObsoleteCoroutinesApi")
optIn("kotlinx.coroutines.FlowPreview")
optIn("kotlinx.coroutines.DelicateCoroutinesApi")

optIn("io.ktor.util.InternalAPI")
optIn("io.ktor.utils.io.core.internal.DangerousInternalIoApi")

optIn("io.rsocket.kotlin.TransportApi")
optIn("io.rsocket.kotlin.ExperimentalMetadataApi")
optIn("io.rsocket.kotlin.ExperimentalStreamsApi")
optIn("io.rsocket.kotlin.RSocketLoggingApi")
}
4 changes: 4 additions & 0 deletions buildSrc/src/main/kotlin/extensions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import org.gradle.api.*
import org.jetbrains.kotlin.gradle.dsl.*

fun Project.kotlin(configure: Action<KotlinMultiplatformExtension>): Unit = extensions.configure("kotlin", configure)
21 changes: 21 additions & 0 deletions buildSrc/src/main/kotlin/rsocket.multiplatform.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
plugins {
org.jetbrains.kotlin.multiplatform
`kotlinx-atomicfu`
}

kotlin {
sourceSets.all {
languageSettings {
progressiveMode = true

optIn("kotlin.RequiresOptIn")

//TODO: kludge, this is needed now,
// as ktor isn't fully supports kotlin 1.5.3x opt-in changes
// will be not needed after ktor 2.0.0
optIn("io.ktor.utils.io.core.ExperimentalIoApi")

if (name.contains("test", ignoreCase = true)) optInForTest()
}
}
}
16 changes: 16 additions & 0 deletions buildSrc/src/main/kotlin/rsocket.template.library.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
plugins {
id("rsocket.multiplatform")
id("rsocket.publication")
}

kotlin {
explicitApi()

sourceSets {
commonTest {
dependencies {
implementation(project(":rsocket-test"))
}
}
}
}
47 changes: 47 additions & 0 deletions buildSrc/src/main/kotlin/targetsJs.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import org.gradle.api.*
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.targets.js.yarn.*
import java.io.*

enum class JsTarget(
val supportBrowser: Boolean,
val supportNodejs: Boolean
) {
Browser(true, false),
Nodejs(false, true),
Both(true, true)
}

fun KotlinMultiplatformExtension.configureJs(
jsTarget: JsTarget = JsTarget.Both,
block: TargetBuilder.() -> Unit = {}
) {
js {
useCommonJs()

//configure running tests for JS
if (jsTarget.supportBrowser) browser {
testTask {
useKarma {
useConfigDirectory(project.jsDir("karma.config.d"))
useChromeHeadless()
}
}
}
if (jsTarget.supportNodejs) nodejs {
testTask {
useMocha {
timeout = "600s"
}
}
}
}
TargetBuilder(sourceSets, "js").block()
}

//should be called only in root project
fun Project.configureYarn() {
yarn.lockFileDirectory = project.jsDir("yarn")
}

private fun Project.jsDir(folder: String): File = rootDir.resolve("gradle").resolve("js").resolve(folder)
14 changes: 14 additions & 0 deletions buildSrc/src/main/kotlin/targetsJvm.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import org.jetbrains.kotlin.gradle.dsl.*

fun KotlinMultiplatformExtension.configureJvm(block: TargetBuilder.() -> Unit = {}) {
jvm {
testRuns.all {
executionTask.configure {
// ActiveProcessorCount is used here, to make sure local setup is similar as on CI
// Github Actions linux runners have 2 cores
jvmArgs("-Xmx4g", "-XX:ActiveProcessorCount=2")
}
}
}
TargetBuilder(sourceSets, "jvm").block()
}
60 changes: 60 additions & 0 deletions buildSrc/src/main/kotlin/targetsNative.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import org.gradle.kotlin.dsl.*
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.plugin.mpp.*

enum class NativeTargets {
Posix,
Nix,
Darwin
}

fun KotlinMultiplatformExtension.configureNative(
nativeTargets: NativeTargets = NativeTargets.Posix,
block: TargetBuilder.() -> Unit = {}
) {
val nativeMain by sourceSets.creating {
dependsOn(sourceSets["commonMain"])
}
val nativeTest by sourceSets.creating {
dependsOn(sourceSets["commonTest"])
}

when (nativeTargets) {
NativeTargets.Posix -> posixTargets()
NativeTargets.Nix -> nixTargets()
NativeTargets.Darwin -> darwinTargets()
}.forEach {
sourceSets["${it.name}Main"].dependsOn(nativeMain)
sourceSets["${it.name}Test"].dependsOn(nativeTest)
}

targets.all {
//add another test task with release binary
if (this is KotlinNativeTargetWithTests<*>) {
binaries.test(listOf(NativeBuildType.RELEASE))
val releaseTest by testRuns.creating {
setExecutionSourceFrom(binaries.getTest(NativeBuildType.RELEASE))
}
}
}

TargetBuilder(sourceSets, "native").block()
}

private fun KotlinMultiplatformExtension.darwinTargets(): List<KotlinNativeTarget> {
val macosTargets = listOf(macosX64(), macosArm64())
val iosTargets = listOf(iosArm32(), iosArm64(), iosX64(), iosSimulatorArm64())
val tvosTargets = listOf(tvosArm64(), tvosX64(), tvosSimulatorArm64())
val watchosTargets = listOf(watchosArm32(), watchosArm64(), watchosX86(), watchosX64(), watchosSimulatorArm64())
return macosTargets + iosTargets + tvosTargets + watchosTargets
}

//ktor network supports only jvm and nix targets, but not mingw
private fun KotlinMultiplatformExtension.nixTargets(): List<KotlinNativeTarget> {
return darwinTargets() + linuxX64()
}

//rsocket core and local transport supports all native targets, that are supported by ktor-io and kotlinx-coroutines
private fun KotlinMultiplatformExtension.posixTargets(): List<KotlinNativeTarget> {
return nixTargets() + mingwX64()
}
File renamed without changes.
Loading

0 comments on commit e76d8f5

Please sign in to comment.