299 lines
12 KiB
Groovy
299 lines
12 KiB
Groovy
/*
|
|
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
|
|
*/
|
|
|
|
apply plugin: 'org.jetbrains.kotlin.multiplatform'
|
|
apply plugin: 'org.jetbrains.dokka'
|
|
apply from: rootProject.file("gradle/compile-jvm-multiplatform.gradle")
|
|
apply from: rootProject.file("gradle/compile-common.gradle")
|
|
|
|
if (rootProject.ext.native_targets_enabled) {
|
|
apply from: rootProject.file("gradle/compile-native-multiplatform.gradle")
|
|
}
|
|
|
|
apply from: rootProject.file("gradle/compile-js-multiplatform.gradle")
|
|
apply from: rootProject.file('gradle/publish-npm-js.gradle')
|
|
|
|
apply from: rootProject.file('gradle/dokka.gradle.kts')
|
|
apply from: rootProject.file('gradle/publish.gradle')
|
|
/* ==========================================================================
|
|
Configure source sets structure for kotlinx-coroutines-core:
|
|
|
|
TARGETS SOURCE SETS
|
|
------- ----------------------------------------------
|
|
|
|
js -----------------------------------------------------+
|
|
|
|
|
V
|
|
jvm -------------------------------> concurrent ---> common
|
|
^
|
|
ios \ |
|
|
macos | ---> nativeDarwin ---> native --+
|
|
tvos | ^
|
|
watchos / |
|
|
|
|
|
linux \ ---> nativeOther -------+
|
|
mingw /
|
|
|
|
========================================================================== */
|
|
|
|
project.ext.sourceSetSuffixes = ["Main", "Test"]
|
|
|
|
void defineSourceSet(newName, dependsOn, includedInPred) {
|
|
for (suffix in project.ext.sourceSetSuffixes) {
|
|
def newSS = kotlin.sourceSets.maybeCreate(newName + suffix)
|
|
for (dep in dependsOn) {
|
|
newSS.dependsOn(kotlin.sourceSets[dep + suffix])
|
|
}
|
|
for (curSS in kotlin.sourceSets) {
|
|
def curName = curSS.name
|
|
if (curName.endsWith(suffix)) {
|
|
def prefix = curName.substring(0, curName.length() - suffix.length())
|
|
if (includedInPred(prefix)) curSS.dependsOn(newSS)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static boolean isNativeDarwin(String name) { return ["ios", "macos", "tvos", "watchos"].any { name.startsWith(it) } }
|
|
static boolean isNativeOther(String name) { return ["linux", "mingw"].any { name.startsWith(it) } }
|
|
|
|
defineSourceSet("concurrent", ["common"]) { it in ["jvm", "native"] }
|
|
|
|
if (rootProject.ext.native_targets_enabled) {
|
|
defineSourceSet("nativeDarwin", ["native"]) { isNativeDarwin(it) }
|
|
defineSourceSet("nativeOther", ["native"]) { isNativeOther(it) }
|
|
}
|
|
|
|
/* ========================================================================== */
|
|
|
|
/*
|
|
* All platform plugins and configuration magic happens here instead of build.gradle
|
|
* because JMV-only projects depend on core, thus core should always be initialized before configuration.
|
|
*/
|
|
kotlin {
|
|
sourceSets.forEach {
|
|
SourceSetsKt.configureMultiplatform(it)
|
|
}
|
|
|
|
/*
|
|
* Configure four test runs:
|
|
* 1) Old memory model, Main thread
|
|
* 2) New memory model, Main thread
|
|
* 3) Old memory model, BG thread
|
|
* 4) New memory model, BG thread (required for Dispatchers.Main tests on Darwin)
|
|
*
|
|
* All new MM targets are build with optimize = true to have stress tests properly run.
|
|
*/
|
|
targets.withType(org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTargetWithTests.class).configureEach {
|
|
binaries {
|
|
// Test for memory leaks using a special entry point that does not exit but returns from main
|
|
binaries.getTest("DEBUG").freeCompilerArgs += ["-e", "kotlinx.coroutines.mainNoExit"]
|
|
}
|
|
|
|
binaries.test("newMM", [DEBUG]) {
|
|
def thisTest = it
|
|
freeCompilerArgs += ["-e", "kotlinx.coroutines.mainNoExit"]
|
|
optimized = true
|
|
binaryOptions["memoryModel"] = "experimental"
|
|
testRuns.create("newMM") {
|
|
setExecutionSourceFrom(thisTest)
|
|
// A hack to get different suffixes in the aggregated report.
|
|
executionTask.configure { targetName = "$targetName new MM" }
|
|
}
|
|
}
|
|
|
|
binaries.test("worker", [DEBUG]) {
|
|
def thisTest = it
|
|
freeCompilerArgs += ["-e", "kotlinx.coroutines.mainBackground"]
|
|
testRuns.create("worker") {
|
|
setExecutionSourceFrom(thisTest)
|
|
executionTask.configure { targetName = "$targetName worker" }
|
|
}
|
|
}
|
|
|
|
binaries.test("workerWithNewMM", [DEBUG]) {
|
|
def thisTest = it
|
|
optimized = true
|
|
freeCompilerArgs += ["-e", "kotlinx.coroutines.mainBackground"]
|
|
binaryOptions["memoryModel"] = "experimental"
|
|
testRuns.create("workerWithNewMM") {
|
|
setExecutionSourceFrom(thisTest)
|
|
executionTask.configure { targetName = "$targetName worker with new MM" }
|
|
}
|
|
}
|
|
}
|
|
|
|
jvm {
|
|
// For animal sniffer
|
|
withJava()
|
|
}
|
|
}
|
|
|
|
|
|
configurations {
|
|
configureKotlinJvmPlatform(kotlinCompilerPluginClasspath)
|
|
}
|
|
|
|
// Update module name for metadata artifact to avoid conflicts
|
|
// see https://github.com/Kotlin/kotlinx.coroutines/issues/1797
|
|
compileKotlinMetadata {
|
|
kotlinOptions {
|
|
freeCompilerArgs += ["-module-name", "kotlinx-coroutines-core-common"]
|
|
}
|
|
}
|
|
|
|
// :KLUDGE: Idea.active: This is needed to workaround resolve problems after importing this project to IDEA
|
|
def configureNativeSourceSetPreset(name, preset) {
|
|
def hostMainCompilation = project.kotlin.targetFromPreset(preset).compilations.main
|
|
// Look for platform libraries in "implementation" for default source set
|
|
def implementationConfiguration = configurations[hostMainCompilation.defaultSourceSet.implementationMetadataConfigurationName]
|
|
// Now find the libraries: Finds platform libs & stdlib, but platform declarations are still not resolved due to IDE bugs
|
|
def hostNativePlatformLibs = files(
|
|
provider {
|
|
implementationConfiguration.findAll {
|
|
it.path.endsWith(".klib") || it.absolutePath.contains("klib${File.separator}platform") || it.absolutePath.contains("stdlib")
|
|
}
|
|
}
|
|
)
|
|
// Add all those dependencies
|
|
for (suffix in sourceSetSuffixes) {
|
|
configure(kotlin.sourceSets[name + suffix]) {
|
|
dependencies.add(implementationMetadataConfigurationName, hostNativePlatformLibs)
|
|
}
|
|
}
|
|
}
|
|
|
|
// :KLUDGE: Idea.active: Configure platform libraries for native source sets when working in IDEA
|
|
if (Idea.active && rootProject.ext.native_targets_enabled) {
|
|
def manager = project.ext.hostManager
|
|
def linuxPreset = kotlin.presets.linuxX64
|
|
def macosPreset = kotlin.presets.macosX64
|
|
// linux should be always available (cross-compilation capable) -- use it as default
|
|
assert manager.isEnabled(linuxPreset.konanTarget)
|
|
// use macOS libs for nativeDarwin if available
|
|
def macosAvailable = manager.isEnabled(macosPreset.konanTarget)
|
|
// configure source sets
|
|
configureNativeSourceSetPreset("native", linuxPreset)
|
|
configureNativeSourceSetPreset("nativeOther", linuxPreset)
|
|
configureNativeSourceSetPreset("nativeDarwin", macosAvailable ? macosPreset : linuxPreset)
|
|
}
|
|
|
|
kotlin.sourceSets {
|
|
jvmMain.dependencies {
|
|
compileOnly "com.google.android:annotations:4.1.1.4"
|
|
}
|
|
|
|
jvmTest.dependencies {
|
|
api "org.jetbrains.kotlinx:lincheck:$lincheck_version"
|
|
api "org.jetbrains.kotlinx:kotlinx-knit-test:$knit_version"
|
|
implementation project(":android-unit-tests")
|
|
}
|
|
}
|
|
|
|
jvmTest {
|
|
minHeapSize = '1g'
|
|
maxHeapSize = '1g'
|
|
enableAssertions = true
|
|
if (!Idea.active) {
|
|
// We should not set this security manager when `jvmTest`
|
|
// is invoked by IntelliJ IDEA since we need to pass
|
|
// system properties for Lincheck and stress tests.
|
|
// TODO Remove once IDEA is smart enough to select between `jvmTest`/`jvmStressTest`/`jvmLincheckTest` #KTIJ-599
|
|
systemProperty 'java.security.manager', 'kotlinx.coroutines.TestSecurityManager'
|
|
}
|
|
// 'stress' is required to be able to run all subpackage tests like ":jvmTests --tests "*channels*" -Pstress=true"
|
|
if (!Idea.active && rootProject.properties['stress'] == null) {
|
|
exclude '**/*LincheckTest.*'
|
|
exclude '**/*StressTest.*'
|
|
}
|
|
if (Idea.active) {
|
|
// Configure the IDEA runner for Lincheck
|
|
configureJvmForLincheck(jvmTest)
|
|
}
|
|
}
|
|
|
|
// Setup manifest for kotlinx-coroutines-core-jvm.jar
|
|
jvmJar { setupManifest(it) }
|
|
|
|
/*
|
|
* Setup manifest for kotlinx-coroutines-core.jar
|
|
* This is convenient for users that pass -javaagent arg manually and also is a workaround #2619 and KTIJ-5659.
|
|
* This manifest contains reference to AgentPremain that belongs to
|
|
* kotlinx-coroutines-core-jvm, but our resolving machinery guarantees that
|
|
* any JVM project that depends on -core artifact also depends on -core-jvm one.
|
|
*/
|
|
metadataJar { setupManifest(it) }
|
|
|
|
static def setupManifest(Jar jar) {
|
|
jar.manifest {
|
|
attributes "Premain-Class": "kotlinx.coroutines.debug.AgentPremain"
|
|
attributes "Can-Retransform-Classes": "true"
|
|
}
|
|
}
|
|
|
|
task jvmStressTest(type: Test, dependsOn: compileTestKotlinJvm) {
|
|
classpath = files { jvmTest.classpath }
|
|
testClassesDirs = files { jvmTest.testClassesDirs }
|
|
minHeapSize = '1g'
|
|
maxHeapSize = '1g'
|
|
include '**/*StressTest.*'
|
|
enableAssertions = true
|
|
testLogging.showStandardStreams = true
|
|
systemProperty 'kotlinx.coroutines.scheduler.keep.alive.sec', '100000' // any unpark problem hangs test
|
|
systemProperty 'kotlinx.coroutines.semaphore.segmentSize', '2'
|
|
systemProperty 'kotlinx.coroutines.semaphore.maxSpinCycles', '10'
|
|
}
|
|
|
|
task jvmLincheckTest(type: Test, dependsOn: compileTestKotlinJvm) {
|
|
classpath = files { jvmTest.classpath }
|
|
testClassesDirs = files { jvmTest.testClassesDirs }
|
|
include '**/*LincheckTest.*'
|
|
enableAssertions = true
|
|
testLogging.showStandardStreams = true
|
|
configureJvmForLincheck(jvmLincheckTest)
|
|
}
|
|
|
|
static void configureJvmForLincheck(task) {
|
|
task.minHeapSize = '1g'
|
|
task.maxHeapSize = '4g' // we may need more space for building an interleaving tree in the model checking mode
|
|
task.jvmArgs = ['--add-opens', 'java.base/jdk.internal.misc=ALL-UNNAMED', // required for transformation
|
|
'--add-exports', 'java.base/jdk.internal.util=ALL-UNNAMED'] // in the model checking mode
|
|
task.systemProperty 'kotlinx.coroutines.semaphore.segmentSize', '2'
|
|
task.systemProperty 'kotlinx.coroutines.semaphore.maxSpinCycles', '1' // better for the model checking mode
|
|
}
|
|
|
|
// Always check additional test sets
|
|
task moreTest(dependsOn: [jvmStressTest, jvmLincheckTest])
|
|
check.dependsOn moreTest
|
|
|
|
tasks.jvmLincheckTest {
|
|
kover {
|
|
enabled = false // Always disabled, lincheck doesn't really support coverage
|
|
}
|
|
}
|
|
|
|
def commonKoverExcludes =
|
|
["kotlinx.coroutines.debug.*", // Tested by debug module
|
|
"kotlinx.coroutines.channels.ChannelsKt__DeprecatedKt.*", // Deprecated
|
|
"kotlinx.coroutines.scheduling.LimitingDispatcher", // Deprecated
|
|
"kotlinx.coroutines.scheduling.ExperimentalCoroutineDispatcher" // Deprecated
|
|
]
|
|
|
|
tasks.koverHtmlReport {
|
|
excludes = commonKoverExcludes
|
|
}
|
|
|
|
tasks.koverVerify {
|
|
excludes = commonKoverExcludes
|
|
}
|
|
|
|
task testsJar(type: Jar, dependsOn: jvmTestClasses) {
|
|
classifier = 'tests'
|
|
from compileTestKotlinJvm.destinationDir
|
|
}
|
|
|
|
artifacts {
|
|
archives testsJar
|
|
}
|