[MPP] Fix import of cinterops for non-leaf single target source sets

KT-54975
This commit is contained in:
Pavel Kirpichenkov
2023-01-11 17:55:15 +02:00
committed by Space Team
parent 7bae2303aa
commit 9f15cc11a7
8 changed files with 97 additions and 4 deletions
@@ -110,7 +110,8 @@ class MppIdeDependencyResolutionIT : KGPBaseTest() {
dependencies["commonTest"].cinteropDependencies()
.assertMatches(binaryCoordinates(Regex("a:dep.*\\(linux_arm64, linux_x64\\)")))
// TODO (kirpichenkov): consider extracting cinterops from platform libraries (they are library roots currently)
// CInterops are currently imported as extra roots of a platform publication, not as separate libraries
// This is a bit inconsistent with other CInterop dependencies, but correctly represents the published artifacts
dependencies["linuxX64Main"].cinteropDependencies().assertMatches()
dependencies["linuxX64Test"].cinteropDependencies().assertMatches()
dependencies["linuxArm64Main"].cinteropDependencies().assertMatches()
@@ -132,6 +133,47 @@ class MppIdeDependencyResolutionIT : KGPBaseTest() {
dependencies["linuxArm64Test"].cinteropDependencies()
.assertMatches(binaryCoordinates(Regex("a:dep-with-cinterop-cinterop-dep.*linux_arm64")))
}
resolveIdeDependencies("client-with-complex-hierarchy") { dependencies ->
dependencies["commonMain"].cinteropDependencies().assertMatches()
dependencies["commonTest"].cinteropDependencies().assertMatches()
dependencies["nativeMain"].cinteropDependencies().assertMatches(
binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*\\(ios_arm64, ios_x64, linux_x64\\)"))
)
dependencies["nativeTest"].cinteropDependencies().assertMatches(
binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*\\(ios_arm64, ios_x64, linux_x64\\)"))
)
dependencies["iosMain"].cinteropDependencies()
.assertMatches(binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*\\(ios_arm64, ios_x64\\)")))
dependencies["iosTest"].cinteropDependencies()
.assertMatches(binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*\\(ios_arm64, ios_x64\\)")))
dependencies["iosX64Main"].cinteropDependencies()
.assertMatches(binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*:ios_x64$")))
dependencies["iosX64Test"].cinteropDependencies()
.assertMatches(binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*:ios_x64$")))
dependencies["iosArm64Main"].cinteropDependencies()
.assertMatches(binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*:ios_arm64$")))
dependencies["iosArm64Test"].cinteropDependencies()
.assertMatches(binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*:ios_arm64$")))
dependencies["linuxOtherMain"].cinteropDependencies().assertMatches(
binaryCoordinates(Regex("a:dep-with-cinterop-cinterop-dep.*:linux_x64$")),
binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*:linux_x64$")),
)
dependencies["linuxOtherTest"].cinteropDependencies().assertMatches(
binaryCoordinates(Regex("a:dep-with-cinterop-cinterop-dep.*:linux_x64$")),
binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*:linux_x64$")),
)
dependencies["linuxMain"].cinteropDependencies().assertMatches(
binaryCoordinates(Regex("a:dep-with-cinterop-cinterop-dep.*:linux_x64$")),
binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*:linux_x64$")),
)
dependencies["linuxTest"].cinteropDependencies().assertMatches(
binaryCoordinates(Regex("a:dep-with-cinterop-cinterop-dep.*:linux_x64$")),
binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*:linux_x64$"))
)
}
}
}
}
@@ -0,0 +1,40 @@
plugins {
kotlin("multiplatform")
}
kotlin {
jvm()
ios {
compilations.getByName("main").cinterops.create("w")
}
linuxX64("linux").compilations.getByName("main").cinterops.create("w")
sourceSets {
val commonMain by getting
val commonTest by getting
val linuxMain by getting
val linuxTest by getting
val nativeMain by creating {
this.dependsOn(commonMain)
getByName("iosMain").dependsOn(this)
}
val nativeTest by creating {
this.dependsOn(commonTest)
getByName("iosTest").dependsOn(this)
}
val linuxOtherMain by creating {
this.dependsOn(nativeMain)
linuxMain.dependsOn(this)
dependencies {
implementation(project(":dep-with-cinterop"))
}
}
val linuxOtherTest by creating {
this.dependsOn(nativeTest)
linuxTest.dependsOn(this)
}
}
}
@@ -4,3 +4,4 @@ rootProject.name = "cinterops"
include(":dep-with-cinterop")
include(":client-for-binary-dep")
include(":client-for-project-to-project-dep")
include(":client-with-complex-hierarchy")
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.SourceSetCo
import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.plugin.sources.project
import org.jetbrains.kotlin.gradle.targets.metadata.isNativeSourceSet
import org.jetbrains.kotlin.gradle.targets.metadata.isSingleKotlinTargetSourceSet
import org.jetbrains.kotlin.gradle.targets.metadata.isSinglePlatformTypeSourceSet
import org.jetbrains.kotlin.gradle.utils.getOrPut
import org.jetbrains.kotlin.tooling.core.Extras
@@ -170,6 +171,8 @@ interface IdeMultiplatformImport {
val isSinglePlatformType = SourceSetConstraint { isSinglePlatformTypeSourceSet(it) }
val isSingleKotlinTarget = SourceSetConstraint { isSingleKotlinTargetSourceSet(it) }
val isLeaf = SourceSetConstraint { sourceSet ->
(sourceSet.project.multiplatformExtensionOrNull ?: return@SourceSetConstraint true).sourceSets
.none { otherSourceSet -> sourceSet in otherSourceSet.dependsOn }
@@ -88,7 +88,7 @@ internal fun IdeMultiplatformImport(extension: KotlinProjectExtension): IdeMulti
registerDependencyResolver(
resolver = IdePlatformCinteropDependencyResolver,
constraint = { sourceSet -> SourceSetConstraint.isLeaf(sourceSet) && SourceSetConstraint.isNative(sourceSet) },
constraint = { sourceSet -> SourceSetConstraint.isSingleKotlinTarget(sourceSet) && SourceSetConstraint.isNative(sourceSet) },
phase = IdeMultiplatformImport.DependencyResolutionPhase.BinaryDependencyResolution,
level = IdeMultiplatformImport.DependencyResolutionLevel.Default,
)
@@ -102,14 +102,14 @@ internal fun IdeMultiplatformImport(extension: KotlinProjectExtension): IdeMulti
registerDependencyResolver(
resolver = IdeCInteropMetadataDependencyClasspathResolver,
constraint = { SourceSetConstraint.isNative(it) && !SourceSetConstraint.isLeaf(it) },
constraint = { SourceSetConstraint.isNative(it) && !SourceSetConstraint.isSingleKotlinTarget(it) },
phase = IdeMultiplatformImport.DependencyResolutionPhase.BinaryDependencyResolution,
level = IdeMultiplatformImport.DependencyResolutionLevel.Default,
)
registerDependencyResolver(
resolver = IdeProjectToProjectCInteropDependencyResolver,
constraint = { SourceSetConstraint.isNative(it) && SourceSetConstraint.isLeaf(it) },
constraint = { SourceSetConstraint.isNative(it) && SourceSetConstraint.isSingleKotlinTarget(it) },
phase = IdeMultiplatformImport.DependencyResolutionPhase.BinaryDependencyResolution,
level = IdeMultiplatformImport.DependencyResolutionLevel.Default,
)
@@ -534,6 +534,11 @@ internal fun isSinglePlatformTypeSourceSet(sourceSet: KotlinSourceSet): Boolean
return platformCompilations.map { it.platformType }.toSet().size == 1
}
internal fun isSingleKotlinTargetSourceSet(sourceSet: KotlinSourceSet): Boolean {
val platformCompilations = sourceSet.internal.compilations.filterNot { it.platformType == KotlinPlatformType.common }
return platformCompilations.map { it.target }.toSet().size == 1
}
internal fun dependsOnClosureWithInterCompilationDependencies(sourceSet: KotlinSourceSet): Set<KotlinSourceSet> =
sourceSet.internal.dependsOnClosure.toMutableSet().apply {
addAll(getVisibleSourceSetsFromAssociateCompilations(sourceSet))