[Gradle] Implement setupCInteropPropagatedDependencies
This commit will forward/propagate cinterops to intermediate source sets with only one native dependent (and their metadata compilation) ^KT-47523 Verification Pending
This commit is contained in:
committed by
Space
parent
fee670e1a5
commit
882d72b1f7
+3
-5
@@ -14,10 +14,7 @@ import org.jetbrains.kotlin.compilerRunner.konanVersion
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
|
||||
import org.jetbrains.kotlin.gradle.targets.native.DisabledNativeTargetsReporter
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.NativeDistributionTypeProvider
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.PlatformLibrariesGenerator
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.setupCInteropCommonizerDependencies
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.setupKotlinNativePlatformDependencies
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.*
|
||||
import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader
|
||||
import org.jetbrains.kotlin.gradle.utils.SingleActionPerProject
|
||||
import org.jetbrains.kotlin.konan.CompilerVersion
|
||||
@@ -92,8 +89,9 @@ abstract class AbstractKotlinNativeTargetPreset<T : KotlinNativeTarget>(
|
||||
}
|
||||
}
|
||||
|
||||
SingleActionPerProject.run(project, "setupCInteropCommonizerDependencies") {
|
||||
SingleActionPerProject.run(project, "setupCInteropDependencies") {
|
||||
project.setupCInteropCommonizerDependencies()
|
||||
project.setupCInteropPropagatedDependencies()
|
||||
}
|
||||
|
||||
if (!konanTarget.enabledOnCurrentHost) {
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.file.FileCollection
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||
|
||||
/**
|
||||
* Dependencies here are using a special configuration called 'intransitiveMetadataConfiguration'.
|
||||
* This special configuration can tell the IDE that this dependencies shall *not* be transitively be visible
|
||||
* to dependsOn edges. This is necessary for the way the commonizer handles it's "expect refinement" approach.
|
||||
* In this mode, every source set will receive exactly one commonized library to analyze its source code with.
|
||||
*/
|
||||
internal fun Project.addIntransitiveMetadataDependencyIfPossible(sourceSet: DefaultKotlinSourceSet, dependency: FileCollection) {
|
||||
val dependencyConfigurationName =
|
||||
if (project.isIntransitiveMetadataConfigurationEnabled) sourceSet.intransitiveMetadataConfigurationName
|
||||
else sourceSet.implementationMetadataConfigurationName
|
||||
project.dependencies.add(dependencyConfigurationName, dependency)
|
||||
}
|
||||
+4
-21
@@ -6,9 +6,7 @@
|
||||
package org.jetbrains.kotlin.gradle.targets.native.internal
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.utils.filesProvider
|
||||
@@ -17,13 +15,11 @@ import java.io.File
|
||||
internal fun Project.setupCInteropCommonizerDependencies() {
|
||||
val kotlin = this.multiplatformExtensionOrNull ?: return
|
||||
|
||||
kotlin.targets.withType(KotlinMetadataTarget::class.java).all { target ->
|
||||
target.compilations.withType(KotlinSharedNativeCompilation::class.java).all { compilation ->
|
||||
setupCInteropCommonizerDependenciesForCompilation(compilation)
|
||||
}
|
||||
kotlin.forAllSharedNativeCompilations { compilation ->
|
||||
setupCInteropCommonizerDependenciesForCompilation(compilation)
|
||||
}
|
||||
|
||||
kotlin.sourceSets.withType(DefaultKotlinSourceSet::class.java).all { sourceSet ->
|
||||
kotlin.forAllDefaultKotlinSourceSets { sourceSet ->
|
||||
setupCInteropCommonizerDependenciesForIde(sourceSet)
|
||||
}
|
||||
}
|
||||
@@ -45,7 +41,7 @@ private fun Project.setupCInteropCommonizerDependenciesForCompilation(compilatio
|
||||
private fun Project.setupCInteropCommonizerDependenciesForIde(sourceSet: DefaultKotlinSourceSet) {
|
||||
val cinteropCommonizerTask = project.copyCommonizeCInteropForIdeTask ?: return
|
||||
|
||||
addDependency(sourceSet, filesProvider files@{
|
||||
addIntransitiveMetadataDependencyIfPossible(sourceSet, filesProvider files@{
|
||||
val directlyDependent = CInteropCommonizerDependent.from(project, sourceSet)
|
||||
val associateDependent = CInteropCommonizerDependent.fromAssociateCompilations(project, sourceSet)
|
||||
|
||||
@@ -54,16 +50,3 @@ private fun Project.setupCInteropCommonizerDependenciesForIde(sourceSet: Default
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Dependencies here are using a special configuration called 'intransitiveMetadataConfiguration'.
|
||||
* This special configuration can tell the IDE that this dependencies shall *not* be transitively be visible
|
||||
* to dependsOn edges. This is necessary for the way the commonizer handles it's "expect refinement" approach.
|
||||
* In this mode, every source set will receive exactly one commonized library to analyze its source code with.
|
||||
*/
|
||||
private fun Project.addDependency(sourceSet: DefaultKotlinSourceSet, dependency: FileCollection) {
|
||||
val dependencyConfigurationName =
|
||||
if (project.isIntransitiveMetadataConfigurationEnabled) sourceSet.intransitiveMetadataConfigurationName
|
||||
else sourceSet.implementationMetadataConfigurationName
|
||||
project.dependencies.add(dependencyConfigurationName, dependency)
|
||||
}
|
||||
|
||||
+1
-25
@@ -7,15 +7,11 @@ package org.jetbrains.kotlin.gradle.targets.native.internal
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.CompilationSourceSetUtil.compilationsBySourceSets
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithTransitiveClosure
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.kotlinSourceSetsIncludingDefault
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropIdentifier.Scope
|
||||
import org.jetbrains.kotlin.gradle.utils.UnsafeApi
|
||||
|
||||
@@ -80,7 +76,7 @@ internal fun CInteropCommonizerDependent.Factory.from(
|
||||
internal fun CInteropCommonizerDependent.Factory.from(compilation: KotlinSharedNativeCompilation): CInteropCommonizerDependent? {
|
||||
return from(
|
||||
compilation.project.getCommonizerTarget(compilation) as? SharedCommonizerTarget ?: return null,
|
||||
compilation.findDependingNativeCompilations()
|
||||
compilation.getImplicitlyDependingNativeCompilations()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -104,23 +100,3 @@ internal fun CInteropCommonizerDependent.Factory.fromAssociateCompilations(
|
||||
.toSet()
|
||||
)
|
||||
}
|
||||
|
||||
private fun KotlinSharedNativeCompilation.findDependingNativeCompilations(): Set<KotlinNativeCompilation> {
|
||||
val multiplatformExtension = project.multiplatformExtensionOrNull ?: return emptySet()
|
||||
val allParticipatingSourceSetsOfCompilation = allParticipatingSourceSets()
|
||||
|
||||
return multiplatformExtension.targets
|
||||
.flatMap { target -> target.compilations }
|
||||
.filterIsInstance<KotlinNativeCompilation>()
|
||||
.filter { nativeCompilation -> nativeCompilation.allParticipatingSourceSets().containsAll(allParticipatingSourceSetsOfCompilation) }
|
||||
.toSet()
|
||||
}
|
||||
|
||||
/**
|
||||
* Some implementations of [KotlinCompilation] do not contain the default source set in
|
||||
* [KotlinCompilation.kotlinSourceSets] or [KotlinCompilation.allKotlinSourceSets]
|
||||
* see KT-45412
|
||||
*/
|
||||
private fun KotlinCompilation<*>.allParticipatingSourceSets(): Set<KotlinSourceSet> {
|
||||
return kotlinSourceSetsIncludingDefault + kotlinSourceSetsIncludingDefault.resolveAllDependsOnSourceSets()
|
||||
}
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.file.FileCollection
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.CompilationSourceSetUtil
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
|
||||
import org.jetbrains.kotlin.gradle.utils.filesProvider
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Will propagate "original"/"platform" cinterops to intermediate source sets
|
||||
* and 'shared native' compilations if necessary.
|
||||
*
|
||||
* cinterops will be forwarded when a source set/ compilation has just a single platform
|
||||
* dependee
|
||||
*
|
||||
* e.g.
|
||||
*
|
||||
* ```
|
||||
* kotlin {
|
||||
* sourceSets {
|
||||
* val nativeMain by sourceSets.creating
|
||||
* val linuxX64Main by sourceSets.getting
|
||||
* linuxX64Main.dependsOn(nativeMain)
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* In this example 'nativeMain' has only a single native
|
||||
* target and a single native source set depending on it.
|
||||
* All cinterops defined on linuxX64's main compilation shall be propagated
|
||||
* to the 'nativeMain' source set (and its 'shared native' compilation) if it exists.
|
||||
*/
|
||||
internal fun Project.setupCInteropPropagatedDependencies() {
|
||||
val kotlin = this.multiplatformExtensionOrNull ?: return
|
||||
|
||||
kotlin.forAllSharedNativeCompilations { compilation ->
|
||||
compilation.compileDependencyFiles += getPropagatedCInteropDependenciesOrEmpty(compilation)
|
||||
}
|
||||
|
||||
kotlin.forAllDefaultKotlinSourceSets { sourceSet ->
|
||||
addIntransitiveMetadataDependencyIfPossible(
|
||||
sourceSet, getPropagatedCInteropDependenciesOrEmpty(sourceSet)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.getPropagatedCInteropDependenciesOrEmpty(sourceSet: DefaultKotlinSourceSet): FileCollection {
|
||||
return filesProvider files@{
|
||||
/*
|
||||
compatibility metadata variant will still register
|
||||
a 'KotlinMetadataCompilation for 'commonMain' which is irrelevant here
|
||||
*/
|
||||
val compilations = CompilationSourceSetUtil.compilationsBySourceSets(this)[sourceSet].orEmpty()
|
||||
.filter { compilation -> compilation !is KotlinMetadataCompilation }
|
||||
|
||||
/* Participating in multiple compilations? -> can't propagate -> should be commonized */
|
||||
val compilation = compilations.singleOrNull() as? KotlinNativeCompilation ?: return@files emptySet<File>()
|
||||
|
||||
/* Source Set is directly included in compilation -> No need to add dependency again (will be handled already) */
|
||||
if (sourceSet in compilation.kotlinSourceSets) return@files emptySet<File>()
|
||||
getAllCInteropOutputFiles(compilation)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.getPropagatedCInteropDependenciesOrEmpty(compilation: KotlinSharedNativeCompilation) = filesProvider files@{
|
||||
val compilations = compilation.getImplicitlyDependingNativeCompilations()
|
||||
val platformCompilation = compilations.singleOrNull() ?: return@files emptySet<File>()
|
||||
getAllCInteropOutputFiles(platformCompilation)
|
||||
}
|
||||
|
||||
private fun Project.getAllCInteropOutputFiles(compilation: KotlinNativeCompilation): List<File> {
|
||||
return compilation.cinterops
|
||||
.map { interop -> interop.interopProcessingTaskName }
|
||||
.mapNotNull { taskName -> tasks.findByName(taskName) as? CInteropProcess }
|
||||
.map { it.outputFile }
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.kotlinSourceSetsIncludingDefault
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||
|
||||
internal fun KotlinSharedNativeCompilation.getImplicitlyDependingNativeCompilations(): Set<KotlinNativeCompilation> {
|
||||
val multiplatformExtension = project.multiplatformExtensionOrNull ?: return emptySet()
|
||||
val allParticipatingSourceSetsOfCompilation = allParticipatingSourceSets()
|
||||
|
||||
return multiplatformExtension.targets
|
||||
.flatMap { target -> target.compilations }
|
||||
.filterIsInstance<KotlinNativeCompilation>()
|
||||
.filter { nativeCompilation -> nativeCompilation.allParticipatingSourceSets().containsAll(allParticipatingSourceSetsOfCompilation) }
|
||||
.toSet()
|
||||
}
|
||||
|
||||
/**
|
||||
* Some implementations of [KotlinCompilation] do not contain the default source set in
|
||||
* [KotlinCompilation.kotlinSourceSets] or [KotlinCompilation.allKotlinSourceSets]
|
||||
* see KT-45412
|
||||
*/
|
||||
private fun KotlinCompilation<*>.allParticipatingSourceSets(): Set<KotlinSourceSet> {
|
||||
return kotlinSourceSetsIncludingDefault + kotlinSourceSetsIncludingDefault.resolveAllDependsOnSourceSets()
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||
|
||||
internal inline fun KotlinMultiplatformExtension.forAllSharedNativeCompilations(
|
||||
crossinline action: (compilation: KotlinSharedNativeCompilation) -> Unit
|
||||
) {
|
||||
targets.withType(KotlinMetadataTarget::class.java).all { target ->
|
||||
target.compilations.withType(KotlinSharedNativeCompilation::class.java).all { compilation ->
|
||||
action(compilation)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal inline fun KotlinMultiplatformExtension.forAllDefaultKotlinSourceSets(
|
||||
crossinline action: (sourceSet: DefaultKotlinSourceSet) -> Unit
|
||||
) {
|
||||
sourceSets.withType(DefaultKotlinSourceSet::class.java).all { sourceSet ->
|
||||
action(sourceSet)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user