[Gradle][KPM] Split fragment factories into composable entities

This compasability will ensure that external target authors
(AGP) are able to reuse most of KPM code whilst allowing a lot of
customizability.
This commit is contained in:
sebastian.sellmair
2021-11-24 11:37:36 +01:00
committed by Space
parent 386e2e0950
commit 1fb723f844
44 changed files with 1228 additions and 480 deletions
+1
View File
@@ -2,6 +2,7 @@
<dictionary name="sebastiansellmair">
<words>
<w>cinterops</w>
<w>instantiator</w>
<w>interops</w>
<w>klibrary</w>
</words>
@@ -0,0 +1,49 @@
/*
* 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.plugin.mpp.pm20
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.artifacts.Configuration
interface KotlinDependencyConfigurations {
val apiConfiguration: NamedDomainObjectProvider<Configuration>
val implementationConfiguration: NamedDomainObjectProvider<Configuration>
val compileOnlyConfiguration: NamedDomainObjectProvider<Configuration>
val runtimeOnlyConfiguration: NamedDomainObjectProvider<Configuration>
/** This configuration includes the dependencies from the refines-parents */
val transitiveApiConfiguration: NamedDomainObjectProvider<Configuration>
/** This configuration includes the dependencies from the refines-parents */
val transitiveImplementationConfiguration: NamedDomainObjectProvider<Configuration>
private class Impl(
override val apiConfiguration: NamedDomainObjectProvider<Configuration>,
override val implementationConfiguration: NamedDomainObjectProvider<Configuration>,
override val compileOnlyConfiguration: NamedDomainObjectProvider<Configuration>,
override val runtimeOnlyConfiguration: NamedDomainObjectProvider<Configuration>,
override val transitiveApiConfiguration: NamedDomainObjectProvider<Configuration>,
override val transitiveImplementationConfiguration: NamedDomainObjectProvider<Configuration>
) : KotlinDependencyConfigurations
companion object {
fun create(
apiConfiguration: NamedDomainObjectProvider<Configuration>,
implementationConfiguration: NamedDomainObjectProvider<Configuration>,
compileOnlyConfiguration: NamedDomainObjectProvider<Configuration>,
runtimeOnlyConfiguration: NamedDomainObjectProvider<Configuration>,
transitiveApiConfiguration: NamedDomainObjectProvider<Configuration>,
transitiveImplementationConfiguration: NamedDomainObjectProvider<Configuration>
): KotlinDependencyConfigurations = Impl(
apiConfiguration = apiConfiguration,
implementationConfiguration = implementationConfiguration,
compileOnlyConfiguration = compileOnlyConfiguration,
runtimeOnlyConfiguration = runtimeOnlyConfiguration,
transitiveApiConfiguration = transitiveApiConfiguration,
transitiveImplementationConfiguration = transitiveImplementationConfiguration
)
}
}
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
import org.jetbrains.kotlin.project.model.KotlinModuleFragment
import org.jetbrains.kotlin.project.model.refinesClosure
interface KotlinGradleFragment : KotlinModuleFragment, HasKotlinDependencies, Named {
interface KotlinGradleFragment : KotlinModuleFragment, HasKotlinDependencies, KotlinDependencyConfigurations, Named {
override val kotlinSourceRoots: SourceDirectorySet
override val containingModule: KotlinGradleModule
@@ -38,16 +38,22 @@ interface KotlinGradleFragment : KotlinModuleFragment, HasKotlinDependencies, Na
const val COMMON_FRAGMENT_NAME = "common"
}
/** This configuration includes the dependencies from the refines-parents */
val transitiveApiConfigurationName: String
override val apiConfigurationName: String
get() = apiConfiguration.name
/** This configuration includes the dependencies from the refines-parents */
val transitiveImplementationConfigurationName: String
override val implementationConfigurationName: String
get() = implementationConfiguration.name
override val compileOnlyConfigurationName: String
get() = compileOnlyConfiguration.name
override val runtimeOnlyConfigurationName: String
get() = runtimeOnlyConfiguration.name
override val relatedConfigurationNames: List<String>
get() = super.relatedConfigurationNames +
// TODO: resolvable metadata configurations?
listOf(transitiveApiConfigurationName, transitiveImplementationConfigurationName)
listOf(transitiveApiConfiguration.name, transitiveImplementationConfiguration.name)
}
val KotlinGradleFragment.refinesClosure: Set<KotlinGradleFragment>
@@ -5,11 +5,11 @@
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.artifacts.Configuration
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.project.model.KotlinModuleVariant
@@ -18,7 +18,7 @@ interface KotlinGradleVariant : KotlinGradleFragment, KotlinModuleVariant {
val platformType: KotlinPlatformType
// TODO generalize with KotlinCompilation?
val compileDependencyConfigurationName: String
val compileDependenciesConfiguration: NamedDomainObjectProvider<Configuration>
var compileDependencyFiles: FileCollection
@@ -29,30 +29,28 @@ interface KotlinGradleVariant : KotlinGradleFragment, KotlinModuleVariant {
val sourceArchiveTaskName: String
// TODO generalize exposing outputs: what if a variant has more than one such configurations or none?
val apiElementsConfigurationName: String
val apiElementsConfiguration: NamedDomainObjectProvider<Configuration>
val gradleVariantNames: Set<String>
}
interface KotlinGradleVariantWithRuntime : KotlinGradleVariant {
// TODO deduplicate with KotlinCompilation?
val runtimeDependencyConfigurationName: String
val runtimeDependenciesConfiguration: NamedDomainObjectProvider<Configuration>
var runtimeDependencyFiles: FileCollection
val runtimeFiles: ConfigurableFileCollection
// TODO generalize exposing outputs: what if a variant has more than one such configurations or none?
val runtimeElementsConfigurationName: String
val runtimeElementsConfiguration: NamedDomainObjectProvider<Configuration>
}
interface KotlinNativeVariant : KotlinGradleVariant {
override val platformType: KotlinPlatformType
get() = KotlinPlatformType.native
/** A configuration name for the metadata of the host-specific fragments which this variant includes,
* if applies to this Native variant; null otherwise */
val hostSpecificMetadataElementsConfigurationName: String?
val hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider<Configuration>?
var enableEndorsedLibraries: Boolean
}
@@ -48,7 +48,7 @@ internal fun customizeKotlinDependencies(project: Project) {
}
private fun configureDefaultVersionsResolutionStrategy(project: Project) {
project.configurations.all { configuration ->
project.configurations.configureEach { configuration ->
// Use the API introduced in Gradle 4.4 to modify the dependencies directly before they are resolved:
configuration.withDependencies { dependencySet ->
val coreLibrariesVersion = project.topLevelExtension.coreLibrariesVersion
@@ -334,7 +334,7 @@ class GradleModuleVariantResolver : ModuleVariantResolver {
project.configurations.getByName(compilation.compileDependencyConfigurationName)
}
is KotlinPm20ProjectExtension -> {
(requestingVariant as KotlinGradleVariant).compileDependencyConfiguration
(requestingVariant as KotlinGradleVariant).compileDependenciesConfiguration.get()
}
else -> error("could not find the compile dependencies configuration for variant $requestingVariant")
}
@@ -347,4 +347,4 @@ class GradleModuleVariantResolver : ModuleVariantResolver {
}
}
}
}
}
@@ -161,7 +161,7 @@ internal class FragmentGranularMetadataResolver(
// resolve the dependencies of that variant getting the host-specific metadata artifact
relevantVariantResolution?.let { resolution ->
val configurationResolvingPlatformVariant =
(resolution.requestingVariant as KotlinGradleVariant).compileDependencyConfiguration
(resolution.requestingVariant as KotlinGradleVariant).compileDependenciesConfiguration.get()
val hostSpecificArtifact = ResolvedMppVariantsProvider.get(project)
.getHostSpecificMetadataArtifactByRootModule(
dependencyModule.moduleIdentifier,
@@ -5,7 +5,10 @@
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.gradle.api.*
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.component.SoftwareComponentFactory
import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.publish.PublishingExtension
@@ -17,7 +20,6 @@ import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies
import org.jetbrains.kotlin.gradle.utils.checkGradleCompatibility
import org.jetbrains.kotlin.project.model.KotlinModuleIdentifier
import javax.inject.Inject
import kotlin.reflect.KClass
abstract class KotlinPm20GradlePlugin @Inject constructor(
@Inject private val softwareComponentFactory: SoftwareComponentFactory
@@ -42,22 +44,20 @@ abstract class KotlinPm20GradlePlugin @Inject constructor(
KotlinJvmVariantFactory(module)
)
fun <T: KotlinNativeVariantInternal> registerNativeVariantFactory(variantClass: KClass<T>) {
module.fragments.registerFactory(
variantClass.java,
KotlinNativeVariantFactory(module, variantClass)
)
}
fun <T : KotlinNativeVariantInternal> registerNativeVariantFactory(
constructor: KotlinNativeVariantConstructor<T>
) = module.fragments.registerFactory(
constructor.variantClass, KotlinNativeVariantFactory(KotlinNativeVariantInstantiator(module, constructor))
)
listOf(
// FIXME codegen, add missing native targets
KotlinLinuxX64Variant::class,
KotlinMacosX64Variant::class,
KotlinMacosArm64Variant::class,
KotlinIosX64Variant::class,
KotlinIosArm64Variant::class
).forEach { variantClass ->
registerNativeVariantFactory(variantClass)
}
KotlinLinuxX64Variant.constructor,
KotlinMacosX64Variant.constructor,
KotlinMacosArm64Variant.constructor,
KotlinIosX64Variant.constructor,
KotlinIosArm64Variant.constructor
).forEach { constructor -> registerNativeVariantFactory(constructor) }
}
}
@@ -198,4 +198,4 @@ open class KotlinFragmentSlice<T : KotlinGradleFragment>(
fun inModule(module: KotlinGradleModule, configure: T.() -> Unit) {
getOrCreateFragment(module).configure()
}
}
}
@@ -0,0 +1,43 @@
/*
* 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.
*/
@file:Suppress("FunctionName")
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation
typealias KotlinCommonFragmentFactory = KotlinGradleFragmentFactory<KotlinGradleFragmentInternal>
fun KotlinCommonFragmentFactory(module: KotlinGradleModule): KotlinCommonFragmentFactory =
KotlinCommonFragmentFactory(KotlinCommonFragmentInstantiator(module))
fun KotlinCommonFragmentFactory(
commonFragmentInstantiator: KotlinCommonFragmentInstantiator,
commonFragmentConfigurator: KotlinCommonFragmentConfigurator = KotlinCommonFragmentConfigurator()
): KotlinGradleFragmentFactory<KotlinGradleFragmentInternal> = KotlinGradleFragmentFactory(
fragmentInstantiator = commonFragmentInstantiator,
fragmentConfigurator = commonFragmentConfigurator
)
class KotlinCommonFragmentInstantiator(
private val module: KotlinGradleModule,
private val dependencyConfigurationsFactory: KotlinDependencyConfigurationsFactory =
DefaultKotlinDependencyConfigurationsFactory
) : KotlinGradleFragmentFactory.FragmentInstantiator<KotlinGradleFragmentInternal> {
override fun create(name: String): KotlinGradleFragmentInternal {
val names = FragmentNameDisambiguation(module, name)
return KotlinGradleFragmentInternal(module, name, dependencyConfigurationsFactory.create(module, names))
}
}
class KotlinCommonFragmentConfigurator(
private val sourceDirectoriesSetup: KotlinSourceDirectoriesConfigurator<KotlinGradleFragmentInternal> =
DefaultKotlinSourceDirectoriesConfigurator
) : KotlinGradleFragmentFactory.FragmentConfigurator<KotlinGradleFragmentInternal> {
override fun configure(fragment: KotlinGradleFragmentInternal) {
sourceDirectoriesSetup.configure(fragment)
}
}
@@ -0,0 +1,49 @@
/*
* 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.plugin.mpp.pm20
import org.gradle.api.artifacts.Configuration
import org.gradle.api.tasks.TaskProvider
import org.gradle.jvm.tasks.Jar
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
interface KotlinCompileTaskConfigurator<in T : KotlinGradleVariant> {
fun registerCompileTasks(variant: T): TaskProvider<*>
}
object KotlinJvmCompileTaskConfigurator : KotlinCompileTaskConfigurator<KotlinJvmVariant> {
override fun registerCompileTasks(variant: KotlinJvmVariant): TaskProvider<*> {
val compilationData = variant.compilationData
LifecycleTasksManager(variant.project).registerClassesTask(compilationData)
return KotlinCompilationTaskConfigurator(variant.project).createKotlinJvmCompilationTask(variant, compilationData)
}
}
object KotlinNativeCompileTaskConfigurator : KotlinCompileTaskConfigurator<KotlinNativeVariantInternal> {
override fun registerCompileTasks(variant: KotlinNativeVariantInternal): TaskProvider<*> {
val compilationData = variant.compilationData
LifecycleTasksManager(variant.project).registerClassesTask(compilationData)
return KotlinCompilationTaskConfigurator(variant.project).createKotlinNativeCompilationTask(variant, compilationData)
}
}
// TODO NOW: Find place
object KotlinFragmentJarArtifactElementsConfigurator : KotlinFragmentConfigurationsConfigurator<KotlinGradleVariant> {
override fun configure(fragment: KotlinGradleVariant, configuration: Configuration) {
val project = fragment.project
val module = fragment.containingModule
val jarTaskName = fragment.disambiguateName("jar")
val jarTask = project.locateOrRegisterTask<Jar>(jarTaskName) {
it.from(fragment.compilationOutputs.allOutputs)
it.archiveClassifier.set(dashSeparatedName(fragment.name, module.moduleClassifier))
}
project.artifacts.add(configuration.name, jarTask)
}
}
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.project.model.refinesClosure
@@ -45,4 +46,4 @@ interface KotlinVariantCompilationDataInternal<T : KotlinCommonOptions> : Kotlin
fun KotlinCompilationData<*>.isMainCompilationData(): Boolean = when (this) {
is KotlinCompilation<*> -> isMain()
else -> compilationPurpose == KotlinGradleModule.MAIN_MODULE_NAME
}
}
@@ -0,0 +1,54 @@
/*
* 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.plugin.mpp.pm20
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.locateOrRegister
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
import org.jetbrains.kotlin.gradle.utils.extendsFrom
interface KotlinDependencyConfigurationsFactory {
fun create(module: KotlinGradleModule, names: FragmentNameDisambiguation): KotlinDependencyConfigurations
}
object DefaultKotlinDependencyConfigurationsFactory : KotlinDependencyConfigurationsFactory {
override fun create(module: KotlinGradleModule, names: FragmentNameDisambiguation): KotlinDependencyConfigurations {
val configurations = module.project.configurations
val apiConfiguration = configurations.locateOrRegister(names.disambiguateName("api"))
val implementationConfiguration = configurations.locateOrRegister(names.disambiguateName("implementation"))
val compileOnlyConfiguration = configurations.locateOrRegister(names.disambiguateName("compileOnly"))
val runtimeOnlyConfiguration = configurations.locateOrRegister(names.disambiguateName("runtimeOnly"))
val transitiveApiConfiguration = configurations.locateOrRegister(names.disambiguateName("transitiveApi"))
val transitiveImplementationConfiguration = configurations.locateOrRegister(names.disambiguateName("transitiveImplementation"))
listOf(
apiConfiguration,
implementationConfiguration,
compileOnlyConfiguration,
runtimeOnlyConfiguration,
transitiveApiConfiguration,
transitiveImplementationConfiguration
).forEach { configurationProvider ->
configurationProvider.configure { configuration ->
configuration.isCanBeConsumed = false
configuration.isCanBeResolved = false
}
}
transitiveApiConfiguration.extendsFrom(apiConfiguration)
transitiveImplementationConfiguration.extendsFrom(implementationConfiguration)
return KotlinDependencyConfigurations.create(
apiConfiguration = apiConfiguration,
implementationConfiguration = implementationConfiguration,
compileOnlyConfiguration = compileOnlyConfiguration,
runtimeOnlyConfiguration = runtimeOnlyConfiguration,
transitiveApiConfiguration = transitiveApiConfiguration,
transitiveImplementationConfiguration = transitiveImplementationConfiguration
)
}
}
@@ -0,0 +1,18 @@
/*
* 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.plugin.mpp.pm20
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.artifacts.Configuration
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation
interface KotlinFragmentConfigurationInstantiator {
fun locateOrRegister(
module: KotlinGradleModule,
names: FragmentNameDisambiguation,
dependencies: KotlinDependencyConfigurations
): NamedDomainObjectProvider<Configuration>
}
@@ -0,0 +1,110 @@
/*
* 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.
*/
@file:Suppress("FunctionName")
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.gradle.api.artifacts.Configuration
import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages.consumerApiUsage
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages.consumerRuntimeUsage
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages.producerApiUsage
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages.producerRuntimeUsage
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.ComputedCapability
import org.jetbrains.kotlin.gradle.plugin.usageByName
fun interface KotlinFragmentConfigurationsConfigurator<in T : KotlinGradleFragment> {
fun configure(fragment: T, configuration: Configuration)
}
object KotlinFragmentPlatformAttributesConfigurator : KotlinFragmentConfigurationsConfigurator<KotlinGradleVariant> {
override fun configure(fragment: KotlinGradleVariant, configuration: Configuration) {
configuration.attributes.attribute(KotlinPlatformType.attribute, fragment.platformType)
}
}
object KotlinFragmentConsumerApiUsageAttributesConfigurator : KotlinFragmentConfigurationsConfigurator<KotlinGradleVariant> {
override fun configure(fragment: KotlinGradleVariant, configuration: Configuration) {
configuration.attributes.attribute(USAGE_ATTRIBUTE, consumerApiUsage(fragment.project, fragment.platformType))
}
}
object KotlinFragmentProducerApiUsageAttributesConfigurator : KotlinFragmentConfigurationsConfigurator<KotlinGradleVariant> {
override fun configure(fragment: KotlinGradleVariant, configuration: Configuration) {
configuration.attributes.attribute(USAGE_ATTRIBUTE, producerApiUsage(fragment.project, fragment.platformType))
}
}
object KotlinFragmentConsumerRuntimeUsageAttributesConfigurator : KotlinFragmentConfigurationsConfigurator<KotlinGradleVariant> {
override fun configure(fragment: KotlinGradleVariant, configuration: Configuration) {
configuration.attributes.attribute(USAGE_ATTRIBUTE, consumerRuntimeUsage(fragment.project, fragment.platformType))
}
}
object KotlinFragmentProducerRuntimeUsageAttributesConfigurator : KotlinFragmentConfigurationsConfigurator<KotlinGradleVariant> {
override fun configure(fragment: KotlinGradleVariant, configuration: Configuration) {
configuration.attributes.attribute(USAGE_ATTRIBUTE, producerRuntimeUsage(fragment.project, fragment.platformType))
}
}
object KotlinFragmentMetadataUsageAttributeConfigurator : KotlinFragmentConfigurationsConfigurator<KotlinGradleVariant> {
override fun configure(fragment: KotlinGradleVariant, configuration: Configuration) {
configuration.attributes.attribute(USAGE_ATTRIBUTE, fragment.project.usageByName(KotlinUsages.KOTLIN_METADATA))
}
}
object KonanTargetAttributesConfigurator : KotlinFragmentConfigurationsConfigurator<KotlinNativeVariantInternal> {
override fun configure(fragment: KotlinNativeVariantInternal, configuration: Configuration) {
configuration.attributes.attribute(KotlinNativeTarget.konanTargetAttribute, fragment.konanTarget.name)
}
}
object KotlinFragmentModuleCapabilityConfigurator : KotlinFragmentConfigurationsConfigurator<KotlinGradleVariant> {
override fun configure(fragment: KotlinGradleVariant, configuration: Configuration) {
setModuleCapability(configuration, fragment.containingModule)
}
internal fun setModuleCapability(configuration: Configuration, module: KotlinGradleModule) {
if (module.moduleClassifier != null) {
configuration.outgoing.capability(ComputedCapability.fromModule(module))
}
}
}
operator fun <T : KotlinGradleFragment> KotlinFragmentConfigurationsConfigurator<T>.plus(
other: KotlinFragmentConfigurationsConfigurator<T>
): KotlinFragmentConfigurationsConfigurator<T> {
if (this is CompositeKotlinFragmentConfigurationsConfigurator && other is CompositeKotlinFragmentConfigurationsConfigurator) {
return CompositeKotlinFragmentConfigurationsConfigurator(this.setups + other.setups)
}
if (this is CompositeKotlinFragmentConfigurationsConfigurator) {
return CompositeKotlinFragmentConfigurationsConfigurator(this.setups + other)
}
if (other is CompositeKotlinFragmentConfigurationsConfigurator) {
return CompositeKotlinFragmentConfigurationsConfigurator(listOf(this) + other.setups)
}
return CompositeKotlinFragmentConfigurationsConfigurator(listOf(this, other))
}
fun <T : KotlinGradleFragment> KotlinConfigurationsConfigurator(
vararg configurators: KotlinFragmentConfigurationsConfigurator<T>
): KotlinFragmentConfigurationsConfigurator<T> {
return CompositeKotlinFragmentConfigurationsConfigurator(configurators.toList())
}
private class CompositeKotlinFragmentConfigurationsConfigurator<in T : KotlinGradleFragment>(
val setups: List<KotlinFragmentConfigurationsConfigurator<T>>
) : KotlinFragmentConfigurationsConfigurator<T> {
override fun configure(fragment: T, configuration: Configuration) {
setups.forEach { setup -> setup.configure(fragment, configuration) }
}
}
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
import org.jetbrains.kotlin.gradle.plugin.sources.FragmentConsistencyChecker
import org.jetbrains.kotlin.gradle.plugin.sources.FragmentConsistencyChecks
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.gradle.utils.runProjectConfigurationHealthCheckWhenEvaluated
import org.jetbrains.kotlin.project.model.KotlinModuleDependency
import org.jetbrains.kotlin.project.model.KotlinModuleFragment
@@ -27,11 +26,12 @@ import org.jetbrains.kotlin.project.model.refinesClosure
import javax.inject.Inject
open class KotlinGradleFragmentInternal @Inject constructor(
override val containingModule: KotlinGradleModule,
override val fragmentName: String
) : KotlinGradleFragment {
final override val containingModule: KotlinGradleModule,
final override val fragmentName: String,
dependencyConfigurations: KotlinDependencyConfigurations
) : KotlinGradleFragment, KotlinDependencyConfigurations by dependencyConfigurations {
override fun getName(): String = fragmentName
final override fun getName(): String = fragmentName
final override val project: Project // overriding with final to avoid warnings
get() = super.project
@@ -49,12 +49,14 @@ open class KotlinGradleFragmentInternal @Inject constructor(
override fun refines(other: NamedDomainObjectProvider<KotlinGradleFragment>) {
_directRefinesDependencies.add(other)
other.configure { checkCanRefine(it) }
listOf(
KotlinGradleFragment::transitiveApiConfigurationName,
KotlinGradleFragment::transitiveImplementationConfigurationName
).forEach { getConfiguration ->
project.addExtendsFromRelation(getConfiguration(this), getConfiguration(other.get())) // todo eager instantiation; fix?
}
project.addExtendsFromRelation(
this.transitiveApiConfiguration.name, other.get().transitiveApiConfiguration.name
)
project.addExtendsFromRelation(
this.transitiveImplementationConfiguration.name, other.get().transitiveImplementationConfiguration.name
)
project.runProjectConfigurationHealthCheckWhenEvaluated {
kotlinGradleFragmentConsistencyChecker.runAllChecks(this@KotlinGradleFragmentInternal, other.get())
@@ -71,6 +73,7 @@ open class KotlinGradleFragmentInternal @Inject constructor(
override fun dependencies(configureClosure: Closure<Any?>) =
dependencies f@{ ConfigureUtil.configure(configureClosure, this@f) }
/*
override val apiConfigurationName: String
get() = disambiguateName("api")
@@ -83,6 +86,8 @@ open class KotlinGradleFragmentInternal @Inject constructor(
override val runtimeOnlyConfigurationName: String
get() = disambiguateName("runtimeOnly")
*/
private val _directRefinesDependencies = mutableSetOf<Provider<KotlinGradleFragment>>()
override val directRefinesDependencies: Iterable<KotlinGradleFragment>
@@ -96,18 +101,9 @@ open class KotlinGradleFragmentInternal @Inject constructor(
"$fragmentName.kotlin", "Kotlin sources for fragment $fragmentName"
)
override val transitiveApiConfigurationName: String
get() = disambiguateName("transitiveApi")
override val transitiveImplementationConfigurationName: String
get() = disambiguateName("transitiveImplementation")
override fun toString(): String = "fragment $fragmentName in $containingModule"
}
internal fun KotlinModuleFragment.disambiguateName(simpleName: String) =
lowerCamelCaseName(fragmentName, containingModule.moduleIdentifier.moduleClassifier ?: KotlinGradleModule.MAIN_MODULE_NAME, simpleName)
val KotlinGradleFragment.refinesClosure: Set<KotlinGradleFragment>
get() = (this as KotlinModuleFragment).refinesClosure.map { it as KotlinGradleFragment }.toSet()
@@ -0,0 +1,26 @@
/*
* 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.plugin.mpp.pm20
import org.gradle.api.NamedDomainObjectFactory
class KotlinGradleFragmentFactory<T : KotlinGradleFragment>(
private val fragmentInstantiator: FragmentInstantiator<T>,
private val fragmentConfigurator: FragmentConfigurator<T>
) : NamedDomainObjectFactory<T> {
interface FragmentInstantiator<out T : KotlinGradleFragment> {
fun create(name: String): T
}
interface FragmentConfigurator<in T : KotlinGradleFragment> {
fun configure(fragment: T)
}
override fun create(name: String): T {
return fragmentInstantiator.create(name).apply(fragmentConfigurator::configure)
}
}
@@ -42,6 +42,6 @@ open class KotlinGradleModuleFactory(private val project: Project) : NamedDomain
}
protected open fun registerFragmentFactory(module: KotlinGradleModule) {
module.fragments.registerFactory(KotlinGradleFragment::class.java, CommonGradleFragmentFactory(module))
module.fragments.registerFactory(KotlinGradleFragment::class.java, KotlinCommonFragmentFactory(module))
}
}
}
@@ -0,0 +1,46 @@
/*
* 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.plugin.mpp.pm20
import org.gradle.api.artifacts.Dependency
import org.gradle.jvm.tasks.Jar
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName
import org.jetbrains.kotlin.gradle.targets.metadata.filesWithUnpackedArchives
import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION
import org.jetbrains.kotlin.project.model.refinesClosure
object KotlinHostSpecificMetadataArtifactConfigurator :
KotlinGradleFragmentFactory.FragmentConfigurator<KotlinNativeVariantInternal> {
override fun configure(fragment: KotlinNativeVariantInternal) {
val project = fragment.project
val hostSpecificMetadataElements = fragment.hostSpecificMetadataElementsConfiguration ?: return
val hostSpecificMetadataJar = project.registerTask<Jar>(fragment.disambiguateName("hostSpecificMetadataJar")) { jar ->
jar.archiveClassifier.set("metadata")
jar.archiveAppendix.set(fragment.disambiguateName(""))
project.pm20Extension.metadataCompilationRegistryByModuleId.getValue(fragment.containingModule.moduleIdentifier)
.withAll { metadataCompilation ->
val metadataFragment = metadataCompilation.fragment
if (metadataCompilation is KotlinNativeFragmentMetadataCompilationData) {
jar.from(project.files(project.provider {
if (metadataFragment in fragment.refinesClosure && metadataFragment.isNativeHostSpecific())
project.filesWithUnpackedArchives(metadataCompilation.output.allOutputs, setOf(KLIB_FILE_EXTENSION))
else emptyList<Any>()
})) { spec -> spec.into(metadataFragment.name) }
}
}
}
hostSpecificMetadataElements.configure { configuration ->
project.artifacts.add(configuration.name, hostSpecificMetadataJar)
configuration.dependencies.addAllLater(project.objects.listProperty(Dependency::class.java).apply {
set(project.provider { fragment.apiElementsConfiguration.get().allDependencies })
})
}
}
}
@@ -5,14 +5,31 @@
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.artifacts.Configuration
import org.gradle.api.plugins.BasePluginConvention
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.filterModuleName
open class KotlinJvmVariant(containingModule: KotlinGradleModule, fragmentName: String) :
KotlinGradlePublishedVariantWithRuntime(containingModule, fragmentName) {
open class KotlinJvmVariant(
containingModule: KotlinGradleModule,
fragmentName: String,
dependencyConfigurations: KotlinDependencyConfigurations,
compileDependenciesConfiguration: NamedDomainObjectProvider<Configuration>,
apiElementsConfiguration: NamedDomainObjectProvider<Configuration>,
runtimeDependenciesConfiguration: NamedDomainObjectProvider<Configuration>,
runtimeElementsConfiguration: NamedDomainObjectProvider<Configuration>
) : KotlinGradlePublishedVariantWithRuntime(
containingModule = containingModule,
fragmentName = fragmentName,
dependencyConfigurations = dependencyConfigurations,
compileDependencyConfiguration = compileDependenciesConfiguration,
apiElementsConfiguration = apiElementsConfiguration,
runtimeDependencyConfiguration = runtimeDependenciesConfiguration,
runtimeElementsConfiguration = runtimeElementsConfiguration
) {
override val compilationData: KotlinJvmVariantCompilationData by lazy { KotlinJvmVariantCompilationData(this) }
override val platformType: KotlinPlatformType
@@ -3,44 +3,109 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("FunctionName")
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.gradle.api.tasks.TaskProvider
import org.gradle.jvm.tasks.Jar
import org.gradle.language.base.plugins.LifecycleBasePlugin
import org.jetbrains.kotlin.gradle.plugin.Kotlin2JvmSourceSetProcessor
import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion
import org.jetbrains.kotlin.gradle.plugin.mpp.addCommonSourcesToKotlinCompileTask
import org.jetbrains.kotlin.gradle.plugin.mpp.addSourcesToKotlinCompileTask
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.configuration.*
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation
open class KotlinJvmVariantFactory(module: KotlinGradleModule) :
AbstractKotlinGradleRuntimePublishedVariantFactory<KotlinJvmVariant>(module) {
override fun instantiateFragment(name: String) = KotlinJvmVariant(module, name)
typealias KotlinJvmVariantFactory = KotlinGradleFragmentFactory<KotlinJvmVariant>
// FIXME expose the JAR with the artifacts API
private fun getOrCreateJarTask(fragment: KotlinJvmVariant): TaskProvider<Jar> {
val jarTaskName = fragment.disambiguateName("jar")
return project.locateOrRegisterTask(jarTaskName) {
it.from(fragment.compilationOutputs.allOutputs)
it.archiveClassifier.set(dashSeparatedName(fragment.name, module.moduleClassifier))
}
}
fun KotlinJvmVariantFactory(module: KotlinGradleModule): KotlinJvmVariantFactory =
KotlinJvmVariantFactory(KotlinJvmVariantInstantiator(module))
override fun createElementsConfigurations(fragment: KotlinJvmVariant) {
super.createElementsConfigurations(fragment)
listOf(fragment.apiElementsConfigurationName, fragment.runtimeElementsConfigurationName).forEach {
project.artifacts.add(it, getOrCreateJarTask(fragment))
}
}
fun KotlinJvmVariantFactory(
jvmVariantInstantiator: KotlinJvmVariantInstantiator,
jvmVariantConfigurator: KotlinJvmVariantConfigurator = KotlinJvmVariantConfigurator()
): KotlinJvmVariantFactory = KotlinGradleFragmentFactory(
fragmentInstantiator = jvmVariantInstantiator,
fragmentConfigurator = jvmVariantConfigurator
)
override fun configureKotlinCompilation(fragment: KotlinJvmVariant) {
val compilationData = fragment.compilationData
LifecycleTasksManager(project).registerClassesTask(compilationData)
KotlinCompilationTaskConfigurator(project).createKotlinJvmCompilationTask(fragment, compilationData)
class KotlinJvmVariantInstantiator(
private val module: KotlinGradleModule,
private val dependenciesConfigurationFactory: KotlinDependencyConfigurationsFactory =
DefaultKotlinDependencyConfigurationsFactory,
private val compileDependenciesConfigurationInstantiator: KotlinCompileDependenciesConfigurationInstantiator =
DefaultKotlinCompileDependenciesConfigurationInstantiator,
private val apiElementsConfigurationInstantiator: KotlinApiElementsConfigurationInstantiator =
DefaultKotlinApiElementsConfigurationInstantiator,
private val runtimeDependenciesConfigurationInstantiator: KotlinRuntimeDependenciesConfigurationInstantiator =
DefaultKotlinRuntimeDependenciesConfigurationInstantiator,
private val runtimeElementsConfigurationInstantiator: KotlinRuntimeElementsConfigurationFactory =
DefaultKotlinRuntimeElementsConfigurationInstantiator,
) : KotlinGradleFragmentFactory.FragmentInstantiator<KotlinJvmVariant> {
override fun create(name: String): KotlinJvmVariant {
val names = FragmentNameDisambiguation(module, name)
val dependencies = dependenciesConfigurationFactory.create(module, names)
return KotlinJvmVariant(
containingModule = module,
fragmentName = name,
dependencyConfigurations = dependencies,
compileDependenciesConfiguration = compileDependenciesConfigurationInstantiator.locateOrRegister(module, names, dependencies),
apiElementsConfiguration = apiElementsConfigurationInstantiator.locateOrRegister(module, names, dependencies),
runtimeDependenciesConfiguration = runtimeDependenciesConfigurationInstantiator.locateOrRegister(module, names, dependencies),
runtimeElementsConfiguration = runtimeElementsConfigurationInstantiator.locateOrRegister(module, names, dependencies)
)
}
}
//endregion Variant
class KotlinJvmVariantConfigurator(
private val compileTaskConfigurator: KotlinCompileTaskConfigurator<KotlinJvmVariant> =
KotlinJvmCompileTaskConfigurator,
private val sourceArchiveTaskConfigurator: KotlinSourceArchiveTaskConfigurator<KotlinJvmVariant> =
DefaultKotlinSourceArchiveTaskConfigurator,
private val sourceDirectoriesConfigurator: KotlinSourceDirectoriesConfigurator<KotlinJvmVariant> =
DefaultKotlinSourceDirectoriesConfigurator,
private val compileDependenciesConfigurator: KotlinFragmentConfigurationsConfigurator<KotlinJvmVariant> =
DefaultKotlinCompileDependenciesConfigurator,
private val runtimeDependenciesConfigurator: KotlinFragmentConfigurationsConfigurator<KotlinJvmVariant> =
DefaultKotlinRuntimeDependenciesConfigurator,
private val apiElementsConfigurator: KotlinFragmentConfigurationsConfigurator<KotlinJvmVariant> =
DefaultKotlinApiElementsConfigurator,
private val runtimeElementsConfigurator: KotlinFragmentConfigurationsConfigurator<KotlinJvmVariant> =
DefaultKotlinRuntimeElementsConfigurator,
private val publicationConfigurator: KotlinPublicationConfigurator<KotlinJvmVariant> =
KotlinPublicationConfigurator.SingleVariantPublication
) : KotlinGradleFragmentFactory.FragmentConfigurator<KotlinJvmVariant> {
override fun configure(fragment: KotlinJvmVariant) {
fragment.compileDependenciesConfiguration.configure { configuration ->
compileDependenciesConfigurator.configure(fragment, configuration)
}
fragment.runtimeDependenciesConfiguration.configure { configuration ->
runtimeDependenciesConfigurator.configure(fragment, configuration)
}
fragment.apiElementsConfiguration.configure { configuration ->
apiElementsConfigurator.configure(fragment, configuration)
}
fragment.runtimeElementsConfiguration.configure { configuration ->
runtimeElementsConfigurator.configure(fragment, configuration)
}
sourceDirectoriesConfigurator.configure(fragment)
compileTaskConfigurator.registerCompileTasks(fragment)
sourceArchiveTaskConfigurator.registerSourceArchiveTask(fragment)
publicationConfigurator.configure(fragment)
}
}
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptionsImpl
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName
import org.jetbrains.kotlin.gradle.targets.metadata.ResolvedMetadataFilesProvider
import org.jetbrains.kotlin.gradle.targets.metadata.createMetadataDependencyTransformationClasspath
import org.jetbrains.kotlin.gradle.utils.getValue
@@ -5,12 +5,12 @@
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultCInteropSettings
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeCompileOptions
import org.jetbrains.kotlin.gradle.plugin.mpp.isHostSpecificKonanTargetsSet
import org.jetbrains.kotlin.gradle.plugin.mpp.publishedConfigurationName
import org.jetbrains.kotlin.konan.target.KonanTarget
import javax.inject.Inject
@@ -18,18 +18,25 @@ import javax.inject.Inject
abstract class KotlinNativeVariantInternal(
containingModule: KotlinGradleModule,
fragmentName: String,
val konanTarget: KonanTarget
val konanTarget: KonanTarget,
dependencyConfigurations: KotlinDependencyConfigurations,
compileDependencyConfiguration: NamedDomainObjectProvider<Configuration>,
apiElementsConfiguration: NamedDomainObjectProvider<Configuration>,
final override val hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider<Configuration>?
) : KotlinNativeVariant,
KotlinGradleVariantInternal(containingModule, fragmentName),
KotlinGradleVariantInternal(
containingModule = containingModule,
fragmentName = fragmentName,
dependencyConfigurations = dependencyConfigurations,
compileDependenciesConfiguration = compileDependencyConfiguration,
apiElementsConfiguration = apiElementsConfiguration
),
SingleMavenPublishedModuleHolder by DefaultSingleMavenPublishedModuleHolder(containingModule, fragmentName) {
final override val hostSpecificMetadataElementsConfigurationName: String?
get() = disambiguateName("hostSpecificMetadataElements").takeIf { includesHostSpecificMetadata }
override var enableEndorsedLibraries: Boolean = false
override val gradleVariantNames: Set<String>
get() = listOf(apiElementsConfigurationName).flatMap { listOf(it, publishedConfigurationName(it)) }.toSet()
get() = listOf(apiElementsConfiguration.name).flatMap { listOf(it, publishedConfigurationName(it)) }.toSet()
val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName ->
DefaultCInteropSettings(project, cinteropName, compilationData)
@@ -38,24 +45,149 @@ abstract class KotlinNativeVariantInternal(
override val compilationData by lazy { KotlinNativeVariantCompilationData(this) }
}
internal val KotlinNativeVariantInternal.includesHostSpecificMetadata: Boolean
get() = isHostSpecificKonanTargetsSet(setOf(konanTarget))
class KotlinNativeVariantConstructor<T : KotlinNativeVariantInternal>(
val konanTarget: KonanTarget,
val variantClass: Class<T>,
private val constructor: (
containingModule: KotlinGradleModule,
fragmentName: String,
dependencyConfigurations: KotlinDependencyConfigurations,
compileDependencyConfiguration: NamedDomainObjectProvider<Configuration>,
apiElementsConfiguration: NamedDomainObjectProvider<Configuration>,
hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider<Configuration>?
) -> T
) {
operator fun invoke(
containingModule: KotlinGradleModule,
fragmentName: String,
dependencyConfigurations: KotlinDependencyConfigurations,
compileDependencyConfiguration: NamedDomainObjectProvider<Configuration>,
apiElementsConfiguration: NamedDomainObjectProvider<Configuration>,
hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider<Configuration>?
): T = constructor(
containingModule, fragmentName,
dependencyConfigurations,
compileDependencyConfiguration,
apiElementsConfiguration,
hostSpecificMetadataElementsConfiguration
)
}
// FIXME codegen
open class KotlinLinuxX64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) :
KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.LINUX_X64)
open class KotlinLinuxX64Variant @Inject constructor(
containingModule: KotlinGradleModule,
fragmentName: String,
dependencyConfigurations: KotlinDependencyConfigurations,
compileDependencyConfiguration: NamedDomainObjectProvider<Configuration>,
apiElementsConfiguration: NamedDomainObjectProvider<Configuration>,
hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider<Configuration>?
) : KotlinNativeVariantInternal(
containingModule = containingModule,
fragmentName = fragmentName,
konanTarget = KonanTarget.LINUX_X64,
dependencyConfigurations = dependencyConfigurations,
compileDependencyConfiguration = compileDependencyConfiguration,
apiElementsConfiguration = apiElementsConfiguration,
hostSpecificMetadataElementsConfiguration = hostSpecificMetadataElementsConfiguration
) {
companion object {
val constructor = KotlinNativeVariantConstructor(
KonanTarget.LINUX_X64, KotlinLinuxX64Variant::class.java, ::KotlinLinuxX64Variant
)
}
}
open class KotlinMacosX64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) :
KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.MACOS_X64)
open class KotlinMacosX64Variant @Inject constructor(
containingModule: KotlinGradleModule,
fragmentName: String,
dependencyConfigurations: KotlinDependencyConfigurations,
compileDependencyConfiguration: NamedDomainObjectProvider<Configuration>,
apiElementsConfiguration: NamedDomainObjectProvider<Configuration>,
hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider<Configuration>?
) : KotlinNativeVariantInternal(
containingModule = containingModule,
fragmentName = fragmentName,
konanTarget = KonanTarget.MACOS_X64,
dependencyConfigurations = dependencyConfigurations,
compileDependencyConfiguration = compileDependencyConfiguration,
apiElementsConfiguration = apiElementsConfiguration,
hostSpecificMetadataElementsConfiguration = hostSpecificMetadataElementsConfiguration
) {
companion object {
val constructor = KotlinNativeVariantConstructor(
KonanTarget.MACOS_X64, KotlinMacosX64Variant::class.java, ::KotlinMacosX64Variant
)
}
}
open class KotlinMacosArm64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) :
KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.MACOS_ARM64)
open class KotlinMacosArm64Variant @Inject constructor(
containingModule: KotlinGradleModule, fragmentName: String,
dependencyConfigurations: KotlinDependencyConfigurations,
compileDependencyConfiguration: NamedDomainObjectProvider<Configuration>,
apiElementsConfiguration: NamedDomainObjectProvider<Configuration>,
hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider<Configuration>?
) : KotlinNativeVariantInternal(
containingModule = containingModule,
fragmentName = fragmentName,
konanTarget = KonanTarget.MACOS_ARM64,
dependencyConfigurations = dependencyConfigurations,
compileDependencyConfiguration = compileDependencyConfiguration,
apiElementsConfiguration = apiElementsConfiguration,
hostSpecificMetadataElementsConfiguration = hostSpecificMetadataElementsConfiguration
) {
companion object {
val constructor = KotlinNativeVariantConstructor(
KonanTarget.MACOS_ARM64, KotlinMacosArm64Variant::class.java, ::KotlinMacosArm64Variant
)
}
}
open class KotlinIosX64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) :
KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.IOS_X64)
open class KotlinIosX64Variant @Inject constructor(
containingModule: KotlinGradleModule,
fragmentName: String,
dependencyConfigurations: KotlinDependencyConfigurations,
compileDependencyConfiguration: NamedDomainObjectProvider<Configuration>,
apiElementsConfiguration: NamedDomainObjectProvider<Configuration>,
hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider<Configuration>?
) : KotlinNativeVariantInternal(
containingModule = containingModule,
fragmentName = fragmentName,
konanTarget = KonanTarget.IOS_X64,
dependencyConfigurations = dependencyConfigurations,
compileDependencyConfiguration = compileDependencyConfiguration,
apiElementsConfiguration = apiElementsConfiguration,
hostSpecificMetadataElementsConfiguration = hostSpecificMetadataElementsConfiguration
) {
companion object {
val constructor = KotlinNativeVariantConstructor(
KonanTarget.IOS_X64, KotlinIosX64Variant::class.java, ::KotlinIosX64Variant
)
}
}
open class KotlinIosArm64Variant @Inject constructor(
containingModule: KotlinGradleModule,
fragmentName: String,
dependencyConfigurations: KotlinDependencyConfigurations,
compileDependencyConfiguration: NamedDomainObjectProvider<Configuration>,
apiElementsConfiguration: NamedDomainObjectProvider<Configuration>,
hostSpecificMetadataElementsConfiguration: NamedDomainObjectProvider<Configuration>?
) : KotlinNativeVariantInternal(
containingModule = containingModule,
fragmentName = fragmentName,
konanTarget = KonanTarget.IOS_ARM64,
dependencyConfigurations = dependencyConfigurations,
compileDependencyConfiguration = compileDependencyConfiguration,
apiElementsConfiguration = apiElementsConfiguration,
hostSpecificMetadataElementsConfiguration = hostSpecificMetadataElementsConfiguration
) {
companion object {
val constructor = KotlinNativeVariantConstructor(
KonanTarget.IOS_ARM64, KotlinIosArm64Variant::class.java, ::KotlinIosArm64Variant
)
}
}
open class KotlinIosArm64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) :
KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.IOS_ARM64)
interface KotlinNativeCompilationData<T : KotlinCommonOptions> : KotlinCompilationData<T> {
val konanTarget: KonanTarget
@@ -3,87 +3,98 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("FunctionName")
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.Dependency
import org.gradle.api.attributes.Usage
import org.gradle.jvm.tasks.Jar
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
import org.jetbrains.kotlin.gradle.plugin.KotlinNativeTargetConfigurator
import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.gradle.plugin.usageByName
import org.jetbrains.kotlin.gradle.targets.metadata.filesWithUnpackedArchives
import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION
import org.jetbrains.kotlin.project.model.refinesClosure
import kotlin.reflect.KClass
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.configuration.*
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation
open class KotlinNativeVariantFactory<T : KotlinNativeVariantInternal>(
module: KotlinGradleModule,
val variantClass: KClass<out T>
) :
AbstractKotlinGradleVariantFactory<T>(module) {
fun <T : KotlinNativeVariantInternal> KotlinNativeVariantFactory(
nativeVariantInstantiator: KotlinNativeVariantInstantiator<T>,
nativeVariantConfigurator: KotlinNativeVariantConfigurator<T> = KotlinNativeVariantConfigurator()
) = KotlinGradleFragmentFactory(
fragmentInstantiator = nativeVariantInstantiator,
fragmentConfigurator = nativeVariantConfigurator
)
override fun instantiateFragment(name: String): T =
module.project.objects.newInstance(variantClass.java, module, name)
class KotlinNativeVariantInstantiator<T : KotlinNativeVariantInternal>(
private val module: KotlinGradleModule,
override fun setPlatformAttributesInConfiguration(fragment: T, configuration: Configuration) {
super.setPlatformAttributesInConfiguration(fragment, configuration)
configuration.attributes.attribute(KotlinNativeTarget.konanTargetAttribute, fragment.konanTarget.name)
private val kotlinNativeVariantConstructor: KotlinNativeVariantConstructor<T>,
private val dependenciesConfigurationFactory: KotlinDependencyConfigurationsFactory =
DefaultKotlinDependencyConfigurationsFactory,
private val compileDependenciesConfigurationInstantiator: KotlinCompileDependenciesConfigurationInstantiator =
DefaultKotlinCompileDependenciesConfigurationInstantiator,
private val apiElementsConfigurationInstantiator: KotlinApiElementsConfigurationInstantiator =
DefaultKotlinApiElementsConfigurationInstantiator,
private val hostSpecificMetadataElementsConfigurationInstantiator: KotlinHostSpecificMetadataElementsConfigurationInstantiator? =
DefaultKotlinHostSpecificMetadataElementsConfigurationInstantiator(kotlinNativeVariantConstructor.konanTarget)
) : KotlinGradleFragmentFactory.FragmentInstantiator<T> {
override fun create(name: String): T {
val names = FragmentNameDisambiguation(module, name)
val dependencies = dependenciesConfigurationFactory.create(module, names)
return kotlinNativeVariantConstructor.invoke(
containingModule = module,
fragmentName = name,
dependencyConfigurations = dependencies,
compileDependencyConfiguration = compileDependenciesConfigurationInstantiator.locateOrRegister(module, names, dependencies),
apiElementsConfiguration = apiElementsConfigurationInstantiator.locateOrRegister(module, names, dependencies),
hostSpecificMetadataElementsConfiguration =
hostSpecificMetadataElementsConfigurationInstantiator?.locateOrRegister(module, names, dependencies)
)
}
}
override fun create(name: String): T =
super.create(name).also { result ->
configureHostSpecificMetadata(result)
configureVariantPublishing(result)
class KotlinNativeVariantConfigurator<T : KotlinNativeVariantInternal>(
private val compileTaskConfigurator: KotlinCompileTaskConfigurator<T> =
KotlinNativeCompileTaskConfigurator,
private val sourceArchiveTaskConfigurator: KotlinSourceArchiveTaskConfigurator<T> =
DefaultKotlinSourceArchiveTaskConfigurator,
private val sourceDirectoriesConfigurator: KotlinSourceDirectoriesConfigurator<T> =
DefaultKotlinSourceDirectoriesConfigurator,
private val compileDependenciesConfigurator: KotlinFragmentConfigurationsConfigurator<T> =
DefaultKotlinCompileDependenciesConfigurator + KonanTargetAttributesConfigurator,
private val apiElementsConfigurator: KotlinFragmentConfigurationsConfigurator<T> =
DefaultKotlinApiElementsConfigurator + KonanTargetAttributesConfigurator,
private val hostSpecificMetadataElementsConfigurator: KotlinFragmentConfigurationsConfigurator<T> =
DefaultHostSpecificMetadataElementsConfigurator,
private val hostSpecificMetadataArtifactConfigurator: KotlinGradleFragmentFactory.FragmentConfigurator<T> =
KotlinHostSpecificMetadataArtifactConfigurator,
private val publicationConfigurator: KotlinPublicationConfigurator<KotlinNativeVariantInternal> =
KotlinPublicationConfigurator.NativeVariantPublication
) : KotlinGradleFragmentFactory.FragmentConfigurator<T> {
override fun configure(fragment: T) {
fragment.compileDependenciesConfiguration.configure { configuration ->
compileDependenciesConfigurator.configure(fragment, configuration)
}
override fun configureKotlinCompilation(fragment: T) {
val compilationData = fragment.compilationData
LifecycleTasksManager(project).registerClassesTask(compilationData)
KotlinCompilationTaskConfigurator(project).createKotlinNativeCompilationTask(fragment, compilationData)
}
private fun configureHostSpecificMetadata(variant: T) {
val hostSpecificConfigurationNameIfEnabled = variant.hostSpecificMetadataElementsConfigurationName
?: return
val hostSpecificMetadataJar = project.registerTask<Jar>(variant.disambiguateName("hostSpecificMetadataJar")) { jar ->
jar.archiveClassifier.set("metadata")
jar.archiveAppendix.set(variant.disambiguateName(""))
project.pm20Extension.metadataCompilationRegistryByModuleId.getValue(variant.containingModule.moduleIdentifier)
.withAll { metadataCompilation ->
val fragment = metadataCompilation.fragment
if (metadataCompilation is KotlinNativeFragmentMetadataCompilationData) {
jar.from(project.files(project.provider {
if (fragment in variant.refinesClosure && fragment.isNativeHostSpecific())
project.filesWithUnpackedArchives(metadataCompilation.output.allOutputs, setOf(KLIB_FILE_EXTENSION))
else emptyList<Any>()
})) { spec -> spec.into(fragment.name) }
}
}
fragment.apiElementsConfiguration.configure { configuration ->
apiElementsConfigurator.configure(fragment, configuration)
}
val apiElements = project.configurations.getByName(variant.apiElementsConfigurationName)
project.configurations.create(hostSpecificConfigurationNameIfEnabled).apply {
isCanBeResolved = false
isCanBeConsumed = false
setPlatformAttributesAndMetadataUsage(variant)
project.artifacts.add(name, hostSpecificMetadataJar)
dependencies.addAllLater(project.objects.listProperty(Dependency::class.java).apply {
set(project.provider { apiElements.allDependencies })
})
fragment.hostSpecificMetadataElementsConfiguration?.configure { configuration ->
hostSpecificMetadataElementsConfigurator.configure(fragment, configuration)
}
}
open fun configureVariantPublishing(variant: T) {
VariantPublishingConfigurator.get(project).configureNativeVariantPublication(variant)
hostSpecificMetadataArtifactConfigurator.configure(fragment)
sourceDirectoriesConfigurator.configure(fragment)
compileTaskConfigurator.registerCompileTasks(fragment)
sourceArchiveTaskConfigurator.registerSourceArchiveTask(fragment)
publicationConfigurator.configure(fragment)
}
private fun Configuration.setPlatformAttributesAndMetadataUsage(variant: T) {
configureApiElementsConfiguration(variant, this) // then override the Usage attribute
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA))
}
}
}
@@ -0,0 +1,25 @@
/*
* 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.plugin.mpp.pm20
interface KotlinPublicationConfigurator<in T : KotlinGradleVariant> : KotlinGradleFragmentFactory.FragmentConfigurator<T> {
object NoPublication : KotlinPublicationConfigurator<KotlinGradleVariant> {
override fun configure(fragment: KotlinGradleVariant) = Unit
}
object SingleVariantPublication : KotlinPublicationConfigurator<KotlinGradlePublishedVariantWithRuntime> {
override fun configure(fragment: KotlinGradlePublishedVariantWithRuntime) {
VariantPublishingConfigurator.get(fragment.project).configureSingleVariantPublication(fragment)
}
}
object NativeVariantPublication : KotlinPublicationConfigurator<KotlinNativeVariantInternal> {
override fun configure(fragment: KotlinNativeVariantInternal) {
VariantPublishingConfigurator.get(fragment.project).configureNativeVariantPublication(fragment)
}
}
}
@@ -0,0 +1,27 @@
/*
* 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.plugin.mpp.pm20
import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.sourcesJarTaskNamed
interface KotlinSourceArchiveTaskConfigurator<in T : KotlinGradleVariant> {
fun registerSourceArchiveTask(variant: T): TaskProvider<*>?
}
object DefaultKotlinSourceArchiveTaskConfigurator : KotlinSourceArchiveTaskConfigurator<KotlinGradleVariant> {
override fun registerSourceArchiveTask(variant: KotlinGradleVariant): TaskProvider<*> {
return sourcesJarTaskNamed(
taskName = variant.sourceArchiveTaskName,
project = variant.project,
sourceSets = lazy {
FragmentSourcesProvider().getSourcesFromRefinesClosureAsMap(variant)
.entries.associate { it.key.fragmentName to it.value.get() }
},
artifactNameAppendix = variant.name
)
}
}
@@ -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.plugin.mpp.pm20
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import java.io.File
interface KotlinSourceDirectoriesConfigurator<in T : KotlinGradleFragment>: KotlinGradleFragmentFactory.FragmentConfigurator<T>
object DefaultKotlinSourceDirectoriesConfigurator : KotlinSourceDirectoriesConfigurator<KotlinGradleFragment> {
override fun configure(fragment: KotlinGradleFragment) {
fragment.kotlinSourceRoots.srcDir(
defaultSourceFolder(
project = fragment.project,
moduleName = fragment.containingModule.name,
fragmentName = fragment.fragmentName,
type = "kotlin"
)
)
}
fun defaultSourceFolder(project: Project, moduleName: String, fragmentName: String, type: String): File {
return project.file("src/${lowerCamelCaseName(fragmentName, moduleName)}/$type")
}
}
@@ -10,6 +10,7 @@ import org.gradle.api.file.FileCollection
import org.gradle.api.tasks.*
import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataDependencyResolution
import org.jetbrains.kotlin.gradle.plugin.mpp.getAllCompiledSourceSetMetadata
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName
import org.jetbrains.kotlin.gradle.targets.metadata.ResolvedMetadataFilesProvider
import org.jetbrains.kotlin.gradle.utils.getValue
import java.io.File
@@ -53,7 +54,7 @@ internal open class TransformKotlinGranularMetadataForFragment
val participatingFragments = fragment.refinesClosure
val participatingCompilations = participatingFragments.flatMap { it.containingModule.variantsContainingFragment(it) }
participatingCompilations.associate { variant ->
variant.fragmentName to project.configurations.getByName(variant.compileDependencyConfigurationName)
variant.fragmentName to variant.compileDependenciesConfiguration.get()
.allDependencies.map { listOf(it.group, it.name, it.version) }.toSet()
}
}
@@ -1,153 +0,0 @@
/*
* 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.plugin.mpp.pm20
import org.gradle.api.artifacts.Configuration
import org.gradle.api.attributes.Bundling
import org.gradle.api.attributes.Category
import org.gradle.api.attributes.Usage
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.ComputedCapability
import org.jetbrains.kotlin.gradle.plugin.mpp.sourcesJarTaskNamed
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
abstract class AbstractKotlinGradleVariantFactory<T : KotlinGradleVariant>(
module: KotlinGradleModule
) : AbstractKotlinGradleFragmentFactory<T>(module) {
override fun create(name: String): T =
super.create(name).also { fragment ->
createSourcesArchiveTask(fragment)
createElementsConfigurations(fragment)
configureKotlinCompilation(fragment)
// TODO configure resources processing
}
protected open fun setPlatformAttributesInConfiguration(fragment: T, configuration: Configuration) {
configuration.attributes.attribute(KotlinPlatformType.attribute, fragment.platformType)
}
open fun configureCompileResolvableConfiguration(fragment: T, configuration: Configuration) {
setPlatformAttributesInConfiguration(fragment, configuration)
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(project, fragment.platformType))
}
open fun configureApiElementsConfiguration(fragment: T, configuration: Configuration) {
setPlatformAttributesInConfiguration(fragment, configuration)
configuration.attributes.apply {
attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(project, fragment.platformType))
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category::class.java, Category.LIBRARY))
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling::class.java, Bundling.EXTERNAL))
}
}
abstract fun configureKotlinCompilation(fragment: T)
open fun createSourcesArchiveTask(fragment: T) {
sourcesJarTaskNamed(
fragment.sourceArchiveTaskName,
project,
lazy { FragmentSourcesProvider().getSourcesFromRefinesClosureAsMap(fragment).entries.associate { it.key.fragmentName to it.value.get() } },
fragment.name
)
}
override fun createDependencyConfigurations(fragment: T) {
super.createDependencyConfigurations(fragment)
fragment.compileDependencyFiles = project.configurations.create(fragment.compileDependencyConfigurationName).apply {
isCanBeConsumed = false
isCanBeResolved = true
configureCompileResolvableConfiguration(fragment, this@apply)
project.addExtendsFromRelation(name, fragment.transitiveApiConfigurationName)
project.addExtendsFromRelation(name, fragment.transitiveImplementationConfigurationName)
}
// FIXME runtime classpath if supported
}
open fun createElementsConfigurations(fragment: T) {
project.configurations.maybeCreate(fragment.apiElementsConfigurationName).apply {
isCanBeResolved = false
isCanBeConsumed = false
module.ifMadePublic {
isCanBeConsumed = true
}
setModuleCapability(this, fragment.containingModule)
attributes.attribute<Usage>(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(project, fragment.platformType))
extendsFrom(project.configurations.getByName(fragment.transitiveApiConfigurationName))
// FIXME + compileOnly
configureApiElementsConfiguration(fragment, this@apply)
}
}
}
abstract class AbstractKotlinGradleVariantWithRuntimeFactory<T : KotlinGradleVariantWithRuntime>(module: KotlinGradleModule) :
AbstractKotlinGradleVariantFactory<T>(module) {
open fun configureRuntimeResolvableConfiguration(fragment: T, configuration: Configuration) {
setPlatformAttributesInConfiguration(fragment, configuration)
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(project, fragment.platformType))
}
open fun configureRuntimeElementsConfiguration(fragment: T, configuration: Configuration) {
setPlatformAttributesInConfiguration(fragment, configuration)
configuration.attributes.apply {
attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(project, fragment.platformType))
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category::class.java, Category.LIBRARY))
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling::class.java, Bundling.EXTERNAL))
}
}
override fun createDependencyConfigurations(fragment: T) {
super.createDependencyConfigurations(fragment)
fragment.runtimeDependencyFiles = project.configurations.create(fragment.runtimeDependencyConfigurationName).apply {
isCanBeConsumed = false
isCanBeResolved = true
configureRuntimeResolvableConfiguration(fragment, this@apply)
project.addExtendsFromRelation(name, fragment.transitiveApiConfigurationName)
project.addExtendsFromRelation(name, fragment.transitiveImplementationConfigurationName)
}
}
override fun createElementsConfigurations(fragment: T) {
super.createElementsConfigurations(fragment)
project.configurations.maybeCreate(fragment.runtimeElementsConfigurationName).apply {
isCanBeResolved = false
isCanBeConsumed = false
module.ifMadePublic {
isCanBeConsumed = true
setModuleCapability(this, fragment.containingModule)
}
configureRuntimeElementsConfiguration(fragment, this@apply)
extendsFrom(project.configurations.getByName(fragment.transitiveApiConfigurationName))
extendsFrom(project.configurations.getByName(fragment.transitiveImplementationConfigurationName))
// FIXME + runtimeOnly
}
}
}
abstract class AbstractKotlinGradleRuntimePublishedVariantFactory<T : KotlinGradlePublishedVariantWithRuntime>(module: KotlinGradleModule) :
AbstractKotlinGradleVariantWithRuntimeFactory<T>(module) {
override fun create(name: String): T {
val result = super.create(name)
configureVariantPublishing(result)
return result
}
open fun configureVariantPublishing(variant: T) {
VariantPublishingConfigurator.get(project).configureSingleVariantPublication(variant)
}
}
internal fun setModuleCapability(configuration: Configuration, module: KotlinGradleModule) {
if (module.moduleClassifier != null) {
configuration.outgoing.capability(ComputedCapability.fromModule(module))
}
}
@@ -5,81 +5,69 @@
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.gradle.api.Project
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.artifacts.Configuration
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinCompilationOutput
import org.jetbrains.kotlin.gradle.plugin.mpp.MavenPublicationCoordinatesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.ComputedCapability
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName
import org.jetbrains.kotlin.gradle.plugin.mpp.publishedConfigurationName
import org.jetbrains.kotlin.gradle.tasks.withType
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
import org.jetbrains.kotlin.project.model.KotlinAttributeKey
import org.jetbrains.kotlin.project.model.KotlinPlatformTypeAttribute
abstract class KotlinGradleVariantInternal(
containingModule: KotlinGradleModule,
override val fragmentName: String
) : KotlinGradleFragmentInternal(containingModule, fragmentName), KotlinGradleVariant {
fragmentName: String,
dependencyConfigurations: KotlinDependencyConfigurations,
final override val compileDependenciesConfiguration: NamedDomainObjectProvider<Configuration>,
final override val apiElementsConfiguration: NamedDomainObjectProvider<Configuration>
) : KotlinGradleFragmentInternal(
containingModule, fragmentName, dependencyConfigurations
), KotlinGradleVariant {
override val variantAttributes: Map<KotlinAttributeKey, String>
get() = mapOf(KotlinPlatformTypeAttribute to kotlinPlatformTypeAttributeFromPlatform(platformType)) // TODO user attributes
// TODO generalize with KotlinCompilation?
override val compileDependencyConfigurationName: String
get() = disambiguateName("CompileDependencies")
override lateinit var compileDependencyFiles: FileCollection
override var compileDependencyFiles: FileCollection = project.files({ compileDependenciesConfiguration.get() })
internal abstract val compilationData: KotlinVariantCompilationDataInternal<*>
// TODO rewrite using our own artifacts API?
override val compilationOutputs: KotlinCompilationOutput =
DefaultKotlinCompilationOutput(
project,
project.provider { project.buildDir.resolve("processedResources/${containingModule.name}/${fragmentName}") }
)
override val compilationOutputs: KotlinCompilationOutput = DefaultKotlinCompilationOutput(
project, project.provider { project.buildDir.resolve("processedResources/${containingModule.name}/${fragmentName}") }
)
// TODO rewrite using our own artifacts API
override val sourceArchiveTaskName: String
get() = defaultSourceArtifactTaskName
// TODO generalize exposing outputs: what if a variant has more than one such configurations or none?
override val apiElementsConfigurationName: String
get() = disambiguateName("apiElements")
override fun toString(): String = "variant $fragmentName in $containingModule"
}
internal val KotlinGradleVariant.compileDependencyConfiguration: Configuration
get() = containingModule.project.configurations.getByName(compileDependencyConfigurationName)
class DefaultSingleMavenPublishedModuleHolder(
private var module: KotlinGradleModule,
override val defaultPublishedModuleSuffix: String?
private var module: KotlinGradleModule, override val defaultPublishedModuleSuffix: String?
) : SingleMavenPublishedModuleHolder {
private val project get() = module.project
private var assignedMavenPublication: MavenPublication? = null
override fun assignMavenPublication(publication: MavenPublication) {
if (assignedMavenPublication != null)
error("already assigned publication $publication")
if (assignedMavenPublication != null) error("already assigned publication $publication")
assignedMavenPublication = publication
}
override val publishedMavenModuleCoordinates: PublishedModuleCoordinatesProvider =
MavenPublicationCoordinatesProvider(
project,
{ assignedMavenPublication },
defaultPublishedModuleSuffix,
capabilities = listOfNotNull(ComputedCapability.capabilityStringFromModule(module))
)
override val publishedMavenModuleCoordinates: PublishedModuleCoordinatesProvider = MavenPublicationCoordinatesProvider(
project,
{ assignedMavenPublication },
defaultPublishedModuleSuffix,
capabilities = listOfNotNull(ComputedCapability.capabilityStringFromModule(module))
)
}
private fun kotlinPlatformTypeAttributeFromPlatform(platformType: KotlinPlatformType) = platformType.name
@@ -90,39 +78,50 @@ internal val KotlinGradleVariant.defaultSourceArtifactTaskName: String
abstract class KotlinGradleVariantWithRuntimeInternal(
containingModule: KotlinGradleModule,
fragmentName: String
) : KotlinGradleVariantInternal(containingModule, fragmentName), KotlinGradleVariantWithRuntime {
fragmentName: String,
dependencyConfigurations: KotlinDependencyConfigurations,
compileDependencyConfiguration: NamedDomainObjectProvider<Configuration>,
apiElementsConfiguration: NamedDomainObjectProvider<Configuration>,
final override val runtimeDependenciesConfiguration: NamedDomainObjectProvider<Configuration>,
final override val runtimeElementsConfiguration: NamedDomainObjectProvider<Configuration>
) : KotlinGradleVariantInternal(
containingModule = containingModule,
fragmentName = fragmentName,
dependencyConfigurations = dependencyConfigurations,
compileDependenciesConfiguration = compileDependencyConfiguration,
apiElementsConfiguration = apiElementsConfiguration
), KotlinGradleVariantWithRuntime {
// TODO deduplicate with KotlinCompilation?
override val runtimeDependencyConfigurationName: String
get() = disambiguateName("RuntimeDependencies")
override lateinit var runtimeDependencyFiles: FileCollection
override var runtimeDependencyFiles: FileCollection = project.files(runtimeDependenciesConfiguration)
override val runtimeFiles: ConfigurableFileCollection = project.files(
listOf(
{ compilationOutputs.allOutputs },
{ runtimeDependencyFiles }
)
)
// TODO generalize exposing outputs: what if a variant has more than one such configurations or none?
override val runtimeElementsConfigurationName: String
get() = disambiguateName("runtimeElements")
override val runtimeFiles: ConfigurableFileCollection =
project.files(listOf({ compilationOutputs.allOutputs }, { runtimeDependencyFiles }))
}
private fun defaultModuleSuffix(module: KotlinGradleModule, variantName: String): String =
dashSeparatedName(variantName, module.moduleClassifier)
abstract class KotlinGradlePublishedVariantWithRuntime(containingModule: KotlinGradleModule, fragmentName: String) :
KotlinGradleVariantWithRuntimeInternal(containingModule, fragmentName),
SingleMavenPublishedModuleHolder by DefaultSingleMavenPublishedModuleHolder(
containingModule,
defaultModuleSuffix(containingModule, fragmentName)
) {
abstract class KotlinGradlePublishedVariantWithRuntime(
containingModule: KotlinGradleModule, fragmentName: String,
dependencyConfigurations: KotlinDependencyConfigurations,
compileDependencyConfiguration: NamedDomainObjectProvider<Configuration>,
apiElementsConfiguration: NamedDomainObjectProvider<Configuration>,
runtimeDependencyConfiguration: NamedDomainObjectProvider<Configuration>,
runtimeElementsConfiguration: NamedDomainObjectProvider<Configuration>
) : KotlinGradleVariantWithRuntimeInternal(
containingModule = containingModule,
fragmentName = fragmentName,
dependencyConfigurations = dependencyConfigurations,
compileDependencyConfiguration = compileDependencyConfiguration,
apiElementsConfiguration = apiElementsConfiguration,
runtimeDependenciesConfiguration = runtimeDependencyConfiguration,
runtimeElementsConfiguration = runtimeElementsConfiguration
), SingleMavenPublishedModuleHolder by DefaultSingleMavenPublishedModuleHolder(
containingModule, defaultModuleSuffix(containingModule, fragmentName)
) {
override val gradleVariantNames: Set<String>
get() =
listOf(apiElementsConfigurationName, runtimeElementsConfigurationName).flatMapTo(mutableSetOf()) {
listOf(it, publishedConfigurationName(it))
}
}
get() = listOf(apiElementsConfiguration.name, runtimeElementsConfiguration.name).flatMapTo(mutableSetOf()) {
listOf(it, publishedConfigurationName(it))
}
}
@@ -0,0 +1,40 @@
/*
* 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.plugin.mpp.pm20.configuration
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.artifacts.Configuration
import org.gradle.api.attributes.Bundling
import org.gradle.api.attributes.Category
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.locateOrRegister
interface KotlinApiElementsConfigurationInstantiator : KotlinFragmentConfigurationInstantiator
object DefaultKotlinApiElementsConfigurationInstantiator : KotlinApiElementsConfigurationInstantiator {
override fun locateOrRegister(
module: KotlinGradleModule,
names: FragmentNameDisambiguation,
dependencies: KotlinDependencyConfigurations
): NamedDomainObjectProvider<Configuration> {
return module.project.configurations.locateOrRegister(names.disambiguateName("apiElements")) {
isCanBeResolved = false
isCanBeConsumed = false
extendsFrom(dependencies.transitiveApiConfiguration.get())
module.ifMadePublic { isCanBeConsumed = true }
attributes.attribute(Category.CATEGORY_ATTRIBUTE, module.project.objects.named(Category::class.java, Category.LIBRARY))
attributes.attribute(Bundling.BUNDLING_ATTRIBUTE, module.project.objects.named(Bundling::class.java, Bundling.EXTERNAL))
}
}
}
val DefaultKotlinApiElementsConfigurator = KotlinConfigurationsConfigurator(
KotlinFragmentPlatformAttributesConfigurator,
KotlinFragmentModuleCapabilityConfigurator,
KotlinFragmentProducerApiUsageAttributesConfigurator
)
@@ -0,0 +1,35 @@
/*
* 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.plugin.mpp.pm20.configuration
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.artifacts.Configuration
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.locateOrRegister
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
interface KotlinCompileDependenciesConfigurationInstantiator : KotlinFragmentConfigurationInstantiator
object DefaultKotlinCompileDependenciesConfigurationInstantiator : KotlinCompileDependenciesConfigurationInstantiator {
override fun locateOrRegister(
module: KotlinGradleModule,
names: FragmentNameDisambiguation,
dependencies: KotlinDependencyConfigurations
): NamedDomainObjectProvider<Configuration> {
return module.project.configurations.locateOrRegister(names.disambiguateName("compileDependencies")) {
isCanBeConsumed = false
isCanBeResolved = true
module.project.addExtendsFromRelation(name, dependencies.transitiveApiConfiguration.name)
module.project.addExtendsFromRelation(name, dependencies.transitiveImplementationConfiguration.name)
}
}
}
val DefaultKotlinCompileDependenciesConfigurator = KotlinConfigurationsConfigurator(
KotlinFragmentPlatformAttributesConfigurator, KotlinFragmentConsumerApiUsageAttributesConfigurator
)
@@ -0,0 +1,41 @@
/*
* 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.
*/
@file:Suppress("FunctionName")
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20.configuration
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.artifacts.Configuration
import org.jetbrains.kotlin.gradle.plugin.mpp.isHostSpecificKonanTargetsSet
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.locateOrRegister
import org.jetbrains.kotlin.konan.target.KonanTarget
interface KotlinHostSpecificMetadataElementsConfigurationInstantiator : KotlinFragmentConfigurationInstantiator
fun DefaultKotlinHostSpecificMetadataElementsConfigurationInstantiator(
konanTarget: KonanTarget
): KotlinHostSpecificMetadataElementsConfigurationInstantiator? = if (isHostSpecificKonanTargetsSet(setOf(konanTarget)))
DefaultKotlinHostSpecificMetadataElementsConfigurationInstantiator else null
private object DefaultKotlinHostSpecificMetadataElementsConfigurationInstantiator :
KotlinHostSpecificMetadataElementsConfigurationInstantiator {
override fun locateOrRegister(
module: KotlinGradleModule, names: FragmentNameDisambiguation, dependencies: KotlinDependencyConfigurations
): NamedDomainObjectProvider<Configuration> {
return module.project.configurations.locateOrRegister(names.disambiguateName("hostSpecificMetadataElements")) {
isCanBeResolved = false
isCanBeConsumed = false
}
}
}
val DefaultHostSpecificMetadataElementsConfigurator = KotlinConfigurationsConfigurator(
KotlinFragmentPlatformAttributesConfigurator,
KonanTargetAttributesConfigurator,
KotlinFragmentMetadataUsageAttributeConfigurator
)
@@ -0,0 +1,35 @@
/*
* 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.plugin.mpp.pm20.configuration
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.artifacts.Configuration
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.locateOrRegister
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
interface KotlinRuntimeDependenciesConfigurationInstantiator : KotlinFragmentConfigurationInstantiator
object DefaultKotlinRuntimeDependenciesConfigurationInstantiator : KotlinRuntimeDependenciesConfigurationInstantiator {
override fun locateOrRegister(
module: KotlinGradleModule,
names: FragmentNameDisambiguation,
dependencies: KotlinDependencyConfigurations
): NamedDomainObjectProvider<Configuration> {
return module.project.configurations.locateOrRegister(names.disambiguateName("runtimeDependencies")) {
isCanBeConsumed = false
isCanBeResolved = true
module.project.addExtendsFromRelation(name, dependencies.transitiveApiConfiguration.name)
module.project.addExtendsFromRelation(name, dependencies.transitiveImplementationConfiguration.name)
}
}
}
val DefaultKotlinRuntimeDependenciesConfigurator = KotlinConfigurationsConfigurator(
KotlinFragmentPlatformAttributesConfigurator,
KotlinFragmentConsumerRuntimeUsageAttributesConfigurator
)
@@ -0,0 +1,45 @@
/*
* 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.plugin.mpp.pm20.configuration
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.artifacts.Configuration
import org.gradle.api.attributes.Bundling
import org.gradle.api.attributes.Category
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinFragmentModuleCapabilityConfigurator.setModuleCapability
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.FragmentNameDisambiguation
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.locateOrRegister
interface KotlinRuntimeElementsConfigurationFactory : KotlinFragmentConfigurationInstantiator
object DefaultKotlinRuntimeElementsConfigurationInstantiator : KotlinRuntimeElementsConfigurationFactory {
override fun locateOrRegister(
module: KotlinGradleModule,
names: FragmentNameDisambiguation,
dependencies: KotlinDependencyConfigurations
): NamedDomainObjectProvider<Configuration> {
return module.project.configurations.locateOrRegister(names.disambiguateName("runtimeElements")) {
isCanBeResolved = false
isCanBeConsumed = false
attributes.attribute(Category.CATEGORY_ATTRIBUTE, module.project.objects.named(Category::class.java, Category.LIBRARY))
attributes.attribute(Bundling.BUNDLING_ATTRIBUTE, module.project.objects.named(Bundling::class.java, Bundling.EXTERNAL))
extendsFrom(dependencies.transitiveApiConfiguration.get())
extendsFrom(dependencies.transitiveImplementationConfiguration.get())
module.ifMadePublic {
isCanBeConsumed = true
setModuleCapability(this, module)
}
}
}
}
val DefaultKotlinRuntimeElementsConfigurator = KotlinConfigurationsConfigurator(
KotlinFragmentPlatformAttributesConfigurator,
KotlinFragmentProducerRuntimeUsageAttributesConfigurator
)
@@ -1,66 +0,0 @@
/*
* 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.plugin.mpp.pm20
import org.gradle.api.NamedDomainObjectFactory
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.plugin.sources.METADATA_CONFIGURATION_NAME_SUFFIX
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.project.model.KotlinModuleFragment
import java.io.File
abstract class AbstractKotlinGradleFragmentFactory<T : KotlinGradleFragment>(
protected val module: KotlinGradleModule
) : NamedDomainObjectFactory<T> {
protected val project: Project
get() = module.project
abstract fun instantiateFragment(name: String): T
override fun create(name: String): T =
instantiateFragment(name).apply {
createDependencyConfigurations(this)
addDefaultSourceDirectories(this)
}
protected open fun createDependencyConfigurations(fragment: T) {
with(project.configurations) {
fragment.relatedConfigurationNames.forEach { configurationName ->
maybeCreate(configurationName).apply {
// FIXME add metadata configurations or API for IDE import?
if (!configurationName.endsWith(METADATA_CONFIGURATION_NAME_SUFFIX)) {
isCanBeResolved = false
}
isCanBeConsumed = false
}
}
listOf(
fragment.apiConfigurationName to fragment.transitiveApiConfigurationName,
fragment.implementationConfigurationName to fragment.transitiveImplementationConfigurationName
).forEach { (configuration, transitiveConfiguration) ->
project.addExtendsFromRelation(transitiveConfiguration, configuration)
}
}
}
protected open fun addDefaultSourceDirectories(fragment: KotlinGradleFragment) {
fragment.kotlinSourceRoots.srcDir(defaultSourceFolder(project, module.name, fragment.fragmentName, "kotlin"))
// TODO handle resources
}
companion object {
fun defaultSourceFolder(project: Project, moduleName: String, fragmentName: String, type: String): File {
return project.file("src/${lowerCamelCaseName(fragmentName, moduleName)}/$type")
}
}
}
class CommonGradleFragmentFactory(module: KotlinGradleModule) : AbstractKotlinGradleFragmentFactory<KotlinGradleFragmentInternal>(module) {
override fun instantiateFragment(name: String): KotlinGradleFragmentInternal =
project.objects.newInstance(KotlinGradleFragmentInternal::class.java, module, name)
}
@@ -14,7 +14,9 @@ import org.jetbrains.kotlin.gradle.dsl.pm20Extension
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.KotlinCommonSourceSetProcessor
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinFragmentModuleCapabilityConfigurator.setModuleCapability
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.ComputedCapability
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName
import org.jetbrains.kotlin.gradle.targets.metadata.createGenerateProjectStructureMetadataTask
import org.jetbrains.kotlin.gradle.targets.metadata.filesWithUnpackedArchives
import org.jetbrains.kotlin.gradle.tasks.*
@@ -0,0 +1,40 @@
/*
* 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.
*/
@file:Suppress("FunctionName")
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.project.model.KotlinModule
import org.jetbrains.kotlin.project.model.KotlinModuleFragment
internal typealias FragmentNameDisambiguation = KotlinFragmentNameDisambiguation
internal fun FragmentNameDisambiguation(module: KotlinModule, fragmentName: String): FragmentNameDisambiguation {
return DefaultKotlinFragmentNameDisambiguation(module, fragmentName)
}
interface KotlinFragmentNameDisambiguation {
fun disambiguateName(simpleName: String): String
}
private class DefaultKotlinFragmentNameDisambiguation(
private val module: KotlinModule,
private val fragmentName: String
) : KotlinFragmentNameDisambiguation {
override fun disambiguateName(simpleName: String): String {
return KotlinModuleFragment.disambiguateName(module, fragmentName, simpleName)
}
}
internal fun KotlinModuleFragment.disambiguateName(simpleName: String) =
KotlinModuleFragment.disambiguateName(containingModule, fragmentName, simpleName)
internal fun KotlinModuleFragment.Companion.disambiguateName(module: KotlinModule, fragmentName: String, simpleName: String) =
lowerCamelCaseName(fragmentName, module.moduleIdentifier.moduleClassifier ?: KotlinGradleModule.MAIN_MODULE_NAME, simpleName)
@@ -0,0 +1,14 @@
/*
* 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.plugin.mpp.pm20.util
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.NamedDomainObjectProvider
fun <T> NamedDomainObjectContainer<T>.locateOrRegister(name: String, configure: T.() -> Unit = {}): NamedDomainObjectProvider<T> {
return if (name in names) named(name, configure)
else register(name, configure)
}
@@ -17,7 +17,9 @@ import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.publish.maven.internal.publication.DefaultMavenPublication
import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinFragmentModuleCapabilityConfigurator.setModuleCapability
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.ComputedCapability
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName
import org.jetbrains.kotlin.gradle.plugin.mpp.publishedConfigurationName
import org.jetbrains.kotlin.gradle.plugin.usageByName
import org.jetbrains.kotlin.gradle.tasks.withType
@@ -26,14 +28,14 @@ import javax.inject.Inject
fun VariantPublishingConfigurator.configureNativeVariantPublication(variant: KotlinNativeVariantInternal) {
val publishConfigurations = listOfNotNull(
variant.apiElementsConfigurationName,
variant.hostSpecificMetadataElementsConfigurationName // host-specific metadata may be absent
variant.apiElementsConfiguration.name,
variant.hostSpecificMetadataElementsConfiguration?.name // host-specific metadata may be absent
)
configurePublishing(variant, variant, publishConfigurations)
}
fun VariantPublishingConfigurator.configureSingleVariantPublication(variant: KotlinGradlePublishedVariantWithRuntime) {
val publishConfigurations = listOf(variant.apiElementsConfigurationName, variant.runtimeElementsConfigurationName)
val publishConfigurations = listOf(variant.apiElementsConfiguration.name, variant.runtimeElementsConfiguration.name)
configurePublishing(variant, variant, publishConfigurations)
}
@@ -50,8 +52,8 @@ open class VariantPublishingConfigurator @Inject constructor(
open fun inferMavenScopes(variant: KotlinGradleVariant, configurationNames: Iterable<String>): Map<String, String?> =
configurationNames.associateWith { configurationName ->
when {
configurationName == variant.apiElementsConfigurationName -> "compile"
variant is KotlinGradleVariantWithRuntime && configurationName == variant.runtimeElementsConfigurationName -> "runtime"
configurationName == variant.apiElementsConfiguration.name -> "compile"
variant is KotlinGradleVariantWithRuntime && configurationName == variant.runtimeElementsConfiguration.name -> "runtime"
else -> null
}
}
@@ -201,4 +203,4 @@ open class DocumentationVariantConfigurator {
ComputedCapability.fromModuleOrNull(variant.containingModule)
)
}
}
}
@@ -50,7 +50,7 @@ class AndroidExtensionsSubpluginIndicator @Inject internal constructor(private v
private fun addAndroidExtensionsRuntime(project: Project) {
val kotlinPluginVersion = project.getKotlinPluginVersion()
project.configurations.all { configuration ->
project.configurations.configureEach all@{ configuration ->
val name = configuration.name
if (name != "implementation" && name != "compile") return@all
@@ -303,4 +303,4 @@ class AndroidSubplugin :
kotlinCompilation: KotlinCompilation<KotlinCommonOptions>?
): List<SubpluginOption> = emptyList()
//endregion
}
}
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeCompilationData
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeVariantCompilationData
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.disambiguateName
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropIdentifier
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import java.io.File
@@ -142,4 +143,4 @@ private fun KotlinNativeCompilationData<*>.disambiguateName(simpleName: String):
this.compilationPurpose.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
simpleName
)
}
}
@@ -539,7 +539,7 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
private val KotlinNativeCompilationData<*>.apiElementsConfigurationName: String
get() = when (val dataOwner = owner) {
is KotlinGradleVariant -> dataOwner.apiElementsConfigurationName
is KotlinGradleVariant -> dataOwner.apiElementsConfiguration.name
is KotlinTarget -> dataOwner.apiElementsConfigurationName
else -> error("unexpected owner of $this")
}
@@ -5,8 +5,9 @@
package org.jetbrains.kotlin.gradle.utils
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.Project
import java.lang.RuntimeException
import org.gradle.api.artifacts.Configuration
fun Project.addExtendsFromRelation(extendingConfigurationName: String, extendsFromConfigurationName: String, forced: Boolean = true) {
if (extendingConfigurationName == extendsFromConfigurationName) return
@@ -16,4 +17,9 @@ fun Project.addExtendsFromRelation(extendingConfigurationName: String, extendsFr
else return
extending.extendsFrom(configurations.getByName(extendsFromConfigurationName))
}
}
fun NamedDomainObjectProvider<Configuration>.extendsFrom(other: NamedDomainObjectProvider<Configuration>) {
if (name == other.name) return
configure { extending -> extending.extendsFrom(other.get()) }
}
@@ -21,6 +21,8 @@ interface KotlinModuleFragment {
// TODO: should this be source roots or source files?
val kotlinSourceRoots: Iterable<File>
companion object
}
interface KotlinModuleVariant : KotlinModuleFragment {
@@ -72,4 +74,4 @@ class BasicKotlinModuleVariant(
), KotlinModuleVariant {
override val variantAttributes: MutableMap<KotlinAttributeKey, String> = mutableMapOf()
override fun toString(): String = "variant $fragmentName"
}
}