[Gradle] Make CInterop[MDT]Task compatible with Configuration Cache

^KT-49933
This commit is contained in:
Anton Lakotka
2023-01-16 14:25:05 +01:00
committed by Space Team
parent 458e69f698
commit 9ff9fa35ec
2 changed files with 47 additions and 38 deletions
@@ -61,11 +61,11 @@ class ConfigurationCacheIT : AbstractConfigurationCacheIT() {
@MppGradlePluginTests @MppGradlePluginTests
@DisplayName("works with MPP publishing") @DisplayName("works with MPP publishing")
@GradleTestVersions(minVersion = TestVersions.Gradle.G_7_4)
@GradleTest @GradleTest
fun testMppWithMavenPublish(gradleVersion: GradleVersion) { fun testMppWithMavenPublish(gradleVersion: GradleVersion) {
project("new-mpp-lib-and-app/sample-lib", 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( testConfigurationCacheOf(
":buildKotlinToolingMetadata", // Remove it when KT-49933 is fixed and `kotlinMultiplatform` publication works ":buildKotlinToolingMetadata", // Remove it when KT-49933 is fixed and `kotlinMultiplatform` publication works
@@ -102,6 +102,7 @@ class ConfigurationCacheIT : AbstractConfigurationCacheIT() {
":lib:compileTestKotlinIosX64", ":lib:compileTestKotlinIosX64",
":lib:linkDebugTestIosX64", ":lib:linkDebugTestIosX64",
":lib:transformCommonMainDependenciesMetadata", ":lib:transformCommonMainDependenciesMetadata",
":lib:transformCommonMainCInteropDependenciesMetadata"
) )
} }
@@ -109,12 +110,6 @@ class ConfigurationCacheIT : AbstractConfigurationCacheIT() {
testConfigurationCacheOf( testConfigurationCacheOf(
"build", "build",
executedTaskNames = expectedTasks, executedTaskNames = expectedTasks,
buildOptions = defaultBuildOptions.copy(
freeArgs = listOf(
// remove after KT-49933 is fixed
"-x", ":lib:transformCommonMainCInteropDependenciesMetadata",
)
)
) )
} }
} }
@@ -10,6 +10,9 @@ import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.component.ProjectComponentIdentifier import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.file.FileCollection 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.gradle.api.tasks.*
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet 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.MetadataDependencyResolution.ChooseVisibleSourceSets.MetadataProvider.ProjectMetadataProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.toKpmModuleIdentifiers import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.toKpmModuleIdentifiers
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet 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.plugin.sources.internal
import org.jetbrains.kotlin.gradle.tasks.dependsOn import org.jetbrains.kotlin.gradle.tasks.dependsOn
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
import org.jetbrains.kotlin.gradle.tasks.withType import org.jetbrains.kotlin.gradle.tasks.withType
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName 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.library.KLIB_FILE_EXTENSION
import org.jetbrains.kotlin.project.model.KpmModuleIdentifier import org.jetbrains.kotlin.project.model.KpmModuleIdentifier
import java.io.File import java.io.File
@@ -109,21 +109,19 @@ private fun CInteropMetadataDependencyTransformationTask.configureTaskOrder() {
} }
private fun CInteropMetadataDependencyTransformationTask.onlyIfSourceSetIsSharedNative() { private fun CInteropMetadataDependencyTransformationTask.onlyIfSourceSetIsSharedNative() {
onlyIf { getCommonizerTarget(sourceSet) is SharedCommonizerTarget } val isSharedCommonizerTarget = getCommonizerTarget(sourceSet) is SharedCommonizerTarget
onlyIf { isSharedCommonizerTarget }
} }
internal open class CInteropMetadataDependencyTransformationTask @Inject constructor( internal open class CInteropMetadataDependencyTransformationTask @Inject constructor(
@Transient @get:Internal val sourceSet: DefaultKotlinSourceSet, @Transient @get:Internal val sourceSet: DefaultKotlinSourceSet,
@get:OutputDirectory val outputDirectory: File, @get:OutputDirectory val outputDirectory: File,
@get:Internal val outputLibraryFilesDiscovery: OutputLibraryFilesDiscovery, @get:Internal val outputLibraryFilesDiscovery: OutputLibraryFilesDiscovery,
@get:Internal val cleaning: Cleaning @get:Internal val cleaning: Cleaning,
objectFactory: ObjectFactory
) : DefaultTask() { ) : DefaultTask() {
init { private val parameters = GranularMetadataTransformation.Params(project, sourceSet)
notCompatibleWithConfigurationCacheCompat(
"Task $name does not support Gradle Configuration Cache. Check KT-49933 for more info"
)
}
sealed class OutputLibraryFilesDiscovery : Serializable { sealed class OutputLibraryFilesDiscovery : Serializable {
abstract fun resolveOutputLibraryFiles(outputDirectory: File, resolutions: Iterable<ChooseVisibleSourceSets>): Set<File> abstract fun resolveOutputLibraryFiles(outputDirectory: File, resolutions: Iterable<ChooseVisibleSourceSets>): Set<File>
@@ -188,33 +186,38 @@ internal open class CInteropMetadataDependencyTransformationTask @Inject constru
@Suppress("unused") @Suppress("unused")
@get:Classpath @get:Classpath
protected val inputArtifactFiles: FileCollection get() = sourceSet protected val inputArtifactFiles: FileCollection by lazy {
.internal sourceSet
.resolvableMetadataConfiguration .internal
.withoutProjectDependencies() .resolvableMetadataConfiguration
.withoutProjectDependencies()
}
@get:OutputFile
val outputLibrariesFileIndex: RegularFileProperty = objectFactory
.fileProperty()
.apply { set(outputDirectory.resolve("${sourceSet.name}.transformedCinteropLibraries")) }
@get:Internal @get:Internal
protected val chooseVisibleSourceSets val outputLibraryFiles: Provider<Set<File>> get() = outputLibrariesFileIndex.map { file ->
get() = sourceSet TransformedCinteropLibrariesFile(file.asFile).read()
.compileDependenciesTransformationOrFail }
.metadataDependencyResolutions
.filterIsInstance<ChooseVisibleSourceSets>()
@Suppress("unused")
@get:Nested
protected val chooseVisibleSourceSetsProjection
get() = chooseVisibleSourceSets.map(::ChooseVisibleSourceSetProjection).toSet()
@get:Internal
val outputLibraryFiles = outputFilesProvider(lazy {
outputLibraryFilesDiscovery.resolveOutputLibraryFiles(outputDirectory, chooseVisibleSourceSets)
})
@TaskAction @TaskAction
protected fun transformDependencies() { protected fun transformDependencies() {
cleaning.cleanOutputDirectory(outputDirectory) cleaning.cleanOutputDirectory(outputDirectory)
if (getCommonizerTarget(sourceSet) !is SharedCommonizerTarget) return outputDirectory.mkdirs()
val transformation = GranularMetadataTransformation(parameters) { emptyList() }
val chooseVisibleSourceSets = transformation.metadataDependencyResolutions.filterIsInstance<ChooseVisibleSourceSets>()
outputLibraryFilesDiscovery.resolveOutputLibraryFiles(outputDirectory, chooseVisibleSourceSets)
chooseVisibleSourceSets.forEach(::materializeMetadata) chooseVisibleSourceSets.forEach(::materializeMetadata)
val transformedLibraries = outputLibraryFilesDiscovery.resolveOutputLibraryFiles(outputDirectory, chooseVisibleSourceSets)
TransformedCinteropLibrariesFile(outputLibrariesFileIndex.get().asFile).write(transformedLibraries)
}
private fun writeTransformedLibraries(files: Set<File>) {
val content = files.joinToString("\n")
outputLibrariesFileIndex.get().asFile.writeText(content)
} }
private fun materializeMetadata( private fun materializeMetadata(
@@ -240,3 +243,14 @@ internal open class CInteropMetadataDependencyTransformationTask @Inject constru
}.files }.files
} }
} }
private class TransformedCinteropLibrariesFile(
private val indexFile: File
) {
fun read(): Set<File> = indexFile.readLines().mapTo(mutableSetOf()) { File(it) }
fun write(files: Iterable<File>) {
val content = files.joinToString("\n")
indexFile.writeText(content)
}
}