From 8753ea592f5c682bb94e0d24875113290512324a Mon Sep 17 00:00:00 2001 From: Sergey Igushkin Date: Tue, 1 Feb 2022 15:54:34 +0400 Subject: [PATCH] KPM-mapped-model: simple mapping of JVM variants --- .../internal/KotlinDependenciesManagement.kt | 21 ++- .../kotlin/gradle/plugin/KotlinPlugin.kt | 2 +- .../kotlin/gradle/plugin/KotlinProperties.kt | 5 +- .../plugin/mpp/KotlinMultiplatformPlugin.kt | 13 ++ .../gradle/plugin/mpp/kotlinCompilations.kt | 2 +- .../gradle/plugin/mpp/pm20/GradlePlugin.kt | 41 +---- ...inFragmentCompilationOutputsJarArtifact.kt | 5 +- .../plugin/mpp/pm20/KotlinJvmVariant.kt | 155 +++++++++++++++++- .../mpp/pm20/KotlinMetadataCompilationData.kt | 6 +- .../plugin/mpp/pm20/ModulePublishing.kt | 60 +++++++ .../plugin/mpp/pm20/VariantFactories.kt | 34 ++++ .../mpp/pm20/fragmentsMetadataCompilation.kt | 7 + .../jvm/KotlinJvmCompilationFactory.kt | 2 +- .../jvm/KotlinJvmTargetConfigurator.kt | 2 +- .../targets/jvm/KotlinJvmTargetPreset.kt | 12 +- .../KotlinMetadataTargetConfigurator.kt | 22 +-- 16 files changed, 315 insertions(+), 74 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/ModulePublishing.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/VariantFactories.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt index 976707052a2..1017d49005b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt @@ -24,7 +24,8 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.plugin.mpp.* import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleFragment import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.hasKpmModel +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.kpmModules import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets import org.jetbrains.kotlin.gradle.plugin.sources.sourceSetDependencyConfigurationByScope @@ -100,12 +101,11 @@ internal fun configureStdlibDefaultDependency(project: Project) = with(project) val scopesToHandleConfigurations = listOf(KotlinDependencyScope.API_SCOPE, KotlinDependencyScope.IMPLEMENTATION_SCOPE) - when (val topLevelExtension = project.topLevelExtension) { - is KotlinPm20ProjectExtension -> { - addStdlibToPm20Project(topLevelExtension) - } - is KotlinProjectExtension -> { - topLevelExtension.sourceSets.all { kotlinSourceSet -> + val ext = topLevelExtension + when { + project.hasKpmModel -> addStdlibToKpmProject(project) + ext is KotlinProjectExtension -> { + ext.sourceSets.all { kotlinSourceSet -> scopesToHandleConfigurations.forEach { scope -> val scopeConfiguration = project.sourceSetDependencyConfigurationByScope(kotlinSourceSet, scope) @@ -130,11 +130,10 @@ internal fun configureStdlibDefaultDependency(project: Project) = with(project) } } -private fun addStdlibToPm20Project( - topLevelExtension: KotlinPm20ProjectExtension +private fun addStdlibToKpmProject( + project: Project ) { - val project = topLevelExtension.project - topLevelExtension.modules.matching { it.name == KotlinGradleModule.MAIN_MODULE_NAME }.configureEach { main -> + project.kpmModules.matching { it.name == KotlinGradleModule.MAIN_MODULE_NAME }.configureEach { main -> main.fragments.matching { it.name == KotlinGradleFragment.COMMON_FRAGMENT_NAME }.configureEach { common -> common.dependencies { api(project.kotlinDependency("kotlin-stdlib-common", project.topLevelExtension.coreLibrariesVersion)) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index f14e5bad9ed..ea0d4ffaa2e 100755 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -368,7 +368,7 @@ internal class KotlinCommonSourceSetProcessor( project.locateTask(kotlinCompilation.target.artifactsTaskName)?.dependsOn(kotlinTask) } - if (kotlinCompilation is AbstractKotlinCompilation<*>) { + if (kotlinCompilation is KotlinCompilation<*>) { project.whenEvaluated { val subpluginEnvironment: SubpluginEnvironment = SubpluginEnvironment.loadSubplugins(project) subpluginEnvironment.addSubpluginOptions(project, kotlinCompilation) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt index 7c1dd27c682..8fbf7915801 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinProperties.kt @@ -206,7 +206,10 @@ internal class PropertiesProvider private constructor(private val project: Proje get() = booleanProperty(KOTLIN_MPP_HIERARCHICAL_STRUCTURE_BY_DEFAULT) ?: true val enableCompatibilityMetadataVariant: Boolean - get() = booleanProperty("kotlin.mpp.enableCompatibilityMetadataVariant") ?: !mppHierarchicalStructureByDefault + get() { + return (booleanProperty("kotlin.mpp.enableCompatibilityMetadataVariant") ?: !mppHierarchicalStructureByDefault) && + !experimentalKpmModelMapping + } val enableKotlinToolingMetadataArtifact: Boolean get() = booleanProperty("kotlin.mpp.enableKotlinToolingMetadataArtifact") ?: true diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt index 38ee3415b42..4a5047975ff 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt @@ -26,6 +26,12 @@ import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin.Companion.sourceSetFreeCompilerArgsPropertyName import org.jetbrains.kotlin.gradle.plugin.mpp.internal.handleHierarchicalStructureFlagsMigration +import org.jetbrains.kotlin.gradle.plugin.mpp.isMain +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.* +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.hasKpmModel +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.registerDefaultVariantFactories +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.setupFragmentsMetadataForKpmModules +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.setupKpmModulesPublication import org.jetbrains.kotlin.gradle.plugin.sources.CleanupStaleSourceSetMetadataEntriesService import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder import org.jetbrains.kotlin.gradle.plugin.sources.SourceSetMetadataStorageForIde @@ -125,6 +131,13 @@ class KotlinMultiplatformPlugin : Plugin { } } } + + if (project.hasKpmModel) { + setupFragmentsMetadataForKpmModules(project) + setupKpmModulesPublication(project) + registerDefaultVariantFactories(project) + project.kpmModules.matching { it.name == KotlinGradleModule.MAIN_MODULE_NAME }.all { it.makePublic() } + } } private fun exportProjectStructureMetadataForOtherBuilds( diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt index 5ac3d7d3b71..582715de247 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt @@ -151,7 +151,7 @@ abstract class AbstractKotlinCompilation( } } - final override fun source(sourceSet: KotlinSourceSet) { + override fun source(sourceSet: KotlinSourceSet) { if (kotlinSourceSets.add(sourceSet)) { target.project.whenEvaluated { addExactSourceSetsEagerly(sourceSet.withAllDependsOnSourceSets()) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradlePlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradlePlugin.kt index e9ce0b7d6ae..3c9cbab412f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradlePlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradlePlugin.kt @@ -35,32 +35,8 @@ abstract class KotlinPm20GradlePlugin @Inject constructor( createDefaultModules(project) customizeKotlinDependencies(project) registerDefaultVariantFactories(project) - setupFragmentsMetadata(project) - setupPublication(project) - } - - private fun registerDefaultVariantFactories(project: Project) { - project.pm20Extension.modules.configureEach { module -> - module.fragments.registerFactory( - KotlinJvmVariant::class.java, - KotlinJvmVariantFactory(module) - ) - - fun registerNativeVariantFactory( - constructor: KotlinNativeVariantConstructor - ) = module.fragments.registerFactory( - constructor.variantClass, KotlinNativeVariantFactory(module, constructor) - ) - - listOf( - // FIXME codegen, add missing native targets - KotlinLinuxX64Variant.constructor, - KotlinMacosX64Variant.constructor, - KotlinMacosArm64Variant.constructor, - KotlinIosX64Variant.constructor, - KotlinIosArm64Variant.constructor - ).forEach { constructor -> registerNativeVariantFactory(constructor) } - } + setupFragmentsMetadataForKpmModules(project) + setupKpmModulesPublication(project) } private fun createDefaultModules(project: Project) { @@ -71,19 +47,6 @@ abstract class KotlinPm20GradlePlugin @Inject constructor( } } - private fun setupFragmentsMetadata(project: Project) { - project.pm20Extension.modules.all { module -> - configureMetadataResolutionAndBuild(module) - configureMetadataExposure(module) - } - } - - private fun setupPublication(project: Project) { - project.pm20Extension.modules.all { module -> - setupPublicationForModule(module) - } - } - private fun setupPublicationForModule(module: KotlinGradleModule) { val project = module.project diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinFragmentCompilationOutputsJarArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinFragmentCompilationOutputsJarArtifact.kt index 2155867e427..0e11f0ecf9c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinFragmentCompilationOutputsJarArtifact.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinFragmentCompilationOutputsJarArtifact.kt @@ -14,8 +14,11 @@ import org.jetbrains.kotlin.gradle.utils.dashSeparatedName * Registers a [Jar] task with the variant's compilation outputs and attaches this artifact to the given configuration. */ val KotlinFragmentCompilationOutputsJarArtifact = FragmentArtifacts { - artifact(project.locateOrRegisterTask(fragment.disambiguateName("jar")) { + artifact(project.locateOrRegisterTask(fragment.outputsJarTaskName) { it.from(fragment.compilationOutputs.allOutputs) it.archiveClassifier.set(dashSeparatedName(fragment.name, fragment.containingModule.moduleClassifier)) }) } + +internal val KotlinGradleVariant.outputsJarTaskName: String + get() = disambiguateName("jar") \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariant.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariant.kt index a959d0e9e9b..23319fb25f4 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariant.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariant.kt @@ -5,12 +5,30 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 +import groovy.lang.Closure import org.gradle.api.artifacts.Configuration import org.gradle.api.plugins.BasePluginConvention +import org.gradle.api.GradleException +import org.gradle.api.Project +import org.gradle.api.attributes.AttributeContainer +import org.gradle.api.file.FileCollection +import org.gradle.api.plugins.BasePluginExtension +import org.gradle.api.tasks.TaskProvider +import org.gradle.api.tasks.bundling.Jar +import org.gradle.api.tasks.bundling.Zip import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl -import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType -import org.jetbrains.kotlin.gradle.plugin.mpp.filterModuleName +import org.jetbrains.kotlin.gradle.dsl.kotlinExtension +import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.mpp.* +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.unambiguousNameInProject +import org.jetbrains.kotlin.gradle.plugin.sources.kpm.FragmentMappedKotlinSourceSet +import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget +import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTargetConfigurator +import org.jetbrains.kotlin.gradle.tasks.* +import org.jetbrains.kotlin.gradle.tasks.locateTask +import org.jetbrains.kotlin.project.model.refinesClosure +import java.util.concurrent.Callable open class KotlinJvmVariant( containingModule: KotlinGradleModule, @@ -49,3 +67,136 @@ internal fun KotlinGradleVariant.ownModuleName(): String { val suffix = if (containingModule.moduleClassifier == null) "" else "_${containingModule.moduleClassifier}" return filterModuleName("$baseName$suffix") } + +open class KotlinVariantMappedJvmCompilation( + override val target: KotlinJvmTarget, + internal val variant: KotlinJvmVariant, +) : KotlinJvmCompilation(target, variant.containingModule.name) { + // TODO: in the legacy model, it used to be a KotlinCompilationWithResources + + override val runtimeDependencyConfigurationName: String + get() = variant.runtimeDependenciesConfiguration.name + + override var runtimeDependencyFiles: FileCollection + get() = variant.runtimeDependencyFiles + set(value) { + variant.runtimeDependencyFiles = value + } + + // TODO: compilation data implements compileDependencyFiles as a val, not var, fix this? + override val compileDependencyConfigurationName: String + get() = variant.compileDependenciesConfiguration.name + + override var compileDependencyFiles: FileCollection + get() = compilationData.compileDependencyFiles + set(value) { + variant.compileDependencyFiles = value + } + + private val compilationData: KotlinJvmVariantCompilationData + get() = variant.compilationData + + override val kotlinOptions: KotlinJvmOptions = compilationData.kotlinOptions + + override val compilationName: String + get() = compilationData.compilationPurpose + + // FIXME: mutating this set should not be allowed + override val kotlinSourceSets: MutableSet + get() = super.kotlinSourceSets + + override val allKotlinSourceSets: Set + get() { + val allMappedSourceSets = target.project.kotlinExtension.sourceSets + .filterIsInstance() + .associateBy { it.underlyingFragment } + return variant.refinesClosure.mapNotNull { allMappedSourceSets[it] }.toSet() + } + + override val defaultSourceSetName: String + get() = variant.unambiguousNameInProject + + override fun source(sourceSet: KotlinSourceSet) { + defaultSourceSet.dependsOn(sourceSet) + } + + override fun associateWith(other: KotlinCompilation<*>) { + throw UnsupportedOperationException("not supported in the mapped model") + } + + override val associateWith: List> get() = emptyList() + + override fun getAttributes(): AttributeContainer { + // TODO: not implemented? + return HierarchyAttributeContainer(target.attributes) + } + + override fun dependencies(configure: KotlinDependencyHandler.() -> Unit) { + variant.dependencies(configure) + } + + override fun dependencies(configureClosure: Closure) { + variant.dependencies(configureClosure) + } + + override val apiConfigurationName: String + get() = variant.apiConfigurationName + override val implementationConfigurationName: String + get() = variant.implementationConfigurationName + override val compileOnlyConfigurationName: String + get() = variant.compileOnlyConfigurationName + override val runtimeOnlyConfigurationName: String + get() = variant.runtimeOnlyConfigurationName + + override val project: Project + get() = variant.project + + override val output: KotlinCompilationOutput + get() = variant.compilationOutputs + + override val compileKotlinTaskName: String + get() = compilationData.compileKotlinTaskName + + override val compileAllTaskName: String + get() = compilationData.compileAllTaskName + + override val moduleName: String + get() = compilationData.moduleName +} + +class KotlinMappedJvmCompilationFactory( + target: KotlinJvmTarget +) : KotlinJvmCompilationFactory(target) { + override fun create(name: String): KotlinVariantMappedJvmCompilation { + val module = target.project.kpmModules.maybeCreate(name) + val variant = module.fragments.create(target.name, KotlinJvmVariant::class.java) + return KotlinVariantMappedJvmCompilation(target, variant) + } +} + +class KotlinMappedJvmTargetConfigurator : KotlinJvmTargetConfigurator() { + override fun defineConfigurationsForTarget(target: KotlinJvmTarget) = Unit // done in KPM + override fun configureCompilationDefaults(target: KotlinJvmTarget) { + // everything else is done in KPM, but KPM doesn't have resources processing yet + target.compilations.all { compilation -> + configureResourceProcessing( + compilation, + target.project.files(Callable { compilation.allKotlinSourceSets.map { it.resources } }) + ) + } + } + + override fun configureCompilations(target: KotlinJvmTarget) { + target.compilations.create(KotlinCompilation.MAIN_COMPILATION_NAME) + target.compilations.create(KotlinCompilation.TEST_COMPILATION_NAME) + } + + override fun configureArchivesAndComponent(target: KotlinJvmTarget) = Unit // done in KPM + + override fun createArchiveTasks(target: KotlinJvmTarget): TaskProvider = + checkNotNull( + target.project.locateTask( + (target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) as KotlinVariantMappedJvmCompilation).variant.outputsJarTaskName + ) + ) +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinMetadataCompilationData.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinMetadataCompilationData.kt index 625d4a07ce5..62f9d191ef7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinMetadataCompilationData.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinMetadataCompilationData.kt @@ -11,10 +11,8 @@ import org.gradle.api.file.FileCollection import org.gradle.api.file.SourceDirectorySet import org.gradle.api.plugins.BasePluginExtension import org.gradle.api.tasks.TaskProvider -import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptions +import org.jetbrains.kotlin.gradle.dsl.* 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 @@ -41,7 +39,7 @@ internal abstract class AbstractKotlinFragmentMetadataCompilationData { override val owner - get() = project.pm20Extension + get() = project.topLevelExtension override val compilationPurpose: String get() = fragment.fragmentName diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/ModulePublishing.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/ModulePublishing.kt new file mode 100644 index 00000000000..effef09fafe --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/ModulePublishing.kt @@ -0,0 +1,60 @@ +/* + * 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.gradle.api.component.SoftwareComponentFactory +import org.gradle.api.publish.PublishingExtension +import org.gradle.api.publish.maven.MavenPublication +import org.jetbrains.kotlin.gradle.dsl.pm20Extension +import javax.inject.Inject + +internal fun setupKpmModulesPublication(project: Project) { + project.kpmModules.all { module -> + setupPublicationForModule(module) + } +} + +internal fun setupPublicationForModule(module: KotlinGradleModule) { + val project = module.project + + val metadataElements = project.configurations.getByName(metadataElementsConfigurationName(module)) + val sourceElements = project.configurations.getByName(sourceElementsConfigurationName(module)) + + val componentName = rootPublicationComponentName(module) + val rootSoftwareComponent = SoftwareComponentFactoryHolder(project).softwareComponentFactory.adhoc(componentName).also { + project.components.add(it) + it.addVariantsFromConfiguration(metadataElements) { } + it.addVariantsFromConfiguration(sourceElements) { } + } + + module.ifMadePublic { + val metadataDependencyConfiguration = resolvableMetadataConfiguration(module) + project.pluginManager.withPlugin("maven-publish") { + project.extensions.getByType(PublishingExtension::class.java).publications.create( + componentName, + MavenPublication::class.java + ) { publication -> + publication.from(rootSoftwareComponent) + publication.versionMapping { versionMapping -> + versionMapping.allVariants { + it.fromResolutionOf(metadataDependencyConfiguration) + } + } + } + } + } +} + +private open class SoftwareComponentFactoryHolder @Inject constructor( + @Inject val softwareComponentFactory: SoftwareComponentFactory +) { + companion object { + operator fun invoke(project: Project): SoftwareComponentFactoryHolder { + return project.objects.newInstance(SoftwareComponentFactoryHolder::class.java) + } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/VariantFactories.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/VariantFactories.kt new file mode 100644 index 00000000000..3f54a9fb4a4 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/VariantFactories.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 + +import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.dsl.pm20Extension +import kotlin.reflect.KClass + +internal fun registerDefaultVariantFactories(project: Project) { + project.kpmModules.configureEach { module -> + module.fragments.registerFactory( + KotlinJvmVariant::class.java, + KotlinJvmVariantFactory(module) + ) + + fun registerNativeVariantFactory( + constructor: KotlinNativeVariantConstructor + ) = module.fragments.registerFactory( + constructor.variantClass, KotlinNativeVariantFactory(module, constructor) + ) + + listOf( + // FIXME codegen, add missing native targets + KotlinLinuxX64Variant.constructor, + KotlinMacosX64Variant.constructor, + KotlinMacosArm64Variant.constructor, + KotlinIosX64Variant.constructor, + KotlinIosArm64Variant.constructor + ).forEach { constructor -> registerNativeVariantFactory(constructor) } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentsMetadataCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentsMetadataCompilation.kt index f76989e8a8b..88f8759955c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentsMetadataCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentsMetadataCompilation.kt @@ -29,6 +29,13 @@ import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION import org.jetbrains.kotlin.project.model.KotlinModuleFragment import java.util.concurrent.Callable +internal fun setupFragmentsMetadataForKpmModules(project: Project) { + project.kpmModules.all { module -> + configureMetadataResolutionAndBuild(module) + configureMetadataExposure(module) + } +} + internal fun configureMetadataResolutionAndBuild(module: KotlinGradleModule) { val project = module.project createResolvableMetadataConfigurationForModule(module) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilationFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilationFactory.kt index e1e20b8bfde..329b5856951 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilationFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilationFactory.kt @@ -8,7 +8,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget -class KotlinJvmCompilationFactory( +open class KotlinJvmCompilationFactory( val target: KotlinJvmTarget ) : KotlinCompilationFactory { override val itemClass: Class diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetConfigurator.kt index 288acd4cf12..12a869b6c2d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetConfigurator.kt @@ -19,7 +19,7 @@ import org.jetbrains.kotlin.gradle.tasks.registerTask import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry import org.jetbrains.kotlin.gradle.testing.testTaskName -class KotlinJvmTargetConfigurator : +open class KotlinJvmTargetConfigurator : KotlinOnlyTargetConfigurator(true, true), KotlinTargetWithTestsConfigurator { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetPreset.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetPreset.kt index 1d3b810b4e4..a9f1e65ada6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetPreset.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmTargetPreset.kt @@ -8,6 +8,9 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.Project import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinMappedJvmCompilationFactory +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinMappedJvmTargetConfigurator import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTargetConfigurator @@ -23,9 +26,14 @@ class KotlinJvmTargetPreset( override fun getName(): String = PRESET_NAME override fun createCompilationFactory(forTarget: KotlinJvmTarget): KotlinCompilationFactory = - KotlinJvmCompilationFactory(forTarget) + if (PropertiesProvider(project).experimentalKpmModelMapping) + KotlinMappedJvmCompilationFactory(forTarget) + else KotlinJvmCompilationFactory(forTarget) - override fun createKotlinTargetConfigurator() = KotlinJvmTargetConfigurator() + override fun createKotlinTargetConfigurator() = + if (PropertiesProvider(project).experimentalKpmModelMapping) + KotlinMappedJvmTargetConfigurator() + else KotlinJvmTargetConfigurator() override val platformType: KotlinPlatformType get() = KotlinPlatformType.jvm diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt index cdd8ab1a7ec..bbe6ef9bc75 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt @@ -70,7 +70,7 @@ class KotlinMetadataTargetConfigurator : override fun configureTarget(target: KotlinMetadataTarget) { super.configureTarget(target) - if (target.project.isKotlinGranularMetadataEnabled) { + if (target.project.isKotlinGranularMetadataEnabled && !target.project.hasKpmModel) { KotlinBuildStatsService.getInstance()?.report(BooleanMetrics.ENABLED_HMPP, true) target.compilations.withType(KotlinCommonCompilation::class.java).getByName(KotlinCompilation.MAIN_COMPILATION_NAME).run { @@ -147,16 +147,18 @@ class KotlinMetadataTargetConfigurator : } } - val legacyJar = target.project.registerTask(target.legacyArtifactsTaskName) - legacyJar.configure { - // Capture it here to use in onlyIf spec. Direct usage causes serialization of target attempt when configuration cache is enabled - val isCompatibilityMetadataVariantEnabled = target.project.isCompatibilityMetadataVariantEnabled - it.description = "Assembles an archive containing the Kotlin metadata of the commonMain source set." - if (!isCompatibilityMetadataVariantEnabled) { - it.archiveClassifier.set("commonMain") + if (target.project.isCompatibilityMetadataVariantEnabled) { + val legacyJar = target.project.registerTask(target.legacyArtifactsTaskName) + legacyJar.configure { + // Capture it here to use in onlyIf spec. Direct usage causes serialization of target attempt when configuration cache is enabled + val isCompatibilityMetadataVariantEnabled = target.project.isCompatibilityMetadataVariantEnabled + it.description = "Assembles an archive containing the Kotlin metadata of the commonMain source set." + if (!isCompatibilityMetadataVariantEnabled) { + it.archiveClassifier.set("commonMain") + } + it.onlyIf { isCompatibilityMetadataVariantEnabled } + it.from(target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME).output.allOutputs) } - it.onlyIf { isCompatibilityMetadataVariantEnabled } - it.from(target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME).output.allOutputs) } return result