Skip to content

Commit 8414954

Browse files
elizarovqwwdfsad
authored andcommitted
Refactor mpp/native build, introduce "concurrent" source set, test launcher
New source sets: * "concurrent" source set is shared between "jvm" and "native" * "native" source set is subdivided into "nativeDarwin" (Apple) and "nativeOther" (Linux, etc) Native tests are launched in two variants: * A default "test" task runs tests with memory leak checker from "mainNoExit" entry point. * A special "backgroundTest" task runs tests in a background worker from "mainBackground" entry point. Other build improvement: * Modernize old-style IDEA-active hacks to kts helper. * Extract versions of JS test runner dependencies. * Remove redundant google repo reference from android tests.
1 parent 9d79f33 commit 8414954

File tree

13 files changed

+209
-73
lines changed

13 files changed

+209
-73
lines changed

build.gradle

+2-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ buildscript {
8787
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
8888

8989
// Hierarchical project structures are not fully supported in 1.3.7x MPP, enable conditionally for 1.4.x
90-
if (VersionNumber.parse(kotlin_version) > VersionNumber.parse("1.3.79")) {
90+
// Also enable it in IDEA to properly import project structure
91+
if (Idea.active || VersionNumber.parse(kotlin_version) > VersionNumber.parse("1.3.79")) {
9192
ext.set("kotlin.mpp.enableGranularSourceSetsMetadata", "true")
9293
}
9394

buildSrc/src/main/kotlin/Idea.kt

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
object Idea {
2+
@JvmStatic // for Gradle
23
val active: Boolean
34
get() = System.getProperty("idea.active") == "true"
45
}

gradle.properties

+5-3
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@ kotlin.js.compiler=both
3636
gradle_node_version=1.2.0
3737
node_version=8.9.3
3838
npm_version=5.7.1
39-
mocha_version=4.1.0
39+
mocha_version=6.2.2
4040
mocha_headless_chrome_version=1.8.2
41-
mocha_teamcity_reporter_version=2.2.2
42-
source_map_support_version=0.5.3
41+
mocha_teamcity_reporter_version=3.0.0
42+
source_map_support_version=0.5.16
43+
jsdom_version=15.2.1
44+
jsdom_global_version=3.0.2
4345

4446
# Settings
4547
kotlin.incremental.multiplatform=true

gradle/compile-native-multiplatform.gradle

+14-26
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,24 @@ kotlin {
1313
}
1414

1515
targets {
16-
if (project.ext.ideaActive) {
17-
fromPreset(project.ext.ideaPreset, 'native')
18-
} else {
19-
addTarget(presets.linuxX64)
20-
addTarget(presets.iosArm64)
21-
addTarget(presets.iosArm32)
22-
addTarget(presets.iosX64)
23-
addTarget(presets.macosX64)
24-
addTarget(presets.mingwX64)
25-
addTarget(presets.tvosArm64)
26-
addTarget(presets.tvosX64)
27-
addTarget(presets.watchosArm32)
28-
addTarget(presets.watchosArm64)
29-
addTarget(presets.watchosX86)
30-
}
16+
addTarget(presets.linuxX64)
17+
addTarget(presets.iosArm64)
18+
addTarget(presets.iosArm32)
19+
addTarget(presets.iosX64)
20+
addTarget(presets.macosX64)
21+
addTarget(presets.mingwX64)
22+
addTarget(presets.tvosArm64)
23+
addTarget(presets.tvosX64)
24+
addTarget(presets.watchosArm32)
25+
addTarget(presets.watchosArm64)
26+
addTarget(presets.watchosX86)
3127
}
3228

3329
sourceSets {
3430
nativeMain { dependsOn commonMain }
35-
// Empty source set is required in order to have native tests task
36-
nativeTest {}
31+
nativeTest { dependsOn commonTest }
3732

38-
if (!project.ext.ideaActive) {
39-
configure(nativeMainSets) {
40-
dependsOn nativeMain
41-
}
42-
43-
configure(nativeTestSets) {
44-
dependsOn nativeTest
45-
}
46-
}
33+
configure(nativeMainSets) { dependsOn nativeMain }
34+
configure(nativeTestSets) { dependsOn nativeTest }
4735
}
4836
}

gradle/targets.gradle

-28
This file was deleted.

gradle/test-mocha-js.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ task testMochaChrome(type: NodeTask, dependsOn: prepareMochaChrome) {
8686
task installDependenciesMochaJsdom(type: NpmTask, dependsOn: [npmInstall]) {
8787
args = ['install',
8888
"mocha@$mocha_version",
89-
'jsdom@15.2.1',
90-
'jsdom-global@3.0.2',
89+
"jsdom@$jsdom_version",
90+
"jsdom-global@$jsdom_global_version",
9191
"source-map-support@$source_map_support_version",
9292
'--no-save']
9393
if (project.hasProperty("teamcity")) args += ["mocha-teamcity-reporter@$mocha_teamcity_reporter_version"]

kotlinx-coroutines-core/build.gradle

+107-9
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,60 @@
33
*/
44

55
apply plugin: 'kotlin-multiplatform'
6-
apply from: rootProject.file("gradle/targets.gradle")
76
apply from: rootProject.file("gradle/compile-jvm-multiplatform.gradle")
87
apply from: rootProject.file("gradle/compile-common.gradle")
98
apply from: rootProject.file("gradle/compile-js-multiplatform.gradle")
109
apply from: rootProject.file("gradle/compile-native-multiplatform.gradle")
1110
apply from: rootProject.file('gradle/publish-npm-js.gradle')
1211

12+
/* ==========================================================================
13+
Configure source sets structure for kotlinx-coroutines-core:
14+
15+
TARGETS SOURCE SETS
16+
------- ----------------------------------------------
17+
18+
js -----------------------------------------------------+
19+
|
20+
V
21+
jvm -------------------------------> concurrent ---> common
22+
^
23+
ios \ |
24+
macos | ---> nativeDarwin ---> native --+
25+
tvos | ^
26+
watchos / |
27+
|
28+
linux \ ---> nativeOther -------+
29+
mingw /
30+
31+
========================================================================== */
32+
33+
project.ext.sourceSetSuffixes = ["Main", "Test"]
34+
35+
void defineSourceSet(newName, dependsOn, includedInPred) {
36+
for (suffix in project.ext.sourceSetSuffixes) {
37+
def newSS = kotlin.sourceSets.maybeCreate(newName + suffix)
38+
for (dep in dependsOn) {
39+
newSS.dependsOn(kotlin.sourceSets[dep + suffix])
40+
}
41+
for (curSS in kotlin.sourceSets) {
42+
def curName = curSS.name
43+
if (curName.endsWith(suffix)) {
44+
def prefix = curName.substring(0, curName.length() - suffix.length())
45+
if (includedInPred(prefix)) curSS.dependsOn(newSS)
46+
}
47+
}
48+
}
49+
}
50+
51+
static boolean isNativeDarwin(String name) { return ["ios", "macos", "tvos", "watchos"].any { name.startsWith(it) } }
52+
static boolean isNativeOther(String name) { return ["linux", "mingw"].any { name.startsWith(it) } }
53+
54+
defineSourceSet("concurrent", ["common"]) { it in ["jvm", "native"] }
55+
defineSourceSet("nativeDarwin", ["native"]) { isNativeDarwin(it) }
56+
defineSourceSet("nativeOther", ["native"]) { isNativeOther(it) }
57+
58+
/* ========================================================================== */
59+
1360
/*
1461
* All platform plugins and configuration magic happens here instead of build.gradle
1562
* because JMV-only projects depend on core, thus core should always be initialized before configuration.
@@ -18,7 +65,7 @@ kotlin {
1865
configure(sourceSets) {
1966
def srcDir = name.endsWith('Main') ? 'src' : 'test'
2067
def platform = name[0..-5]
21-
kotlin.srcDir "$platform/$srcDir"
68+
kotlin.srcDirs = ["$platform/$srcDir"]
2269
if (name == "jvmMain") {
2370
resources.srcDirs = ["$platform/resources"]
2471
} else if (name == "jvmTest") {
@@ -31,12 +78,18 @@ kotlin {
3178
}
3279

3380
configure(targets) {
34-
def targetName = it.name
35-
compilations.all { compilation ->
36-
def compileTask = tasks.getByName(compilation.compileKotlinTaskName)
37-
// binary compatibility support
38-
if (targetName.contains("jvm") && compilation.compilationName == "main") {
39-
compileTask.kotlinOptions.freeCompilerArgs += ["-Xdump-declarations-to=${buildDir}/visibilities.json"]
81+
// Configure additional binaries and test runs -- one for each OS
82+
if (["macos", "linux", "mingw"].any { name.startsWith(it) }) {
83+
binaries {
84+
// Test for memory leaks using a special entry point that does not exit but returns from main
85+
binaries.getTest("DEBUG").freeCompilerArgs += ["-e", "kotlinx.coroutines.mainNoExit"]
86+
// Configure a separate test where code runs in background
87+
test("background", [org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType.DEBUG]) {
88+
freeCompilerArgs += ["-e", "kotlinx.coroutines.mainBackground"]
89+
}
90+
}
91+
testRuns {
92+
background { setExecutionSourceFrom(binaries.backgroundDebugTest) }
4093
}
4194
}
4295
}
@@ -54,6 +107,51 @@ compileKotlinMetadata {
54107
}
55108
}
56109

110+
// :KLUDGE: Idea.active: This is needed to workaround resolve problems after importing this project to IDEA
111+
def configureNativeSourceSetPreset(name, preset) {
112+
def hostMainCompilation = project.kotlin.targetFromPreset(preset).compilations.main
113+
// Kotlin 1.3.x: Look for platform libraries in "compile" configuration
114+
def compileConfiguration = configurations[hostMainCompilation.compileDependencyConfigurationName]
115+
// Kotlin 1.4.x: Look for platform libraries in "implementation" for default source set
116+
def implementationConfiguration = configurations[hostMainCompilation.defaultSourceSet.implementationMetadataConfigurationName]
117+
// Now find the libraries:
118+
// Kotlin 1.3.x: Find all platform libs
119+
// Kotlin 1.4.x: Finds platform lib & stdlib, but platform declarations are still not resolved due to IDE bugs
120+
def hostNativePlatformLibs = files(
121+
provider {
122+
compileConfiguration.findAll {
123+
it.path.endsWith(".klib") || it.absolutePath.contains("klib${File.separator}platform")
124+
}
125+
},
126+
provider {
127+
implementationConfiguration.findAll {
128+
it.path.endsWith(".klib") || it.absolutePath.contains("klib${File.separator}platform") || it.absolutePath.contains("stdlib")
129+
}
130+
}
131+
)
132+
// Add all those dependencies
133+
for (suffix in sourceSetSuffixes) {
134+
configure(kotlin.sourceSets[name + suffix]) {
135+
dependencies.add(implementationMetadataConfigurationName, hostNativePlatformLibs)
136+
}
137+
}
138+
}
139+
140+
// :KLUDGE: Idea.active: Configure platform libraries for native source sets when working in IDEA
141+
if (Idea.active) {
142+
def manager = project.ext.hostManager
143+
def linuxPreset = kotlin.presets.linuxX64
144+
def macosPreset = kotlin.presets.macosX64
145+
// linux should be always available (cross-compilation capable) -- use it as default
146+
assert manager.isEnabled(linuxPreset.konanTarget)
147+
// use macOS libs for nativeDarwin if available
148+
def macosAvailable = manager.isEnabled(macosPreset.konanTarget)
149+
// configure source sets
150+
configureNativeSourceSetPreset("native", linuxPreset)
151+
configureNativeSourceSetPreset("nativeOther", linuxPreset)
152+
configureNativeSourceSetPreset("nativeDarwin", macosAvailable ? macosPreset : linuxPreset)
153+
}
154+
57155
kotlin.sourceSets {
58156
jvmMain.dependencies {
59157
compileOnly "com.google.android:annotations:4.1.1.4"
@@ -97,7 +195,7 @@ jvmTest {
97195
enableAssertions = true
98196
systemProperty 'java.security.manager', 'kotlinx.coroutines.TestSecurityManager'
99197
// 'stress' is required to be able to run all subpackage tests like ":jvmTests --tests "*channels*" -Pstress=true"
100-
if (!project.ext.ideaActive && rootProject.properties['stress'] == null) {
198+
if (!Idea.active && rootProject.properties['stress'] == null) {
101199
exclude '**/*StressTest.*'
102200
}
103201
systemProperty 'kotlinx.coroutines.scheduler.keep.alive.sec', '100000' // any unpark problem hangs test
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/*
2+
* Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package kotlinx.coroutines
6+
7+
internal expect inline fun workerMain(block: () -> Unit)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*
2+
* Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package kotlinx.coroutines
6+
7+
import kotlinx.cinterop.*
8+
9+
internal actual inline fun workerMain(block: () -> Unit) {
10+
autoreleasepool {
11+
block()
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package kotlinx.coroutines
6+
7+
import platform.CoreFoundation.*
8+
import kotlin.native.concurrent.*
9+
import kotlin.native.internal.test.*
10+
import kotlin.system.*
11+
12+
// This is a separate entry point for tests in background
13+
fun mainBackground(args: Array<String>) {
14+
val worker = Worker.start(name = "main-background")
15+
worker.execute(TransferMode.SAFE, { args.freeze() }) {
16+
val result = testLauncherEntryPoint(it)
17+
exitProcess(result)
18+
}
19+
CFRunLoopRun()
20+
error("CFRunLoopRun should never return")
21+
}
22+
23+
// This is a separate entry point for tests with leak checker
24+
fun mainNoExit(args: Array<String>) {
25+
workerMain { // autoreleasepool to make sure interop objects are properly freed
26+
testLauncherEntryPoint(args)
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/*
2+
* Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package kotlinx.coroutines
6+
7+
internal actual inline fun workerMain(block: () -> Unit) = block()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package kotlinx.coroutines
6+
7+
import kotlin.native.concurrent.*
8+
import kotlin.native.internal.test.*
9+
import kotlin.system.*
10+
11+
// This is a separate entry point for tests in background
12+
fun mainBackground(args: Array<String>) {
13+
val worker = Worker.start(name = "main-background")
14+
worker.execute(TransferMode.SAFE, { args.freeze() }) {
15+
val result = testLauncherEntryPoint(it)
16+
exitProcess(result)
17+
}.result // block main thread
18+
}
19+
20+
// This is a separate entry point for tests with leak checker
21+
fun mainNoExit(args: Array<String>) {
22+
testLauncherEntryPoint(args)
23+
}

ui/kotlinx-coroutines-android/build.gradle.kts

-4
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink
66
import org.jetbrains.dokka.gradle.DokkaTask
77
import java.net.URL
88

9-
repositories {
10-
google()
11-
}
12-
139
configurations {
1410
create("r8")
1511
}

0 commit comments

Comments
 (0)