/* * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ apply plugin: 'org.jetbrains.kotlin.multiplatform' apply from: rootProject.file("gradle/compile-jvm-multiplatform.gradle") apply from: rootProject.file("gradle/compile-common.gradle") apply from: rootProject.file("gradle/compile-js-multiplatform.gradle") apply from: rootProject.file("gradle/compile-native-multiplatform.gradle") apply from: rootProject.file('gradle/publish-npm-js.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"] } 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 { configure(sourceSets) { def srcDir = name.endsWith('Main') ? 'src' : 'test' def platform = name[0..-5] kotlin.srcDirs = ["$platform/$srcDir"] if (name == "jvmMain") { resources.srcDirs = ["$platform/resources"] } else if (name == "jvmTest") { resources.srcDirs = ["$platform/test-resources"] } languageSettings { progressiveMode = true experimentalAnnotations.each { useExperimentalAnnotation(it) } } } configure(targets) { // Configure additional binaries and test runs -- one for each OS if (["macos", "linux", "mingw"].any { name.startsWith(it) }) { 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"] // Configure a separate test where code runs in background test("background", [org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType.DEBUG]) { freeCompilerArgs += ["-e", "kotlinx.coroutines.mainBackground"] } } testRuns { background { setExecutionSourceFrom(binaries.backgroundDebugTest) } } } } } 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) { 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" api "com.esotericsoftware:kryo:4.0.0" implementation project(":android-unit-tests") } } task checkJdk16() { // only fail w/o JDK_16 when actually trying to compile, not during project setup phase doLast { if (!System.env.JDK_16) { throw new GradleException("JDK_16 environment variable is not defined. " + "Can't build against JDK 1.6 runtime and run JDK 1.6 compatibility tests. " + "Please ensure JDK 1.6 is installed and that JDK_16 points to it.") } } } tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) { kotlinOptions.jdkHome = System.env.JDK_16 // only fail when actually trying to compile, not during project setup phase dependsOn(checkJdk16) } jvmTest { minHeapSize = '1g' maxHeapSize = '1g' enableAssertions = true 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 '**/*StressTest.*' } systemProperty 'kotlinx.coroutines.scheduler.keep.alive.sec', '100000' // any unpark problem hangs test } jvmJar { 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 jdk16Test(type: Test, dependsOn: [compileTestKotlinJvm, checkJdk16]) { classpath = files { jvmTest.classpath } testClassesDirs = files { jvmTest.testClassesDirs } executable = "$System.env.JDK_16/bin/java" exclude '**/*LFStressTest.*' // lock-freedom tests use LockFreedomTestEnvironment which needs JDK8 exclude '**/*LCStressTest.*' // lin-check tests use LinChecker which needs JDK8 exclude '**/exceptions/**' // exceptions tests check suppressed exception which needs JDK8 exclude '**/ExceptionsGuideTest.*' exclude '**/RunInterruptibleStressTest.*' // fails on JDK 1.6 due to JDK bug } // Run these tests only during nightly stress test jdk16Test.onlyIf { project.properties['stressTest'] != null } // Always run those tests task moreTest(dependsOn: [jvmStressTest, jdk16Test]) build.dependsOn moreTest task testsJar(type: Jar, dependsOn: jvmTestClasses) { classifier = 'tests' from compileTestKotlinJvm.destinationDir } artifacts { archives testsJar }