From c08fb1cae6aefc2a7e090a4277ba4c02a2a39996 Mon Sep 17 00:00:00 2001 From: Anton Lakotka Date: Mon, 16 Oct 2023 00:02:38 +0200 Subject: [PATCH] [Gradle] add rootOutputDirectoryProperty to NativeDistributionCommonizerTask And read commonized klibs in execution time only. it is possible only when rootOutputDirectoryProperty is marked as OutputDirectory. ```kotlin class Producer { @get:OutputDirectory val foo: RegularFileProperty @get:Internal val bar: RegularFileProperty } val foo = producer.flatMap { it.foo.map { it.listFiles() } } val bar = producer.flatMap { it.bar.map { it.listFiles() } } ``` `foo` file collection will be evaluated at execution time. Because `Producer.foo` is an OutputDirectory and its content unknown during configuration time. But `bar` file collection will be evaluated at configuration time. Because according to gradle model it is not Output and therefore its content can be evaluated before task execution. ^KT-61359 Verification Pending --- .../jetbrains/kotlin/gradle/CommonizerIT.kt | 1 + ...monizedNativePlatformDependencyResolver.kt | 2 +- .../native/internal/CommonizerTasks.kt | 2 +- .../KotlinNativePlatformDependencies.kt | 12 ++++-- .../NativeDistributionCommonizerTask.kt | 39 +++++++++++++------ 5 files changed, 39 insertions(+), 17 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 b15f88a0608..171203ae177 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 @@ -91,6 +91,7 @@ open class CommonizerIT : KGPBaseTest() { } @DisplayName("KT-61359: commonize native distribution and compile with configuration cache") + @GradleTestVersions(minVersion = TestVersions.Gradle.G_7_4) @GradleTest fun testCleanCommonizationWithConfigurationCache(gradleVersion: GradleVersion) { project("commonizeNativeDistributionWithConfigurationCache", gradleVersion) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/IdeCommonizedNativePlatformDependencyResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/IdeCommonizedNativePlatformDependencyResolver.kt index bc877e26111..14fea79eb41 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/IdeCommonizedNativePlatformDependencyResolver.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/ide/dependencyResolvers/IdeCommonizedNativePlatformDependencyResolver.kt @@ -23,7 +23,7 @@ internal object IdeCommonizedNativePlatformDependencyResolver : val project = sourceSet.project val commonizerTarget = sourceSet.commonizerTarget.getOrThrow() as? SharedCommonizerTarget ?: return emptySet() val commonizerTask = project.commonizeNativeDistributionTask?.get() ?: return emptySet() - val outputDirectory = resolveCommonizedDirectory(commonizerTask.rootOutputDirectory, commonizerTarget) + val outputDirectory = resolveCommonizedDirectory(commonizerTask.rootOutputDirectoryProperty.get().asFile, commonizerTarget) return outputDirectory.listFiles().orEmpty() .filter { it.isDirectory || it.extension == KLIB_FILE_EXTENSION } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CommonizerTasks.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CommonizerTasks.kt index 4ae4f0cb8cc..10332007ac8 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CommonizerTasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CommonizerTasks.kt @@ -165,7 +165,7 @@ internal val Project.cleanNativeDistributionCommonizerTask: TaskProvider getOriginalPlatformLibrariesFor(target) - is SharedCommonizerTarget -> commonizeNativeDistributionTask?.get()?.getCommonizedPlatformLibrariesFor(target) ?: project.files() + is SharedCommonizerTarget -> { + val commonizerTaskProvider = commonizeNativeDistributionTask ?: return project.files() + val commonizedLibrariesProvider = commonizerTaskProvider.flatMap { task -> + task.rootOutputDirectoryProperty.map { getCommonizedPlatformLibrariesFor(it.asFile, target) } + } + project.files(commonizedLibrariesProvider) + } } } @@ -79,9 +85,9 @@ private fun Project.getOriginalPlatformLibrariesFor(target: LeafCommonizerTarget konanDistribution.platformLibsDir.resolve(target.konanTarget.name).listLibraryFiles().toSet() } -private fun NativeDistributionCommonizerTask.getCommonizedPlatformLibrariesFor(target: SharedCommonizerTarget): FileCollection { +private fun getCommonizedPlatformLibrariesFor(rootOutputDirectory: File, target: SharedCommonizerTarget): List { val targetOutputDirectory = CommonizerOutputFileLayout.resolveCommonizedDirectory(rootOutputDirectory, target) - return project.filesProvider { targetOutputDirectory.listLibraryFiles() }.builtBy(this) + return targetOutputDirectory.listLibraryFiles() } private suspend fun Project.addDependencies( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/NativeDistributionCommonizerTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/NativeDistributionCommonizerTask.kt index 83efe01eaf4..fc1fe6aebfe 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/NativeDistributionCommonizerTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/NativeDistributionCommonizerTask.kt @@ -8,6 +8,8 @@ package org.jetbrains.kotlin.gradle.targets.native.internal import org.gradle.api.DefaultTask import org.gradle.api.Project import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.ProjectLayout +import org.gradle.api.file.RegularFileProperty import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property @@ -15,6 +17,7 @@ import org.gradle.api.provider.Provider import org.gradle.api.tasks.Classpath import org.gradle.api.tasks.Input import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction import org.gradle.process.ExecOperations import org.gradle.work.DisableCachingByDefault @@ -45,6 +48,7 @@ internal abstract class NativeDistributionCommonizerTask @Inject constructor( private val objectFactory: ObjectFactory, private val execOperations: ExecOperations, + private val projectLayout: ProjectLayout, ) : DefaultTask(), UsesBuildMetricsService { private val konanHome = project.file(project.konanHome) @@ -80,19 +84,30 @@ internal abstract class NativeDistributionCommonizerTask private val additionalSettings = project.additionalCommonizerSettings @get:Internal - internal val rootOutputDirectory: File = project.file { - project.file(project.konanHome) - .resolve(KONAN_DISTRIBUTION_KLIB_DIR) - .resolve(KONAN_DISTRIBUTION_COMMONIZED_LIBS_DIR) - .resolve(URLEncoder.encode(project.getKotlinPluginVersion(), Charsets.UTF_8.name())) - } + @Deprecated("Use lazy replacement", replaceWith = ReplaceWith("rootOutputDirectoryProperty.get().asFile")) + internal val rootOutputDirectory: File get() = rootOutputDirectoryProperty.asFile.get() - private val commonizerCache = NativeDistributionCommonizerCache( - outputDirectory = rootOutputDirectory, - konanHome = konanHome, - logger = logger, - isCachingEnabled = project.kotlinPropertiesProvider.enableNativeDistributionCommonizationCache - ) + @get:OutputDirectory + internal val rootOutputDirectoryProperty: RegularFileProperty = objectFactory + .fileProperty() + .apply { + set( + project.file(project.konanHome) + .resolve(KONAN_DISTRIBUTION_KLIB_DIR) + .resolve(KONAN_DISTRIBUTION_COMMONIZED_LIBS_DIR) + .resolve(URLEncoder.encode(project.getKotlinPluginVersion(), Charsets.UTF_8.name())) + ) + } + + private val isCachingEnabled = project.kotlinPropertiesProvider.enableNativeDistributionCommonizationCache + + private val commonizerCache + get() = NativeDistributionCommonizerCache( + outputDirectory = rootOutputDirectoryProperty.get().asFile, + konanHome = konanHome, + logger = logger, + isCachingEnabled = isCachingEnabled + ) @get:Internal val metrics: Property> = project.objects