diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompilationDetails.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompilationDetails.kt index 2db9f61c741..dcfc10db8b7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompilationDetails.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/CompilationDetails.kt @@ -14,6 +14,7 @@ import org.gradle.api.file.SourceDirectorySet import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.bundling.AbstractArchiveTask +import org.gradle.kotlin.dsl.withType import org.jetbrains.kotlin.gradle.dsl.* import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl import org.jetbrains.kotlin.gradle.plugin.* @@ -25,6 +26,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.ofVariantCompileDependen import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.unambiguousNameInProject import org.jetbrains.kotlin.gradle.plugin.sources.defaultSourceSetLanguageSettingsChecker import org.jetbrains.kotlin.gradle.plugin.sources.getVisibleSourceSetsFromAssociateCompilations +import org.jetbrains.kotlin.gradle.plugin.sources.kpm.FragmentMappedKotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets import org.jetbrains.kotlin.gradle.plugin.sources.withAllDependsOnSourceSets import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget @@ -403,6 +405,39 @@ internal open class SharedNativeCompilationDetails( } } +internal open class MetadataMappedCompilationDetails( + override val target: KotlinMetadataTarget, + final override val compilationData: AbstractKotlinFragmentMetadataCompilationData +) : CompilationDetails { + override val compileDependencyFilesHolder: DependencyFilesHolder = + DependencyFilesHolder.ofMetadataCompilationDependencies(compilationData) + + override val kotlinDependenciesHolder: HasKotlinDependencies + get() = compilationData.fragment + + override fun associateWith(other: CompilationDetails<*>) { + throw UnsupportedOperationException("not supported in the mapped model") + } + + override val associateCompilations: Set> + get() = emptySet() + + override fun source(sourceSet: KotlinSourceSet) { + throw UnsupportedOperationException("metadata compilations have predefined sources") + } + + private val underlyingSourceSet: FragmentMappedKotlinSourceSet + get() = target.project.kotlinExtension.sourceSets.withType().single { + it.underlyingFragment == compilationData.fragment + } + + override val directlyIncludedKotlinSourceSets: MutableSet + get() = Collections.unmodifiableSet(hashSetOf(underlyingSourceSet)) + + override val defaultSourceSetName: String + get() = underlyingSourceSet.name +} + internal open class VariantMappedCompilationDetails( open val variant: KotlinGradleVariantInternal, override val target: KotlinTarget diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCommonCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCommonCompilation.kt index 8ac1af0563a..c59458b1d4e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCommonCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCommonCompilation.kt @@ -19,11 +19,12 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompileCommon interface KotlinMetadataCompilation : KotlinCompilation class KotlinCommonCompilation( - target: KotlinTarget, - name: String -) : AbstractKotlinCompilation( - MetadataCompilationDetails(target, name) -), KotlinMetadataCompilation { + compilationDetails: CompilationDetails +) : AbstractKotlinCompilation(compilationDetails), + KotlinMetadataCompilation { + + override fun getName() = + if (compilationDetails is MetadataMappedCompilationDetails) defaultSourceSetName else super.compilationPurpose override val compileKotlinTask: KotlinCompileCommon get() = super.compileKotlinTask as KotlinCompileCommon diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCompilationFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCompilationFactory.kt index 9c14a35133a..ac18b363c57 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCompilationFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCompilationFactory.kt @@ -20,5 +20,5 @@ class KotlinCommonCompilationFactory( get() = KotlinCommonCompilation::class.java override fun create(name: String): KotlinCommonCompilation = - KotlinCommonCompilation(target, name) + KotlinCommonCompilation(MetadataCompilationDetails(target, name)) } \ No newline at end of file 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 039d8825a8b..5ebc6358658 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 @@ -93,7 +93,7 @@ abstract class AbstractKotlinCompilation( compilationDetails.source(sourceSet) } - override fun toString(): String = "compilation '$compilationPurpose' ($target)" + override fun toString(): String = "compilation '$name' ($target)" override fun associateWith(other: KotlinCompilation<*>) { compilationDetails.associateWith((other as AbstractKotlinCompilation<*>).compilationDetails) 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 1ad2aeb81f4..46b59b15181 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 @@ -19,6 +19,8 @@ import org.jetbrains.kotlin.gradle.targets.metadata.ResolvedMetadataFilesProvide import org.jetbrains.kotlin.gradle.targets.metadata.createMetadataDependencyTransformationClasspath import org.jetbrains.kotlin.gradle.utils.getValue import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName +import org.jetbrains.kotlin.gradle.utils.newProperty +import org.jetbrains.kotlin.gradle.utils.setValue import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget @@ -55,7 +57,7 @@ internal abstract class AbstractKotlinFragmentMetadataCompilationData? = + fun getForFragmentOrNull(fragment: KotlinGradleFragment): AbstractKotlinFragmentMetadataCompilationData<*>? = listOf(commonCompilationDataPerFragment.getValue(fragment), nativeCompilationDataPerFragment.getValue(fragment)).singleOrNull { it.isActive } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KpmAwareTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KpmAwareTargetConfigurator.kt index 240617b5107..26fadf80faa 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KpmAwareTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KpmAwareTargetConfigurator.kt @@ -30,9 +30,9 @@ internal open class KpmAwareTargetConfigurator( } override fun configureCompilations(target: T) { - target.compilations.create(KotlinCompilation.MAIN_COMPILATION_NAME) + target.compilations.maybeCreate(KotlinCompilation.MAIN_COMPILATION_NAME) if (legacyModelTargetConfigurator.createTestCompilation) { - target.compilations.create(KotlinCompilation.TEST_COMPILATION_NAME) + target.compilations.maybeCreate(KotlinCompilation.TEST_COMPILATION_NAME) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/util/DependencyFilesHolder.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/util/DependencyFilesHolder.kt index 4d825bda547..d3c139b0b22 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/util/DependencyFilesHolder.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/util/DependencyFilesHolder.kt @@ -7,8 +7,10 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util import org.gradle.api.Project import org.gradle.api.file.FileCollection +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.AbstractKotlinFragmentMetadataCompilationData import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleVariant import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleVariantWithRuntime +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.resolvableMetadataConfigurationName interface DependencyFilesHolder { val dependencyConfigurationName: String @@ -35,6 +37,17 @@ internal fun DependencyFilesHolder.Companion.ofVariantRuntimeDependencies(varian set(value) { variant.runtimeDependencyFiles = value } } +internal fun DependencyFilesHolder.Companion.ofMetadataCompilationDependencies( + compilationData: AbstractKotlinFragmentMetadataCompilationData<*> +) = object : DependencyFilesHolder { + override val dependencyConfigurationName: String + get() = compilationData.fragment.containingModule.resolvableMetadataConfigurationName + + override var dependencyFiles: FileCollection + get() = compilationData.compileDependencyFiles + set(value) { compilationData.compileDependencyFiles = value } +} + class SimpleDependencyFilesHolder( override val dependencyConfigurationName: String, override var dependencyFiles: FileCollection 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 3bd73d38b7e..c09cbcc4c30 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 @@ -21,9 +21,9 @@ import org.jetbrains.kotlin.gradle.dsl.* import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.* import org.jetbrains.kotlin.gradle.plugin.mpp.CompilationSourceSetUtil.compilationsBySourceSets -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeFragmentMetadataCompilationData +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.metadataCompilationRegistryByModuleId import org.jetbrains.kotlin.gradle.plugin.sources.* import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService import org.jetbrains.kotlin.gradle.targets.native.internal.* @@ -70,7 +70,7 @@ class KotlinMetadataTargetConfigurator : override fun configureTarget(target: KotlinMetadataTarget) { super.configureTarget(target) - if (target.project.isKotlinGranularMetadataEnabled && !target.project.hasKpmModel) { + if (target.project.isKotlinGranularMetadataEnabled) { KotlinBuildStatsService.getInstance()?.report(BooleanMetrics.ENABLED_HMPP, true) target.compilations.withType(KotlinCommonCompilation::class.java).getByName(KotlinCompilation.MAIN_COMPILATION_NAME).run { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetPreset.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetPreset.kt index 9b8c77fdba0..a9bfa80a0ac 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetPreset.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetPreset.kt @@ -9,8 +9,11 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.Project import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KpmAwareTargetConfigurator +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.hasKpmModel import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToKotlinOptions import org.jetbrains.kotlin.gradle.targets.metadata.KotlinMetadataTargetConfigurator +import org.jetbrains.kotlin.gradle.targets.metadata.KpmMetadataTargetConfigurator class KotlinMetadataTargetPreset( project: Project @@ -37,8 +40,12 @@ class KotlinMetadataTargetPreset( const val PRESET_NAME = "metadata" } - override fun createKotlinTargetConfigurator(): KotlinOnlyTargetConfigurator, KotlinMetadataTarget> = - KotlinMetadataTargetConfigurator() + override fun createKotlinTargetConfigurator(): AbstractKotlinTargetConfigurator { + val metadataConfigurator = KotlinMetadataTargetConfigurator() + return if (project.hasKpmModel) + KpmMetadataTargetConfigurator(metadataConfigurator) + else metadataConfigurator + } override fun instantiateTarget(name: String): KotlinMetadataTarget { return project.objects.newInstance(KotlinMetadataTarget::class.java, project) @@ -52,9 +59,11 @@ class KotlinMetadataTargetPreset( mainCompilation.source(commonMainSourceSet) project.whenEvaluated { - // Since there's no default source set, apply language settings from commonMain: - mainCompilation.compileKotlinTaskProvider.configure { compileKotlinMetadata -> - applyLanguageSettingsToKotlinOptions(commonMainSourceSet.languageSettings, compileKotlinMetadata.kotlinOptions) + if (!project.hasKpmModel) { + // Since there's no default source set, apply language settings from commonMain: + mainCompilation.compileKotlinTaskProvider.configure { compileKotlinMetadata -> + applyLanguageSettingsToKotlinOptions(commonMainSourceSet.languageSettings, compileKotlinMetadata.kotlinOptions) + } } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KpmMetadataTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KpmMetadataTargetConfigurator.kt new file mode 100644 index 00000000000..02a315a503f --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KpmMetadataTargetConfigurator.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.targets.metadata + +import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptions +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.mpp.* +import org.jetbrains.kotlin.gradle.plugin.mpp.MetadataMappedCompilationDetails +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.* +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KpmAwareTargetConfigurator +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.kpmModules +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.metadataCompilationRegistryByModuleId +import org.jetbrains.kotlin.gradle.plugin.whenEvaluated + +internal class KpmMetadataTargetConfigurator(private val metadataTargetConfigurator: KotlinMetadataTargetConfigurator) : + KpmAwareTargetConfigurator(metadataTargetConfigurator) { + + override fun configureTarget(target: KotlinMetadataTarget) { + super.configureTarget(target) + configureTargetWithKpm(target) + } + + override fun configureCompilationDefaults(target: KotlinMetadataTarget) { + super.configureCompilationDefaults(target) + + // we still want to configure the legacy "main" compilation + run { + val mainCompilation = target.compilations.create(KotlinCompilation.MAIN_COMPILATION_NAME) + defineConfigurationsForCompilation(mainCompilation) + createLifecycleTask(mainCompilation) + metadataTargetConfigurator + .buildCompilationProcessor(mainCompilation) + .run() + mainCompilation.compileKotlinTaskProvider.configure { it.enabled = false } + } + } + + private fun configureTargetWithKpm(target: KotlinMetadataTarget) { + target.project.whenEvaluated { + val mainModule = target.project.kpmModules.getByName(KotlinGradleModule.MAIN_MODULE_NAME) + val metadataCompilations = target.project.metadataCompilationRegistryByModuleId.getValue(mainModule.moduleIdentifier) + mainModule.fragments.forEach { fragment -> + val compilationData = metadataCompilations.getForFragmentOrNull(fragment) ?: return@forEach + if (!compilationData.isActive) return@forEach + + val compilationDetails = MetadataMappedCompilationDetails(target, compilationData) + + val isNative = compilationData is KotlinNativeFragmentMetadataCompilationData + + @Suppress("UNCHECKED_CAST") + val compilation = when { + isNative -> { + val konanTargets = + mainModule.variantsContainingFragment(fragment).map { (it as KotlinNativeVariantInternal).konanTarget } + KotlinSharedNativeCompilation(konanTargets, compilationDetails as CompilationDetails) + } + else -> KotlinCommonCompilation(compilationDetails as CompilationDetails) + } + + target.compilations.add(compilation) + } + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilation.kt index c09d77fc311..8b8f4e5b03d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilation.kt @@ -118,18 +118,21 @@ class KotlinNativeCompilation( } class KotlinSharedNativeCompilation( - target: KotlinMetadataTarget, - val konanTargets: List, name: String) : - KotlinNativeFragmentMetadataCompilationData, + val konanTargets: List, + compilationDetails: CompilationDetails +) : KotlinNativeFragmentMetadataCompilationData, AbstractKotlinNativeCompilation( // TODO: this will end up as '-target' argument passed to K2Native, which is wrong. // Rewrite this when we'll compile native-shared source-sets against commonized platform libs // We find any konan target that is enabled on the current host in order to pass the checks that avoid compiling the code otherwise. konanTargets.find { it.enabledOnCurrentHost } ?: konanTargets.first(), - SharedNativeCompilationDetails(target, name) { NativeCompileOptions { defaultSourceSet.languageSettings } } + compilationDetails ), KotlinMetadataCompilation { + override fun getName() = + if (compilationDetails is MetadataMappedCompilationDetails) defaultSourceSetName else super.compilationPurpose + override val target: KotlinMetadataTarget get() = super.target as KotlinMetadataTarget override val isActive: Boolean diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilationFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilationFactory.kt index 0c7387e4daa..c7da4d861cd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilationFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilationFactory.kt @@ -36,5 +36,8 @@ class KotlinSharedNativeCompilationFactory( get() = KotlinSharedNativeCompilation::class.java override fun create(name: String): KotlinSharedNativeCompilation = - KotlinSharedNativeCompilation(target, konanTargets, name) + KotlinSharedNativeCompilation( + konanTargets, + SharedNativeCompilationDetails(target, name) { NativeCompileOptions { defaultSourceSet.languageSettings } } + ) } \ No newline at end of file