[K/N][Gradle] Use build service to read konan.properties
Also pass additionalCacheFlags when compiling compiler caches.
This commit is contained in:
committed by
TeamCityServer
parent
84e7b53926
commit
708931b404
+2
-3
@@ -11,10 +11,9 @@ import org.jetbrains.kotlin.gradle.dsl.NativeCacheKind
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.isAtLeast
|
import org.jetbrains.kotlin.gradle.plugin.mpp.isAtLeast
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.nativeUseEmbeddableCompilerJar
|
import org.jetbrains.kotlin.gradle.plugin.mpp.nativeUseEmbeddableCompilerJar
|
||||||
import org.jetbrains.kotlin.gradle.tasks.CacheBuilder
|
import org.jetbrains.kotlin.gradle.targets.native.KonanPropertiesBuildService
|
||||||
import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader
|
import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader
|
||||||
import org.jetbrains.kotlin.konan.CompilerVersion
|
import org.jetbrains.kotlin.konan.CompilerVersion
|
||||||
import org.jetbrains.kotlin.konan.file.File
|
|
||||||
import org.jetbrains.kotlin.konan.properties.resolvablePropertyString
|
import org.jetbrains.kotlin.konan.properties.resolvablePropertyString
|
||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
@@ -42,7 +41,7 @@ internal fun Project.getKonanCacheKind(target: KonanTarget): NativeCacheKind {
|
|||||||
return when {
|
return when {
|
||||||
targetCacheKind != null -> targetCacheKind
|
targetCacheKind != null -> targetCacheKind
|
||||||
commonCacheKind != null -> commonCacheKind
|
commonCacheKind != null -> commonCacheKind
|
||||||
else -> CacheBuilder.defaultCacheKindForTarget(target)
|
else -> KonanPropertiesBuildService.registerIfAbsent(gradle).get().defaultCacheKindForTarget(target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+72
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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
|
||||||
|
|
||||||
|
import org.gradle.api.invocation.Gradle
|
||||||
|
import org.gradle.api.provider.Property
|
||||||
|
import org.gradle.api.provider.Provider
|
||||||
|
import org.gradle.api.services.BuildService
|
||||||
|
import org.gradle.api.services.BuildServiceParameters
|
||||||
|
import org.jetbrains.kotlin.compilerRunner.konanHome
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.NativeCacheKind
|
||||||
|
import org.jetbrains.kotlin.konan.properties.resolvablePropertyList
|
||||||
|
import org.jetbrains.kotlin.konan.target.Distribution
|
||||||
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
abstract class KonanPropertiesBuildService : BuildService<KonanPropertiesBuildService.Parameters> {
|
||||||
|
|
||||||
|
internal interface Parameters : BuildServiceParameters {
|
||||||
|
val konanHome: Property<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
private val properties: Properties by lazy {
|
||||||
|
Distribution(parameters.konanHome.get()).properties
|
||||||
|
}
|
||||||
|
|
||||||
|
private val cacheableTargets: List<KonanTarget> by lazy {
|
||||||
|
properties
|
||||||
|
.resolvablePropertyList("cacheableTargets", HostManager.hostName)
|
||||||
|
.map { KonanTarget.predefinedTargets.getValue(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val targetsWithOptInStaticCaches: List<KonanTarget> by lazy {
|
||||||
|
properties
|
||||||
|
.resolvablePropertyList("optInCacheableTargets", HostManager.hostName)
|
||||||
|
.map { KonanTarget.predefinedTargets.getValue(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun defaultCacheKindForTarget(target: KonanTarget): NativeCacheKind =
|
||||||
|
if (target in cacheableTargets && target !in targetsWithOptInStaticCaches) {
|
||||||
|
NativeCacheKind.STATIC
|
||||||
|
} else {
|
||||||
|
NativeCacheKind.NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun cacheWorksFor(target: KonanTarget): Boolean =
|
||||||
|
target in cacheableTargets
|
||||||
|
|
||||||
|
internal fun additionalCacheFlags(target: KonanTarget): List<String> =
|
||||||
|
properties.resolvablePropertyList("additionalCacheFlags", target.visibleName)
|
||||||
|
|
||||||
|
internal val compilerVersion: String? by lazy {
|
||||||
|
properties["compilerVersion"]?.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun registerIfAbsent(gradle: Gradle): Provider<KonanPropertiesBuildService> =
|
||||||
|
gradle.sharedServices.registerIfAbsent(serviceName, KonanPropertiesBuildService::class.java) { service ->
|
||||||
|
service.parameters.konanHome.set(gradle.rootProject.konanHome)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val serviceName: String
|
||||||
|
get() {
|
||||||
|
val clazz = KonanPropertiesBuildService::class.java
|
||||||
|
return "${clazz}_${clazz.classLoader.hashCode()}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
-1
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.compilerRunner.getKonanCacheKind
|
|||||||
import org.jetbrains.kotlin.compilerRunner.konanHome
|
import org.jetbrains.kotlin.compilerRunner.konanHome
|
||||||
import org.jetbrains.kotlin.gradle.dsl.NativeCacheKind
|
import org.jetbrains.kotlin.gradle.dsl.NativeCacheKind
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.native.KonanPropertiesBuildService
|
||||||
import org.jetbrains.kotlin.gradle.tasks.CacheBuilder
|
import org.jetbrains.kotlin.gradle.tasks.CacheBuilder
|
||||||
import org.jetbrains.kotlin.gradle.tasks.addArg
|
import org.jetbrains.kotlin.gradle.tasks.addArg
|
||||||
import org.jetbrains.kotlin.gradle.utils.lifecycleWithDuration
|
import org.jetbrains.kotlin.gradle.utils.lifecycleWithDuration
|
||||||
@@ -35,12 +36,15 @@ internal class PlatformLibrariesGenerator(val project: Project, val konanTarget:
|
|||||||
private val defDirectory =
|
private val defDirectory =
|
||||||
File(distribution.platformDefs(konanTarget)).absoluteFile
|
File(distribution.platformDefs(konanTarget)).absoluteFile
|
||||||
|
|
||||||
|
private val konanPropertiesService: KonanPropertiesBuildService
|
||||||
|
get() = KonanPropertiesBuildService.registerIfAbsent(project.gradle).get()
|
||||||
|
|
||||||
private val konanCacheKind: NativeCacheKind by lazy {
|
private val konanCacheKind: NativeCacheKind by lazy {
|
||||||
project.getKonanCacheKind(konanTarget)
|
project.getKonanCacheKind(konanTarget)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val shouldBuildCaches: Boolean =
|
private val shouldBuildCaches: Boolean =
|
||||||
CacheBuilder.cacheWorksFor(konanTarget, project) && konanCacheKind != NativeCacheKind.NONE
|
konanPropertiesService.cacheWorksFor(konanTarget) && konanCacheKind != NativeCacheKind.NONE
|
||||||
|
|
||||||
private val mode: String? by lazy {
|
private val mode: String? by lazy {
|
||||||
PropertiesProvider(project).nativePlatformLibrariesMode
|
PropertiesProvider(project).nativePlatformLibrariesMode
|
||||||
@@ -117,6 +121,10 @@ internal class PlatformLibrariesGenerator(val project: Project, val konanTarget:
|
|||||||
CacheBuilder.getRootCacheDirectory(File(konanHome), konanTarget, true, konanCacheKind).absolutePath
|
CacheBuilder.getRootCacheDirectory(File(konanHome), konanTarget, true, konanCacheKind).absolutePath
|
||||||
)
|
)
|
||||||
args.addArg("-cache-arg", "-g")
|
args.addArg("-cache-arg", "-g")
|
||||||
|
val additionalCacheFlags = konanPropertiesService.additionalCacheFlags(konanTarget)
|
||||||
|
additionalCacheFlags.forEach {
|
||||||
|
args.addArg("-cache-arg", it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mode?.let {
|
mode?.let {
|
||||||
|
|||||||
+17
-48
@@ -33,31 +33,29 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeCompilationData
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeFragmentMetadataCompilationData
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeFragmentMetadataCompilationData
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.isMainCompilationData
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.isMainCompilationData
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
|
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.native.KonanPropertiesBuildService
|
||||||
import org.jetbrains.kotlin.gradle.targets.native.internal.isAllowCommonizer
|
import org.jetbrains.kotlin.gradle.targets.native.internal.isAllowCommonizer
|
||||||
import org.jetbrains.kotlin.gradle.utils.*
|
import org.jetbrains.kotlin.gradle.utils.*
|
||||||
import org.jetbrains.kotlin.gradle.utils.klibModuleName
|
|
||||||
import org.jetbrains.kotlin.gradle.utils.listFilesOrEmpty
|
import org.jetbrains.kotlin.gradle.utils.listFilesOrEmpty
|
||||||
import org.jetbrains.kotlin.konan.CompilerVersion
|
import org.jetbrains.kotlin.konan.CompilerVersion
|
||||||
import org.jetbrains.kotlin.konan.library.KLIB_INTEROP_IR_PROVIDER_IDENTIFIER
|
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.properties.saveToFile
|
||||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||||
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.Distribution
|
||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import org.jetbrains.kotlin.library.*
|
import org.jetbrains.kotlin.library.*
|
||||||
import org.jetbrains.kotlin.project.model.LanguageSettings
|
import org.jetbrains.kotlin.project.model.LanguageSettings
|
||||||
import org.jetbrains.kotlin.utils.ResolvedDependency as KResolvedDependency
|
|
||||||
import org.jetbrains.kotlin.utils.ResolvedDependencyId as KResolvedDependencyId
|
|
||||||
import org.jetbrains.kotlin.utils.ResolvedDependencies as KResolvedDependencies
|
|
||||||
import org.jetbrains.kotlin.utils.ResolvedDependenciesSupport as KResolvedDependenciesSupport
|
|
||||||
import org.jetbrains.kotlin.utils.ResolvedDependencyArtifactPath as KResolvedDependencyArtifactPath
|
|
||||||
import org.jetbrains.kotlin.utils.ResolvedDependencyVersion as KResolvedDependencyVersion
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import org.jetbrains.kotlin.konan.file.File as KFile
|
import org.jetbrains.kotlin.konan.file.File as KFile
|
||||||
|
import org.jetbrains.kotlin.utils.ResolvedDependencies as KResolvedDependencies
|
||||||
|
import org.jetbrains.kotlin.utils.ResolvedDependenciesSupport as KResolvedDependenciesSupport
|
||||||
|
import org.jetbrains.kotlin.utils.ResolvedDependency as KResolvedDependency
|
||||||
|
import org.jetbrains.kotlin.utils.ResolvedDependencyArtifactPath as KResolvedDependencyArtifactPath
|
||||||
|
import org.jetbrains.kotlin.utils.ResolvedDependencyId as KResolvedDependencyId
|
||||||
|
import org.jetbrains.kotlin.utils.ResolvedDependencyVersion as KResolvedDependencyVersion
|
||||||
|
|
||||||
// TODO: It's just temporary tasks used while KN isn't integrated with Big Kotlin compilation infrastructure.
|
// TODO: It's just temporary tasks used while KN isn't integrated with Big Kotlin compilation infrastructure.
|
||||||
// region Useful extensions
|
// region Useful extensions
|
||||||
@@ -730,8 +728,12 @@ private class ExternalDependenciesBuilder(
|
|||||||
private val sourceCodeModuleId: KResolvedDependencyId =
|
private val sourceCodeModuleId: KResolvedDependencyId =
|
||||||
intermediateLibraryName?.let { KResolvedDependencyId(it) } ?: KResolvedDependencyId.DEFAULT_SOURCE_CODE_MODULE_ID
|
intermediateLibraryName?.let { KResolvedDependencyId(it) } ?: KResolvedDependencyId.DEFAULT_SOURCE_CODE_MODULE_ID
|
||||||
|
|
||||||
|
private val konanPropertiesService: KonanPropertiesBuildService
|
||||||
|
get() = KonanPropertiesBuildService.registerIfAbsent(project.gradle).get()
|
||||||
|
|
||||||
fun buildCompilerArgs(): List<String> {
|
fun buildCompilerArgs(): List<String> {
|
||||||
val konanVersion = Distribution(project.konanHome).compilerVersion?.let(CompilerVersion.Companion::fromString)
|
val compilerVersion = Distribution.getCompilerVersion(konanPropertiesService.compilerVersion, project.konanHome)
|
||||||
|
val konanVersion = compilerVersion?.let(CompilerVersion.Companion::fromString)
|
||||||
?: project.konanVersion
|
?: project.konanVersion
|
||||||
|
|
||||||
if (konanVersion.isAtLeast(1, 6, 0)) {
|
if (konanVersion.isAtLeast(1, 6, 0)) {
|
||||||
@@ -907,6 +909,9 @@ internal class CacheBuilder(
|
|||||||
private val debuggable: Boolean
|
private val debuggable: Boolean
|
||||||
get() = binary.debuggable
|
get() = binary.debuggable
|
||||||
|
|
||||||
|
private val konanPropertiesService: KonanPropertiesBuildService
|
||||||
|
get() = KonanPropertiesBuildService.registerIfAbsent(project.gradle).get()
|
||||||
|
|
||||||
private val konanCacheKind: NativeCacheKind
|
private val konanCacheKind: NativeCacheKind
|
||||||
get() = project.getKonanCacheKind(konanTarget)
|
get() = project.getKonanCacheKind(konanTarget)
|
||||||
|
|
||||||
@@ -986,13 +991,7 @@ internal class CacheBuilder(
|
|||||||
)
|
)
|
||||||
if (debuggable)
|
if (debuggable)
|
||||||
args += "-g"
|
args += "-g"
|
||||||
// It's a dirty workaround, but we need a Gradle Build Service for a proper solution,
|
args += konanPropertiesService.additionalCacheFlags(konanTarget)
|
||||||
// which is too big to put in 1.6.0, so let's use ad-hoc solution for now.
|
|
||||||
// TODO: https://youtrack.jetbrains.com/issue/KT-48553.
|
|
||||||
if (konanTarget == KonanTarget.IOS_ARM64) {
|
|
||||||
// See https://youtrack.jetbrains.com/issue/KT-48552
|
|
||||||
args += "-Xembed-bitcode-marker"
|
|
||||||
}
|
|
||||||
args += externalDependenciesArgs
|
args += externalDependenciesArgs
|
||||||
args += "-Xadd-cache=${library.libraryFile.absolutePath}"
|
args += "-Xadd-cache=${library.libraryFile.absolutePath}"
|
||||||
args += "-Xcache-directory=${cacheDirectory.absolutePath}"
|
args += "-Xcache-directory=${cacheDirectory.absolutePath}"
|
||||||
@@ -1071,7 +1070,7 @@ internal class CacheBuilder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun buildCompilerArgs(): List<String> = mutableListOf<String>().apply {
|
fun buildCompilerArgs(): List<String> = mutableListOf<String>().apply {
|
||||||
if (konanCacheKind != NativeCacheKind.NONE && !optimized && cacheWorksFor(konanTarget, project)) {
|
if (konanCacheKind != NativeCacheKind.NONE && !optimized && konanPropertiesService.cacheWorksFor(konanTarget)) {
|
||||||
rootCacheDirectory.mkdirs()
|
rootCacheDirectory.mkdirs()
|
||||||
ensureCompilerProvidedLibsPrecached()
|
ensureCompilerProvidedLibsPrecached()
|
||||||
add("-Xcache-directory=${rootCacheDirectory.absolutePath}")
|
add("-Xcache-directory=${rootCacheDirectory.absolutePath}")
|
||||||
@@ -1102,36 +1101,6 @@ internal class CacheBuilder(
|
|||||||
cacheKind.outputKind?.let {
|
cacheKind.outputKind?.let {
|
||||||
"${baseName}-cache"
|
"${baseName}-cache"
|
||||||
} ?: error("No output for kind $cacheKind")
|
} ?: error("No output for kind $cacheKind")
|
||||||
|
|
||||||
private fun getCacheableTargets(project: Project) =
|
|
||||||
Distribution(project.konanHome)
|
|
||||||
.properties
|
|
||||||
.resolvablePropertyList("cacheableTargets", HostManager.hostName)
|
|
||||||
.map { KonanTarget.predefinedTargets.getValue(it) }
|
|
||||||
|
|
||||||
// Targets with well-tested static caches that can be enabled by default.
|
|
||||||
// TODO: There is a corresponding property in konan.properties (optInCacheableTargets),
|
|
||||||
// but naïve implementation makes build slower because it makes reading of konan.properties significantly more frequent.
|
|
||||||
// One possible solution is to use [Gradle Build service](https://docs.gradle.org/current/userguide/build_services.html).
|
|
||||||
// Tracking issue: https://youtrack.jetbrains.com/issue/KT-47529
|
|
||||||
private val targetsWithStableStaticCaches = setOf(
|
|
||||||
KonanTarget.IOS_X64,
|
|
||||||
KonanTarget.MACOS_X64,
|
|
||||||
KonanTarget.IOS_SIMULATOR_ARM64,
|
|
||||||
KonanTarget.MACOS_ARM64,
|
|
||||||
KonanTarget.IOS_ARM64,
|
|
||||||
KonanTarget.LINUX_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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,13 +69,11 @@ class Distribution(
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consider using [org.jetbrains.kotlin.gradle.targets.native.KonanPropertiesBuildService] in case of Gradle.
|
||||||
|
*/
|
||||||
val compilerVersion by lazy {
|
val compilerVersion by lazy {
|
||||||
val propertyVersion = properties["compilerVersion"]?.toString()
|
getCompilerVersion(properties["compilerVersion"]?.toString(), konanHome)
|
||||||
val bundleVersion = if (konanHome.contains("-1"))
|
|
||||||
konanHome.substring(konanHome.lastIndexOf("-1") + 1)
|
|
||||||
else
|
|
||||||
null
|
|
||||||
propertyVersion ?: bundleVersion
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val klib = "$konanHome/klib"
|
val klib = "$konanHome/klib"
|
||||||
@@ -98,6 +96,20 @@ class Distribution(
|
|||||||
override fun availableSubTarget(genericName: String) =
|
override fun availableSubTarget(genericName: String) =
|
||||||
additionalPropertyFiles(genericName).map { it.name }
|
additionalPropertyFiles(genericName).map { it.name }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* Try to guess compiler version using [konanHome].
|
||||||
|
*/
|
||||||
|
private fun getBundleVersion(konanHome: String): String? =
|
||||||
|
if (konanHome.contains("-1"))
|
||||||
|
konanHome.substring(konanHome.lastIndexOf("-1") + 1)
|
||||||
|
else
|
||||||
|
null
|
||||||
|
|
||||||
|
fun getCompilerVersion(propertyVersion: String?, konanHome: String): String? =
|
||||||
|
propertyVersion ?: getBundleVersion(konanHome)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move into K/N?
|
// TODO: Move into K/N?
|
||||||
|
|||||||
Reference in New Issue
Block a user