diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/nativeToolRunners.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/nativeToolRunners.kt index 25ba6ba7a19..546c35e700d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/nativeToolRunners.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/nativeToolRunners.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.cli.common.messages.MessageRenderer import org.jetbrains.kotlin.gradle.dsl.NativeCacheKind import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.plugin.mpp.isAtLeast +import org.jetbrains.kotlin.gradle.tasks.CacheBuilder import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader import org.jetbrains.kotlin.konan.CompilerVersion import org.jetbrains.kotlin.konan.properties.resolvablePropertyString @@ -33,8 +34,15 @@ internal val Project.konanVersion: CompilerVersion get() = PropertiesProvider(this).nativeVersion?.let { CompilerVersion.fromString(it) } ?: NativeCompilerDownloader.DEFAULT_KONAN_VERSION -internal val Project.konanCacheKind: NativeCacheKind - get() = PropertiesProvider(this).nativeCacheKind +internal fun Project.getKonanCacheKind(target: KonanTarget): NativeCacheKind { + val commonCacheKind = PropertiesProvider(this).nativeCacheKind + val targetCacheKind = PropertiesProvider(this).nativeCacheKindForTarget(target) + return when { + targetCacheKind != null -> targetCacheKind + commonCacheKind != null -> commonCacheKind + else -> CacheBuilder.defaultCacheKindForTarget(target) + } +} internal abstract class KotlinNativeToolRunner( protected val toolName: String, 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 71c59fba972..de35734af2b 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.tasks.CacheBuilder import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild +import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.statistics.metrics.StringMetrics import java.io.File import java.util.* @@ -195,10 +196,16 @@ internal class PropertiesProvider private constructor(private val project: Proje get() = property("kotlin.commonizer.jvmArgs") /** - * Dependencies caching strategy. The default is static. + * Dependencies caching strategy for all targets that support caches. */ - val nativeCacheKind: NativeCacheKind - get() = property("kotlin.native.cacheKind")?.let { NativeCacheKind.byCompilerArgument(it) } ?: CacheBuilder.DEFAULT_CACHE_KIND + val nativeCacheKind: NativeCacheKind? + get() = property("kotlin.native.cacheKind")?.let { NativeCacheKind.byCompilerArgument(it) } + + /** + * Dependencies caching strategy for [target]. + */ + fun nativeCacheKindForTarget(target: KonanTarget): NativeCacheKind? = + property("kotlin.native.cacheKind.${target.name}")?.let { NativeCacheKind.byCompilerArgument(it) } /** * Ignore overflow in [org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessageOutputStreamHandler] diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/PlatformLibrariesGenerator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/PlatformLibrariesGenerator.kt index 6dac2960d61..402254a2d41 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/PlatformLibrariesGenerator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/PlatformLibrariesGenerator.kt @@ -7,7 +7,7 @@ package org.jetbrains.kotlin.gradle.targets.native.internal import org.gradle.api.Project import org.jetbrains.kotlin.compilerRunner.KotlinNativeLibraryGenerationRunner -import org.jetbrains.kotlin.compilerRunner.konanCacheKind +import org.jetbrains.kotlin.compilerRunner.getKonanCacheKind import org.jetbrains.kotlin.compilerRunner.konanHome import org.jetbrains.kotlin.gradle.dsl.NativeCacheKind import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider @@ -35,8 +35,12 @@ internal class PlatformLibrariesGenerator(val project: Project, val konanTarget: private val defDirectory = File(distribution.platformDefs(konanTarget)).absoluteFile + private val konanCacheKind: NativeCacheKind by lazy { + project.getKonanCacheKind(konanTarget) + } + private val shouldBuildCaches: Boolean = - CacheBuilder.cacheWorksFor(konanTarget) && project.konanCacheKind != NativeCacheKind.NONE + CacheBuilder.cacheWorksFor(konanTarget, project) && konanCacheKind != NativeCacheKind.NONE private val mode: String? by lazy { PropertiesProvider(project).nativePlatformLibrariesMode @@ -72,10 +76,10 @@ internal class PlatformLibrariesGenerator(val project: Project, val konanTarget: } val cacheDirectory = CacheBuilder.getRootCacheDirectory( - File(project.konanHome), konanTarget, true, project.konanCacheKind + File(project.konanHome), konanTarget, true, konanCacheKind ) return presentDefs.toPlatformLibNames().all { - cacheDirectory.resolve(CacheBuilder.getCacheFileName(it, project.konanCacheKind)).listFilesOrEmpty().isNotEmpty() + cacheDirectory.resolve(CacheBuilder.getCacheFileName(it, konanCacheKind)).listFilesOrEmpty().isNotEmpty() } } @@ -130,7 +134,7 @@ internal class PlatformLibrariesGenerator(val project: Project, val konanTarget: // Don't run the generator if libraries/caches for this target were already built during this Gradle invocation. val alreadyGenerated = alreadyProcessed.isGenerated(platformLibsDirectory) - val alreadyCached = alreadyProcessed.isCached(platformLibsDirectory, project.konanCacheKind) + val alreadyCached = alreadyProcessed.isCached(platformLibsDirectory, konanCacheKind) if ((alreadyGenerated && alreadyCached) || !defDirectory.exists()) { return } @@ -143,14 +147,14 @@ internal class PlatformLibrariesGenerator(val project: Project, val konanTarget: val cachesAreReady = checkCaches() if (cachesAreReady) { - alreadyProcessed.setCached(platformLibsDirectory, project.konanCacheKind) + alreadyProcessed.setCached(platformLibsDirectory, konanCacheKind) } val generationMessage = when { !platformLibsAreReady && !cachesAreReady -> - "Generate and precompile platform libraries for $konanTarget (precompilation: ${project.konanCacheKind.visibleName})" + "Generate and precompile platform libraries for $konanTarget (precompilation: ${konanCacheKind.visibleName})" platformLibsAreReady && !cachesAreReady -> - "Precompile platform libraries for $konanTarget (precompilation: ${project.konanCacheKind.visibleName})" + "Precompile platform libraries for $konanTarget (precompilation: ${konanCacheKind.visibleName})" !platformLibsAreReady && cachesAreReady -> "Generate platform libraries for $konanTarget" else -> { @@ -173,7 +177,7 @@ internal class PlatformLibrariesGenerator(val project: Project, val konanTarget: val librariesAreActuallyCached = checkCaches() assert(librariesAreActuallyCached) { "Some platform libraries were not precompiled" } if (librariesAreActuallyCached) { - alreadyProcessed.setCached(platformLibsDirectory, project.konanCacheKind) + alreadyProcessed.setCached(platformLibsDirectory, konanCacheKind) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt index a3b8ee549ab..236c44d860e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt @@ -34,10 +34,12 @@ import org.jetbrains.kotlin.gradle.utils.klibModuleName import org.jetbrains.kotlin.gradle.utils.newProperty import org.jetbrains.kotlin.gradle.utils.listFilesOrEmpty import org.jetbrains.kotlin.konan.library.KLIB_INTEROP_IR_PROVIDER_IDENTIFIER +import org.jetbrains.kotlin.konan.properties.resolvablePropertyList import org.jetbrains.kotlin.konan.properties.saveToFile import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.CompilerOutputKind.* import org.jetbrains.kotlin.konan.target.Distribution +import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.library.* import java.io.File @@ -520,7 +522,7 @@ open class KotlinNativeLink : AbstractKotlinNativeCompile = mutableListOf().apply { - if (konanCacheKind != NativeCacheKind.NONE && !optimized && cacheWorksFor(konanTarget)) { + if (konanCacheKind != NativeCacheKind.NONE && !optimized && cacheWorksFor(konanTarget, project)) { rootCacheDirectory.mkdirs() ensureCompilerProvidedLibsPrecached() add("-Xcache-directory=${rootCacheDirectory.absolutePath}") @@ -896,10 +898,26 @@ internal class CacheBuilder(val project: Project, val binary: NativeBinary, val "${baseName}-cache" } ?: error("No output for kind $cacheKind") - internal fun cacheWorksFor(target: KonanTarget) = - target == KonanTarget.IOS_X64 || target == KonanTarget.MACOS_X64 + private fun getCacheableTargets(project: Project) = + Distribution(project.konanHome) + .properties + .resolvablePropertyList("cacheableTargets", HostManager.hostName) + .map { KonanTarget.predefinedTargets.getValue(it) } - internal val DEFAULT_CACHE_KIND: NativeCacheKind = NativeCacheKind.STATIC + // Targets with well-tested static caches that can be enabled by default. + // TODO: Move it to konan.properties. + private val targetsWithStableStaticCaches = + setOf(KonanTarget.IOS_X64, KonanTarget.MACOS_X64) + + internal fun cacheWorksFor(target: KonanTarget, project: Project) = + target in getCacheableTargets(project) + + internal fun defaultCacheKindForTarget(target: KonanTarget): NativeCacheKind = + if (target in targetsWithStableStaticCaches) { + NativeCacheKind.STATIC + } else { + NativeCacheKind.NONE + } } }