diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NativePlatformLibsIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NativePlatformLibsIT.kt index 435ba2c8296..84c2497742f 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NativePlatformLibsIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NativePlatformLibsIT.kt @@ -40,14 +40,31 @@ class NativePlatformLibsIT : BaseGradleIT() { } } + private fun BaseGradleIT.Project.buildWithLightDist(vararg tasks: String, check: CompiledProject.() -> Unit) = + build(*tasks, "-Pkotlin.native.distribution.type=light", check = check) + @Test fun testNoGenerationForOldCompiler() = with(platformLibrariesProject("linuxX64")) { deleteInstalledCompilers() // Check that we don't run the library generator for old compiler distributions where libraries are prebuilt. // Don't run the build to reduce execution time. - build("tasks", "-Pkotlin.native.version=1.3.60") { + build("tasks", "-Pkotlin.native.version=$oldCompilerVersion") { assertSuccessful() + assertContains("Unpack Kotlin/Native compiler to ") + assertContainsRegex("Kotlin/Native distribution: .*kotlin-native-(macos|linux|windows)".toRegex()) + assertNotContains("Generate platform libraries for ") + } + } + + @Test + fun testNoGenerationByDefault() = with(platformLibrariesProject("linuxX64")) { + deleteInstalledCompilers() + + // Check that a prebuilt distribution is used by default. + build("assemble") { + assertSuccessful() + assertContainsRegex("Kotlin/Native distribution: .*kotlin-native-prebuilt-(macos|linux|windows)".toRegex()) assertNotContains("Generate platform libraries for ") } } @@ -66,14 +83,15 @@ class NativePlatformLibsIT : BaseGradleIT() { with(rootProject) { // Check that platform libraries are correctly generated for both root project and a subproject. - build("assemble") { + buildWithLightDist("assemble") { assertSuccessful() + assertContainsRegex("Kotlin/Native distribution: .*kotlin-native-(macos|linux|windows)".toRegex()) assertContains("Generate platform libraries for linux_x64") assertContains("Generate platform libraries for linux_arm64") } // Check that we don't generate libraries during a second run. Don't clean to reduce execution time. - build("assemble") { + buildWithLightDist("assemble") { assertSuccessful() assertNotContains("Generate platform libraries for ") } @@ -89,7 +107,7 @@ class NativePlatformLibsIT : BaseGradleIT() { else -> KonanTarget.IOS_X64 } - platformLibrariesProject(unsupportedTarget.presetName).build("assemble") { + platformLibrariesProject(unsupportedTarget.presetName).buildWithLightDist("assemble") { assertSuccessful() assertNotContains("Generate platform libraries for ") } @@ -104,13 +122,13 @@ class NativePlatformLibsIT : BaseGradleIT() { with(platformLibrariesProject("iosX64")) { // Build Mac libraries without caches. - build("tasks") { + buildWithLightDist("tasks") { assertSuccessful() assertContains("Generate platform libraries for ios_x64") } // Change cache kind and check that platform libraries generator was executed. - build("tasks", "-Pkotlin.native.cacheKind=static") { + buildWithLightDist("tasks", "-Pkotlin.native.cacheKind=static") { assertSuccessful() assertContains("Precompile platform libraries for ios_x64 (precompilation: static)") } @@ -128,12 +146,53 @@ class NativePlatformLibsIT : BaseGradleIT() { } } + @Test + fun testDeprecatedRestrictedDistributionProperty() = with(platformLibrariesProject("linuxX64")) { + build("tasks", "-Pkotlin.native.restrictedDistribution=true", "-Pkotlin.native.version=$oldCompilerVersion") { + assertSuccessful() + assertContains("Warning: Project property 'kotlin.native.restrictedDistribution' is deprecated. Please use 'kotlin.native.distribution.type=light' instead") + + // Restricted distribution is available for Mac hosts only. + if (HostManager.hostIsMac) { + assertContainsRegex("Kotlin/Native distribution: .*kotlin-native-restricted-(macos|linux|windows)".toRegex()) + } else { + assertNotContains("Kotlin/Native distribution: .*kotlin-native-restricted-(macos|linux|windows)".toRegex()) + } + } + + // We allow using this deprecated property for 1.4 too. Just download the distribution without platform libs in this case. + build("tasks", "-Pkotlin.native.restrictedDistribution=true") { + assertSuccessful() + assertContains("Warning: Project property 'kotlin.native.restrictedDistribution' is deprecated. Please use 'kotlin.native.distribution.type=light' instead") + assertContainsRegex("Kotlin/Native distribution: .*kotlin-native-(macos|linux|windows)".toRegex()) + } + } + + @Test + fun testSettingDistributionTypeForOldCompiler() = with(platformLibrariesProject("linuxX64")) { + build("tasks", "-Pkotlin.native.distribution.type=prebuilt", "-Pkotlin.native.version=$oldCompilerVersion") { + assertSuccessful() + assertContainsRegex("Kotlin/Native distribution: .*kotlin-native-(macos|linux|windows)".toRegex()) + } + + build("tasks", "-Pkotlin.native.distribution.type=light", "-Pkotlin.native.version=$oldCompilerVersion") { + assertSuccessful() + + // Restricted distribution is available for Mac hosts only. + if (HostManager.hostIsMac) { + assertContainsRegex("Kotlin/Native distribution: .*kotlin-native-restricted-(macos|linux|windows)".toRegex()) + } else { + assertNotContains("Kotlin/Native distribution: .*kotlin-native-restricted-(macos|linux|windows)".toRegex()) + } + } + } + @Test fun testSettingGenerationMode() = with(platformLibrariesProject("linuxX64")) { deleteInstalledCompilers() // Check that user can change generation mode used by the cinterop tool. - build("tasks", "-Pkotlin.native.platform.libraries.mode=metadata") { + buildWithLightDist("tasks", "-Pkotlin.native.platform.libraries.mode=metadata") { assertSuccessful() assertContainsRegex("Run tool: \"generatePlatformLibraries\" with args: .* -mode metadata".toRegex()) } @@ -144,13 +203,13 @@ class NativePlatformLibsIT : BaseGradleIT() { deleteInstalledCompilers() // Install the compiler at the first time. Don't build to reduce execution time. - build("tasks") { + buildWithLightDist("tasks") { assertSuccessful() assertContains("Generate platform libraries for linux_x64") } // Reinstall the compiler. - build("tasks", "-Pkotlin.native.reinstall=true") { + buildWithLightDist("tasks", "-Pkotlin.native.reinstall=true") { assertSuccessful() assertContains("Unpack Kotlin/Native compiler to ") assertContains("Generate platform libraries for linux_x64") diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt index 6f899b4725c..4baf36cff2a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinProjectExtension.kt @@ -15,14 +15,11 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType.* import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsSingleTargetPreset import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget -import org.jetbrains.kotlin.gradle.plugin.mpp.isAtLeast import org.jetbrains.kotlin.gradle.targets.js.calculateJsCompilerType import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrSingleTargetPreset import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName -import org.jetbrains.kotlin.konan.CompilerVersion import org.jetbrains.kotlin.konan.target.CompilerOutputKind -import org.jetbrains.kotlin.konan.target.KonanTarget import kotlin.reflect.KClass private const val KOTLIN_PROJECT_EXTENSION_NAME = "kotlin" @@ -239,24 +236,3 @@ enum class ExplicitApiMode(private val cliOption: String) { fun toCompilerArg() = "-Xexplicit-api=$cliOption" } - -enum class NativeDistributionType(val suffix: String?) { - LIGHT(null) { - override fun isAvailableFor(host: KonanTarget, version: CompilerVersion) = true - }, - RESTRICTED("restricted") { - override fun isAvailableFor(host: KonanTarget, version: CompilerVersion): Boolean = - host == KonanTarget.MACOS_X64 && version.major == 1 && version.minor == 3 - }, - PREBUILT("prebuilt") { - override fun isAvailableFor(host: KonanTarget, version: CompilerVersion): Boolean = - version.isAtLeast(1, 4, 0) - }; - - abstract fun isAvailableFor(host: KonanTarget, version: CompilerVersion): Boolean - - companion object { - fun byCompilerArgument(argument: String): NativeDistributionType? = - values().firstOrNull { it.name.equals(argument, ignoreCase = true) } - } -} \ No newline at end of file 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 80d15754e3f..8d90307d862 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 @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.gradle.plugin import org.gradle.api.Project import org.jetbrains.kotlin.gradle.dsl.Coroutines import org.jetbrains.kotlin.gradle.dsl.NativeCacheKind -import org.jetbrains.kotlin.gradle.dsl.NativeDistributionType import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType.Companion.jsCompilerProperty import org.jetbrains.kotlin.gradle.targets.native.DisabledNativeTargetsReporter import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile @@ -126,27 +125,17 @@ internal class PropertiesProvider private constructor(private val project: Proje /** * Allow a user to choose distribution type. The following distribution types are available: - * - regular - The default distribution. Includes all platform libraries in 1.3 and generates them at the user side in 1.4. - * - restricted - Doesn't include Apple platform libraries. Available for MacOS only and in 1.3 only. - * - prebuilt - Includes all platform libraries. Available in 1.4 only. Used to workaround possible problems with library generation at the use side. + * - light - Doesn't include platform libraries and generates them at the user side. For 1.3 corresponds to the restricted distribution. + * - prebuilt - Includes all platform libraries. */ - val nativeDistributionType: NativeDistributionType? - get() { - var result = property("kotlin.native.distribution.type")?.let { - NativeDistributionType.byCompilerArgument(it) - } + val nativeDistributionType: String? + get() = property("kotlin.native.distribution.type") - val deprecatedRestricted = booleanProperty("kotlin.native.restrictedDistribution") - if (result == null && deprecatedRestricted != null) { - SingleWarningPerBuild.show( - project, - "Project property 'kotlin.native.restrictedDistribution' is deprecated. Please use 'kotlin.native.distribution.type=restricted' instead" - ) - result = if (deprecatedRestricted) NativeDistributionType.RESTRICTED else NativeDistributionType.LIGHT - } - - return result - } + /** + * A property that was used to choose a restricted distribution in 1.3. + */ + val nativeDeprecatedRestricted: Boolean? + get() = booleanProperty("kotlin.native.restrictedDistribution") /** * Allows a user to force a particular cinterop mode for platform libraries generation. Available modes: sourcecode, metadata. 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 0770c925dea..a019162945f 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 @@ -13,10 +13,10 @@ import org.gradle.api.Project import org.gradle.api.invocation.Gradle import org.jetbrains.kotlin.compilerRunner.konanHome import org.jetbrains.kotlin.compilerRunner.konanVersion -import org.jetbrains.kotlin.gradle.dsl.NativeDistributionType.LIGHT import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.targets.native.DisabledNativeTargetsReporter +import org.jetbrains.kotlin.gradle.targets.native.internal.NativeDistributionTypeProvider import org.jetbrains.kotlin.gradle.targets.native.internal.PlatformLibrariesGenerator import org.jetbrains.kotlin.gradle.targets.native.internal.setUpKotlinNativePlatformDependencies import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader @@ -64,10 +64,8 @@ abstract class AbstractKotlinNativeTargetPreset( logger.info("User-provided Kotlin/Native distribution: $konanHome") } - val distributionType = PropertiesProvider(project).nativeDistributionType - if (konanVersion.isAtLeast(1, 4, 0) && - (distributionType == null || distributionType == LIGHT) - ) { + val distributionType = NativeDistributionTypeProvider(project).getDistributionType(konanVersion) + if (distributionType.mustGeneratePlatformLibs) { PlatformLibrariesGenerator(project, konanTarget).generatePlatformLibsIfNeeded() } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/NativeCompilerDownloader.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/NativeCompilerDownloader.kt index afd13b39f67..e96f85e5c52 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/NativeCompilerDownloader.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/NativeCompilerDownloader.kt @@ -12,9 +12,9 @@ import org.gradle.api.file.FileTree import org.gradle.api.logging.Logger import org.jetbrains.kotlin.compilerRunner.KotlinNativeCompilerRunner import org.jetbrains.kotlin.compilerRunner.konanVersion -import org.jetbrains.kotlin.gradle.dsl.NativeDistributionType import org.jetbrains.kotlin.gradle.logging.kotlinInfo -import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider +import org.jetbrains.kotlin.gradle.targets.native.internal.NativeDistributionType +import org.jetbrains.kotlin.gradle.targets.native.internal.NativeDistributionTypeProvider import org.jetbrains.kotlin.konan.CompilerVersion import org.jetbrains.kotlin.konan.MetaVersion import org.jetbrains.kotlin.konan.target.HostManager @@ -41,9 +41,7 @@ class NativeCompilerDownloader( get() = project.logger private val distributionType: NativeDistributionType - get() = PropertiesProvider(project).nativeDistributionType?.takeIf { - it.isAvailableFor(HostManager.host, compilerVersion) - } ?: NativeDistributionType.LIGHT + get() = NativeDistributionTypeProvider(project).getDistributionType(compilerVersion) private val simpleOsName: String get() = HostManager.simpleOsName() diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/NativeDistributionType.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/NativeDistributionType.kt new file mode 100644 index 00000000000..0140d5efd86 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/NativeDistributionType.kt @@ -0,0 +1,76 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.targets.native.internal + +import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider +import org.jetbrains.kotlin.gradle.plugin.mpp.isAtLeast +import org.jetbrains.kotlin.gradle.targets.native.internal.NativeDistributionType.* +import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild +import org.jetbrains.kotlin.konan.CompilerVersion +import org.jetbrains.kotlin.konan.target.HostManager + +internal enum class NativeDistributionType(val suffix: String?, val mustGeneratePlatformLibs: Boolean) { + LIGHT(null, true), + PREBUILT("prebuilt", false), + + // Distribution types for 1.3: + LIGHT_1_3("restricted", false), // aka "restricted" distribution without platform libs for Apple targets. + PREBUILT_1_3(null, false) +} + +internal class NativeDistributionTypeProvider(private val project: Project) { + private val propertiesProvider = PropertiesProvider(project) + + private fun warning(message: String) = SingleWarningPerBuild.show(project, "Warning: $message") + + private fun chooseDistributionType( + prebuiltType: NativeDistributionType, + lightType: NativeDistributionType, + defaultType: NativeDistributionType + ): NativeDistributionType { + val requestedByUser = propertiesProvider.nativeDistributionType?.toLowerCase() + val deprecatedRestricted = propertiesProvider.nativeDeprecatedRestricted + + // A case when a deprecated property (kotlin.native.restrictedDistribution) is used to choose the restricted distribution. + // Effectively the restricted distribution from 1.3 and the light distribution from 1.4 are the same, + // so we allow user to specify kotlin.native.restrictedDistribution in both 1.3 and 1.4 + if (requestedByUser == null && deprecatedRestricted != null) { + return if (deprecatedRestricted) { + lightType + } else { + defaultType + } + } + + // A normal path: no deprecated properties, only kotlin.native.distribution.type. + return when (requestedByUser) { + null -> defaultType + "prebuilt" -> prebuiltType + "light" -> lightType + else -> { + warning("Unknown Kotlin/Native distribution type: $requestedByUser. Available values: prebuilt, light") + defaultType + } + } + } + + fun getDistributionType(version: CompilerVersion): NativeDistributionType { + if (propertiesProvider.nativeDeprecatedRestricted != null) { + warning("Project property 'kotlin.native.restrictedDistribution' is deprecated. Please use 'kotlin.native.distribution.type=light' instead") + } + + return if (version.isAtLeast(1, 4, 0)) { + chooseDistributionType(prebuiltType = PREBUILT, lightType = LIGHT, defaultType = PREBUILT) + } else { + // In 1.3, the distribution type can be chosen for Mac hosts only. + if (!HostManager.hostIsMac) { + return PREBUILT_1_3 + } + chooseDistributionType(prebuiltType = PREBUILT_1_3, lightType = LIGHT_1_3, defaultType = PREBUILT_1_3) + } + } +}