diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt index 8cbb0de9860..66100f80493 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt @@ -1290,7 +1290,7 @@ class NewMultiplatformIT : BaseGradleIT() { @Test fun testNativeCompilerDownloading() { - // The plugin shouldn't download the K/N compiler if there is no corresponding targets in the project. + // The plugin shouldn't download the K/N compiler if there are no corresponding targets in the project. with(Project("sample-old-style-app", gradleVersion, "new-mpp-lib-and-app")) { build("tasks") { assertSuccessful() @@ -1316,6 +1316,35 @@ class NewMultiplatformIT : BaseGradleIT() { assertTrue(dists.none { it.contains("-restricted-") }) } } + + // This directory actually doesn't contain a K/N distribution + // but we still can run a project configuration and check logs. + val currentDir = projectDir.absolutePath + build("tasks", "-Pkotlin.native.home=$currentDir") { + assertSuccessful() + assertContains("User-provided Kotlin/Native distribution: $currentDir") + assertNotContains("Project property 'org.jetbrains.kotlin.native.home' is deprecated") + } + + // Deprecated property. + build("tasks", "-Porg.jetbrains.kotlin.native.home=$currentDir") { + assertSuccessful() + assertContains("User-provided Kotlin/Native distribution: $currentDir") + assertContains("Project property 'org.jetbrains.kotlin.native.home' is deprecated") + } + + build("tasks", "-Pkotlin.native.version=1.3-eap-10779") { + assertSuccessful() + assertContainsRegex("Kotlin/Native distribution: .*kotlin-native-(macos|linux|windows)-1\\.3-eap-10779".toRegex()) + assertNotContains("Project property 'org.jetbrains.kotlin.native.version' is deprecated") + } + + // Deprecated property + build("tasks", "-Porg.jetbrains.kotlin.native.version=1.3-eap-10779") { + assertSuccessful() + assertContainsRegex("Kotlin/Native distribution: .*kotlin-native-(macos|linux|windows)-1\\.3-eap-10779".toRegex()) + assertContains("Project property 'org.jetbrains.kotlin.native.version' is deprecated") + } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinNativeToolRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinNativeToolRunner.kt index 84a18d979a5..6b64d0c41ba 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinNativeToolRunner.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinNativeToolRunner.kt @@ -20,6 +20,8 @@ import org.gradle.api.Named import org.gradle.api.Project import org.gradle.api.file.FileCollection import org.jetbrains.kotlin.cli.common.messages.MessageRenderer +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.KOTLIN_NATIVE_HOME import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader import org.jetbrains.kotlin.konan.KonanVersion import org.jetbrains.kotlin.konan.target.HostManager @@ -29,32 +31,16 @@ import java.util.* /** Copied from Kotlin/Native repository. */ -internal enum class KotlinNativeProjectProperty(val propertyName: String) { - KONAN_HOME_OVERRIDE("org.jetbrains.kotlin.native.home"), - KONAN_JVM_ARGS("org.jetbrains.kotlin.native.jvmArgs"), - KONAN_VERSION("org.jetbrains.kotlin.native.version"), - KONAN_USE_ENVIRONMENT_VARIABLES("org.jetbrains.kotlin.native.useEnvironmentVariables") -} - -internal fun Project.hasProperty(property: KotlinNativeProjectProperty) = hasProperty(property.propertyName) -internal fun Project.findProperty(property: KotlinNativeProjectProperty): Any? = findProperty(property.propertyName) - -internal fun Project.setProperty(property: KotlinNativeProjectProperty, value: Any?) = - extensions.extraProperties.set(property.propertyName, value) - -internal fun Project.getProperty(property: KotlinNativeProjectProperty) = findProperty(property) - ?: throw IllegalArgumentException("No such property in the project: ${property.propertyName}") - -internal val Project.jvmArgs - get() = (findProperty(KotlinNativeProjectProperty.KONAN_JVM_ARGS) as String?)?.split("\\s+".toRegex()).orEmpty() +private val Project.jvmArgs + get() = PropertiesProvider(this).nativeJvmArgs?.split("\\s+".toRegex()).orEmpty() internal val Project.konanHome: String - get() = findProperty(KotlinNativeProjectProperty.KONAN_HOME_OVERRIDE)?.let { + get() = PropertiesProvider(this).nativeHome?.let { file(it).absolutePath } ?: NativeCompilerDownloader(project).compilerDirectory.absolutePath internal val Project.konanVersion: KonanVersion - get() = project.findProperty(KotlinNativeProjectProperty.KONAN_VERSION)?.let { + get() = PropertiesProvider(this).nativeVersion?.let { KonanVersion.fromString(it.toString()) } ?: NativeCompilerDownloader.DEFAULT_KONAN_VERSION @@ -132,7 +118,7 @@ internal abstract class KonanCliRunner( if (classpath.isEmpty) { throw IllegalStateException( "Classpath of the tool is empty: $toolName\n" + - "Probably the '${KotlinNativeProjectProperty.KONAN_HOME_OVERRIDE.propertyName}' project property contains an incorrect path.\n" + + "Probably the '$KOTLIN_NATIVE_HOME' project property contains an incorrect path.\n" + "Please change it to the compiler root directory and rerun the build." ) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt index a3a20ec83a4..56b47be0cfa 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.dsl.Coroutines import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild import java.io.File import java.util.* @@ -117,7 +118,31 @@ internal class PropertiesProvider(private val project: Project) { val nativeRestrictedDistribution: Boolean? get() = booleanProperty("kotlin.native.restrictedDistribution") - // TODO: Add other native props here. + /** + * Allows a user to provide a local Kotlin/Native distribution instead of a downloaded one. + */ + val nativeHome: String? + get() = propertyWithDeprecatedVariant(KOTLIN_NATIVE_HOME, "org.jetbrains.kotlin.native.home") + + /** + * Allows a user to override Kotlin/Native version. + */ + val nativeVersion: String? + get() = propertyWithDeprecatedVariant("kotlin.native.version", "org.jetbrains.kotlin.native.version") + + /** + * Allows a user to specify additional arguments of a JVM executing a K/N compiler. + */ + val nativeJvmArgs: String? + get() = propertyWithDeprecatedVariant("kotlin.native.jvmArgs", "org.jetbrains.kotlin.native.jvmArgs") + + private fun propertyWithDeprecatedVariant(propName: String, deprecatedPropName: String): String? { + val deprecatedProperty = property(deprecatedPropName) + if (deprecatedProperty != null) { + SingleWarningPerBuild.show(project, "Project property '$deprecatedPropName' is deprecated. Please use '$propName' instead.") + } + return property(propName) ?: deprecatedProperty + } private fun booleanProperty(propName: String): Boolean? = property(propName)?.toBoolean() @@ -128,4 +153,8 @@ internal class PropertiesProvider(private val project: Project) { } else { localProperties.getProperty(propName) } + + companion object { + internal const val KOTLIN_NATIVE_HOME = "kotlin.native.home" + } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetPreset.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetPreset.kt index ec00d388e8b..96692382b0d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetPreset.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetPreset.kt @@ -8,24 +8,14 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.Project import org.gradle.api.artifacts.Dependency -import org.gradle.api.internal.file.FileResolver -import org.gradle.api.plugins.JavaPlugin -import org.gradle.internal.reflect.Instantiator -import org.jetbrains.kotlin.compilerRunner.KotlinNativeProjectProperty -import org.jetbrains.kotlin.compilerRunner.hasProperty import org.jetbrains.kotlin.compilerRunner.konanHome -import org.jetbrains.kotlin.gradle.dsl.KotlinCompile -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions -import org.jetbrains.kotlin.gradle.dsl.kotlinExtension -import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinTask -import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinNativeTargetConfigurator +import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader -import org.jetbrains.kotlin.konan.KonanVersion import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget -import java.io.File -import java.util.* class KotlinNativeTargetPreset( private val name: String, @@ -46,8 +36,11 @@ class KotlinNativeTargetPreset( extensions.extraProperties.set(KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY, konanHome) } + private val isKonanHomeOverridden: Boolean + get() = PropertiesProvider(project).nativeHome != null + private fun setupNativeCompiler() = with(project) { - if (!hasProperty(KotlinNativeProjectProperty.KONAN_HOME_OVERRIDE)) { + if (!isKonanHomeOverridden) { NativeCompilerDownloader(this).downloadIfNeeded() logger.info("Kotlin/Native distribution: $konanHome") } else {