[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.NamedDomainObjectFactory
|
||||||
import org.gradle.api.Plugin
|
import org.gradle.api.Plugin
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.internal.FeaturePreviews
|
|
||||||
import org.gradle.api.logging.Logger
|
import org.gradle.api.logging.Logger
|
||||||
import org.gradle.api.logging.Logging
|
import org.gradle.api.logging.Logging
|
||||||
import org.gradle.api.model.ObjectFactory
|
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.KotlinJsCompilerAttribute
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlugin
|
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlugin
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.npm.addNpmDependencyExtension
|
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.AbstractKotlinCompile
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_COMPILER_EMBEDDABLE
|
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.tasks.KOTLIN_MODULE_GROUP
|
||||||
import org.jetbrains.kotlin.gradle.testing.internal.KotlinTestsRegistry
|
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.tooling.buildKotlinToolingMetadataTask
|
||||||
import org.jetbrains.kotlin.gradle.utils.checkGradleCompatibility
|
import org.jetbrains.kotlin.gradle.utils.checkGradleCompatibility
|
||||||
import org.jetbrains.kotlin.gradle.utils.loadPropertyFromResources
|
import org.jetbrains.kotlin.gradle.utils.loadPropertyFromResources
|
||||||
@@ -148,6 +146,7 @@ abstract class KotlinBasePluginWrapper : Plugin<Project> {
|
|||||||
KotlinUsages.setupAttributesMatchingStrategy(project, this)
|
KotlinUsages.setupAttributesMatchingStrategy(project, this)
|
||||||
KotlinJsCompilerAttribute.setupAttributesMatchingStrategy(project.dependencies.attributesSchema)
|
KotlinJsCompilerAttribute.setupAttributesMatchingStrategy(project.dependencies.attributesSchema)
|
||||||
ProjectLocalConfigurations.setupAttributesMatchingStrategy(this)
|
ProjectLocalConfigurations.setupAttributesMatchingStrategy(this)
|
||||||
|
CInteropKlibLibraryElements.setupAttributesMatchingStrategy(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal abstract fun getPlugin(
|
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.getVisibleSourceSetsFromAssociateCompilations
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||||
import org.jetbrains.kotlin.gradle.targets.metadata.getMetadataCompilationForSourceSet
|
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.tasks.KotlinNativeCompile
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.filesProvider
|
||||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -122,16 +122,10 @@ class KotlinNativeCompilation(
|
|||||||
get() = lowerCamelCaseName(target.disambiguationClassifier, compilationPurpose, "binaries")
|
get() = lowerCamelCaseName(target.disambiguationClassifier, compilationPurpose, "binaries")
|
||||||
|
|
||||||
override fun addAssociateCompilationDependencies(other: KotlinCompilation<*>) {
|
override fun addAssociateCompilationDependencies(other: KotlinCompilation<*>) {
|
||||||
with(target.project) {
|
compileDependencyFiles += other.output.classesDirs + project.filesProvider { other.compileDependencyFiles }
|
||||||
// Kotlin native does not support either 'compileOnly' or 'runtimeOnly' configurations
|
|
||||||
dependencies.add(
|
|
||||||
implementationConfigurationName,
|
|
||||||
project.files({ other.output.classesDirs })
|
|
||||||
)
|
|
||||||
|
|
||||||
configurations.named(implementationConfigurationName).configure {
|
target.project.configurations.named(implementationConfigurationName).configure { configuration ->
|
||||||
it.extendsFrom(configurations.findByName(other.implementationConfigurationName))
|
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.Project
|
||||||
import org.gradle.api.Task
|
import org.gradle.api.Task
|
||||||
import org.gradle.api.artifacts.Configuration
|
import org.gradle.api.artifacts.Configuration
|
||||||
import org.gradle.api.artifacts.ConfigurationContainer
|
|
||||||
import org.gradle.api.artifacts.Dependency
|
import org.gradle.api.artifacts.Dependency
|
||||||
import org.gradle.api.attributes.Attribute
|
import org.gradle.api.attributes.Attribute
|
||||||
import org.gradle.api.attributes.AttributeContainer
|
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.Exec
|
||||||
import org.gradle.api.tasks.TaskProvider
|
import org.gradle.api.tasks.TaskProvider
|
||||||
import org.gradle.language.base.plugins.LifecycleBasePlugin
|
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.KotlinCompilation.Companion.TEST_COMPILATION_NAME
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.KOTLIN_NATIVE_IGNORE_INCORRECT_DEPENDENCIES
|
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.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.registerEmbedAndSignAppleFrameworkTask
|
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.metadata.isKotlinGranularMetadataEnabled
|
||||||
import org.jetbrains.kotlin.gradle.targets.native.*
|
import org.jetbrains.kotlin.gradle.targets.native.*
|
||||||
import org.jetbrains.kotlin.gradle.targets.native.internal.commonizeCInteropTask
|
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.internal.createCInteropApiElementsKlibArtifact
|
||||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeSimulatorTest
|
import org.jetbrains.kotlin.gradle.targets.native.internal.locateOrCreateCInteropDependencyConfiguration
|
||||||
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest
|
import org.jetbrains.kotlin.gradle.targets.native.tasks.*
|
||||||
import org.jetbrains.kotlin.gradle.tasks.*
|
import org.jetbrains.kotlin.gradle.tasks.*
|
||||||
import org.jetbrains.kotlin.gradle.testing.internal.configureConventions
|
import org.jetbrains.kotlin.gradle.testing.internal.configureConventions
|
||||||
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
|
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
|
||||||
@@ -51,17 +52,6 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
|||||||
createTestCompilation = true
|
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.
|
// region Task creation.
|
||||||
private fun Project.createLinkTask(binary: NativeBinary) {
|
private fun Project.createLinkTask(binary: NativeBinary) {
|
||||||
val result = registerTask<KotlinNativeLink>(
|
val result = registerTask<KotlinNativeLink>(
|
||||||
@@ -219,8 +209,20 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
|||||||
if (isMain()) {
|
if (isMain()) {
|
||||||
// Register the interop library as an outgoing klib to allow depending on projects with cinterops.
|
// Register the interop library as an outgoing klib to allow depending on projects with cinterops.
|
||||||
project.dependencies.add(target.apiElementsConfigurationName, interopOutput)
|
project.dependencies.add(target.apiElementsConfigurationName, interopOutput)
|
||||||
|
|
||||||
|
// Add interop library to special CInteropApiElements configuration
|
||||||
|
createCInteropApiElementsKlibArtifact(interop, interopTask)
|
||||||
|
|
||||||
// Add the interop library in publication.
|
// 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
|
// 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
|
// 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.
|
// 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) {
|
protected fun configureCInterops(target: KotlinNativeTarget): Unit = with(target.project) {
|
||||||
target.compilations.all { compilation ->
|
target.compilations.all { compilation ->
|
||||||
createCInteropTasks(compilation, compilation.cinterops)
|
createCInteropTasks(compilation, compilation.cinterops)
|
||||||
compilation.cinterops.all {
|
compilation.cinterops.all { cinterop ->
|
||||||
defineConfigurationsForCInterop(compilation, it, target, configurations)
|
cinterop.dependencyFiles += locateOrCreateCInteropDependencyConfiguration(compilation, cinterop, target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -412,25 +414,6 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
|
|||||||
const val INTEROP_GROUP = "interop"
|
const val INTEROP_GROUP = "interop"
|
||||||
const val RUN_GROUP = "run"
|
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(
|
internal fun createKlibCompilationTask(
|
||||||
compilation: KotlinNativeCompilationData<*>
|
compilation: KotlinNativeCompilationData<*>
|
||||||
): TaskProvider<KotlinNativeCompile> {
|
): 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