[Gradle] Implement 'KotlinOutputDependency' to retain information about kotlin produced dependencies
^KT-60612 In Progress
This commit is contained in:
committed by
Space Team
parent
973c5770b8
commit
6c4ce81237
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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
|
||||
|
||||
import org.gradle.api.artifacts.Dependency
|
||||
import org.gradle.api.artifacts.FileCollectionDependency
|
||||
import org.gradle.api.artifacts.component.ComponentIdentifier
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.internal.artifacts.dependencies.SelfResolvingDependencyInternal
|
||||
import org.gradle.api.tasks.TaskDependency
|
||||
import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropIdentifier
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Identifier used for [KotlinOutputDependency].
|
||||
* All use cases where Kotlin needs to add 'file collection based' dependencies shall be modelled
|
||||
* using [KotlinOutputDependency] where this identifier is able to provide
|
||||
* further information about 'what kind of dependency' this is used.
|
||||
*
|
||||
* This identifier basically contains
|
||||
* 1) The information that this dependency was added by the Kotlin Gradle Plugin
|
||||
* 2) The information that the files are locally built
|
||||
* 3) The information about the semantics of the dependency
|
||||
*/
|
||||
internal sealed class KotlinOutputDependencyIdentifier : ComponentIdentifier {
|
||||
|
||||
/**
|
||||
* Indicates that the dependency is representing the compilation under
|
||||
* the specified coordinates and that the reason for the dependency is a 'compilation association'
|
||||
*
|
||||
* e.g. 'test compilations' are associated with 'main compilations'
|
||||
*/
|
||||
internal class AssociateCompilation(
|
||||
val projectPath: String, val target: String, val compilation: String,
|
||||
) : KotlinOutputDependencyIdentifier() {
|
||||
constructor(compilation: KotlinCompilation<*>) : this(
|
||||
projectPath = compilation.project.path,
|
||||
target = compilation.target.targetName,
|
||||
compilation = compilation.compilationName
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that the dependency represents the output of the 'cinterop tool' for a single cinterop,
|
||||
* identified by the specified [identifier]
|
||||
*/
|
||||
internal class CInterop(
|
||||
val identifier: CInteropIdentifier,
|
||||
) : KotlinOutputDependencyIdentifier()
|
||||
|
||||
override fun getDisplayName(): String = when (this) {
|
||||
is AssociateCompilation -> "Associate Compilation: '$projectPath/$target/$compilation'"
|
||||
is CInterop -> "CInterop ${identifier.uniqueName}"
|
||||
}
|
||||
|
||||
override fun toString(): String = displayName
|
||||
}
|
||||
|
||||
/**
|
||||
* Special 'Dependency' implementation that shall be used to add 'file collection' based dependencies
|
||||
* to Kotlin entities (such as compilations). This dependency implementation retains information about
|
||||
* the semantics of the file collection underneath (by providing a [KotlinOutputDependencyIdentifier])
|
||||
*/
|
||||
internal class KotlinOutputDependency internal constructor(
|
||||
private val identifier: KotlinOutputDependencyIdentifier,
|
||||
private val files: FileCollection,
|
||||
) : FileCollectionDependency, SelfResolvingDependencyInternal {
|
||||
private var reason: String? = null
|
||||
|
||||
override fun getTargetComponentId(): ComponentIdentifier = identifier
|
||||
override fun getGroup(): String? = null
|
||||
override fun getName(): String = "unspecified"
|
||||
override fun getVersion(): String? = null
|
||||
|
||||
override fun contentEquals(dependency: Dependency): Boolean {
|
||||
if (dependency !is KotlinOutputDependency) return false
|
||||
return files == dependency.files
|
||||
}
|
||||
|
||||
override fun copy(): KotlinOutputDependency {
|
||||
return KotlinOutputDependency(identifier, files)
|
||||
}
|
||||
|
||||
override fun getReason(): String? = reason
|
||||
|
||||
override fun because(reason: String?) {
|
||||
this.reason = reason
|
||||
}
|
||||
|
||||
override fun getBuildDependencies(): TaskDependency {
|
||||
return files.buildDependencies
|
||||
}
|
||||
|
||||
override fun resolve(): MutableSet<File> {
|
||||
return files.files
|
||||
}
|
||||
|
||||
override fun resolve(transitive: Boolean): MutableSet<File> {
|
||||
return files.files
|
||||
}
|
||||
|
||||
override fun getFiles(): FileCollection {
|
||||
return files
|
||||
}
|
||||
}
|
||||
+17
-6
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Dependency
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinOutputDependency
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinOutputDependencyIdentifier
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.jvm
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.InternalKotlinCompilation
|
||||
@@ -16,6 +18,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.isTest
|
||||
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
|
||||
import org.jetbrains.kotlin.gradle.utils.filesProvider
|
||||
|
||||
|
||||
internal fun interface KotlinCompilationAssociator {
|
||||
fun associate(target: KotlinTarget, auxiliary: InternalKotlinCompilation<*>, main: InternalKotlinCompilation<*>)
|
||||
}
|
||||
@@ -34,16 +37,24 @@ internal object DefaultKotlinCompilationAssociator : KotlinCompilationAssociator
|
||||
compilation itself (moreover, direct dependencies are not equivalent to transitive ones because of
|
||||
resolution order - e.g. in case of FQNs clash, so it's even harmful)
|
||||
*/
|
||||
project.dependencies.add(auxiliary.compileOnlyConfigurationName, project.files({ main.output.classesDirs }))
|
||||
project.dependencies.add(auxiliary.runtimeOnlyConfigurationName, project.files({ main.output.allOutputs }))
|
||||
project.dependencies.add(
|
||||
auxiliary.compileOnlyConfigurationName,
|
||||
KotlinOutputDependency(KotlinOutputDependencyIdentifier.AssociateCompilation(main), main.output.classesDirs)
|
||||
)
|
||||
|
||||
project.dependencies.add(
|
||||
auxiliary.runtimeOnlyConfigurationName,
|
||||
KotlinOutputDependency(KotlinOutputDependencyIdentifier.AssociateCompilation(main), main.output.allOutputs)
|
||||
)
|
||||
|
||||
|
||||
// Adding classes that could be produced into non-default destination for JVM target
|
||||
// Check KotlinSourceSetProcessor for details
|
||||
project.dependencies.add(
|
||||
auxiliary.implementationConfigurationName,
|
||||
project.objects.fileCollection().from(
|
||||
{
|
||||
main.defaultSourceSet.kotlin.classesDirectory.orNull?.asFile
|
||||
}
|
||||
KotlinOutputDependency(
|
||||
KotlinOutputDependencyIdentifier.AssociateCompilation(main),
|
||||
project.filesProvider { main.defaultSourceSet.kotlin.classesDirectory.orNull?.asFile }
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
+13
-8
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPI
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationInfo.KPM
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.ReadyForExecution
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.KOTLIN_NATIVE_IGNORE_INCORRECT_DEPENDENCIES
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.internal.artifactTypeAttribute
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XcodeVersionTask
|
||||
@@ -124,7 +125,7 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
||||
// FIXME support creating interop tasks for PM20
|
||||
private fun Project.createCInteropTasks(
|
||||
compilation: KotlinNativeCompilation,
|
||||
cinterops: NamedDomainObjectCollection<DefaultCInteropSettings>
|
||||
cinterops: NamedDomainObjectCollection<DefaultCInteropSettings>,
|
||||
) {
|
||||
val compilationInfo = KotlinCompilationInfo(compilation)
|
||||
cinterops.all { interop ->
|
||||
@@ -161,7 +162,10 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
||||
val interopOutput = project.files(interopTask.map { it.outputFileProvider })
|
||||
with(compilation) {
|
||||
// Register the interop library as a dependency of the compilation to make IDE happy.
|
||||
project.dependencies.add(compileDependencyConfigurationName, interopOutput)
|
||||
project.dependencies.add(
|
||||
compileDependencyConfigurationName,
|
||||
KotlinOutputDependency(KotlinOutputDependencyIdentifier.CInterop(interop.identifier), interopOutput)
|
||||
)
|
||||
if (isMain()) {
|
||||
// Add interop library to special CInteropApiElements configuration
|
||||
createCInteropApiElementsKlibArtifact(compilation.target, interop, interopTask)
|
||||
@@ -387,7 +391,7 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
||||
|
||||
internal fun createKlibCompilationTask(
|
||||
compilationInfo: KotlinCompilationInfo,
|
||||
konanTarget: KonanTarget
|
||||
konanTarget: KonanTarget,
|
||||
): TaskProvider<KotlinNativeCompile> {
|
||||
val project = compilationInfo.project
|
||||
val ext = project.topLevelExtension
|
||||
@@ -455,7 +459,7 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
||||
}
|
||||
|
||||
private fun Project.klibOutputDirectory(
|
||||
compilation: KotlinCompilationInfo
|
||||
compilation: KotlinCompilationInfo,
|
||||
): File {
|
||||
val targetSubDirectory = compilation.targetDisambiguationClassifier?.let { "$it/" }.orEmpty()
|
||||
return buildDir.resolve("classes/kotlin/$targetSubDirectory${compilation.compilationName}")
|
||||
@@ -478,7 +482,7 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
||||
internal fun createRegularKlibArtifact(
|
||||
compilation: KotlinCompilationInfo,
|
||||
konanTarget: KonanTarget,
|
||||
compileTask: TaskProvider<out KotlinNativeCompile>
|
||||
compileTask: TaskProvider<out KotlinNativeCompile>,
|
||||
) = createKlibArtifact(compilation, konanTarget, compileTask.map { it.outputFile.get() }, null, compileTask)
|
||||
|
||||
private fun createKlibArtifact(
|
||||
@@ -517,7 +521,8 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
||||
abstract class KotlinNativeTargetWithTestsConfigurator<
|
||||
TargetType : KotlinNativeTargetWithTests<TestRunType>,
|
||||
TestRunType : KotlinNativeBinaryTestRun,
|
||||
TaskType : KotlinNativeTest>(
|
||||
TaskType : KotlinNativeTest,
|
||||
>(
|
||||
) : KotlinNativeTargetConfigurator<TargetType>(),
|
||||
KotlinTargetWithTestsConfigurator<TestRunType, TargetType> {
|
||||
|
||||
@@ -571,7 +576,7 @@ class KotlinNativeTargetWithHostTestsConfigurator() :
|
||||
|
||||
override fun createTestRun(
|
||||
name: String,
|
||||
target: KotlinNativeTargetWithHostTests
|
||||
target: KotlinNativeTargetWithHostTests,
|
||||
): KotlinNativeHostTestRun =
|
||||
DefaultHostTestRun(name, target).apply { configureTestRun(target, this) }
|
||||
}
|
||||
@@ -605,7 +610,7 @@ class KotlinNativeTargetWithSimulatorTestsConfigurator :
|
||||
|
||||
override fun createTestRun(
|
||||
name: String,
|
||||
target: KotlinNativeTargetWithSimulatorTests
|
||||
target: KotlinNativeTargetWithSimulatorTests,
|
||||
): KotlinNativeSimulatorTestRun =
|
||||
DefaultSimulatorTestRun(name, target).apply { configureTestRun(target, this) }
|
||||
}
|
||||
|
||||
+1
-1
@@ -110,7 +110,7 @@ internal fun Project.newFileProperty(initialize: (() -> File)? = null): RegularF
|
||||
|
||||
internal fun Project.filesProvider(
|
||||
vararg buildDependencies: Any,
|
||||
provider: () -> Any
|
||||
provider: () -> Any?
|
||||
): ConfigurableFileCollection {
|
||||
return project.files(provider).builtBy(*buildDependencies)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user