[MPP] CInterop import improvements

- Make cinterop header non-empty in a related test
- Remove ios target from the test to fix CI runs on linux hosts
- Use build dir repository instead of mavenLocal in the test
- Assert cinterop files from published projects
- Some minor refactorings

KT-54975
This commit is contained in:
Pavel Kirpichenkov
2023-01-12 16:17:59 +02:00
committed by Space Team
parent 9f15cc11a7
commit 1d68012668
12 changed files with 65 additions and 49 deletions
@@ -91,7 +91,7 @@ class MppIdeDependencyResolutionIT : KGPBaseTest() {
}
project(projectName = "cinteropImport", gradleVersion = gradleVersion) {
build(":dep-with-cinterop:publishToMavenLocal")
build(":dep-with-cinterop:publishAllPublicationsToBuildRepository")
resolveIdeDependencies("dep-with-cinterop") { dependencies ->
dependencies["commonMain"].cinteropDependencies()
@@ -112,10 +112,26 @@ class MppIdeDependencyResolutionIT : KGPBaseTest() {
// 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()
dependencies["linuxArm64Test"].cinteropDependencies().assertMatches()
fun assertDependencyOnPublishedProjectCInterop(sourceSetName: String) {
val publishedProjectDependencies = dependencies[sourceSetName].filterIsInstance<IdeaKotlinResolvedBinaryDependency>()
.filter { it.coordinates?.module?.contains("dep-with-cinterop") == true }
val fileNames = publishedProjectDependencies
.flatMap { dependency -> dependency.classpath }
.map { file -> file.name }
.toSet()
assert(fileNames == setOf("dep-with-cinterop.klib", "dep-with-cinterop-cinterop-dep.klib")) {
"""Unexpected cinterop dependencies for the source set :client-for-binary-dep:$sourceSetName.
|Expected a project dependency and a cinterop dependency, but instead found:
|$fileNames""".trimMargin()
}
}
assertDependencyOnPublishedProjectCInterop("linuxX64Main")
assertDependencyOnPublishedProjectCInterop("linuxX64Test")
assertDependencyOnPublishedProjectCInterop("linuxArm64Main")
assertDependencyOnPublishedProjectCInterop("linuxArm64Test")
}
resolveIdeDependencies("client-for-project-to-project-dep") { dependencies ->
@@ -138,30 +154,22 @@ class MppIdeDependencyResolutionIT : KGPBaseTest() {
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\\)"))
binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*\\(linux_arm64, linux_x64\\)"))
)
dependencies["nativeTest"].cinteropDependencies().assertMatches(
binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*\\(ios_arm64, ios_x64, linux_x64\\)"))
binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*\\(linux_arm64, 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["linuxArmMain"].cinteropDependencies()
.assertMatches(binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*:linux_arm64$")))
dependencies["linuxArmTest"].cinteropDependencies()
.assertMatches(binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*:linux_arm64$")))
dependencies["linuxOtherMain"].cinteropDependencies().assertMatches(
dependencies["linuxIntermediateMain"].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(
dependencies["linuxIntermediateTest"].cinteropDependencies().assertMatches(
binaryCoordinates(Regex("a:dep-with-cinterop-cinterop-dep.*:linux_x64$")),
binaryCoordinates(Regex("a:client-with-complex-hierarchy-cinterop-w.*:linux_x64$")),
)
@@ -5,5 +5,9 @@ allprojects {
repositories {
mavenLocal()
mavenCentral()
maven {
name = "build"
url = rootProject.buildDir.resolve("repo").toURI()
}
}
}
@@ -4,9 +4,7 @@ plugins {
kotlin {
jvm()
ios {
compilations.getByName("main").cinterops.create("w")
}
linuxArm64("linuxArm").compilations.getByName("main").cinterops.create("w")
linuxX64("linux").compilations.getByName("main").cinterops.create("w")
sourceSets {
@@ -14,17 +12,19 @@ kotlin {
val commonTest by getting
val linuxMain by getting
val linuxTest by getting
val linuxArmMain by getting
val linuxArmTest by getting
val nativeMain by creating {
this.dependsOn(commonMain)
getByName("iosMain").dependsOn(this)
linuxArmMain.dependsOn(this)
}
val nativeTest by creating {
this.dependsOn(commonTest)
getByName("iosTest").dependsOn(this)
linuxArmTest.dependsOn(this)
}
val linuxOtherMain by creating {
val linuxIntermediateMain by creating {
this.dependsOn(nativeMain)
linuxMain.dependsOn(this)
@@ -32,7 +32,7 @@ kotlin {
implementation(project(":dep-with-cinterop"))
}
}
val linuxOtherTest by creating {
val linuxIntermediateTest by creating {
this.dependsOn(nativeTest)
linuxTest.dependsOn(this)
}
@@ -7,3 +7,13 @@ kotlin {
linuxX64().compilations.getByName("main").cinterops.create("dep")
linuxArm64().compilations.getByName("main").cinterops.create("dep")
}
publishing {
repositories {
maven {
name = "build"
url = rootProject.buildDir.resolve("repo").toURI()
}
}
}
@@ -95,7 +95,7 @@ internal fun IdeMultiplatformImport(extension: KotlinProjectExtension): IdeMulti
registerDependencyResolver(
resolver = IdeCommonizedCinteropDependencyResolver,
constraint = { sourceSet -> SourceSetConstraint.isNative(sourceSet) && getCommonizerTarget(sourceSet) is SharedCommonizerTarget },
constraint = { sourceSet -> getCommonizerTarget(sourceSet) is SharedCommonizerTarget },
phase = IdeMultiplatformImport.DependencyResolutionPhase.BinaryDependencyResolution,
level = IdeMultiplatformImport.DependencyResolutionLevel.Default,
)
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.gradle.targets.native.internal.createCInteropMetadat
import org.jetbrains.kotlin.gradle.targets.native.internal.getCommonizerTarget
import org.jetbrains.kotlin.gradle.tasks.locateTask
object IdeCInteropMetadataDependencyClasspathResolver : IdeDependencyResolver, IdeDependencyResolver.WithBuildDependencies {
internal object IdeCInteropMetadataDependencyClasspathResolver : IdeDependencyResolver, IdeDependencyResolver.WithBuildDependencies {
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
if (sourceSet !is DefaultKotlinSourceSet) return emptySet()
@@ -27,7 +27,7 @@ object IdeCInteropMetadataDependencyClasspathResolver : IdeDependencyResolver, I
project.locateDependencyTask(sourceSet) ?: return emptySet()
val cinteropFiles = project.createCInteropMetadataDependencyClasspathForIde(sourceSet)
return resolveCinteropDependencies(project, cinteropFiles)
return project.resolveCinteropDependencies(cinteropFiles)
}
override fun dependencies(project: Project): Iterable<Any> {
@@ -13,13 +13,13 @@ import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
import org.jetbrains.kotlin.gradle.targets.native.internal.cinteropCommonizerDependencies
import org.jetbrains.kotlin.gradle.targets.native.internal.copyCommonizeCInteropForIdeTask
object IdeCommonizedCinteropDependencyResolver : IdeDependencyResolver, IdeDependencyResolver.WithBuildDependencies {
internal object IdeCommonizedCinteropDependencyResolver : IdeDependencyResolver, IdeDependencyResolver.WithBuildDependencies {
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
if (sourceSet !is DefaultKotlinSourceSet) return emptySet()
val project = sourceSet.project
val cinteropFiles = project.cinteropCommonizerDependencies(sourceSet)
return resolveCinteropDependencies(project, cinteropFiles)
return project.resolveCinteropDependencies(cinteropFiles)
}
override fun dependencies(project: Project): Iterable<Any> {
@@ -11,13 +11,13 @@ import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
import org.jetbrains.kotlin.gradle.targets.native.internal.getPlatformCinteropDependenciesOrEmpty
object IdePlatformCinteropDependencyResolver : IdeDependencyResolver {
internal object IdePlatformCinteropDependencyResolver : IdeDependencyResolver {
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
if (sourceSet !is DefaultKotlinSourceSet) return emptySet()
val project = sourceSet.project
val cinteropFiles = project.getPlatformCinteropDependenciesOrEmpty(sourceSet)
return resolveCinteropDependencies(project, cinteropFiles)
return project.resolveCinteropDependencies(cinteropFiles)
}
}
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.targets.native.internal.locateOrCreateCInteropDependencyConfiguration
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object IdeProjectToProjectCInteropDependencyResolver : IdeDependencyResolver {
internal object IdeProjectToProjectCInteropDependencyResolver : IdeDependencyResolver {
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
if (sourceSet !is DefaultKotlinSourceSet) return emptySet()
@@ -27,14 +27,10 @@ object IdeProjectToProjectCInteropDependencyResolver : IdeDependencyResolver {
val project = sourceSet.project
val configuration = project.locateOrCreateCInteropDependencyConfiguration(compilation)
val cinteropFiles = project.files(
{
configuration.incoming.artifactView {
it.componentFilter { identifier -> identifier is ProjectComponentIdentifier }
}.artifacts.map { it.file }
}
)
val cinteropFiles = configuration.incoming.artifactView {
it.componentFilter { identifier -> identifier is ProjectComponentIdentifier }
}.files
return resolveCinteropDependencies(project, cinteropFiles)
return project.resolveCinteropDependencies(cinteropFiles)
}
}
@@ -13,11 +13,11 @@ import org.jetbrains.kotlin.gradle.plugin.ide.KlibExtra
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.library.*
fun resolveCinteropDependencies(project: Project, cinteropFiles: FileCollection): Set<IdeaKotlinDependency> {
internal fun Project.resolveCinteropDependencies(cinteropFiles: FileCollection): Set<IdeaKotlinDependency> {
return cinteropFiles.files
.filter { it.isDirectory || it.extension == KLIB_FILE_EXTENSION }
.mapNotNullTo(mutableSetOf()) { libraryFile ->
createCinteropLibraryDependency(project, libraryFile)
createCinteropLibraryDependency(this, libraryFile)
}
}
@@ -20,6 +20,3 @@ internal inline fun <reified T : MetadataDependencyResolution> KotlinSourceSet.r
if (this !is DefaultKotlinSourceSet) return emptyList()
return compileDependenciesTransformation.metadataDependencyResolutionsOrEmpty.filterIsInstance<T>()
}
internal val KotlinLibrary.moduleDisplayName: String
get() = packageFqName ?: shortName ?: uniqueName