[Gradle] Resolve cinterops only from a single source set of a given dependency

^KT-56729 Verification Pending
This commit is contained in:
Sebastian Sellmair
2023-02-17 15:56:08 +01:00
committed by Space Team
parent c5d219f154
commit 0929e8e30b
3 changed files with 22 additions and 11 deletions
@@ -132,7 +132,7 @@ internal open class CInteropCommonizerTask
} }
getAllInteropsGroups().associateWith { group -> getAllInteropsGroups().associateWith { group ->
(group.targets + group.targets.allLeaves()).map { target -> (group.targets + group.targets.allLeaves()).map { target ->
val externalDependencyFiles = when (target) { val externalDependencyFiles: List<FileCollection> = when (target) {
is LeafCommonizerTarget -> { is LeafCommonizerTarget -> {
cinterops cinterops
.filter { cinterop -> cinterop.identifier in group.interops && cinterop.konanTarget == target.konanTarget } .filter { cinterop -> cinterop.identifier in group.interops && cinterop.konanTarget == target.konanTarget }
@@ -144,6 +144,12 @@ internal open class CInteropCommonizerTask
val groupSourceSets = sourceSetsByGroup[group].orEmpty().toSet() val groupSourceSets = sourceSetsByGroup[group].orEmpty().toSet()
targetSourceSets.intersect(groupSourceSets) targetSourceSets.intersect(groupSourceSets)
.filterIsInstance<DefaultKotlinSourceSet>() .filterIsInstance<DefaultKotlinSourceSet>()
/*
We take dependencies just from a single matching source set!
This is because all source sets matching the target and group constraints
will provide the same dependencies (since cinterops are just based upon KonanTarget)
*/
.take(1)
.map { sourceSet -> project.createCInteropMetadataDependencyClasspath(sourceSet) } .map { sourceSet -> project.createCInteropMetadataDependencyClasspath(sourceSet) }
} }
} }
@@ -55,14 +55,14 @@ private fun Project.createCInteropMetadataDependencyClasspathFromProjectDependen
sourceSet.metadataTransformation sourceSet.metadataTransformation
.metadataDependencyResolutionsOrEmpty .metadataDependencyResolutionsOrEmpty
.filterIsInstance<ChooseVisibleSourceSets>() .filterIsInstance<ChooseVisibleSourceSets>()
.flatMap { chooseVisibleSourceSets -> .mapNotNull { chooseVisibleSourceSets ->
/* We only want to access resolutions that provide metadata from dependency projects */ /* We only want to access resolutions that provide metadata from dependency projects */
val projectMetadataProvider = when (chooseVisibleSourceSets.metadataProvider) { val projectMetadataProvider = when (chooseVisibleSourceSets.metadataProvider) {
is ProjectMetadataProvider -> chooseVisibleSourceSets.metadataProvider is ProjectMetadataProvider -> chooseVisibleSourceSets.metadataProvider
is ArtifactMetadataProvider -> return@flatMap emptyList() is ArtifactMetadataProvider -> return@mapNotNull null
} }
chooseVisibleSourceSets.visibleSourceSetsProvidingCInterops.mapNotNull { visibleSourceSetName -> chooseVisibleSourceSets.visibleSourceSetProvidingCInterops?.let { visibleSourceSetName ->
projectMetadataProvider.getSourceSetCInteropMetadata(visibleSourceSetName, if (forIde) Ide else Cli) projectMetadataProvider.getSourceSetCInteropMetadata(visibleSourceSetName, if (forIde) Ide else Cli)
} }
} }
@@ -95,11 +95,16 @@ private fun Project.createCInteropMetadataDependencyClasspathFromAssociatedCompi
* Names of all source sets that may potentially provide necessary cinterops for this resolution. * Names of all source sets that may potentially provide necessary cinterops for this resolution.
* This will select 'the most bottom' source sets in [ChooseVisibleSourceSets.allVisibleSourceSetNames] * This will select 'the most bottom' source sets in [ChooseVisibleSourceSets.allVisibleSourceSetNames]
*/ */
internal val ChooseVisibleSourceSets.visibleSourceSetsProvidingCInterops: Set<String> internal val ChooseVisibleSourceSets.visibleSourceSetProvidingCInterops: String?
get() { get() {
val dependsOnSourceSets = allVisibleSourceSetNames val dependsOnSourceSets = allVisibleSourceSetNames
.flatMap { projectStructureMetadata.sourceSetsDependsOnRelation[it].orEmpty() } .flatMap { projectStructureMetadata.sourceSetsDependsOnRelation[it].orEmpty() }
.toSet() .toSet()
return allVisibleSourceSetNames.filter { it !in dependsOnSourceSets }.toSet() val bottomSourceSets = allVisibleSourceSetNames.filter { it !in dependsOnSourceSets }.toSet()
/* Select the source set participating in the least amount of variants (the most special one) */
return bottomSourceSets.minByOrNull { sourceSetName ->
projectStructureMetadata.sourceSetNamesByVariantName.count { (_, sourceSetNames) -> sourceSetName in sourceSetNames }
}
} }
@@ -137,12 +137,12 @@ internal open class CInteropMetadataDependencyTransformationTask @Inject constru
class ChooseVisibleSourceSetProjection( class ChooseVisibleSourceSetProjection(
@Input val dependencyModuleIdentifiers: List<KpmModuleIdentifier>, @Input val dependencyModuleIdentifiers: List<KpmModuleIdentifier>,
@Nested val projectStructureMetadata: KotlinProjectStructureMetadata, @Nested val projectStructureMetadata: KotlinProjectStructureMetadata,
@Input val visibleSourceSetsProvidingCInterops: Set<String> @Input val visibleSourceSetProvidingCInterops: String?
) { ) {
constructor(chooseVisibleSourceSets: ChooseVisibleSourceSets) : this( constructor(chooseVisibleSourceSets: ChooseVisibleSourceSets) : this(
dependencyModuleIdentifiers = chooseVisibleSourceSets.dependency.toKpmModuleIdentifiers(), dependencyModuleIdentifiers = chooseVisibleSourceSets.dependency.toKpmModuleIdentifiers(),
projectStructureMetadata = chooseVisibleSourceSets.projectStructureMetadata, projectStructureMetadata = chooseVisibleSourceSets.projectStructureMetadata,
visibleSourceSetsProvidingCInterops = chooseVisibleSourceSets.visibleSourceSetsProvidingCInterops visibleSourceSetProvidingCInterops = chooseVisibleSourceSets.visibleSourceSetProvidingCInterops
) )
} }
@@ -201,9 +201,9 @@ internal open class CInteropMetadataDependencyTransformationTask @Inject constru
/* Extract/Materialize all cinterop files from composite jar file */ /* Extract/Materialize all cinterop files from composite jar file */
is ArtifactMetadataProvider -> chooseVisibleSourceSets.metadataProvider.read { artifactContent -> is ArtifactMetadataProvider -> chooseVisibleSourceSets.metadataProvider.read { artifactContent ->
chooseVisibleSourceSets.visibleSourceSetsProvidingCInterops val visibleSourceSetName = chooseVisibleSourceSets.visibleSourceSetProvidingCInterops ?: return emptyList()
.mapNotNull { visibleSourceSetName -> artifactContent.findSourceSet(visibleSourceSetName) } val sourceSetContent = artifactContent.findSourceSet(visibleSourceSetName) ?: return emptyList()
.flatMap { sourceSetContent -> sourceSetContent.cinteropMetadataBinaries } sourceSetContent.cinteropMetadataBinaries
.onEach { cInteropMetadataBinary -> cInteropMetadataBinary.copyIntoDirectory(outputDirectory) } .onEach { cInteropMetadataBinary -> cInteropMetadataBinary.copyIntoDirectory(outputDirectory) }
.map { cInteropMetadataBinary -> outputDirectory.resolve(cInteropMetadataBinary.relativeFile) } .map { cInteropMetadataBinary -> outputDirectory.resolve(cInteropMetadataBinary.relativeFile) }
} }