From ae88689e5885cc1295014caf093374b4011fbe9a Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Thu, 26 Aug 2021 21:56:47 +0200 Subject: [PATCH] [Gradle] Improve NativeDistributionCommonizerTask's cold startup performance This is done by removing support for Gradle's UP-TO-DATE checker in favour of our own 'NativeDistributionCommonizationCache' --- .../jetbrains/kotlin/gradle/CommonizerIT.kt | 25 +++++++------ .../NativeDistributionCommonizerTask.kt | 37 +++---------------- 2 files changed, 19 insertions(+), 43 deletions(-) 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 8dbb7d47233..9ebed0e8620 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 @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.gradle import org.gradle.api.logging.LogLevel.INFO import org.gradle.internal.os.OperatingSystem import org.jetbrains.kotlin.commonizer.CommonizerTarget -import org.jetbrains.kotlin.gradle.internals.DISABLED_NATIVE_TARGETS_REPORTER_WARNING_PREFIX import org.jetbrains.kotlin.gradle.util.reportSourceSetCommonizerDependencies import org.jetbrains.kotlin.incremental.testingUtils.assertEqualDirectories import org.jetbrains.kotlin.konan.target.HostManager @@ -38,9 +37,9 @@ class CommonizerIT : BaseGradleIT() { assertSuccessful() } - build("commonize", "--rerun-tasks", "-Pkotlin.mpp.enableNativeDistributionCommonizationCache=true") { + build("commonize", "-Pkotlin.mpp.enableNativeDistributionCommonizationCache=true") { assertTasksExecuted(":commonizeNativeDistribution") - assertContains("Native Distribution Commonization: Cache hit") + assertNativeDistributionCommonizationCacheHit() assertContains("Native Distribution Commonization: All available targets are commonized already") assertContains("Native Distribution Commonization: Lock acquired") assertContains("Native Distribution Commonization: Lock released") @@ -48,7 +47,7 @@ class CommonizerIT : BaseGradleIT() { assertSuccessful() } - build("commonize", "--rerun-tasks", "-Pkotlin.mpp.enableNativeDistributionCommonizationCache=false") { + build("commonize", "-Pkotlin.mpp.enableNativeDistributionCommonizationCache=false") { assertTasksExecuted(":commonizeNativeDistribution") assertContains("Native Distribution Commonization: Cache disabled") assertContains(commonizerOutput) @@ -69,7 +68,7 @@ class CommonizerIT : BaseGradleIT() { } build(":commonize") { - assertTasksUpToDate(":commonizeNativeDistribution") + assertNativeDistributionCommonizationCacheHit() assertTasksUpToDate(":cinteropCurlTargetA") assertTasksUpToDate(":cinteropCurlTargetB") assertTasksUpToDate(":commonizeCInterop") @@ -81,7 +80,7 @@ class CommonizerIT : BaseGradleIT() { buildGradleKts.writeText(originalBuildGradleKtsContent.replace("curl", "curl2")) build(":commonize") { - assertTasksUpToDate(":commonizeNativeDistribution") + assertNativeDistributionCommonizationCacheHit() assertTasksExecuted(":cinteropCurl2TargetA") assertTasksExecuted(":cinteropCurl2TargetB") assertTasksExecuted(":commonizeCInterop") @@ -90,7 +89,7 @@ class CommonizerIT : BaseGradleIT() { buildGradleKts.writeText(originalBuildGradleKtsContent.lineSequence().filter { "curl" !in it }.joinToString("\n")) build(":commonize") { - assertTasksUpToDate(":commonizeNativeDistribution") + assertNativeDistributionCommonizationCacheHit() assertTasksNotExecuted(":cinteropCurlTargetA") assertTasksNotExecuted(":cinteropCurlTargetB") assertSuccessful() @@ -116,7 +115,7 @@ class CommonizerIT : BaseGradleIT() { } build(":commonize", "-Pkotlin.mpp.enableCInteropCommonization=true") { - assertTasksUpToDate(":commonizeNativeDistribution") + assertNativeDistributionCommonizationCacheHit() assertTasksExecuted(":cinteropCurlTargetA") assertTasksExecuted(":cinteropCurlTargetB") assertTasksExecuted(":commonizeCInterop") @@ -124,7 +123,7 @@ class CommonizerIT : BaseGradleIT() { } build(":commonize", "-Pkotlin.mpp.enableCInteropCommonization=false") { - assertTasksUpToDate(":commonizeNativeDistribution") + assertNativeDistributionCommonizationCacheHit() assertTasksNotExecuted(":cinteropCurlTargetA") assertTasksNotExecuted(":cinteropCurlTargetB") assertTasksNotExecuted(":commonizeCInterop") @@ -251,7 +250,7 @@ class CommonizerIT : BaseGradleIT() { assertSuccessful() assertTasksUpToDate(":cinteropWithPosixTargetA") assertTasksUpToDate(":cinteropWithPosixTargetB") - assertTasksUpToDate(":commonizeNativeDistribution") + assertNativeDistributionCommonizationCacheHit() assertTasksUpToDate(":commonizeCInterop") } } @@ -520,7 +519,7 @@ class CommonizerIT : BaseGradleIT() { build(":assemble", testSourceSetsDependingOnMainParameter) { assertTestSourceSetsDependingOnMainParameter() assertSuccessful() - assertTasksUpToDate(":commonizeNativeDistribution") + assertContains("Native Distribution Commonization: Cache hit") assertTasksUpToDate(":commonizeCInterop") } @@ -637,6 +636,10 @@ class CommonizerIT : BaseGradleIT() { } } } + + private fun CompiledProject.assertNativeDistributionCommonizationCacheHit() { + assertContains("Native Distribution Commonization: Cache hit") + } } private data class TargetSubstitution(val value: String, val isCompilable: Boolean, val isExecutable: Boolean) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/NativeDistributionCommonizerTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/NativeDistributionCommonizerTask.kt index 46660562084..bd56032599d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/NativeDistributionCommonizerTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/NativeDistributionCommonizerTask.kt @@ -7,7 +7,10 @@ package org.jetbrains.kotlin.gradle.targets.native.internal import org.gradle.api.DefaultTask import org.gradle.api.Project -import org.gradle.api.tasks.* +import org.gradle.api.tasks.Classpath +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.TaskAction import org.jetbrains.kotlin.commonizer.CommonizerOutputFileLayout.resolveCommonizedDirectory import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget import org.jetbrains.kotlin.compilerRunner.GradleCliCommonizer @@ -18,9 +21,7 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.konan.library.KONAN_DISTRIBUTION_COMMONIZED_LIBS_DIR -import org.jetbrains.kotlin.konan.library.KONAN_DISTRIBUTION_COMMON_LIBS_DIR import org.jetbrains.kotlin.konan.library.KONAN_DISTRIBUTION_KLIB_DIR -import org.jetbrains.kotlin.konan.library.KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR import java.io.File import java.net.URLEncoder @@ -32,41 +33,13 @@ internal open class NativeDistributionCommonizerTask : DefaultTask() { internal val commonizerTargets: Set get() = project.getAllCommonizerTargets() - @get:PathSensitive(PathSensitivity.ABSOLUTE) - @get:IgnoreEmptyDirectories - @get:InputDirectory - @Suppress("unused") // Only for up-to-date checker. The directory with the original common libs. - val originalCommonLibrariesDirectory = konanHome - .resolve(KONAN_DISTRIBUTION_KLIB_DIR) - .resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR) - - @get:PathSensitive(PathSensitivity.ABSOLUTE) - @get:IgnoreEmptyDirectories - @get:InputDirectory - @Suppress("unused") // Only for up-to-date checker. The directory with the original platform libs. - val originalPlatformLibrariesDirectory = konanHome - .resolve(KONAN_DISTRIBUTION_KLIB_DIR) - .resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR) - - @get:OutputDirectories - @Suppress("unused") // Only for up-to-date checker. + @get:Internal val outputDirectories: Set get() { val rootOutputDirectory = getRootOutputDirectory() return commonizerTargets.map { target -> resolveCommonizedDirectory(rootOutputDirectory, target) }.toSet() } - /* - Ensures that only one CommonizerTask can run at a time. - This is necessary because of the success-marker mechanism of this task. - This is a phantom file: No one has the intention to actually create this output file. - However, telling Gradle that all those tasks rely on the same output file will enforce - non-parallel execution. - */ - @get:OutputFile - @Suppress("unused") - val taskMutex: File = project.rootProject.file(".commonizer-phantom-output") - @get:Internal internal val commonizerRunner = KotlinNativeCommonizerToolRunner(project)