[MPP] Initial support for cinterop import with KGP resolvers
KT-54975
This commit is contained in:
committed by
Space Team
parent
20e80401b2
commit
7e2a7579e8
+24
@@ -5,11 +5,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.plugin.ide
|
package org.jetbrains.kotlin.gradle.plugin.ide
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
|
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
||||||
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.SourceSetConstraint
|
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.SourceSetConstraint
|
||||||
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers.*
|
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyTransformers.IdePlatformStdlibCommonDependencyFilter
|
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyTransformers.IdePlatformStdlibCommonDependencyFilter
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.native.internal.getCommonizerTarget
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.ide.dependencyTransformers.UnusedSourcesAndDocumentationFilter
|
||||||
|
|
||||||
internal fun IdeMultiplatformImport(extension: KotlinProjectExtension): IdeMultiplatformImport {
|
internal fun IdeMultiplatformImport(extension: KotlinProjectExtension): IdeMultiplatformImport {
|
||||||
return IdeMultiplatformImportImpl(extension).apply {
|
return IdeMultiplatformImportImpl(extension).apply {
|
||||||
@@ -84,6 +87,27 @@ internal fun IdeMultiplatformImport(extension: KotlinProjectExtension): IdeMulti
|
|||||||
level = IdeMultiplatformImport.DependencyResolutionLevel.Default
|
level = IdeMultiplatformImport.DependencyResolutionLevel.Default
|
||||||
)
|
)
|
||||||
|
|
||||||
|
registerDependencyResolver(
|
||||||
|
resolver = IdePlatformCinteropDependencyResolver,
|
||||||
|
constraint = { sourceSet -> SourceSetConstraint.isLeaf(sourceSet) && SourceSetConstraint.isNative(sourceSet) },
|
||||||
|
phase = IdeMultiplatformImport.DependencyResolutionPhase.BinaryDependencyResolution,
|
||||||
|
level = IdeMultiplatformImport.DependencyResolutionLevel.Default,
|
||||||
|
)
|
||||||
|
|
||||||
|
registerDependencyResolver(
|
||||||
|
resolver = IdeCommonizedCinteropDependencyResolver,
|
||||||
|
constraint = { sourceSet -> SourceSetConstraint.isNative(sourceSet) && getCommonizerTarget(sourceSet) is SharedCommonizerTarget },
|
||||||
|
phase = IdeMultiplatformImport.DependencyResolutionPhase.BinaryDependencyResolution,
|
||||||
|
level = IdeMultiplatformImport.DependencyResolutionLevel.Default,
|
||||||
|
)
|
||||||
|
|
||||||
|
registerDependencyResolver(
|
||||||
|
resolver = IdeCInteropMetadataDependencyClasspathResolver,
|
||||||
|
constraint = { SourceSetConstraint.isNative(it) && !SourceSetConstraint.isLeaf(it) },
|
||||||
|
phase = IdeMultiplatformImport.DependencyResolutionPhase.BinaryDependencyResolution,
|
||||||
|
level = IdeMultiplatformImport.DependencyResolutionLevel.Default,
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Register resolution of dependencies for jvm+android dependencies:
|
Register resolution of dependencies for jvm+android dependencies:
|
||||||
This resolver will resolve dependencies visible to the source set from a 'jvm' perspective.
|
This resolver will resolve dependencies visible to the source set from a 'jvm' perspective.
|
||||||
|
|||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.native.internal.createCInteropMetadataDependencyClasspathForIde
|
||||||
|
|
||||||
|
object IdeCInteropMetadataDependencyClasspathResolver : IdeDependencyResolver {
|
||||||
|
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
|
||||||
|
if (sourceSet !is DefaultKotlinSourceSet) return emptySet()
|
||||||
|
|
||||||
|
val project = sourceSet.project
|
||||||
|
// TODO (kirpichenkov): sensitive to task being registered for the source set
|
||||||
|
val cinteropFiles = project.createCInteropMetadataDependencyClasspathForIde(sourceSet)
|
||||||
|
return resolveCinteropDependencies(project, cinteropFiles)
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.native.internal.cinteropCommonizerDependencies
|
||||||
|
|
||||||
|
object IdeCommonizedCinteropDependencyResolver : IdeDependencyResolver {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.internal
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.native.internal.getAllCInteropOutputFiles
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
|
object IdePlatformCinteropDependencyResolver : IdeDependencyResolver {
|
||||||
|
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
|
||||||
|
if (sourceSet !is DefaultKotlinSourceSet) return emptySet()
|
||||||
|
val project = sourceSet.project
|
||||||
|
|
||||||
|
val nativeCompilation = sourceSet.internal.compilations.singleOrNull().safeAs<KotlinNativeCompilation>() ?: return emptySet()
|
||||||
|
val cinteropFiles = project.getAllCInteropOutputFiles(nativeCompilation)
|
||||||
|
|
||||||
|
return resolveCinteropDependencies(project, cinteropFiles)
|
||||||
|
}
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
|
||||||
|
|
||||||
|
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
|
||||||
|
|
||||||
|
object IdeProjectToProjectCInteropDependencyResolver : IdeDependencyResolver {
|
||||||
|
private val platformDependencyResolver = IdePlatformDependencyResolver(
|
||||||
|
resolvedArtifactHandler = handler@{ artifact, context ->
|
||||||
|
val identifier = artifact.id.componentIdentifier as? ProjectComponentIdentifier
|
||||||
|
?: return@handler null
|
||||||
|
|
||||||
|
val projectArtifact = context.allArtifacts.filter { otherArtifact ->
|
||||||
|
val otherIdentifier = otherArtifact.id.componentIdentifier
|
||||||
|
otherIdentifier is ProjectComponentIdentifier && otherIdentifier.projectName == identifier.projectName
|
||||||
|
}
|
||||||
|
|
||||||
|
null
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
|
||||||
|
return platformDependencyResolver.resolve(sourceSet)
|
||||||
|
}
|
||||||
|
}
|
||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.file.FileCollection
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryCoordinates
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinResolvedBinaryDependency
|
||||||
|
import org.jetbrains.kotlin.gradle.idea.tcs.extras.klibExtra
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.ide.KlibExtra
|
||||||
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
|
import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION
|
||||||
|
import org.jetbrains.kotlin.library.ToolingSingleFileKlibResolveStrategy
|
||||||
|
import org.jetbrains.kotlin.library.commonizerTarget
|
||||||
|
import org.jetbrains.kotlin.library.resolveSingleFileKlib
|
||||||
|
|
||||||
|
fun resolveCinteropDependencies(project: Project, cinteropFiles: FileCollection): Set<IdeaKotlinDependency> {
|
||||||
|
return cinteropFiles.files
|
||||||
|
.filter { it.isDirectory || it.extension == KLIB_FILE_EXTENSION }
|
||||||
|
.mapNotNullTo(mutableSetOf()) { libraryFile ->
|
||||||
|
createCinteropLibraryDependency(project, libraryFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createCinteropLibraryDependency(project: Project, libraryFile: java.io.File): IdeaKotlinResolvedBinaryDependency? {
|
||||||
|
val library = try {
|
||||||
|
resolveSingleFileKlib(
|
||||||
|
libraryFile = File(libraryFile.absolutePath),
|
||||||
|
strategy = ToolingSingleFileKlibResolveStrategy
|
||||||
|
)
|
||||||
|
} catch (error: Throwable) {
|
||||||
|
project.logger.error("Failed to resolve library ${libraryFile.path}", error)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return IdeaKotlinResolvedBinaryDependency(
|
||||||
|
binaryType = IdeaKotlinDependency.CLASSPATH_BINARY_TYPE,
|
||||||
|
binaryFile = libraryFile,
|
||||||
|
coordinates = IdeaKotlinBinaryCoordinates(
|
||||||
|
group = project.group.toString(),
|
||||||
|
module = library.moduleDisplayName,
|
||||||
|
version = null,
|
||||||
|
sourceSetName = library.commonizerTarget
|
||||||
|
),
|
||||||
|
).apply {
|
||||||
|
klibExtra = KlibExtra(library)
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
@@ -9,8 +9,17 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution
|
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.metadataDependencyResolutionsOrEmpty
|
import org.jetbrains.kotlin.gradle.plugin.mpp.metadataDependencyResolutionsOrEmpty
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope.*
|
||||||
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
|
import org.jetbrains.kotlin.library.packageFqName
|
||||||
|
import org.jetbrains.kotlin.library.shortName
|
||||||
|
import org.jetbrains.kotlin.library.uniqueName
|
||||||
|
|
||||||
internal inline fun <reified T : MetadataDependencyResolution> KotlinSourceSet.resolveMetadata(): List<T> {
|
internal inline fun <reified T : MetadataDependencyResolution> KotlinSourceSet.resolveMetadata(): List<T> {
|
||||||
if (this !is DefaultKotlinSourceSet) return emptyList()
|
if (this !is DefaultKotlinSourceSet) return emptyList()
|
||||||
return compileDependenciesTransformation.metadataDependencyResolutionsOrEmpty.filterIsInstance<T>()
|
return compileDependenciesTransformation.metadataDependencyResolutionsOrEmpty.filterIsInstance<T>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val KotlinLibrary.moduleDisplayName: String
|
||||||
|
get() = packageFqName ?: shortName ?: uniqueName
|
||||||
|
|||||||
+8
-3
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.gradle.targets.native.internal
|
package org.jetbrains.kotlin.gradle.targets.native.internal
|
||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.file.FileCollection
|
||||||
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
|
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
|
||||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
|
||||||
@@ -42,16 +43,20 @@ private fun Project.setupCInteropCommonizerDependenciesForCompilation(compilatio
|
|||||||
* The copying task prevent red code within the IDE after cleaning the build output.
|
* The copying task prevent red code within the IDE after cleaning the build output.
|
||||||
*/
|
*/
|
||||||
private fun Project.setupCInteropCommonizerDependenciesForIde(sourceSet: DefaultKotlinSourceSet) {
|
private fun Project.setupCInteropCommonizerDependenciesForIde(sourceSet: DefaultKotlinSourceSet) {
|
||||||
val cinteropCommonizerTask = project.copyCommonizeCInteropForIdeTask ?: return
|
addIntransitiveMetadataDependencyIfPossible(sourceSet, cinteropCommonizerDependencies(sourceSet))
|
||||||
|
}
|
||||||
|
|
||||||
addIntransitiveMetadataDependencyIfPossible(sourceSet, filesProvider files@{
|
internal fun Project.cinteropCommonizerDependencies(sourceSet: DefaultKotlinSourceSet): FileCollection {
|
||||||
|
val cinteropCommonizerTask = project.copyCommonizeCInteropForIdeTask ?: return project.files()
|
||||||
|
|
||||||
|
return filesProvider {
|
||||||
val directlyDependent = CInteropCommonizerDependent.from(sourceSet)
|
val directlyDependent = CInteropCommonizerDependent.from(sourceSet)
|
||||||
val associateDependent = CInteropCommonizerDependent.fromAssociateCompilations(sourceSet)
|
val associateDependent = CInteropCommonizerDependent.fromAssociateCompilations(sourceSet)
|
||||||
|
|
||||||
listOfNotNull(directlyDependent, associateDependent).map { cinteropCommonizerDependent ->
|
listOfNotNull(directlyDependent, associateDependent).map { cinteropCommonizerDependent ->
|
||||||
cinteropCommonizerTask.get().commonizedOutputLibraries(cinteropCommonizerDependent)
|
cinteropCommonizerTask.get().commonizedOutputLibraries(cinteropCommonizerDependent)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Project.setupCInteropTransformCompositeMetadataDependenciesForIde(sourceSet: DefaultKotlinSourceSet) {
|
private fun Project.setupCInteropTransformCompositeMetadataDependenciesForIde(sourceSet: DefaultKotlinSourceSet) {
|
||||||
|
|||||||
+1
-1
@@ -81,7 +81,7 @@ private fun Project.getPropagatedCInteropDependenciesOrEmpty(compilation: Kotlin
|
|||||||
getAllCInteropOutputFiles(platformCompilation)
|
getAllCInteropOutputFiles(platformCompilation)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Project.getAllCInteropOutputFiles(compilation: KotlinNativeCompilation): FileCollection {
|
internal fun Project.getAllCInteropOutputFiles(compilation: KotlinNativeCompilation): FileCollection {
|
||||||
val cinteropTasks = compilation.cinterops.map { interop -> interop.interopProcessingTaskName }
|
val cinteropTasks = compilation.cinterops.map { interop -> interop.interopProcessingTaskName }
|
||||||
.mapNotNull { taskName -> tasks.findByName(taskName) as? CInteropProcess }
|
.mapNotNull { taskName -> tasks.findByName(taskName) as? CInteropProcess }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user