[Gradle] Process project dependencies in CLI version of CInterop[MDT]Task

If MetadataDependencyTransformation is triggered it will resolve related
metadata dependency configuration. Which is not recommended from gradle
performance point of view.
Update CInterop[MDT]Task to work as regular [MDT]Task i.e. it will
process project dependencies during task execution but keep the original
functionality for IDE. Since during IDE import it is expected to resolve
configurations during gradle configuration phase.

^KT-58471 Verification Pending
This commit is contained in:
Anton Lakotka
2023-05-24 11:17:40 +02:00
committed by Space Team
parent 72c7d15be8
commit e937f0739b
2 changed files with 54 additions and 38 deletions
@@ -35,21 +35,33 @@ internal fun Project.createCInteropMetadataDependencyClasspath(sourceSet: Defaul
else locateOrRegisterCInteropMetadataDependencyTransformationTask(sourceSet) else locateOrRegisterCInteropMetadataDependencyTransformationTask(sourceSet)
if (dependencyTransformationTask == null) return project.files() if (dependencyTransformationTask == null) return project.files()
/* val dependencyTransformationTaskOutputs = project.files(dependencyTransformationTask.map { it.outputLibraryFiles })
The classpath will be assembled by three independent parts return if (forIde) {
1) C-Interop Metadata which will be downloaded Jar files that get transformed by the transformation task /*
2) C-Interop Metadata directly provided by dependency projects (in the same build) For IDE Import the classpath will be assembled by three independent parts:
3) C-Interop Metadata from 'associated compilations' / additionalVisible source sets 1) C-Interop Metadata which will be downloaded Jar files that get transformed by the transformation task
(e.g. 'nativeTest' will be able to access the classpath from 'nativeMain') 2) C-Interop Metadata directly provided by dependency projects (in the same build)
*/ 3) C-Interop Metadata from 'associated compilations' / additionalVisible source sets
return project.files(dependencyTransformationTask.map { it.outputLibraryFiles }) + (e.g. 'nativeTest' will be able to access the classpath from 'nativeMain')
createCInteropMetadataDependencyClasspathFromProjectDependencies(sourceSet, forIde) + */
createCInteropMetadataDependencyClasspathFromAssociatedCompilations(sourceSet, forIde) dependencyTransformationTaskOutputs +
createCInteropMetadataDependencyClasspathFromProjectDependenciesForIde(sourceSet) +
createCInteropMetadataDependencyClasspathFromAssociatedCompilations(sourceSet, true)
} else {
/*
For CLI execution the classpath will be assembled from two parts:
1) C-Interop metadata from the transformation task which transforms
Project Dependencies and External Module Dependencies (e.g. the ones that downloaded from maven repo)
2) C-Interop Metadata from 'associated compilations' / additionalVisible source sets
(e.g. 'nativeTest' will be able to access the classpath from 'nativeMain')
*/
dependencyTransformationTaskOutputs +
createCInteropMetadataDependencyClasspathFromAssociatedCompilations(sourceSet, false)
}
} }
private fun Project.createCInteropMetadataDependencyClasspathFromProjectDependencies( private fun Project.createCInteropMetadataDependencyClasspathFromProjectDependenciesForIde(
sourceSet: DefaultKotlinSourceSet, sourceSet: DefaultKotlinSourceSet
forIde: Boolean
): FileCollection { ): FileCollection {
return filesProvider { return filesProvider {
sourceSet.metadataTransformation sourceSet.metadataTransformation
@@ -63,7 +75,7 @@ private fun Project.createCInteropMetadataDependencyClasspathFromProjectDependen
} }
chooseVisibleSourceSets.visibleSourceSetProvidingCInterops?.let { visibleSourceSetName -> chooseVisibleSourceSets.visibleSourceSetProvidingCInterops?.let { visibleSourceSetName ->
projectMetadataProvider.getSourceSetCInteropMetadata(visibleSourceSetName, if (forIde) Ide else Cli) projectMetadataProvider.getSourceSetCInteropMetadata(visibleSourceSetName, Ide)
} }
} }
} }
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.gradle.tasks.withType
import org.jetbrains.kotlin.gradle.utils.filesProvider import org.jetbrains.kotlin.gradle.utils.filesProvider
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.project.model.KpmModuleIdentifier import org.jetbrains.kotlin.project.model.KpmModuleIdentifier
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
import java.io.File import java.io.File
import java.io.Serializable import java.io.Serializable
import java.util.concurrent.Callable import java.util.concurrent.Callable
@@ -55,7 +56,9 @@ internal fun Project.locateOrRegisterCInteropMetadataDependencyTransformationTas
/* outputDirectory = */ /* outputDirectory = */
project.layout.kotlinTransformedCInteropMetadataLibraryDirectoryForBuild(sourceSet.name), project.layout.kotlinTransformedCInteropMetadataLibraryDirectoryForBuild(sourceSet.name),
/* cleaning = */ /* cleaning = */
CInteropMetadataDependencyTransformationTask.Cleaning.DeleteOutputDirectory CInteropMetadataDependencyTransformationTask.Cleaning.DeleteOutputDirectory,
/* skipProjectDependencies = */
false, // we want project dependencies to be included in the output
), ),
configureTask = { configureTaskOrder(); onlyIfSourceSetIsSharedNative() } configureTask = { configureTaskOrder(); onlyIfSourceSetIsSharedNative() }
) )
@@ -81,7 +84,9 @@ internal fun Project.locateOrRegisterCInteropMetadataDependencyTransformationTas
/* outputDirectory = */ /* outputDirectory = */
project.kotlinTransformedCInteropMetadataLibraryDirectoryForIde, project.kotlinTransformedCInteropMetadataLibraryDirectoryForIde,
/* cleaning = */ /* cleaning = */
CInteropMetadataDependencyTransformationTask.Cleaning.None CInteropMetadataDependencyTransformationTask.Cleaning.None,
/* skipProjectDependencies = */
true,
), ),
configureTask = { configureTaskOrder(); onlyIfSourceSetIsSharedNative() } configureTask = { configureTaskOrder(); onlyIfSourceSetIsSharedNative() }
) )
@@ -121,7 +126,6 @@ internal open class CInteropMetadataDependencyTransformationTask @Inject constru
private val parameters = GranularMetadataTransformation.Params(project, sourceSet) private val parameters = GranularMetadataTransformation.Params(project, sourceSet)
sealed class Cleaning : Serializable { sealed class Cleaning : Serializable {
abstract fun cleanOutputDirectory(outputDirectory: File) abstract fun cleanOutputDirectory(outputDirectory: File)
@@ -168,32 +172,32 @@ internal open class CInteropMetadataDependencyTransformationTask @Inject constru
private fun materializeMetadata( private fun materializeMetadata(
chooseVisibleSourceSets: ChooseVisibleSourceSets chooseVisibleSourceSets: ChooseVisibleSourceSets
): List<File> = when (chooseVisibleSourceSets.metadataProvider) { ): Iterable<File> {
/* Nothing to transform: We will use original commonizer output in such cases */ val metadataProvider = chooseVisibleSourceSets.metadataProvider
is ProjectMetadataProvider -> emptyList() return when (metadataProvider) {
is ProjectMetadataProvider -> {
/* Extract/Materialize all cinterop files from composite jar file */ if (skipProjectDependencies) return emptyList()
is ArtifactMetadataProvider -> chooseVisibleSourceSets.metadataProvider.read { artifactContent -> val visibleSourceSetName = chooseVisibleSourceSets.visibleSourceSetProvidingCInterops ?: return emptyList()
val visibleSourceSetName = chooseVisibleSourceSets.visibleSourceSetProvidingCInterops ?: return emptyList() metadataProvider
val sourceSetContent = artifactContent.findSourceSet(visibleSourceSetName) ?: return emptyList() .getSourceSetCInteropMetadata(visibleSourceSetName, ProjectMetadataProvider.MetadataConsumer.Cli)
sourceSetContent.cinteropMetadataBinaries ?.files
.onEach { cInteropMetadataBinary -> cInteropMetadataBinary.copyIntoDirectory(outputDirectory) } .orEmpty()
.map { cInteropMetadataBinary -> outputDirectory.resolve(cInteropMetadataBinary.relativeFile) }
}
}
private fun Configuration.withoutProjectDependencies(): FileCollection {
return incoming.artifactView { view ->
view.componentFilter { componentIdentifier ->
componentIdentifier !is ProjectComponentIdentifier
} }
}.files
/* Extract/Materialize all cinterop files from composite jar file */
is ArtifactMetadataProvider -> metadataProvider.read { artifactContent ->
val visibleSourceSetName = chooseVisibleSourceSets.visibleSourceSetProvidingCInterops ?: return emptyList()
val sourceSetContent = artifactContent.findSourceSet(visibleSourceSetName) ?: return emptyList()
sourceSetContent.cinteropMetadataBinaries
.onEach { cInteropMetadataBinary -> cInteropMetadataBinary.copyIntoDirectory(outputDirectory) }
.map { cInteropMetadataBinary -> outputDirectory.resolve(cInteropMetadataBinary.relativeFile) }
}
}
} }
private fun Iterable<MetadataDependencyResolution>.resolutionsToTransform(): List<ChooseVisibleSourceSets> { private fun Iterable<MetadataDependencyResolution>.resolutionsToTransform(): List<ChooseVisibleSourceSets> {
return filterIsInstance<ChooseVisibleSourceSets>() return filterIsInstance<ChooseVisibleSourceSets>()
/* We do not care about Project to Project dependencies: Those shall use the commonizer output directly (no transformation) */ .applyIf(skipProjectDependencies) { filter { it.dependency.id !is ProjectComponentIdentifier } }
.filter { it.dependency.id !is ProjectComponentIdentifier }
} }
} }