[Gradle] Implement KotlinNativeTargetConfigurator.createCInteropTasks as EP based side effects

KT-61634
This commit is contained in:
Sebastian Sellmair
2023-11-02 16:41:02 +01:00
committed by Space Team
parent 8651d67aeb
commit 9b47c98ce9
4 changed files with 100 additions and 84 deletions
@@ -0,0 +1,89 @@
/*
* 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.mpp.compilationImpl
import org.jetbrains.kotlin.gradle.artifacts.createKlibArtifact
import org.jetbrains.kotlin.gradle.artifacts.klibOutputDirectory
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationInfo
import org.jetbrains.kotlin.gradle.plugin.KotlinNativeTargetConfigurator
import org.jetbrains.kotlin.gradle.plugin.launch
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.enabledOnCurrentHost
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
import org.jetbrains.kotlin.gradle.targets.native.internal.commonizeCInteropTask
import org.jetbrains.kotlin.gradle.targets.native.internal.copyCommonizeCInteropForIdeTask
import org.jetbrains.kotlin.gradle.targets.native.internal.createCInteropApiElementsKlibArtifact
import org.jetbrains.kotlin.gradle.targets.native.internal.locateOrCreateCInteropDependencyConfiguration
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.newInstance
internal val KotlinCreateNativeCInteropTasksSideEffect = KotlinCompilationSideEffect<KotlinNativeCompilation> { compilation ->
val project = compilation.project
val compilationInfo = KotlinCompilationInfo(compilation)
compilation.cinterops.all { interop ->
val params = CInteropProcess.Params(
settings = interop,
targetName = compilation.target.name,
compilationName = compilation.name,
konanTarget = compilation.konanTarget,
baseKlibName = run {
val compilationPrefix = if (compilation.isMain()) project.name else compilation.name
"$compilationPrefix-cinterop-${interop.name}"
},
services = project.objects.newInstance()
)
val interopTask = project.registerTask<CInteropProcess>(interop.interopProcessingTaskName, listOf(params)) {
it.destinationDir = project.klibOutputDirectory(compilationInfo).dir("cinterop").map { it.asFile }
it.group = KotlinNativeTargetConfigurator.INTEROP_GROUP
it.description = "Generates Kotlin/Native interop library '${interop.name}' " +
"for compilation '${compilation.compilationName}'" +
"of target '${it.konanTarget.name}'."
it.enabled = compilation.konanTarget.enabledOnCurrentHost
}
project.launch {
project.commonizeCInteropTask()?.configure { commonizeCInteropTask ->
commonizeCInteropTask.from(interopTask)
}
project.copyCommonizeCInteropForIdeTask()
}
val interopOutput = project.files(interopTask.map { it.outputFileProvider })
with(compilation) {
compileDependencyFiles += interopOutput
if (isMain()) {
// Add interop library to special CInteropApiElements configuration
createCInteropApiElementsKlibArtifact(compilation.target, interop, interopTask)
// Add the interop library in publication.
createKlibArtifact(
compilation,
artifactFile = interopTask.map { it.outputFile },
classifier = "cinterop-${interop.name}",
producingTask = interopTask,
)
// 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.
target.compilations.findByName(KotlinCompilation.TEST_COMPILATION_NAME)?.let { testCompilation ->
testCompilation.compileDependencyFiles += interopOutput
testCompilation.cinterops.all {
it.dependencyFiles += interopOutput
}
}
}
}
interop.dependencyFiles += project.locateOrCreateCInteropDependencyConfiguration(compilation)
}
}
@@ -69,6 +69,7 @@ import org.jetbrains.kotlin.gradle.targets.native.ConfigureFrameworkExportSideEf
import org.jetbrains.kotlin.gradle.targets.native.CreateFatFrameworksSetupAction
import org.jetbrains.kotlin.gradle.targets.native.KotlinNativeConfigureBinariesSideEffect
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizedCInteropApiElementsConfigurationsSetupAction
import org.jetbrains.kotlin.gradle.targets.native.internal.SetupCInteropApiElementsConfigurationSideEffect
import org.jetbrains.kotlin.gradle.targets.native.tasks.artifact.KotlinArtifactsExtensionSetupAction
import org.jetbrains.kotlin.gradle.tooling.RegisterBuildKotlinToolingMetadataTask
@@ -117,6 +118,7 @@ internal fun Project.registerKotlinPluginExtensions() {
register(project, KotlinNativeConfigureBinariesSideEffect)
register(project, CreateDefaultTestRunSideEffect)
register(project, ConfigureFrameworkExportSideEffect)
register(project, SetupCInteropApiElementsConfigurationSideEffect)
}
KotlinCompilationSideEffect.extensionPoint.apply {
@@ -125,6 +127,7 @@ internal fun Project.registerKotlinPluginExtensions() {
register(project, KotlinCreateLifecycleTasksSideEffect)
register(project, KotlinCreateNativeCompileTasksSideEffect)
register(project, KotlinCompilationProcessorSideEffect)
register(project, KotlinCreateNativeCInteropTasksSideEffect)
}
KotlinTargetArtifact.extensionPoint.apply {
@@ -6,20 +6,12 @@
@file:Suppress("PackageDirectoryMismatch") // Old package for compatibility
package org.jetbrains.kotlin.gradle.plugin
import org.gradle.api.NamedDomainObjectCollection
import org.gradle.api.Project
import org.gradle.api.artifacts.Dependency
import org.jetbrains.kotlin.gradle.artifacts.createKlibArtifact
import org.jetbrains.kotlin.gradle.artifacts.klibOutputDirectory
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPILATION_NAME
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.mpp.*
import org.jetbrains.kotlin.gradle.plugin.mpp.Framework
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.registerEmbedAndSignAppleFrameworkTask
import org.jetbrains.kotlin.gradle.targets.native.internal.*
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.newInstance
open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotlinTargetConfigurator<T>(
createTestCompilation = true
@@ -27,76 +19,11 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
// FIXME support creating interop tasks for PM20
private fun Project.createCInteropTasks(
compilation: KotlinNativeCompilation,
cinterops: NamedDomainObjectCollection<DefaultCInteropSettings>,
) {
val compilationInfo = KotlinCompilationInfo(compilation)
cinterops.all { interop ->
val params = CInteropProcess.Params(
settings = interop,
targetName = compilation.target.name,
compilationName = compilation.name,
konanTarget = compilation.konanTarget,
baseKlibName = run {
val compilationPrefix = if (compilation.isMain()) project.name else compilation.name
"$compilationPrefix-cinterop-${interop.name}"
},
services = objects.newInstance()
)
val interopTask = registerTask<CInteropProcess>(interop.interopProcessingTaskName, listOf(params)) {
it.destinationDir = klibOutputDirectory(compilationInfo).dir("cinterop").map { it.asFile }
it.group = INTEROP_GROUP
it.description = "Generates Kotlin/Native interop library '${interop.name}' " +
"for compilation '${compilation.compilationName}'" +
"of target '${it.konanTarget.name}'."
it.enabled = compilation.konanTarget.enabledOnCurrentHost
}
project.launch {
project.commonizeCInteropTask()?.configure { commonizeCInteropTask ->
commonizeCInteropTask.from(interopTask)
}
project.copyCommonizeCInteropForIdeTask()
}
val interopOutput = project.files(interopTask.map { it.outputFileProvider })
with(compilation) {
compileDependencyFiles += interopOutput
if (isMain()) {
// Add interop library to special CInteropApiElements configuration
createCInteropApiElementsKlibArtifact(compilation.target, interop, interopTask)
// Add the interop library in publication.
createKlibArtifact(
compilation,
artifactFile = interopTask.map { it.outputFile },
classifier = "cinterop-${interop.name}",
producingTask = interopTask,
)
// 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.
target.compilations.findByName(TEST_COMPILATION_NAME)?.let { testCompilation ->
testCompilation.compileDependencyFiles += interopOutput
testCompilation.cinterops.all {
it.dependencyFiles += interopOutput
}
}
}
}
}
}
// endregion.
// region Configuration.
override fun configurePlatformSpecificModel(target: T) {
configureCInterops(target)
if (target.konanTarget.family.isAppleFamily) {
registerEmbedAndSignAppleFrameworkTasks(target)
}
@@ -106,15 +33,7 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
}
}
protected fun configureCInterops(target: KotlinNativeTarget): Unit = with(target.project) {
locateOrCreateCInteropApiElementsConfiguration(target)
target.compilations.all { compilation ->
createCInteropTasks(compilation, compilation.cinterops)
compilation.cinterops.all { cinterop ->
cinterop.dependencyFiles += locateOrCreateCInteropDependencyConfiguration(compilation)
}
}
}
private fun registerEmbedAndSignAppleFrameworkTasks(target: KotlinNativeTarget) {
val project = target.project
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.gradle.plugin.internal.artifactTypeAttribute
import org.jetbrains.kotlin.gradle.plugin.launchInStage
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf
import org.jetbrains.kotlin.gradle.targets.KotlinTargetSideEffect
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements.cinteropKlibLibraryElements
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
import org.jetbrains.kotlin.gradle.utils.copyAttributes
@@ -67,6 +68,10 @@ internal fun Project.locateOrCreateCInteropDependencyConfiguration(
internal val KotlinNativeCompilation.cInteropDependencyConfigurationName: String
get() = compilation.disambiguateName("CInterop")
internal val SetupCInteropApiElementsConfigurationSideEffect = KotlinTargetSideEffect<KotlinNativeTarget> { target ->
target.project.locateOrCreateCInteropApiElementsConfiguration(target)
}
internal fun Project.locateOrCreateCInteropApiElementsConfiguration(target: KotlinTarget): Configuration {
val configurationName = cInteropApiElementsConfigurationName(target)
configurations.findByName(configurationName)?.let { return it }