[Gradle] Prevent cinterop's from depending on compile tasks
- KotlinNativeCompilation Change how associate compilations are connected. Instead of using the implementation configuration, it now uses the `compileDependencyFiles` directly. This will keep the implementation configuration from containing any main compilation's output. Therefore this configuration can still be forwarded to the cinterop tool. - KotlinNativeTargetConfigurator.kt CInteropConfigurations.kt Create special configurations for cinteropApiElements and cinterop dependencies. This configuration is tries to resolve only cinterop dependencies when such variants are offered by a project. ^KT-47641 Verification Pending
This commit is contained in:
committed by
Space
parent
7b5a3f8d1b
commit
329991217a
+2
-3
@@ -20,7 +20,6 @@ import org.gradle.api.GradleException
|
||||
import org.gradle.api.NamedDomainObjectFactory
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.internal.FeaturePreviews
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.gradle.api.logging.Logging
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
@@ -38,12 +37,11 @@ import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.addNpmDependencyExtension
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_COMPILER_EMBEDDABLE
|
||||
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_KLIB_COMMONIZER_EMBEDDABLE
|
||||
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_MODULE_GROUP
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.KotlinTestsRegistry
|
||||
import org.jetbrains.kotlin.gradle.tooling.BuildKotlinToolingMetadataTask
|
||||
import org.jetbrains.kotlin.gradle.tooling.buildKotlinToolingMetadataTask
|
||||
import org.jetbrains.kotlin.gradle.utils.checkGradleCompatibility
|
||||
import org.jetbrains.kotlin.gradle.utils.loadPropertyFromResources
|
||||
@@ -148,6 +146,7 @@ abstract class KotlinBasePluginWrapper : Plugin<Project> {
|
||||
KotlinUsages.setupAttributesMatchingStrategy(project, this)
|
||||
KotlinJsCompilerAttribute.setupAttributesMatchingStrategy(project.dependencies.attributesSchema)
|
||||
ProjectLocalConfigurations.setupAttributesMatchingStrategy(this)
|
||||
CInteropKlibLibraryElements.setupAttributesMatchingStrategy(this)
|
||||
}
|
||||
|
||||
internal abstract fun getPlugin(
|
||||
|
||||
+4
-10
@@ -20,8 +20,8 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeFragmentMetadataC
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.getVisibleSourceSetsFromAssociateCompilations
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.getMetadataCompilationForSourceSet
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinNativeCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
|
||||
import org.jetbrains.kotlin.gradle.utils.filesProvider
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import java.io.File
|
||||
@@ -122,16 +122,10 @@ class KotlinNativeCompilation(
|
||||
get() = lowerCamelCaseName(target.disambiguationClassifier, compilationPurpose, "binaries")
|
||||
|
||||
override fun addAssociateCompilationDependencies(other: KotlinCompilation<*>) {
|
||||
with(target.project) {
|
||||
// Kotlin native does not support either 'compileOnly' or 'runtimeOnly' configurations
|
||||
dependencies.add(
|
||||
implementationConfigurationName,
|
||||
project.files({ other.output.classesDirs })
|
||||
)
|
||||
compileDependencyFiles += other.output.classesDirs + project.filesProvider { other.compileDependencyFiles }
|
||||
|
||||
configurations.named(implementationConfigurationName).configure {
|
||||
it.extendsFrom(configurations.findByName(other.implementationConfigurationName))
|
||||
}
|
||||
target.project.configurations.named(implementationConfigurationName).configure { configuration ->
|
||||
configuration.extendsFrom(target.project.configurations.findByName(other.implementationConfigurationName))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+22
-39
@@ -11,7 +11,6 @@ import org.gradle.api.NamedDomainObjectCollection
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.ConfigurationContainer
|
||||
import org.gradle.api.artifacts.Dependency
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.attributes.AttributeContainer
|
||||
@@ -25,18 +24,20 @@ import org.gradle.api.tasks.Copy
|
||||
import org.gradle.api.tasks.Exec
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.language.base.plugins.LifecycleBasePlugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPILATION_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.KOTLIN_NATIVE_IGNORE_INCORRECT_DEPENDENCIES
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.registerEmbedAndSignAppleFrameworkTask
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleVariant
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.isMainCompilationData
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
|
||||
import org.jetbrains.kotlin.gradle.targets.native.*
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.commonizeCInteropTask
|
||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeHostTest
|
||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeSimulatorTest
|
||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.createCInteropApiElementsKlibArtifact
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.locateOrCreateCInteropDependencyConfiguration
|
||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.configureConventions
|
||||
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
|
||||
@@ -51,17 +52,6 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
||||
createTestCompilation = true
|
||||
) {
|
||||
|
||||
private fun createCInteropKlibArtifact(
|
||||
interop: DefaultCInteropSettings,
|
||||
interopTask: TaskProvider<out CInteropProcess>
|
||||
) = createKlibArtifact(
|
||||
interop.compilation,
|
||||
interopTask.map { it.outputFile },
|
||||
"cinterop-${interop.name}",
|
||||
interopTask,
|
||||
copy = true
|
||||
)
|
||||
|
||||
// region Task creation.
|
||||
private fun Project.createLinkTask(binary: NativeBinary) {
|
||||
val result = registerTask<KotlinNativeLink>(
|
||||
@@ -219,8 +209,20 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
||||
if (isMain()) {
|
||||
// Register the interop library as an outgoing klib to allow depending on projects with cinterops.
|
||||
project.dependencies.add(target.apiElementsConfigurationName, interopOutput)
|
||||
|
||||
// Add interop library to special CInteropApiElements configuration
|
||||
createCInteropApiElementsKlibArtifact(interop, interopTask)
|
||||
|
||||
// Add the interop library in publication.
|
||||
createCInteropKlibArtifact(interop, interopTask)
|
||||
createKlibArtifact(
|
||||
compilation = interop.compilation,
|
||||
artifactFile = interopTask.map { it.outputFile },
|
||||
classifier = "cinterop-${interop.name}",
|
||||
producingTask = interopTask,
|
||||
copy = true
|
||||
)
|
||||
|
||||
|
||||
// We cannot add the interop library in an compilation output because in this case
|
||||
// IDE doesn't see this library in module dependencies. So we have to manually add
|
||||
// main interop libraries in dependencies of the default test compilation.
|
||||
@@ -278,8 +280,8 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
||||
protected fun configureCInterops(target: KotlinNativeTarget): Unit = with(target.project) {
|
||||
target.compilations.all { compilation ->
|
||||
createCInteropTasks(compilation, compilation.cinterops)
|
||||
compilation.cinterops.all {
|
||||
defineConfigurationsForCInterop(compilation, it, target, configurations)
|
||||
compilation.cinterops.all { cinterop ->
|
||||
cinterop.dependencyFiles += locateOrCreateCInteropDependencyConfiguration(compilation, cinterop, target)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -412,25 +414,6 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
||||
const val INTEROP_GROUP = "interop"
|
||||
const val RUN_GROUP = "run"
|
||||
|
||||
protected fun defineConfigurationsForCInterop(
|
||||
compilation: KotlinNativeCompilation,
|
||||
cinterop: CInteropSettings,
|
||||
target: KotlinTarget,
|
||||
configurations: ConfigurationContainer
|
||||
) {
|
||||
val compileOnlyConfiguration = configurations.getByName(compilation.compileOnlyConfigurationName)
|
||||
val implementationConfiguration = configurations.getByName(compilation.implementationConfigurationName)
|
||||
|
||||
cinterop.dependencyFiles = configurations.maybeCreate(cinterop.dependencyConfigurationName).apply {
|
||||
extendsFrom(compileOnlyConfiguration, implementationConfiguration)
|
||||
usesPlatformOf(target)
|
||||
isVisible = false
|
||||
isCanBeConsumed = false
|
||||
attributes.attribute(USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target))
|
||||
description = "Dependencies for cinterop '${cinterop.name}' (compilation '${compilation.name}')."
|
||||
}
|
||||
}
|
||||
|
||||
internal fun createKlibCompilationTask(
|
||||
compilation: KotlinNativeCompilationData<*>
|
||||
): TaskProvider<KotlinNativeCompile> {
|
||||
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.targets.native.internal
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.attributes.*
|
||||
import org.gradle.api.internal.artifacts.ArtifactAttributes
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.plugin.CInteropSettings
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinNativeTargetConfigurator.NativeArtifactFormat
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultCInteropSettings
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
|
||||
import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements.cinteropKlibLibraryElements
|
||||
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
|
||||
|
||||
internal fun createCInteropApiElementsKlibArtifact(
|
||||
settings: DefaultCInteropSettings,
|
||||
interopTask: TaskProvider<out CInteropProcess>
|
||||
) {
|
||||
val project = settings.compilation.project
|
||||
val configuration = project.locateOrCreateCInteropApiElementsConfiguration(settings.target ?: return)
|
||||
project.artifacts.add(configuration.name, interopTask.map { it.outputFile }) { artifact ->
|
||||
artifact.extension = "klib"
|
||||
artifact.type = "klib"
|
||||
artifact.classifier = "cinterop-${settings.name}"
|
||||
artifact.builtBy(interopTask)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Project.locateOrCreateCInteropDependencyConfiguration(
|
||||
compilation: KotlinNativeCompilation,
|
||||
cinterop: CInteropSettings,
|
||||
target: KotlinTarget
|
||||
): Configuration {
|
||||
val compileOnlyConfiguration = configurations.getByName(compilation.compileOnlyConfigurationName)
|
||||
val implementationConfiguration = configurations.getByName(compilation.implementationConfigurationName)
|
||||
|
||||
return configurations.maybeCreate(cinterop.dependencyConfigurationName).apply {
|
||||
extendsFrom(compileOnlyConfiguration, implementationConfiguration)
|
||||
isVisible = false
|
||||
isCanBeResolved = true
|
||||
isCanBeConsumed = false
|
||||
|
||||
usesPlatformOf(target)
|
||||
attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements())
|
||||
attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_API))
|
||||
description = "Dependencies for cinterop '${cinterop.name}' (compilation '${compilation.name}')."
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.locateOrCreateCInteropApiElementsConfiguration(target: KotlinTarget): Configuration {
|
||||
val configurationName = target.name + "CInteropApiElements"
|
||||
configurations.findByName(configurationName)?.let { return it }
|
||||
|
||||
return configurations.create(configurationName).apply {
|
||||
isCanBeResolved = false
|
||||
isCanBeConsumed = true
|
||||
|
||||
usesPlatformOf(target)
|
||||
attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements())
|
||||
attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_API))
|
||||
attributes.attribute(ArtifactAttributes.ARTIFACT_FORMAT, NativeArtifactFormat.KLIB)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal object CInteropKlibLibraryElements {
|
||||
const val CINTEROP_KLIB = "cinterop-klib"
|
||||
|
||||
fun Project.cinteropKlibLibraryElements(): LibraryElements = objects.named(LibraryElements::class.java, CINTEROP_KLIB)
|
||||
|
||||
fun setupAttributesMatchingStrategy(schema: AttributesSchema) {
|
||||
schema.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE) { strategy ->
|
||||
strategy.compatibilityRules.add(CInteropLibraryElementsCompatibilityRule::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CInteropLibraryElementsCompatibilityRule : AttributeCompatibilityRule<LibraryElements> {
|
||||
override fun execute(details: CompatibilityCheckDetails<LibraryElements>) {
|
||||
if (details.consumerValue?.name == CInteropKlibLibraryElements.CINTEROP_KLIB) {
|
||||
if (details.producerValue?.name == LibraryElements.JAR || details.producerValue?.name == LibraryElements.CLASSES) {
|
||||
details.compatible()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user