[Gradle] Read system properties at configuration time using Gradle providers

The change is a step to fully support Gradle configuration cache.
Relates to #KT-43605
Relates to #KT-44611
This commit is contained in:
Alexander Likhachev
2021-02-12 14:06:50 +03:00
parent d73f5d299a
commit 3537c699b5
14 changed files with 163 additions and 118 deletions
@@ -24,6 +24,7 @@ import org.gradle.api.internal.FeaturePreviews
import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.jetbrains.kotlin.cli.common.CompilerSystemProperties
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget
@@ -76,9 +77,6 @@ abstract class KotlinBasePluginWrapper : Plugin<Project> {
it.add(project.dependencies.create("$KOTLIN_MODULE_GROUP:$KOTLIN_KLIB_COMMONIZER_EMBEDDABLE:$kotlinPluginVersion"))
}
// TODO: consider only set if if daemon or parallel compilation are enabled, though this way it should be safe too
System.setProperty(org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY, "true")
val kotlinGradleBuildServices = KotlinGradleBuildServices.getInstance(project, listenerRegistryHolder)
kotlinGradleBuildServices.detectKotlinPluginLoadedInMultipleProjects(project, kotlinPluginVersion)
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporter
import org.jetbrains.kotlin.build.report.metrics.BuildMetricsReporterImpl
import org.jetbrains.kotlin.build.report.metrics.BuildTime
import org.jetbrains.kotlin.build.report.metrics.measure
import org.jetbrains.kotlin.cli.common.CompilerSystemProperties
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
@@ -334,6 +335,21 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
@TaskAction
fun execute(inputs: IncrementalTaskInputs) {
CompilerSystemProperties.systemPropertyGetter = {
val value = if (it in kotlinDaemonProperties) kotlinDaemonProperties[it] else System.getProperty(it)
logger.warn("System property read $it = $value (declared: ${it in kotlinDaemonProperties})")
value
}
CompilerSystemProperties.systemPropertySetter = setter@{ key, value ->
val oldValue = kotlinDaemonProperties[key]
if (oldValue == value) return@setter oldValue
kotlinDaemonProperties[key] = value
System.setProperty(key, value)
logger.warn("System property set $key = $value (was: $oldValue)")
oldValue
}
CompilerSystemProperties.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY.value = "true"
// If task throws exception, but its outputs are changed during execution,
// then Gradle forces next build to be non-incremental (see Gradle's DefaultTaskArtifactStateRepository#persistNewOutputs)
// To prevent this, we backup outputs before incremental build and restore when exception is thrown
@@ -425,6 +441,15 @@ abstract class AbstractKotlinCompile<T : CommonCompilerArguments>() : AbstractKo
val taskBuildDir = taskBuildDirectory
return taskBuildDir.walk().any { it != taskBuildDir && it.isFile }
}
@get:Internal
val kotlinDaemonProperties: MutableMap<String, String?> by lazy {
if (isGradleVersionAtLeast(6, 5)) {
CompilerSystemProperties.values()
.associate { it.property to project.providers.systemProperty(it.property).forUseAtConfigurationTime().orNull }
.toMutableMap()
} else mutableMapOf()
}
}
open class KotlinCompileArgumentsProvider<T : AbstractKotlinCompile<out CommonCompilerArguments>>(taskProvider: T) {
@@ -686,17 +711,6 @@ open class Kotlin2JsCompile : AbstractKotlinCompile<K2JSCompilerArguments>(), Ko
override fun getSourceRoots() = SourceRoots.KotlinOnly.create(getSource(), sourceFilesExtensions)
@get:InputFiles
@get:Optional
@get:PathSensitive(PathSensitivity.RELATIVE)
internal val friendDependencies: List<String>
get() {
val filter = libraryFilter
return friendPaths.files.filter {
it.exists() && filter(it)
}.map { it.absolutePath }
}
@Suppress("unused")
@get:InputFiles
@get:Optional
@@ -760,6 +774,10 @@ open class Kotlin2JsCompile : AbstractKotlinCompile<K2JSCompilerArguments>(), Ko
null
}
val friendDependencies: List<String> = friendPaths.files.filter {
it.exists() && libraryFilter(it)
}.map { it.absolutePath }
args.friendModules = friendDependencies.joinToString(File.pathSeparator)
if (args.sourceMapBaseDirs == null && !args.sourceMapPrefix.isNullOrEmpty()) {