From 0929e8e30bcfaafd00c1f3bee425acf93cc7e314 Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Fri, 17 Feb 2023 15:56:08 +0100 Subject: [PATCH] [Gradle] Resolve cinterops only from a single source set of a given dependency ^KT-56729 Verification Pending --- .../native/internal/CInteropCommonizerTask.kt | 8 +++++++- .../CInteropMetadataDependencyClasspath.kt | 15 ++++++++++----- ...InteropMetadataDependencyTransformationTask.kt | 10 +++++----- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerTask.kt index 55cd7c8f6b6..daefc25bb11 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerTask.kt @@ -132,7 +132,7 @@ internal open class CInteropCommonizerTask } getAllInteropsGroups().associateWith { group -> (group.targets + group.targets.allLeaves()).map { target -> - val externalDependencyFiles = when (target) { + val externalDependencyFiles: List = when (target) { is LeafCommonizerTarget -> { cinterops .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() targetSourceSets.intersect(groupSourceSets) .filterIsInstance() + /* + 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) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropMetadataDependencyClasspath.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropMetadataDependencyClasspath.kt index a43c1290d77..e114c56a2cd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropMetadataDependencyClasspath.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropMetadataDependencyClasspath.kt @@ -55,14 +55,14 @@ private fun Project.createCInteropMetadataDependencyClasspathFromProjectDependen sourceSet.metadataTransformation .metadataDependencyResolutionsOrEmpty .filterIsInstance() - .flatMap { chooseVisibleSourceSets -> + .mapNotNull { chooseVisibleSourceSets -> /* We only want to access resolutions that provide metadata from dependency projects */ val projectMetadataProvider = when (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) } } @@ -95,11 +95,16 @@ private fun Project.createCInteropMetadataDependencyClasspathFromAssociatedCompi * 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] */ -internal val ChooseVisibleSourceSets.visibleSourceSetsProvidingCInterops: Set +internal val ChooseVisibleSourceSets.visibleSourceSetProvidingCInterops: String? get() { val dependsOnSourceSets = allVisibleSourceSetNames .flatMap { projectStructureMetadata.sourceSetsDependsOnRelation[it].orEmpty() } .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 } + } } 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 f6b5a0a5e83..744710c5fb1 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 @@ -137,12 +137,12 @@ internal open class CInteropMetadataDependencyTransformationTask @Inject constru class ChooseVisibleSourceSetProjection( @Input val dependencyModuleIdentifiers: List, @Nested val projectStructureMetadata: KotlinProjectStructureMetadata, - @Input val visibleSourceSetsProvidingCInterops: Set + @Input val visibleSourceSetProvidingCInterops: String? ) { constructor(chooseVisibleSourceSets: ChooseVisibleSourceSets) : this( dependencyModuleIdentifiers = chooseVisibleSourceSets.dependency.toKpmModuleIdentifiers(), 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 */ is ArtifactMetadataProvider -> chooseVisibleSourceSets.metadataProvider.read { artifactContent -> - chooseVisibleSourceSets.visibleSourceSetsProvidingCInterops - .mapNotNull { visibleSourceSetName -> artifactContent.findSourceSet(visibleSourceSetName) } - .flatMap { sourceSetContent -> sourceSetContent.cinteropMetadataBinaries } + 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) } }