[Gradle] Multiplatform publishing: Support external targets

...by only requiring InternalKotlinTarget instead of AbstractKotlinTarget

KT-60159
This commit is contained in:
Sebastian Sellmair
2023-08-03 12:19:40 +02:00
committed by Space Team
parent 3d593f0ee9
commit 06d5d2522c
3 changed files with 13 additions and 33 deletions
@@ -10,8 +10,6 @@ import org.gradle.api.Project
import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.dsl.explicitApiModeAsCompilerArg
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.hierarchy.orNull
@@ -62,7 +60,7 @@ class KotlinMultiplatformPlugin : Plugin<Project> {
configurePublishingWithMavenPublish(project)
kotlinMultiplatformExtension.targets.withType(AbstractKotlinTarget::class.java).all { applyUserDefinedAttributes(it) }
kotlinMultiplatformExtension.targets.withType(InternalKotlinTarget::class.java).all { applyUserDefinedAttributes(it) }
// propagate compiler plugin options to the source set language settings
setupAdditionalCompilerArguments(project)
@@ -6,8 +6,9 @@
package org.jetbrains.kotlin.gradle.plugin.mpp
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterEvaluateBuildscript
import org.jetbrains.kotlin.gradle.plugin.launchInStage
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.copyAttributes
import org.jetbrains.kotlin.gradle.plugin.whenEvaluated
/**
@@ -15,37 +16,18 @@ import org.jetbrains.kotlin.gradle.plugin.whenEvaluated
* 1. Output configurations of each target need the corresponding compilation's attributes (and, indirectly, the target's attributes)
* 2. Resolvable configurations of each compilation need the compilation's attributes
*/
internal fun applyUserDefinedAttributes(target: AbstractKotlinTarget) {
val project = target.project
project.whenEvaluated {
// To copy the attributes to the output configurations, find those output configurations and their producing compilations
// based on the target's components:
val outputConfigurationsWithCompilations = target.kotlinComponents.filterIsInstance<KotlinVariant>().flatMap { kotlinVariant ->
kotlinVariant.usages.mapNotNull { usageContext ->
project.configurations.findByName(usageContext.dependencyConfigurationName)?.let { configuration ->
configuration to usageContext.compilation
}
}
}.toMutableList()
// Add usages of android library when its variants are grouped by flavor
outputConfigurationsWithCompilations += target.kotlinComponents
.filterIsInstance<JointAndroidKotlinTargetComponent>()
.flatMap { variant -> variant.usages }
.mapNotNull { usage ->
val configuration = project.configurations.findByName(usage.dependencyConfigurationName) ?: return@mapNotNull null
configuration to usage.compilation
}
outputConfigurationsWithCompilations.forEach { (configuration, compilation) ->
copyAttributes(compilation.attributes, configuration.attributes)
internal fun applyUserDefinedAttributes(target: InternalKotlinTarget) {
target.project.launchInStage(AfterEvaluateBuildscript) {
target.kotlinComponents.flatMap { it.internal.usages }.forEach { usage ->
val dependencyConfiguration = target.project.configurations.findByName(usage.dependencyConfigurationName) ?: return@forEach
copyAttributes(usage.compilation.attributes, dependencyConfiguration.attributes)
}
target.compilations.all { compilation ->
val compilationAttributes = compilation.attributes
compilation.allOwnedConfigurationsNames
.mapNotNull { configurationName -> target.project.configurations.findByName(configurationName) }
.mapNotNull { configurationName -> project.configurations.findByName(configurationName) }
.forEach { configuration -> copyAttributes(compilationAttributes, configuration.attributes) }
}
@@ -38,7 +38,7 @@ internal class PomDependenciesRewriter(
// Get the dependencies mapping according to the component's UsageContexts:
private val dependenciesMappingForEachUsageContext by project.provider {
(component as SoftwareComponentInternal).usages.filterIsInstance<KotlinUsageContext>().mapNotNull { usage ->
component.internal.usages.toList().mapNotNull { usage ->
// When maven scope is not set, we can shortcut immediately here, since no dependencies from that usage context
// will be present in maven pom, e.g. from sourcesElements
val mavenScope = usage.mavenScope ?: return@mapNotNull null
@@ -130,7 +130,7 @@ private fun associateDependenciesWithActualModuleDependencies(
}
else -> when (mavenScope) {
MavenScope.COMPILE -> compilation.compileDependencyConfigurationName
MavenScope.RUNTIME -> (compilation as KotlinCompilationToRunnableFiles).runtimeDependencyConfigurationName
MavenScope.RUNTIME -> compilation.runtimeDependencyConfigurationName ?: return emptyMap()
}
}
)
@@ -162,8 +162,8 @@ private fun associateDependenciesWithActualModuleDependencies(
val resolvedToConfiguration = resolved.configuration
val dependencyTargetComponent: KotlinTargetComponent = run {
dependencyProjectKotlinExtension.targets.withType(AbstractKotlinTarget::class.java).forEach { target ->
target.kotlinComponents.forEach { component ->
dependencyProjectKotlinExtension.targets.forEach { target ->
target.internal.kotlinComponents.forEach { component ->
if (component.findUsageContext(resolvedToConfiguration) != null)
return@run component
}