From 9ff9fa35ec9925807672569f569fdd6d0cf9ea30 Mon Sep 17 00:00:00 2001 From: Anton Lakotka Date: Mon, 16 Jan 2023 14:25:05 +0100 Subject: [PATCH] [Gradle] Make CInterop[MDT]Task compatible with Configuration Cache ^KT-49933 --- .../kotlin/gradle/ConfigurationCacheIT.kt | 11 +-- ...ropMetadataDependencyTransformationTask.kt | 74 +++++++++++-------- 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ConfigurationCacheIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ConfigurationCacheIT.kt index 4ae2a9bd260..e9f182cbe16 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ConfigurationCacheIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ConfigurationCacheIT.kt @@ -61,11 +61,11 @@ class ConfigurationCacheIT : AbstractConfigurationCacheIT() { @MppGradlePluginTests @DisplayName("works with MPP publishing") + @GradleTestVersions(minVersion = TestVersions.Gradle.G_7_4) @GradleTest fun testMppWithMavenPublish(gradleVersion: GradleVersion) { project("new-mpp-lib-and-app/sample-lib", gradleVersion) { - // KT-49933: Support Gradle Configuration caching with HMPP - val publishedTargets = listOf(/*"kotlinMultiplatform",*/ "jvm6", "nodeJs", "linux64", "mingw64", "mingw86") + val publishedTargets = listOf("kotlinMultiplatform", "jvm6", "nodeJs", "linux64", "mingw64", "mingw86") testConfigurationCacheOf( ":buildKotlinToolingMetadata", // Remove it when KT-49933 is fixed and `kotlinMultiplatform` publication works @@ -102,6 +102,7 @@ class ConfigurationCacheIT : AbstractConfigurationCacheIT() { ":lib:compileTestKotlinIosX64", ":lib:linkDebugTestIosX64", ":lib:transformCommonMainDependenciesMetadata", + ":lib:transformCommonMainCInteropDependenciesMetadata" ) } @@ -109,12 +110,6 @@ class ConfigurationCacheIT : AbstractConfigurationCacheIT() { testConfigurationCacheOf( "build", executedTaskNames = expectedTasks, - buildOptions = defaultBuildOptions.copy( - freeArgs = listOf( - // remove after KT-49933 is fixed - "-x", ":lib:transformCommonMainCInteropDependenciesMetadata", - ) - ) ) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropMetadataDependencyTransformationTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropMetadataDependencyTransformationTask.kt index 4c728fb6fc0..d460ba386ae 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropMetadataDependencyTransformationTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropMetadataDependencyTransformationTask.kt @@ -10,6 +10,9 @@ import org.gradle.api.Project import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.component.ProjectComponentIdentifier import org.gradle.api.file.FileCollection +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.Provider import org.gradle.api.tasks.* import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet @@ -22,14 +25,11 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution.Choos import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution.ChooseVisibleSourceSets.MetadataProvider.ProjectMetadataProvider import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.toKpmModuleIdentifiers import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet -import org.jetbrains.kotlin.gradle.plugin.sources.compileDependenciesTransformationOrFail import org.jetbrains.kotlin.gradle.plugin.sources.internal import org.jetbrains.kotlin.gradle.tasks.dependsOn import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask import org.jetbrains.kotlin.gradle.tasks.withType import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName -import org.jetbrains.kotlin.gradle.utils.notCompatibleWithConfigurationCacheCompat -import org.jetbrains.kotlin.gradle.utils.outputFilesProvider import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION import org.jetbrains.kotlin.project.model.KpmModuleIdentifier import java.io.File @@ -109,21 +109,19 @@ private fun CInteropMetadataDependencyTransformationTask.configureTaskOrder() { } private fun CInteropMetadataDependencyTransformationTask.onlyIfSourceSetIsSharedNative() { - onlyIf { getCommonizerTarget(sourceSet) is SharedCommonizerTarget } + val isSharedCommonizerTarget = getCommonizerTarget(sourceSet) is SharedCommonizerTarget + onlyIf { isSharedCommonizerTarget } } internal open class CInteropMetadataDependencyTransformationTask @Inject constructor( @Transient @get:Internal val sourceSet: DefaultKotlinSourceSet, @get:OutputDirectory val outputDirectory: File, @get:Internal val outputLibraryFilesDiscovery: OutputLibraryFilesDiscovery, - @get:Internal val cleaning: Cleaning + @get:Internal val cleaning: Cleaning, + objectFactory: ObjectFactory ) : DefaultTask() { - init { - notCompatibleWithConfigurationCacheCompat( - "Task $name does not support Gradle Configuration Cache. Check KT-49933 for more info" - ) - } + private val parameters = GranularMetadataTransformation.Params(project, sourceSet) sealed class OutputLibraryFilesDiscovery : Serializable { abstract fun resolveOutputLibraryFiles(outputDirectory: File, resolutions: Iterable): Set @@ -188,33 +186,38 @@ internal open class CInteropMetadataDependencyTransformationTask @Inject constru @Suppress("unused") @get:Classpath - protected val inputArtifactFiles: FileCollection get() = sourceSet - .internal - .resolvableMetadataConfiguration - .withoutProjectDependencies() + protected val inputArtifactFiles: FileCollection by lazy { + sourceSet + .internal + .resolvableMetadataConfiguration + .withoutProjectDependencies() + } + + @get:OutputFile + val outputLibrariesFileIndex: RegularFileProperty = objectFactory + .fileProperty() + .apply { set(outputDirectory.resolve("${sourceSet.name}.transformedCinteropLibraries")) } @get:Internal - protected val chooseVisibleSourceSets - get() = sourceSet - .compileDependenciesTransformationOrFail - .metadataDependencyResolutions - .filterIsInstance() - - @Suppress("unused") - @get:Nested - protected val chooseVisibleSourceSetsProjection - get() = chooseVisibleSourceSets.map(::ChooseVisibleSourceSetProjection).toSet() - - @get:Internal - val outputLibraryFiles = outputFilesProvider(lazy { - outputLibraryFilesDiscovery.resolveOutputLibraryFiles(outputDirectory, chooseVisibleSourceSets) - }) + val outputLibraryFiles: Provider> get() = outputLibrariesFileIndex.map { file -> + TransformedCinteropLibrariesFile(file.asFile).read() + } @TaskAction protected fun transformDependencies() { cleaning.cleanOutputDirectory(outputDirectory) - if (getCommonizerTarget(sourceSet) !is SharedCommonizerTarget) return + outputDirectory.mkdirs() + val transformation = GranularMetadataTransformation(parameters) { emptyList() } + val chooseVisibleSourceSets = transformation.metadataDependencyResolutions.filterIsInstance() + outputLibraryFilesDiscovery.resolveOutputLibraryFiles(outputDirectory, chooseVisibleSourceSets) chooseVisibleSourceSets.forEach(::materializeMetadata) + val transformedLibraries = outputLibraryFilesDiscovery.resolveOutputLibraryFiles(outputDirectory, chooseVisibleSourceSets) + TransformedCinteropLibrariesFile(outputLibrariesFileIndex.get().asFile).write(transformedLibraries) + } + + private fun writeTransformedLibraries(files: Set) { + val content = files.joinToString("\n") + outputLibrariesFileIndex.get().asFile.writeText(content) } private fun materializeMetadata( @@ -240,3 +243,14 @@ internal open class CInteropMetadataDependencyTransformationTask @Inject constru }.files } } + +private class TransformedCinteropLibrariesFile( + private val indexFile: File +) { + fun read(): Set = indexFile.readLines().mapTo(mutableSetOf()) { File(it) } + + fun write(files: Iterable) { + val content = files.joinToString("\n") + indexFile.writeText(content) + } +}