1/* 2 * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 5import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile 6 7apply plugin: 'kotlin-multiplatform' 8apply from: rootProject.file("gradle/targets.gradle") 9 10ext { 11 nativeMainSets = [] 12 nativeTestSets = [] 13 nativeCompilations = [] 14 15 addNative = { preset -> 16 nativeMainSets.add(preset.compilations['main'].kotlinSourceSets.first()) 17 nativeTestSets.add(preset.compilations['test'].kotlinSourceSets.first()) 18 nativeCompilations.add(preset.compilations['main']) 19 } 20} 21 22 23kotlin { 24 targets { 25 delegate.metaClass.addTarget = { preset -> 26 addNative(delegate.fromPreset(preset, preset.name)) 27 } 28 } 29 30 // JS -- always 31 js(IR) { 32 moduleName = "kotlinx-atomicfu" 33 // TODO: commented out because browser tests do not work on TeamCity 34 // browser() 35 nodejs() 36 } 37 38 // JVM -- always 39 jvm() 40 41 // Wasm -- always 42 wasmJs { 43 nodejs() 44 } 45 46 wasmWasi { 47 nodejs() 48 } 49 50 sourceSets { 51 commonMain { 52 dependencies { 53 implementation 'org.jetbrains.kotlin:kotlin-stdlib-common' 54 } 55 } 56 commonTest { 57 dependencies { 58 implementation 'org.jetbrains.kotlin:kotlin-test-common' 59 implementation 'org.jetbrains.kotlin:kotlin-test-annotations-common' 60 } 61 } 62 63 jsAndWasmSharedMain { 64 dependsOn(sourceSets.commonMain) 65 } 66 67 jsMain { 68 dependsOn(sourceSets.jsAndWasmSharedMain) 69 dependencies { 70 implementation 'org.jetbrains.kotlin:kotlin-stdlib-js' 71 } 72 } 73 jsTest { 74 dependencies { 75 implementation 'org.jetbrains.kotlin:kotlin-test-js' 76 } 77 } 78 79 wasmJsMain { 80 dependsOn(sourceSets.jsAndWasmSharedMain) 81 dependencies { 82 implementation 'org.jetbrains.kotlin:kotlin-stdlib-wasm-js' 83 } 84 } 85 86 wasmJsTest { 87 dependencies { 88 implementation 'org.jetbrains.kotlin:kotlin-test-wasm-js' 89 } 90 } 91 92 wasmWasiMain { 93 dependsOn(sourceSets.jsAndWasmSharedMain) 94 dependencies { 95 implementation 'org.jetbrains.kotlin:kotlin-stdlib-wasm-wasi' 96 } 97 } 98 wasmWasiTest { 99 dependencies { 100 implementation 'org.jetbrains.kotlin:kotlin-test-wasm-wasi' 101 } 102 } 103 104 jvmMain { 105 dependencies { 106 implementation 'org.jetbrains.kotlin:kotlin-stdlib' 107 } 108 } 109 jvmTest { 110 dependencies { 111 implementation 'org.jetbrains.kotlin:kotlin-reflect' 112 implementation 'org.jetbrains.kotlin:kotlin-test' 113 implementation 'org.jetbrains.kotlin:kotlin-test-junit' 114 implementation "junit:junit:$junit_version" 115 } 116 } 117 } 118} 119 120// configure native targets only if they're not disabled 121if (rootProject.ext.native_targets_enabled) { 122 kotlin { 123 targets { 124 if (project.ext.ideaActive) { 125 addNative(fromPreset(project.ext.ideaPreset, 'native')) 126 } else { 127 // Support of all non-deprecated targets from official tier list: https://kotlinlang.org/docs/native-target-support.html 128 129 // Tier #1 130 addTarget(presets.linuxX64) 131 addTarget(presets.macosX64) 132 addTarget(presets.macosArm64) 133 addTarget(presets.iosSimulatorArm64) 134 addTarget(presets.iosX64) 135 136 // Tier #2 137 addTarget(presets.linuxArm64) 138 addTarget(presets.watchosSimulatorArm64) 139 addTarget(presets.watchosX64) 140 addTarget(presets.watchosArm32) 141 addTarget(presets.watchosArm64) 142 addTarget(presets.tvosSimulatorArm64) 143 addTarget(presets.tvosX64) 144 addTarget(presets.tvosArm64) 145 addTarget(presets.iosArm64) 146 147 148 // Tier #3 149 addTarget(presets.androidNativeArm32) 150 addTarget(presets.androidNativeArm64) 151 addTarget(presets.androidNativeX86) 152 addTarget(presets.androidNativeX64) 153 addTarget(presets.mingwX64) 154 addTarget(presets.watchosDeviceArm64) 155 } 156 } 157 158 sourceSets { 159 nativeMain { dependsOn commonMain } 160 161 nativeTest {} 162 163 if (!project.ext.ideaActive) { 164 configure(nativeMainSets) { 165 dependsOn nativeMain 166 } 167 168 configure(nativeTestSets) { 169 dependsOn nativeTest 170 } 171 } 172 } 173 174 configure(nativeCompilations) { 175 cinterops { 176 interop { 177 defFile 'src/nativeInterop/cinterop/interop.def' 178 } 179 } 180 } 181 } 182} 183 184configurations { 185 transformer 186} 187 188apply from: rootProject.file('gradle/compile-options.gradle') 189 190ext.configureKotlin() 191 192dependencies { 193 transformer project(":atomicfu-transformer") 194} 195 196// ==== CONFIGURE JVM ===== 197 198def classesPreAtomicFuDir = file("$buildDir/classes/kotlin/jvm/test") 199def classesPostTransformFU = file("$buildDir/classes/kotlin/jvm/postTransformedFU") 200def classesPostTransformVH = file("$buildDir/classes/kotlin/jvm/postTransformedVH") 201def classesPostTransformBOTH = file("$buildDir/classes/kotlin/jvm/postTransformedBOTH") 202 203tasks.withType(compileTestKotlinJvm.getClass()) { 204 kotlinOptions { 205 jvmTarget = "1.8" 206 } 207} 208 209task transformFU(type: JavaExec, dependsOn: compileTestKotlinJvm) { 210 main = "kotlinx.atomicfu.transformer.AtomicFUTransformerKt" 211 args = [classesPreAtomicFuDir, classesPostTransformFU, "FU"] 212 classpath = configurations.transformer 213 inputs.dir(classesPreAtomicFuDir) 214 outputs.dir(classesPostTransformFU) 215} 216 217task transformBOTH(type: JavaExec, dependsOn: compileTestKotlinJvm) { 218 main = "kotlinx.atomicfu.transformer.AtomicFUTransformerKt" 219 args = [classesPreAtomicFuDir, classesPostTransformBOTH, "BOTH"] 220 classpath = configurations.transformer 221 inputs.dir(classesPreAtomicFuDir) 222 outputs.dir(classesPostTransformBOTH) 223} 224 225task transformVH(type: JavaExec, dependsOn: compileTestKotlinJvm) { 226 main = "kotlinx.atomicfu.transformer.AtomicFUTransformerKt" 227 args = [classesPreAtomicFuDir, classesPostTransformVH, "VH"] 228 classpath = configurations.transformer 229 inputs.dir(classesPreAtomicFuDir) 230 outputs.dir(classesPostTransformVH) 231} 232 233task transformedTestFU_current(type: Test, dependsOn: transformFU) { 234 classpath = files(configurations.jvmTestRuntimeClasspath, classesPostTransformFU) 235 testClassesDirs = project.files(classesPostTransformFU) 236 exclude '**/*LFTest.*', '**/TraceToStringTest.*', '**/AtomicfuReferenceJsTest.*' 237 filter { setFailOnNoMatchingTests(false) } 238} 239 240task transformedTestBOTH_current(type: Test, dependsOn: transformBOTH) { 241 classpath = files(configurations.jvmTestRuntimeClasspath, classesPostTransformBOTH) 242 testClassesDirs = project.files(classesPostTransformBOTH) 243 exclude '**/*LFTest.*', '**/TraceToStringTest.*', '**/TopLevelGeneratedDeclarationsReflectionTest.*', '**/SyntheticFUFieldsTest.*', '**/AtomicfuReferenceJsTest.*' 244 filter { setFailOnNoMatchingTests(false) } 245} 246 247task transformedTestVH(type: Test, dependsOn: transformVH) { 248 classpath = files(configurations.jvmTestRuntimeClasspath, classesPostTransformVH) 249 testClassesDirs = project.files(classesPostTransformVH) 250 exclude '**/*LFTest.*', '**/TraceToStringTest.*', '**/TopLevelGeneratedDeclarationsReflectionTest.*', '**/SyntheticFUFieldsTest.*', '**/AtomicfuReferenceJsTest.*' 251 filter { setFailOnNoMatchingTests(false) } 252} 253 254transformedTestVH.onlyIf { 255 logger.println(JavaVersion.current()) 256 JavaVersion.current().ordinal() >= JavaVersion.VERSION_1_9.ordinal() 257} 258 259task jvmTestAll(dependsOn: [ 260 transformedTestFU_current, 261 transformedTestBOTH_current, 262 transformedTestVH 263]) 264 265tasks.withType(Test) { 266 testLogging { 267 showStandardStreams = true 268 events "passed", "failed" 269 } 270} 271 272task compileJavaModuleInfo(type: JavaCompile) { 273 def moduleName = "kotlinx.atomicfu" // this module's name 274 def compilation = kotlin.targets["jvm"].compilations["main"] 275 def compileKotlinTask = compilation.compileTaskProvider.get() as KotlinJvmCompile 276 def targetDir = compileKotlinTask.destinationDirectory.dir("../java9") 277 def sourceDir = file("src/jvmMain/java9/") 278 279 // Use a Java 11 compiler for the module info. 280 javaCompiler.set(project.javaToolchains.compilerFor { languageVersion.set(JavaLanguageVersion.of(11)) }) 281 282 // Always compile kotlin classes before the module descriptor. 283 dependsOn(compileKotlinTask) 284 285 // Add the module-info source file. 286 source(sourceDir) 287 288 // Also add the module-info.java source file to the Kotlin compile task. 289 // The Kotlin compiler will parse and check module dependencies, 290 // but it currently won't compile to a module-info.class file. 291 // Note that module checking only works on JDK 9+, 292 // because the JDK built-in base modules are not available in earlier versions. 293 def javaVersion = compileKotlinTask.kotlinJavaToolchain.javaVersion.getOrNull() 294 if (javaVersion?.isJava9Compatible() == true) { 295 logger.info("Module-info checking is enabled; $compileKotlinJvm is compiled using Java $javaVersion") 296 compileKotlinJvm.source(sourceDir) 297 } else { 298 logger.info("Module-info checking is disabled") 299 } 300 301 // Set the task outputs and destination dir 302 outputs.dir(targetDir) 303 destinationDirectory.set(targetDir) 304 305 // Configure JVM compatibility 306 sourceCompatibility = JavaVersion.VERSION_1_9.toString() 307 targetCompatibility = JavaVersion.VERSION_1_9.toString() 308 309 // Set the Java release version. 310 options.release.set(9) 311 312 // Ignore warnings about using 'requires transitive' on automatic modules. 313 // not needed when compiling with recent JDKs, e.g. 17 314 options.compilerArgs.add("-Xlint:-requires-transitive-automatic") 315 316 // Patch the compileKotlinJvm output classes into the compilation so exporting packages works correctly. 317 options.compilerArgs.addAll(["--patch-module", "$moduleName=${compileKotlinTask.destinationDirectory.get().getAsFile()}"]) 318 319 // Use the classpath of the compileKotlinJvm task. 320 // Also ensure that the module path is used instead of classpath. 321 classpath = compileKotlinTask.libraries 322 modularity.inferModulePath.set(true) 323 324 doFirst { 325 logger.warn("Task destination directory: ${destinationDirectory.get().getAsFile()}") 326 } 327} 328 329// Configure the JAR task so that it will include the compiled module-info class file. 330tasks.named("jvmJar") { 331 manifest { 332 attributes(["Multi-Release": true]) 333 } 334 from(compileJavaModuleInfo.destinationDirectory) { 335 into("META-INF/versions/9/") 336 } 337} 338 339jvmTest { 340 exclude "**/AtomicfuBytecodeTest*", "**/AtomicfuReferenceJsTest*", '**/TopLevelGeneratedDeclarationsReflectionTest.*', '**/SyntheticFUFieldsTest.*' // run them only for transformed code 341} 342 343jvmTest.dependsOn jvmTestAll 344 345afterEvaluate { 346 publishing.publications { 347 kotlinMultiplatform { 348 apply from: "$rootDir/gradle/publish-mpp-root-module-in-platform.gradle" 349 publishPlatformArtifactsInRootModule(jvm) 350 } 351 } 352} 353 354tasks.matching { it.name == "generatePomFileForKotlinMultiplatformPublication" }.configureEach { 355 dependsOn(tasks["generatePomFileForJvmPublication"]) 356} 357 358// Workaround for https://youtrack.jetbrains.com/issue/KT-58303: 359// the `clean` task can't delete the expanded.lock file on Windows as it's still held by Gradle, failing the build 360tasks.clean { 361 setDelete(layout.buildDirectory.asFileTree.matching { 362 exclude("tmp/.cache/expanded/expanded.lock") 363 }) 364} 365