From 9ac7b6109438e2e2bb337eb325f076713d7af758 Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Wed, 7 Apr 2021 16:54:05 +0200 Subject: [PATCH] [Gradle] HierarchicalNativeDistributionCommonizerTask: Implement project global caching - Implement NativeDistributionCommonizationCache which will act similar to the 'SuccessMarker' used in the non hierarchical commonization task. - Implement 'kotlin.mpp.enableNativeDistributionCommonizationCache' Gradle property to disable project global caching. The cache is turned on by default. --- .../jetbrains/kotlin/gradle/CommonizerIT.kt | 17 +++++- .../kotlin/gradle/plugin/KotlinProperties.kt | 3 + ...rchicalNativeDistributionCommonizerTask.kt | 5 +- .../NativeDistributionCommonizationCache.kt | 56 +++++++++++++++++++ 4 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/NativeDistributionCommonizationCache.kt diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CommonizerIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CommonizerIT.kt index 8cae5165a84..44243efe399 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CommonizerIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CommonizerIT.kt @@ -19,9 +19,24 @@ class CommonizerIT : BaseGradleIT() { @Test fun `test commonizeNativeDistributionWithIosLinuxWindows`() { with(Project("commonizeNativeDistributionWithIosLinuxWindows")) { - build(":p1:commonize") { + build(":p1:commonize", "-Pkotlin.mpp.enableNativeDistributionCommonizationCache=false") { assertTasksExecuted(":p1:commonizeNativeDistribution") assertContains(DISABLED_NATIVE_TARGETS_REPORTER_WARNING_PREFIX) + assertContains("Kotlin KLIB commonizer:") + assertSuccessful() + } + + build(":p1:commonize", "--rerun-tasks", "-Pkotlin.mpp.enableNativeDistributionCommonizationCache=true") { + assertTasksExecuted(":p1:commonizeNativeDistribution") + assertContains("Native Distribution Commonization: Cache hit") + assertNotContains("Kotlin KLIB commonizer:") + assertSuccessful() + } + + build(":p1:commonize", "--rerun-tasks", "-Pkotlin.mpp.enableNativeDistributionCommonizationCache=false") { + assertTasksExecuted(":p1:commonizeNativeDistribution") + assertContains("Native Distribution Commonization: Cache disabled") + assertContains("Kotlin KLIB commonizer:") assertSuccessful() } } 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 9a3b1c25f46..dd8ca70d732 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 @@ -230,6 +230,9 @@ internal class PropertiesProvider private constructor(private val project: Proje val enableHierarchicalCommonization: Boolean get() = booleanProperty("kotlin.mpp.enableHierarchicalCommonization") ?: true + val enableNativeDistributionCommonizationCache: Boolean + get() = booleanProperty("kotlin.mpp.enableNativeDistributionCommonizationCache") ?: true + /** * Dependencies caching strategy for all targets that support caches. */ diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/HierarchicalNativeDistributionCommonizerTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/HierarchicalNativeDistributionCommonizerTask.kt index ff43ba23cba..42974170a31 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/HierarchicalNativeDistributionCommonizerTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/HierarchicalNativeDistributionCommonizerTask.kt @@ -81,8 +81,8 @@ internal open class HierarchicalNativeDistributionCommonizerTask : DefaultTask() @TaskAction protected fun run() { for (target in rootCommonizerTargets) { - getRootOutputDirectory(target).deleteRecursively() - commonizerRunner.run(getCommandLineArguments(target)) + NativeDistributionCommonizationCache(commonizerRunner, getRootOutputDirectory(target)) + .runIfNecessary(getCommandLineArguments(target)) } } @@ -111,3 +111,4 @@ private val String.base64 get() = base64Encoder.encodeToString(toByteArray(StandardCharsets.UTF_8)) private val base64Encoder = Base64.getEncoder().withoutPadding() + diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/NativeDistributionCommonizationCache.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/NativeDistributionCommonizationCache.kt new file mode 100644 index 00000000000..33b3cf6bede --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/NativeDistributionCommonizationCache.kt @@ -0,0 +1,56 @@ +/* + * 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.internal + +import org.gradle.api.Project +import org.jetbrains.kotlin.compilerRunner.KotlinToolRunner +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider +import java.io.File + +internal val Project.isNativeDistributionCommonizationCacheEnabled: Boolean + get() = PropertiesProvider(this).enableNativeDistributionCommonizationCache + +internal class NativeDistributionCommonizationCache( + private val runner: KotlinToolRunner, + private val outputDirectory: File +) { + private val successMarker = outputDirectory.resolve(".commonized") + + fun runIfNecessary(args: List) { + if (!isCached(args)) { + run(args) + } + } + + private fun isCached(args: List): Boolean { + if (!runner.project.isNativeDistributionCommonizationCacheEnabled) { + runner.project.logger.info("Native Distribution Commonization: Cache disabled") + return false + } + + if (successMarker.exists() && successMarker.isFile) { + if (successMarker.readText() == successMarkerText(args)) { + runner.project.logger.info("Native Distribution Commonization: Cache hit for ${outputDirectory.path}") + return true + } else { + runner.project.logger.info("Native Distribution Commonization: Cache miss. Different args") + successMarker.delete() + } + } + + return false + } + + private fun run(args: List) { + outputDirectory.deleteRecursively() + runner.run(args) + successMarker.writeText(successMarkerText(args)) + } + + private fun successMarkerText(args: List): String { + return args.joinToString("\n") + } +}