[Gradle] Implement IdeCommonizedNativePlatformDependencyResolver

KT-55238
This commit is contained in:
Sebastian Sellmair
2022-12-02 14:05:06 +01:00
committed by Space Team
parent c1b1737cf0
commit 4b036cc627
5 changed files with 105 additions and 41 deletions
@@ -32,4 +32,12 @@ val isNativeStdlibKey = extrasKeyOf<Boolean>("isNativeStdlib")
/**
* Marks the dependency as the native stdlib (which is special in the native distribution)
*/
var IdeaKotlinBinaryDependency.isNativeStdlib by isNativeStdlibKey.readWriteProperty.notNull(false)
var IdeaKotlinBinaryDependency.isNativeStdlib by isNativeStdlibKey.readWriteProperty.notNull(false)
val isCommonizedKey = extrasKeyOf<Boolean>("isCommonized")
/**
* Marks dependencies produced by the commonizer
*/
var IdeaKotlinBinaryDependency.isCommonized by isCommonizedKey.readWriteProperty.notNull(false)
@@ -8,10 +8,7 @@ package org.jetbrains.kotlin.gradle.plugin.ide
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinBooleanExtrasSerializer
import org.jetbrains.kotlin.gradle.idea.serialize.IdeaKotlinExtrasSerializer
import org.jetbrains.kotlin.gradle.idea.tcs.extras.KlibExtra
import org.jetbrains.kotlin.gradle.idea.tcs.extras.isIdeaProjectLevelKey
import org.jetbrains.kotlin.gradle.idea.tcs.extras.isNativeDistributionKey
import org.jetbrains.kotlin.gradle.idea.tcs.extras.isNativeStdlibKey
import org.jetbrains.kotlin.gradle.idea.tcs.extras.*
import org.jetbrains.kotlin.gradle.kpm.idea.kotlinDebugKey
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.ide.IdeMultiplatformImport.SourceSetConstraint
@@ -63,6 +60,13 @@ internal fun IdeMultiplatformImport(extension: KotlinProjectExtension): IdeMulti
level = IdeMultiplatformImport.DependencyResolutionLevel.Default
)
registerDependencyResolver(
resolver = IdeCommonizedNativePlatformDependencyResolver,
constraint = SourceSetConstraint.isNative,
phase = IdeMultiplatformImport.DependencyResolutionPhase.BinaryDependencyResolution,
level = IdeMultiplatformImport.DependencyResolutionLevel.Default
)
registerDependencyResolver(
resolver = IdeTransformedMetadataDependencyResolver,
constraint = !SourceSetConstraint.isLeaf,
@@ -120,6 +124,7 @@ internal fun IdeMultiplatformImport(extension: KotlinProjectExtension): IdeMulti
register(isIdeaProjectLevelKey, IdeaKotlinBooleanExtrasSerializer)
register(isNativeDistributionKey, IdeaKotlinBooleanExtrasSerializer)
register(isNativeStdlibKey, IdeaKotlinBooleanExtrasSerializer)
register(isCommonizedKey, IdeaKotlinBooleanExtrasSerializer)
}
}
}
@@ -0,0 +1,32 @@
/*
* 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.commonizer.CommonizerOutputFileLayout.resolveCommonizedDirectory
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
import org.jetbrains.kotlin.gradle.idea.tcs.extras.isCommonized
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.sources.project
import org.jetbrains.kotlin.gradle.targets.native.internal.commonizeNativeDistributionTask
import org.jetbrains.kotlin.gradle.targets.native.internal.getCommonizerTarget
import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION
internal object IdeCommonizedNativePlatformDependencyResolver : IdeDependencyResolver {
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
val project = sourceSet.project
val commonizerTarget = getCommonizerTarget(sourceSet) as? SharedCommonizerTarget ?: return emptySet()
val commonizerTask = project.commonizeNativeDistributionTask?.get() ?: return emptySet()
val outputDirectory = resolveCommonizedDirectory(commonizerTask.rootOutputDirectory, commonizerTarget)
return outputDirectory.listFiles().orEmpty()
.filter { it.isDirectory || it.extension == KLIB_FILE_EXTENSION }
.mapNotNull { libraryFile -> project.resolveNativeDistributionLibraryForIde(libraryFile, commonizerTarget, project.logger) }
.onEach { dependency -> dependency.isCommonized = true }
.toSet()
}
}
@@ -10,59 +10,26 @@ import org.jetbrains.kotlin.commonizer.KonanDistribution
import org.jetbrains.kotlin.commonizer.LeafCommonizerTarget
import org.jetbrains.kotlin.commonizer.platformLibsDir
import org.jetbrains.kotlin.compilerRunner.konanHome
import org.jetbrains.kotlin.compilerRunner.konanVersion
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.isNativeDistribution
import org.jetbrains.kotlin.gradle.idea.tcs.extras.klibExtra
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.ide.KlibExtra
import org.jetbrains.kotlin.gradle.plugin.sources.project
import org.jetbrains.kotlin.gradle.targets.native.internal.getCommonizerTarget
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.library.*
import java.io.File
import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION
object IdeNativePlatformDependencyResolver : IdeDependencyResolver {
override fun resolve(sourceSet: KotlinSourceSet): Set<IdeaKotlinDependency> {
val project = sourceSet.project
val commonizerTarget = getCommonizerTarget(sourceSet) as? LeafCommonizerTarget ?: return emptySet()
val konanTarget = commonizerTarget.konanTargetOrNull ?: return emptySet()
return sourceSet.project.konanDistribution.platformLibsDir.resolve(konanTarget.name)
.listFiles().orEmpty()
.filter { it.isDirectory || it.extension == KLIB_FILE_EXTENSION }
.mapNotNull { libraryFile -> sourceSet.project.resolveKlib(libraryFile, konanTarget) }
.mapNotNull { libraryFile -> project.resolveNativeDistributionLibraryForIde(libraryFile, commonizerTarget, project.logger) }
.toSet()
}
private val Project.konanDistribution: KonanDistribution
get() = KonanDistribution(project.file(konanHome))
private fun Project.resolveKlib(file: File, konanTarget: KonanTarget): IdeaKotlinResolvedBinaryDependency? {
try {
val kotlinLibrary = resolveSingleFileKlib(
org.jetbrains.kotlin.konan.file.File(file.absolutePath),
strategy = ToolingSingleFileKlibResolveStrategy
)
return IdeaKotlinResolvedBinaryDependency(
binaryType = IdeaKotlinDependency.CLASSPATH_BINARY_TYPE,
binaryFile = file,
coordinates = IdeaKotlinBinaryCoordinates(
group = "org.jetbrains.kotlin.native",
module = kotlinLibrary.packageFqName ?: kotlinLibrary.shortName ?: kotlinLibrary.uniqueName,
version = project.konanVersion.toString(),
sourceSetName = konanTarget.toString()
),
).apply {
isNativeDistribution = true
klibExtra = KlibExtra(kotlinLibrary)
}
} catch (t: Throwable) {
logger.error("Failed resolving library ${file.path}", t)
return null
}
}
}
@@ -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.logging.Logger
import org.jetbrains.kotlin.commonizer.CommonizerTarget
import org.jetbrains.kotlin.commonizer.identityString
import org.jetbrains.kotlin.compilerRunner.konanVersion
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.isNativeDistribution
import org.jetbrains.kotlin.gradle.idea.tcs.extras.klibExtra
import org.jetbrains.kotlin.gradle.plugin.ide.KlibExtra
import org.jetbrains.kotlin.library.*
import java.io.File
internal fun Project.resolveNativeDistributionLibraryForIde(
library: File,
target: CommonizerTarget,
logger: Logger? = null
): IdeaKotlinResolvedBinaryDependency? {
val resolvedLibrary = try {
resolveSingleFileKlib(
libraryFile = org.jetbrains.kotlin.konan.file.File(library.absolutePath),
strategy = ToolingSingleFileKlibResolveStrategy
)
} catch (error: Throwable) {
logger?.error("Failed to resolve library ${library.path}", error)
return null
}
return IdeaKotlinResolvedBinaryDependency(
binaryType = IdeaKotlinDependency.CLASSPATH_BINARY_TYPE,
binaryFile = library,
coordinates = IdeaKotlinBinaryCoordinates(
group = "org.jetbrains.kotlin.native",
module = resolvedLibrary.packageFqName ?: resolvedLibrary.shortName ?: resolvedLibrary.uniqueName,
version = project.konanVersion.toString(),
sourceSetName = target.identityString
),
).apply {
isNativeDistribution = true
klibExtra = KlibExtra(resolvedLibrary)
}
}