diff --git a/README.md b/README.md index c2e65f2f..721c5313 100644 --- a/README.md +++ b/README.md @@ -34,11 +34,18 @@ ## Requirements -Starting from version `0.23.2` of the library your project is required to use: +Starting from version `0.24.0` of the library your project is required to use: * Gradle `7.0` or newer -* Kotlin `1.7.0` or newer +* Kotlin `1.9.0` or newer + +> **Note on Kotlin version:** Currently, the `kotlinx-atomicfu` Gradle plugin only relies on the version of Kotlin Gradle Plugin (KGP) present in the user's project. +> It's important to note this constraint if your project configures the custom Kotlin compiler version or modifies the Kotlin Native compiler version using `kotlin.native.version` property. + +>**In case, you cannot upgrade the Kotlin version to 1.9.0 or newer** in your project, +you can downgrade `kotlinx-atomicfu` plugin version to `0.22.0`. +> Please note, though, that using the latest version of the plugin and upgrading the Kotlin version is the more recommended approach. ## Features @@ -105,8 +112,6 @@ operations. They can be also atomically modified via `+=` and `-=` operators. ### Apply plugin #### Gradle configuration -Gradle configuration is supported for all platforms, minimal version is Gradle 6.8. - In top-level build file:
@@ -256,10 +261,10 @@ IR for all the target backends: * **Native**: atomics are implemented via atomic intrinsics on Kotlin/Native. * **JS**: atomics are unboxed and represented as plain values. -To turn on IR transformation set these properties in your `gradle.properties` file: +To turn on IR transformations set the following properties in your `gradle.properties` file: -
-For Kotlin >= 1.7.20 +> Please note, that starting from version `0.24.0` of the library your project is required to use `Kotlin version >= 1.9.0`. +> See the [requirements section](#Requirements). ```groovy kotlinx.atomicfu.enableJvmIrTransformation=true // for JVM IR transformation @@ -267,25 +272,31 @@ kotlinx.atomicfu.enableNativeIrTransformation=true // for Native IR transformati kotlinx.atomicfu.enableJsIrTransformation=true // for JS IR transformation ``` -
+
+ Here are the configuration properties in case you use older versions of the library lower than 0.24.0. -
+For `Kotlin >= 1.7.20` +```groovy +kotlinx.atomicfu.enableJvmIrTransformation=true // for JVM IR transformation +kotlinx.atomicfu.enableNativeIrTransformation=true // for Native IR transformation +kotlinx.atomicfu.enableJsIrTransformation=true // for JS IR transformation +``` - For Kotlin >= 1.6.20 and Kotlin < 1.7.20 +For `Kotlin >= 1.6.20` and `Kotlin < 1.7.20` ```groovy kotlinx.atomicfu.enableIrTransformation=true // only JS IR transformation is supported ``` -
- Also for JS backend make sure that `ir` or `both` compiler mode is set: ```groovy kotlin.js.compiler=ir // or both ``` +
+ ## Options for post-compilation transformation diff --git a/atomicfu-gradle-plugin/build.gradle b/atomicfu-gradle-plugin/build.gradle index 3db72fc0..b97be930 100644 --- a/atomicfu-gradle-plugin/build.gradle +++ b/atomicfu-gradle-plugin/build.gradle @@ -24,10 +24,6 @@ dependencies { // Atomicfu compiler plugin dependency will be loaded to kotlinCompilerPluginClasspath // Atomicfu plugin will only be applied if the flag is set kotlinx.atomicfu.enableJsIrTransformation=true compileOnly "org.jetbrains.kotlin:atomicfu:$kotlin_version" - // This runtimeOnly dependency is added as a temporary WA for the problem #384. - // The version 1.6.21 was chosen as the lowest valid version of this artifact, - // and it's expected to be resolved to the highest existing version from the user's classpath. - runtimeOnly "org.jetbrains.kotlin:atomicfu:1.6.21" testImplementation gradleTestKit() testImplementation 'org.jetbrains.kotlin:kotlin-test' diff --git a/atomicfu-gradle-plugin/src/main/kotlin/kotlinx/atomicfu/plugin/gradle/AtomicFUGradlePlugin.kt b/atomicfu-gradle-plugin/src/main/kotlin/kotlinx/atomicfu/plugin/gradle/AtomicFUGradlePlugin.kt index 417fa2ea..9a046dea 100644 --- a/atomicfu-gradle-plugin/src/main/kotlin/kotlinx/atomicfu/plugin/gradle/AtomicFUGradlePlugin.kt +++ b/atomicfu-gradle-plugin/src/main/kotlin/kotlinx/atomicfu/plugin/gradle/AtomicFUGradlePlugin.kt @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + * Copyright 2017-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ package kotlinx.atomicfu.plugin.gradle @@ -20,33 +20,33 @@ import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.targets.js.* import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget import org.jetbrains.kotlin.gradle.tasks.* -import org.jetbrains.kotlinx.atomicfu.gradle.* import java.io.* import java.util.* import javax.inject.Inject private const val EXTENSION_NAME = "atomicfu" -private const val ORIGINAL_DIR_NAME = "originalClassesDir" private const val COMPILE_ONLY_CONFIGURATION = "compileOnly" private const val IMPLEMENTATION_CONFIGURATION = "implementation" private const val TEST_IMPLEMENTATION_CONFIGURATION = "testImplementation" + // If the project uses KGP <= 1.6.20, only JS IR compiler plugin is available, and it is turned on via setting this property. // The property is supported for backwards compatibility. private const val ENABLE_JS_IR_TRANSFORMATION_LEGACY = "kotlinx.atomicfu.enableIrTransformation" -private const val ENABLE_JS_IR_TRANSFORMATION = "kotlinx.atomicfu.enableJsIrTransformation" -private const val ENABLE_JVM_IR_TRANSFORMATION = "kotlinx.atomicfu.enableJvmIrTransformation" -private const val ENABLE_NATIVE_IR_TRANSFORMATION = "kotlinx.atomicfu.enableNativeIrTransformation" +internal const val ENABLE_JS_IR_TRANSFORMATION = "kotlinx.atomicfu.enableJsIrTransformation" +internal const val ENABLE_JVM_IR_TRANSFORMATION = "kotlinx.atomicfu.enableJvmIrTransformation" +internal const val ENABLE_NATIVE_IR_TRANSFORMATION = "kotlinx.atomicfu.enableNativeIrTransformation" private const val MIN_SUPPORTED_GRADLE_VERSION = "7.0" private const val MIN_SUPPORTED_KGP_VERSION = "1.7.0" open class AtomicFUGradlePlugin : Plugin { override fun apply(project: Project) = project.run { - checkCompatibility() - // atomicfu version is stored at build time in atomicfu.properties file + // Atomicfu version is stored at build time in atomicfu.properties file // located in atomicfu-gradle-plugin resources - val pluginVersion = loadPropertyFromResources("atomicfu.properties", "atomicfu.version") - extensions.add(EXTENSION_NAME, AtomicFUPluginExtension(pluginVersion)) - applyAtomicfuCompilerPlugin() + val afuPluginVersion = loadPropertyFromResources("atomicfu.properties", "atomicfu.version") + checkCompatibility(afuPluginVersion) + extensions.add(EXTENSION_NAME, AtomicFUPluginExtension(afuPluginVersion)) + // Apply Atomicfu compiler plugin + plugins.apply(AtomicfuKotlinCompilerPluginInternal::class.java) configureDependencies() configureTasks() } @@ -55,59 +55,40 @@ open class AtomicFUGradlePlugin : Plugin { private fun loadPropertyFromResources(propFileName: String, property: String): String { val props = Properties() val inputStream = AtomicFUGradlePlugin::class.java.classLoader!!.getResourceAsStream(propFileName) - ?: throw FileNotFoundException("You are applying `kotlinx-atomicfu` plugin of version 0.23.3 or newer, yet we were unable to determine the specific version of the plugin.\". \n" + - "Starting from version 0.23.3 of `kotlinx-atomicfu`, the plugin version is extracted from the `atomicfu.properties` file, which resides within the atomicfu-gradle-plugin-{version}.jar. \n" + - "However, this file couldn't be found. Please ensure that there are no atomicfu-gradle-plugin-{version}.jar with version older than 0.23.3 present on the classpath.\n" + - "If the problem is not resolved, please submit the issue: https://github.com/Kotlin/kotlinx-atomicfu/" ) + ?: throw FileNotFoundException( + "You are applying `kotlinx-atomicfu` plugin of version 0.24.0 or newer, yet we were unable to determine the specific version of the plugin.\". \n" + + "Starting from version 0.24.0 of `kotlinx-atomicfu`, the plugin version is extracted from the `atomicfu.properties` file, which resides within the atomicfu-gradle-plugin-{version}.jar. \n" + + "However, this file couldn't be found. Please ensure that there are no atomicfu-gradle-plugin-{version}.jar with version older than 0.24.0 present on the classpath.\n" + + "If the problem is not resolved, please submit the issue: https://github.com/Kotlin/kotlinx-atomicfu/issues" + ) inputStream.use { props.load(it) } return props[property] as String } -private fun Project.checkCompatibility() { +private fun Project.checkCompatibility(afuPluginVersion: String) { val currentGradleVersion = GradleVersion.current() val kotlinVersion = getKotlinVersion() val minSupportedVersion = GradleVersion.version(MIN_SUPPORTED_GRADLE_VERSION) if (currentGradleVersion < minSupportedVersion) { throw GradleException( "The current Gradle version is not compatible with Atomicfu gradle plugin. " + - "Please use Gradle $MIN_SUPPORTED_GRADLE_VERSION or newer, or the previous version of Atomicfu gradle plugin." + "Please use Gradle $MIN_SUPPORTED_GRADLE_VERSION or newer, or the previous version of Atomicfu gradle plugin." ) } - if (!kotlinVersion.atLeast(1, 7, 0)) { - throw GradleException( - "The current Kotlin gradle plugin version is not compatible with Atomicfu gradle plugin. " + - "Please use Kotlin $MIN_SUPPORTED_KGP_VERSION or newer, or the previous version of Atomicfu gradle plugin." + if (!kotlinVersion.atLeast(1, 9, 0)) { + // Since Kotlin 1.9.0 the logic of the Gradle plugin from the Kotlin repo (AtomicfuKotlinGradleSubplugin) + // may be moved to the Gradle plugin in the library. The sources of the compiler plugin + // are published as `kotlin-atomicfu-compiler-plugin-embeddable` since Kotlin 1.9.0 and may be accessed out of the Kotlin repo. + error( + "You are applying `kotlinx-atomicfu` plugin of version $afuPluginVersion. " + + "However, this version of the plugin is only compatible with Kotlin versions newer than 1.9.0.\n" + + "If you wish to use this version of the plugin, please upgrade your Kotlin version to 1.9.0 or newer.\n" + + "In case you can not upgrade the Kotlin version, please read further instructions in the README: https://github.com/Kotlin/kotlinx-atomicfu/blob/master/README.md#requirements \n" + + "If you encounter any problems, please submit the issue: https://github.com/Kotlin/kotlinx-atomicfu/issues" ) } } -private fun Project.applyAtomicfuCompilerPlugin() { - val kotlinVersion = getKotlinVersion() - // for KGP >= 1.7.20: - // compiler plugin for JS IR is applied via the property `kotlinx.atomicfu.enableJsIrTransformation` - // compiler plugin for JVM IR is applied via the property `kotlinx.atomicfu.enableJvmIrTransformation` - if (kotlinVersion.atLeast(1, 7, 20)) { - plugins.apply(AtomicfuKotlinGradleSubplugin::class.java) - extensions.getByType(AtomicfuKotlinGradleSubplugin.AtomicfuKotlinGradleExtension::class.java).apply { - isJsIrTransformationEnabled = rootProject.getBooleanProperty(ENABLE_JS_IR_TRANSFORMATION) - isJvmIrTransformationEnabled = rootProject.getBooleanProperty(ENABLE_JVM_IR_TRANSFORMATION) - if (kotlinVersion.atLeast(1, 9, 20)) { - // Native IR transformation is available since Kotlin 1.9.20 - isNativeIrTransformationEnabled = rootProject.getBooleanProperty(ENABLE_NATIVE_IR_TRANSFORMATION) - } - } - } else { - // for KGP >= 1.6.20 && KGP <= 1.7.20: - // compiler plugin for JS IR is applied via the property `kotlinx.atomicfu.enableIrTransformation` - // compiler plugin for JVM IR is not supported yet - if (kotlinVersion.atLeast(1, 6, 20)) { - if (rootProject.getBooleanProperty(ENABLE_JS_IR_TRANSFORMATION_LEGACY)) { - plugins.apply(AtomicfuKotlinGradleSubplugin::class.java) - } - } - } -} - private fun Project.configureDependencies() { withPluginWhenEvaluatedDependencies("kotlin") { version -> dependencies.add( @@ -131,7 +112,8 @@ private fun Project.configureDependencies() { } private fun Project.configureMultiplatformPluginDependencies(version: String) { - val multiplatformExtension = kotlinExtension as? KotlinMultiplatformExtension ?: error("Expected kotlin multiplatform extension") + val multiplatformExtension = + kotlinExtension as? KotlinMultiplatformExtension ?: error("Expected kotlin multiplatform extension") val atomicfuDependency = "org.jetbrains.kotlinx:atomicfu:$version" multiplatformExtension.sourceSets.getByName("commonMain").dependencies { compileOnly(atomicfuDependency) @@ -152,7 +134,6 @@ private fun Project.configureMultiplatformPluginDependencies(version: String) { } } } - // atomicfu should also appear in apiElements config for native targets, // otherwise the warning is triggered, see: KT-64109 multiplatformExtension.targets @@ -186,7 +167,7 @@ private fun KotlinVersion.atLeast(major: Int, minor: Int, patch: Int) = // kotlinx-atomicfu compiler plugin is available for KGP >= 1.6.20 private fun Project.isCompilerPluginAvailable() = getKotlinVersion().atLeast(1, 6, 20) -private fun Project.getBooleanProperty(name: String) = +internal fun Project.getBooleanProperty(name: String) = rootProject.findProperty(name)?.toString()?.toBooleanStrict() ?: false private fun String.toBooleanStrict(): Boolean = when (this) { @@ -195,30 +176,29 @@ private fun String.toBooleanStrict(): Boolean = when (this) { else -> throw IllegalArgumentException("The string doesn't represent a boolean value: $this") } -private fun Project.needsJsIrTransformation(target: KotlinTarget): Boolean = +internal fun Project.needsJsIrTransformation(target: KotlinTarget): Boolean = (rootProject.getBooleanProperty(ENABLE_JS_IR_TRANSFORMATION) || rootProject.getBooleanProperty(ENABLE_JS_IR_TRANSFORMATION_LEGACY)) && target.isJsIrTarget() -private fun Project.needsJvmIrTransformation(target: KotlinTarget): Boolean = +internal fun Project.needsJvmIrTransformation(target: KotlinTarget): Boolean = rootProject.getBooleanProperty(ENABLE_JVM_IR_TRANSFORMATION) && - (target.platformType == KotlinPlatformType.jvm || target.platformType == KotlinPlatformType.androidJvm) + (target.platformType == KotlinPlatformType.jvm || target.platformType == KotlinPlatformType.androidJvm) -private fun Project.needsNativeIrTransformation(target: KotlinTarget): Boolean = +internal fun Project.needsNativeIrTransformation(target: KotlinTarget): Boolean = rootProject.getBooleanProperty(ENABLE_NATIVE_IR_TRANSFORMATION) && - (target.platformType == KotlinPlatformType.native) - + (target.platformType == KotlinPlatformType.native) private fun KotlinTarget.isJsIrTarget() = (this is KotlinJsTarget && this.irTarget != null) || - (this is KotlinJsIrTarget && this.platformType != KotlinPlatformType.wasm) + (this is KotlinJsIrTarget && this.platformType != KotlinPlatformType.wasm) private fun Project.isTransitiveAtomicfuDependencyRequired(target: KotlinTarget): Boolean { val platformType = target.platformType return !config.transformJvm && (platformType == KotlinPlatformType.jvm || platformType == KotlinPlatformType.androidJvm) || - !config.transformJs && platformType == KotlinPlatformType.js || - platformType == KotlinPlatformType.wasm || - // Always add the transitive atomicfu dependency for native targets, see #379 - platformType == KotlinPlatformType.native + (!config.transformJs && platformType == KotlinPlatformType.js) || + platformType == KotlinPlatformType.wasm || + // Always add the transitive atomicfu dependency for native targets, see #379 + platformType == KotlinPlatformType.native } // Adds kotlinx-atomicfu-runtime as an implementation dependency to the JS IR target: @@ -319,7 +299,7 @@ private fun Project.configureJvmTransformation() { if (kotlinExtension is KotlinJvmProjectExtension || kotlinExtension is KotlinAndroidProjectExtension) { val target = (kotlinExtension as KotlinSingleTargetExtension<*>).target if (!needsJvmIrTransformation(target)) { - configureTransformationForTarget(target) + configureTransformationForTarget(target) } } } @@ -334,11 +314,11 @@ private fun Project.configureJsTransformation() { private fun Project.configureMultiplatformTransformation() = withKotlinTargets { target -> // Skip transformation for common, native and wasm targets or in case IR transformation by the compiler plugin is enabled (for JVM or JS targets) - if (target.platformType == KotlinPlatformType.common || + if (target.platformType == KotlinPlatformType.common || target.platformType == KotlinPlatformType.native || target.platformType == KotlinPlatformType.wasm || needsJvmIrTransformation(target) || needsJsIrTransformation(target) - ) { + ) { return@withKotlinTargets } configureTransformationForTarget(target) diff --git a/atomicfu-gradle-plugin/src/main/kotlin/kotlinx/atomicfu/plugin/gradle/AtomicfuKotlinCompilerPluginInternal.kt b/atomicfu-gradle-plugin/src/main/kotlin/kotlinx/atomicfu/plugin/gradle/AtomicfuKotlinCompilerPluginInternal.kt new file mode 100644 index 00000000..1ceb29ad --- /dev/null +++ b/atomicfu-gradle-plugin/src/main/kotlin/kotlinx/atomicfu/plugin/gradle/AtomicfuKotlinCompilerPluginInternal.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2017-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +package kotlinx.atomicfu.plugin.gradle + +import org.gradle.api.provider.Provider +import org.jetbrains.kotlin.gradle.plugin.* + +/** + * This Gradle plugin applies compiler transformations to the project, it was copied from the kotlin repo (org.jetbrains.kotlinx.atomicfu.gradle.AtomicfuKotlinGradleSubplugin). + * + * As the sources of the compiler plugin are published as `org.jetbrains.kotlin.kotlin-atomicfu-compiler-plugin-embeddable` starting from Kotlin 1.9.0, + * the Gradle plugin can access this artifact from the library and apply the transformations. + * + * NOTE: The version of KGP may differ from the version of Kotlin compiler, and kotlin.native.version may override the version of Kotlin native compiler. + * So, the right behavior for the Gradle plugin would be to obtain compiler versions and apply compiler transformations separately to JVM/JS and Native targets. + * This was postponed as a separate task (#408). + */ +internal class AtomicfuKotlinCompilerPluginInternal : KotlinCompilerPluginSupportPlugin { + + companion object { + const val ATOMICFU_ARTIFACT_NAME = "kotlin-atomicfu-compiler-plugin-embeddable" + } + + override fun isApplicable(kotlinCompilation: KotlinCompilation<*>): Boolean { + val target = kotlinCompilation.target + val project = target.project + return project.needsJvmIrTransformation(target) || project.needsJsIrTransformation(target) || project.needsNativeIrTransformation(target) + } + + override fun applyToCompilation( + kotlinCompilation: KotlinCompilation<*> + ): Provider> = kotlinCompilation.target.project.provider { emptyList() } + + override fun getCompilerPluginId() = "org.jetbrains.kotlinx.atomicfu" + + // Gets "org.jetbrains.kotlin:kotlin-atomicfu-compiler-plugin-embeddable:{KGP version}" + override fun getPluginArtifact(): SubpluginArtifact { + return JetBrainsSubpluginArtifact(ATOMICFU_ARTIFACT_NAME) + } +} diff --git a/integration-testing/examples/mpp-version-catalog/build.gradle.kts b/integration-testing/examples/mpp-version-catalog/build.gradle.kts new file mode 100644 index 00000000..6808d404 --- /dev/null +++ b/integration-testing/examples/mpp-version-catalog/build.gradle.kts @@ -0,0 +1,13 @@ +import org.jetbrains.kotlin.gradle.dsl.KotlinCompile + +plugins { + // this is necessary to avoid the plugins to be loaded multiple times + // in each subproject's classloader + alias(libs.plugins.kotlinMultiplatform) apply false +} + +tasks.withType>().configureEach { + kotlinOptions { + freeCompilerArgs += listOf("-Xskip-prerelease-check") + } +} diff --git a/integration-testing/examples/mpp-version-catalog/gradle.properties b/integration-testing/examples/mpp-version-catalog/gradle.properties new file mode 100644 index 00000000..ab1f0b10 --- /dev/null +++ b/integration-testing/examples/mpp-version-catalog/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=2g diff --git a/integration-testing/examples/mpp-version-catalog/gradle/libs.versions.toml b/integration-testing/examples/mpp-version-catalog/gradle/libs.versions.toml new file mode 100644 index 00000000..10e4e9fa --- /dev/null +++ b/integration-testing/examples/mpp-version-catalog/gradle/libs.versions.toml @@ -0,0 +1,21 @@ +[versions] +junit = "4.13.2" +kotlin = "1.9.21" +atomicfu = "0.23.2-SNAPSHOT" +ktor = "2.3.8" +logback = "1.5.0" + +[libraries] +kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } +kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" } +junit = { group = "junit", name = "junit", version.ref = "junit" } +logback = { module = "ch.qos.logback:logback-classic", version.ref = "logback" } +ktor-server-core = { module = "io.ktor:ktor-server-core-jvm", version.ref = "ktor" } +ktor-server-netty = { module = "io.ktor:ktor-server-netty-jvm", version.ref = "ktor" } +ktor-server-tests = { module = "io.ktor:ktor-server-tests-jvm", version.ref = "ktor" } +atomicfuGradlePlugin = { module = "org.jetbrains.kotlinx:atomicfu-gradle-plugin", version.ref = "atomicfu" } + +[plugins] +kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } +ktor = { id = "io.ktor.plugin", version.ref = "ktor" } +kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } diff --git a/integration-testing/examples/mpp-version-catalog/settings.gradle.kts b/integration-testing/examples/mpp-version-catalog/settings.gradle.kts new file mode 100644 index 00000000..c7e78eb0 --- /dev/null +++ b/integration-testing/examples/mpp-version-catalog/settings.gradle.kts @@ -0,0 +1,22 @@ +rootProject.name = "mpp-version-catalog" +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") + +pluginManagement { + repositories { + + google() + gradlePluginPortal() + mavenCentral() + mavenLocal() + } +} + +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + mavenLocal() + } +} + +include(":shared") diff --git a/integration-testing/examples/mpp-version-catalog/shared/build.gradle.kts b/integration-testing/examples/mpp-version-catalog/shared/build.gradle.kts new file mode 100644 index 00000000..16794b89 --- /dev/null +++ b/integration-testing/examples/mpp-version-catalog/shared/build.gradle.kts @@ -0,0 +1,46 @@ +import org.jetbrains.kotlin.gradle.dsl.KotlinCompile + +buildscript { + dependencies { + classpath(libs.atomicfuGradlePlugin) + } +} + +repositories { + mavenCentral() + mavenLocal() +} + +plugins { + alias(libs.plugins.kotlinMultiplatform) +} + +apply (plugin = "kotlinx-atomicfu") + +kotlin { + + jvm() + + js(IR) + + macosArm64() + macosX64() + linuxArm64() + linuxX64() + mingwX64() + + sourceSets { + commonMain{ + dependencies { + implementation(kotlin("stdlib")) + implementation(kotlin("test-junit")) + } + } + } +} + +tasks.withType>().configureEach { + kotlinOptions { + freeCompilerArgs += listOf("-Xskip-prerelease-check") + } +} diff --git a/integration-testing/examples/mpp-version-catalog/shared/src/commonMain/kotlin/Greeting.kt b/integration-testing/examples/mpp-version-catalog/shared/src/commonMain/kotlin/Greeting.kt new file mode 100644 index 00000000..8f7e2b3e --- /dev/null +++ b/integration-testing/examples/mpp-version-catalog/shared/src/commonMain/kotlin/Greeting.kt @@ -0,0 +1,21 @@ +import kotlinx.atomicfu.* +import kotlinx.atomicfu.locks.* +import kotlin.test.* + +public class AtomicSampleClass { + private val _x = atomic(0) + val x get() = _x.value + + public fun doWork(finalValue: Int) { + assertEquals(0, x) + assertEquals(0, _x.getAndSet(3)) + assertEquals(3, x) + assertTrue(_x.compareAndSet(3, finalValue)) + } + + private val lock = reentrantLock() + + public fun synchronizedFoo(value: Int): Int { + return lock.withLock { value } + } +} diff --git a/integration-testing/examples/plugin-order-bug/build.gradle b/integration-testing/examples/plugin-order-bug/build.gradle index d0ba6115..e1319c66 100644 --- a/integration-testing/examples/plugin-order-bug/build.gradle +++ b/integration-testing/examples/plugin-order-bug/build.gradle @@ -51,3 +51,11 @@ tasks.withType(KotlinCompile).configureEach { freeCompilerArgs += ["-Xskip-prerelease-check"] } } + +// Workaround for https://youtrack.jetbrains.com/issue/KT-58303: +// the `clean` task can't delete the expanded.lock file on Windows as it's still held by Gradle, failing the build +tasks.clean { + setDelete(layout.buildDirectory.asFileTree.matching { + exclude("tmp/.cache/expanded/expanded.lock") + }) +} diff --git a/integration-testing/examples/user-project/build.gradle.kts b/integration-testing/examples/user-project/build.gradle.kts index 94548ce8..e4f66aa6 100644 --- a/integration-testing/examples/user-project/build.gradle.kts +++ b/integration-testing/examples/user-project/build.gradle.kts @@ -49,3 +49,11 @@ tasks.withType>().configureEach { freeCompilerArgs += listOf("-Xskip-prerelease-check") } } + +// Workaround for https://youtrack.jetbrains.com/issue/KT-58303: +// the `clean` task can't delete the expanded.lock file on Windows as it's still held by Gradle, failing the build +tasks.clean { + setDelete(layout.buildDirectory.asFileTree.matching { + exclude("tmp/.cache/expanded/expanded.lock") + }) +} diff --git a/integration-testing/src/functionalTest/kotlin/kotlinx.atomicfu.gradle.plugin.test/cases/MppVersionCatalogTest.kt b/integration-testing/src/functionalTest/kotlin/kotlinx.atomicfu.gradle.plugin.test/cases/MppVersionCatalogTest.kt new file mode 100644 index 00000000..811515bf --- /dev/null +++ b/integration-testing/src/functionalTest/kotlin/kotlinx.atomicfu.gradle.plugin.test/cases/MppVersionCatalogTest.kt @@ -0,0 +1,21 @@ +package kotlinx.atomicfu.gradle.plugin.test.cases + +import kotlinx.atomicfu.gradle.plugin.test.framework.checker.* +import kotlinx.atomicfu.gradle.plugin.test.framework.runner.* +import kotlin.test.* + +/** + * This test checks the build of mpp-version-catalog project that uses a versions catalog and was a reproducer for this error (#399). + */ +class MppVersionCatalogTest { + private val mppWithVersionCatalog: GradleBuild = createGradleBuildFromSources("mpp-version-catalog") + + @Test + fun testBuildWithKotlinNewerThan_1_9_0() { + mppWithVersionCatalog.enableJvmIrTransformation = true + mppWithVersionCatalog.enableNativeIrTransformation = true + val buildResult = mppWithVersionCatalog.cleanAndBuild() + assertTrue(buildResult.isSuccessful, buildResult.output) + mppWithVersionCatalog.buildAndCheckBytecode() + } +} diff --git a/integration-testing/src/functionalTest/kotlin/kotlinx.atomicfu.gradle.plugin.test/cases/PluginOrderBugTest.kt b/integration-testing/src/functionalTest/kotlin/kotlinx.atomicfu.gradle.plugin.test/cases/PluginOrderBugTest.kt index 1ec0fd7f..62f3043a 100644 --- a/integration-testing/src/functionalTest/kotlin/kotlinx.atomicfu.gradle.plugin.test/cases/PluginOrderBugTest.kt +++ b/integration-testing/src/functionalTest/kotlin/kotlinx.atomicfu.gradle.plugin.test/cases/PluginOrderBugTest.kt @@ -1,6 +1,5 @@ package kotlinx.atomicfu.gradle.plugin.test.cases -import kotlinx.atomicfu.gradle.plugin.test.framework.checker.getProjectClasspath import kotlinx.atomicfu.gradle.plugin.test.framework.runner.* import kotlinx.atomicfu.gradle.plugin.test.framework.runner.GradleBuild import kotlinx.atomicfu.gradle.plugin.test.framework.runner.cleanAndBuild @@ -19,15 +18,6 @@ class PluginOrderBugTest { assertTrue(buildResult.isSuccessful, buildResult.output) } - /** - * Ensures that the version of atomicfu compiler plugin in the project's classpath equals the version of KGP used in the project. - */ - @Test - fun testResolvedCompilerPluginDependency() { - val classpath = pluginOrderBugProject.getProjectClasspath() - assertTrue(classpath.contains("org.jetbrains.kotlin:atomicfu:${pluginOrderBugProject.getKotlinVersion()}")) - } - /** * kotlin-stdlib is an implementation dependency of :atomicfu module, * because compileOnly dependencies are not applicable for Native targets (#376). diff --git a/integration-testing/src/functionalTest/kotlin/kotlinx.atomicfu.gradle.plugin.test/framework/runner/Environment.kt b/integration-testing/src/functionalTest/kotlin/kotlinx.atomicfu.gradle.plugin.test/framework/runner/Environment.kt index de117a30..924b88db 100644 --- a/integration-testing/src/functionalTest/kotlin/kotlinx.atomicfu.gradle.plugin.test/framework/runner/Environment.kt +++ b/integration-testing/src/functionalTest/kotlin/kotlinx.atomicfu.gradle.plugin.test/framework/runner/Environment.kt @@ -10,6 +10,7 @@ internal const val ENABLE_JVM_IR_TRANSFORMATION = "kotlinx.atomicfu.enableJvmIrT internal const val ENABLE_JS_IR_TRANSFORMATION = "kotlinx.atomicfu.enableJsIrTransformation" internal const val ENABLE_NATIVE_IR_TRANSFORMATION = "kotlinx.atomicfu.enableNativeIrTransformation" internal const val LOCAL_REPOSITORY_URL_PROPERTY = "localRepositoryUrl" +internal const val KOTLIN_VERSION_PROPERTY = "localRepositoryUrl" internal const val DUMMY_VERSION = "DUMMY_VERSION" internal const val LOCAL_REPO_DIR_PREFIX = "build/.m2/"