More precise native cache control.

Introduce `kotlin.native.cacheKind.$targetName`
that allows to control cache kind on per target basis.
This commit is contained in:
Sergey Bogolepov
2021-01-12 14:11:33 +07:00
parent d017e1c2ce
commit 092020577c
4 changed files with 57 additions and 20 deletions
@@ -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,
@@ -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]
@@ -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)
}
}
@@ -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<KotlinCommonToolOption
@get:Input
protected val konanCacheKind: NativeCacheKind by lazy {
project.konanCacheKind
project.getKonanCacheKind(konanTarget)
}
inner class NativeLinkOptions : KotlinCommonToolOptions {
@@ -677,7 +679,7 @@ internal class CacheBuilder(val project: Project, val binary: NativeBinary, val
get() = binary.debuggable
private val konanCacheKind: NativeCacheKind
get() = project.konanCacheKind
get() = project.getKonanCacheKind(konanTarget)
// Inputs and outputs
private val libraries: FileCollection
@@ -857,7 +859,7 @@ internal class CacheBuilder(val project: Project, val binary: NativeBinary, val
fun buildCompilerArgs(): List<String> = mutableListOf<String>().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
}
}
}