From 4cbd715b17de1715de773572424c5428bdf9c3af Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Fri, 30 Sep 2022 00:07:08 +0200 Subject: [PATCH] [Gradle] Implement Kotlin*NativeCompilations with underlying KotlinCompilationImpl KT-54312 --- .../kotlin/gradle/plugin/CinteropSettings.kt | 5 - .../kotlin/gradle/plugin/KotlinCompilation.kt | 1 + .../kotlin/gradle/NewMultiplatformIT.kt | 4 +- .../dsl/KotlinMultiplatformExtension.kt | 6 +- .../gradle/plugin/KotlinTargetConfigurator.kt | 11 +- .../plugin/mpp/AbstractKotlinCompilation.kt | 4 + .../plugin/mpp/InternalKotlinCompilation.kt | 3 + .../mpp/KotlinCommonCompilationFactory.kt | 19 ++ .../plugin/mpp/KotlinCompilationFactory.kt | 12 -- .../gradle/plugin/mpp/KotlinMetadataTarget.kt | 6 +- .../KotlinCompilationDependencyAssociation.kt | 16 +- ...lationDependencyConfigurationsContainer.kt | 7 +- .../KotlinCompilationFriendPathsResolver.kt | 77 +++++-- .../compilationImpl/KotlinCompilationImpl.kt | 6 +- .../KotlinCompilationSourceSetInclusion.kt | 23 +- .../KotlinCompilationTaskContainer.kt | 2 +- .../DefaultCompilationModuleFactory.kt | 27 +++ ...pilationDependencyConfigurationsFactory.kt | 130 ++++++++++++ .../DefaultKotlinCompilationOutputFactory.kt | 17 ++ ...inCompilationSourceSetsContainerFactory.kt | 38 ++++ ...linCompilationTaskNamesContainerFactory.kt | 21 ++ .../DefaultProcessResourcesTaskNameFactory.kt | 18 ++ .../factory/JvmCompilerOptionsFactory.kt | 23 ++ .../factory/KotlinCompilationImplFactory.kt | 94 +++++++++ .../factory/NativeCompilerOptionsFactory.kt | 23 ++ ...linCompilationTaskNamesContainerFactory.kt | 16 ++ .../GradleKpmCompilationTaskConfigurator.kt | 8 +- .../GradleKpmNativeVariantCompilationData.kt | 5 +- .../pm20/GradleKpmNativeVariantInternal.kt | 7 +- .../mpp/pm20/KotlinMetadataCompilationData.kt | 5 +- .../sources/DefaultLanguageSettingsBuilder.kt | 10 +- .../targets/js/KotlinJsTargetConfigurator.kt | 6 +- .../targets/jvm/KotlinJvmCompilation.kt | 48 +---- .../jvm/KotlinJvmCompilationFactory.kt | 167 +-------------- .../KotlinMetadataTargetConfigurator.kt | 35 ++-- .../metadata/KotlinMetadataTargetPreset.kt | 10 +- .../targets/native/DefaultCInteropSettings.kt | 113 ++++++---- .../targets/native/KotlinNativeCompilation.kt | 105 ++++------ .../native/KotlinNativeCompilationFactory.kt | 86 ++------ .../native/KotlinNativeTargetConfigurator.kt | 111 ++++++---- .../KotlinSharedNativeCompilationFactory.kt | 59 ++++++ .../targets/native/NativeCompilerOptions.kt | 19 +- .../native/internal/CInteropCommonizerTask.kt | 7 +- .../native/internal/CInteropConfigurations.kt | 11 +- .../native/internal/CInteropIdentifier.kt | 6 + .../targets/native/tasks/KotlinNativeLink.kt | 2 +- .../targets/native/tasks/KotlinNativeTasks.kt | 198 ++++++++++++------ .../jetbrains/kotlin/gradle/tasks/Tasks.kt | 2 +- .../configuration/KotlinCompileConfig.kt | 5 +- .../gradle/MultiplatformExtensionTest.kt | 4 +- .../mpp/CompilationSpecificPluginPath.kt | 6 +- .../gradle/mpp/KpmCompilerPluginTest.kt | 7 +- .../kotlin/tooling/core/ExtrasUtils.kt | 3 + 53 files changed, 1046 insertions(+), 608 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCommonCompilationFactory.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultCompilationModuleFactory.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultKotlinCompilationDependencyConfigurationsFactory.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultKotlinCompilationOutputFactory.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultKotlinCompilationSourceSetsContainerFactory.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultKotlinCompilationTaskNamesContainerFactory.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultProcessResourcesTaskNameFactory.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/JvmCompilerOptionsFactory.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/KotlinCompilationImplFactory.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/NativeCompilerOptionsFactory.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/NativeKotlinCompilationTaskNamesContainerFactory.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinSharedNativeCompilationFactory.kt diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/CinteropSettings.kt b/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/CinteropSettings.kt index b793abbf6d5..7acc317197d 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/CinteropSettings.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/CinteropSettings.kt @@ -10,8 +10,6 @@ package org.jetbrains.kotlin.gradle.plugin import org.gradle.api.Action import org.gradle.api.Named import org.gradle.api.file.FileCollection -import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptionsDeprecated -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData interface CInteropSettings : Named { @@ -23,9 +21,6 @@ interface CInteropSettings : Named { fun headerFilterOnly(includeDirs: Collection) } - // TODO: Provide an interface for native compilations. - val compilation: KotlinCompilationData - val dependencyConfigurationName: String var dependencyFiles: FileCollection diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilation.kt b/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilation.kt index 9806ce4b52d..9dd067fa6ee 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinCompilation.kt @@ -136,6 +136,7 @@ interface KotlinCompilationToRunnableFiles : val KotlinCompilation.runtimeDependencyConfigurationName: String? get() = (this as? KotlinCompilationToRunnableFiles)?.runtimeDependencyConfigurationName +@Deprecated("Scheduled for removal with Kotlin 1.9") interface KotlinCompilationWithResources : KotlinCompilation { val processResourcesTaskName: String } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt index 74aa0716b6b..c8953a68361 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/NewMultiplatformIT.kt @@ -1769,7 +1769,7 @@ class NewMultiplatformIT : BaseGradleIT() { "Hello.internalFun\$new_mpp_associate_compilations", "HelloTest.internalTestFun\$new_mpp_associate_compilations" ) - assertFileExists("build/classes/kotlin/jvm/integrationTest/META-INF/new-mpp-associate-compilations_integrationTest.kotlin_module") + assertFileExists("build/classes/kotlin/jvm/integrationTest/META-INF/new-mpp-associate-compilations.kotlin_module") // JS: assertFileExists( @@ -2007,7 +2007,7 @@ class NewMultiplatformIT : BaseGradleIT() { @Test fun testResolveMetadataCompileClasspathKt50925() { - Project("lib", directoryPrefix = "kt-50925-resolve-metadata-compile-classpath").apply { + Project("lib", directoryPrefix = "kt-50925-resolve-metadata-compile-classpath").apply { setupWorkingDir() gradleBuildScript().modify(::transformBuildScriptWithPluginsDsl) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinMultiplatformExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinMultiplatformExtension.kt index cef511830cd..d9cabae99b0 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinMultiplatformExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinMultiplatformExtension.kt @@ -59,11 +59,11 @@ abstract class KotlinMultiplatformExtension(project: Project) : val testableTargets: NamedDomainObjectCollection> get() = targets.withType(KotlinTargetWithTests::class.java) - fun metadata(configure: KotlinOnlyTarget>.() -> Unit = { }): KotlinOnlyTarget> = + fun metadata(configure: KotlinOnlyTarget>.() -> Unit = { }): KotlinOnlyTarget> = @Suppress("UNCHECKED_CAST") - (targets.getByName(KotlinMultiplatformPlugin.METADATA_TARGET_NAME) as KotlinOnlyTarget>).also(configure) + (targets.getByName(KotlinMultiplatformPlugin.METADATA_TARGET_NAME) as KotlinOnlyTarget>).also(configure) - fun metadata(configure: Action>>) = metadata { configure.execute(this) } + fun metadata(configure: Action>>) = metadata { configure.execute(this) } fun targetFromPreset( preset: KotlinTargetPreset, diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt index cf30ea9f87d..3caab171081 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinTargetConfigurator.kt @@ -113,8 +113,10 @@ abstract class AbstractKotlinTargetConfigurator defineConfigurationsForCompilation(compilation) - if (compilation is KotlinCompilationWithResources) { - configureResourceProcessing(compilation, project.files(Callable { compilation.allKotlinSourceSets.map { it.resources } })) + compilation.internal.processResourcesTaskName?.let { processResourcesTaskName -> + configureResourceProcessing( + compilation, processResourcesTaskName, project.files(Callable { compilation.allKotlinSourceSets.map { it.resources } }) + ) } createLifecycleTask(compilation) @@ -122,13 +124,14 @@ abstract class AbstractKotlinTargetConfigurator } protected fun configureResourceProcessing( - compilation: KotlinCompilationWithResources<*>, + compilation: KotlinCompilation<*>, + processResourcesTaskName: String, resourceSet: FileCollection ) { val project = compilation.target.project val resourcesDestinationDir = project.file(compilation.output.resourcesDir) - val resourcesTask = project.locateOrRegisterTask(compilation.processResourcesTaskName) { resourcesTask -> + val resourcesTask = project.locateOrRegisterTask(processResourcesTaskName) { resourcesTask -> resourcesTask.description = "Processes $resourceSet." resourcesTask.from(resourceSet) resourcesTask.into(resourcesDestinationDir) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/AbstractKotlinCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/AbstractKotlinCompilation.kt index d1731e9f15f..6d8827e7cc9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/AbstractKotlinCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/AbstractKotlinCompilation.kt @@ -19,6 +19,8 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask import org.jetbrains.kotlin.gradle.tasks.locateTask import org.jetbrains.kotlin.gradle.utils.ObservableSet import org.jetbrains.kotlin.project.model.LanguageSettings +import org.jetbrains.kotlin.tooling.core.MutableExtras +import org.jetbrains.kotlin.tooling.core.mutableExtrasOf import java.util.* abstract class AbstractKotlinCompilation( @@ -62,6 +64,8 @@ abstract class AbstractKotlinCompilation( override val target: KotlinTarget get() = compilationDetails.target + override val extras: MutableExtras = mutableExtrasOf() + final override val compileDependencyConfigurationName: String get() = compilationDetails.compileDependencyFilesHolder.dependencyConfigurationName diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/InternalKotlinCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/InternalKotlinCompilation.kt index f3ac87786db..33525a8059e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/InternalKotlinCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/InternalKotlinCompilation.kt @@ -13,8 +13,11 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationM import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule.Type.Auxiliary import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule.Type.Main import org.jetbrains.kotlin.gradle.utils.ObservableSet +import org.jetbrains.kotlin.tooling.core.MutableExtras internal interface InternalKotlinCompilation : KotlinCompilation { + val extras: MutableExtras + override val kotlinSourceSets: ObservableSet override val allKotlinSourceSets: ObservableSet val friendPaths: Iterable diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCommonCompilationFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCommonCompilationFactory.kt new file mode 100644 index 00000000000..2dacb6a4bea --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCommonCompilationFactory.kt @@ -0,0 +1,19 @@ +/* + * 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.plugin.mpp + +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationDetailsImpl.MetadataCompilationDetails + +class KotlinCommonCompilationFactory( + override val target: KotlinOnlyTarget<*> +) : KotlinCompilationFactory { + override val itemClass: Class + get() = KotlinCommonCompilation::class.java + + override fun create(name: String): KotlinCommonCompilation = target.project.objects.newInstance( + KotlinCommonCompilation::class.java, MetadataCompilationDetails(target, name, getOrCreateDefaultSourceSet(name)) + ) +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCompilationFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCompilationFactory.kt index 72b0a89e696..4c95a2cd68c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCompilationFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinCompilationFactory.kt @@ -12,7 +12,6 @@ import org.jetbrains.kotlin.gradle.dsl.kotlinExtension import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinTarget -import org.jetbrains.kotlin.gradle.plugin.mpp.compilationDetailsImpl.MetadataCompilationDetails import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName interface KotlinCompilationFactory> : NamedDomainObjectFactory { @@ -35,14 +34,3 @@ interface KotlinCompilationFactory> : NamedDomainObject internal fun KotlinCompilationFactory<*>.getOrCreateDefaultSourceSet(compilationName: String): KotlinSourceSet { return project.kotlinExtension.sourceSets.maybeCreate(defaultSourceSetName(compilationName)) } - -class KotlinCommonCompilationFactory( - override val target: KotlinOnlyTarget<*> -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinCommonCompilation::class.java - - override fun create(name: String): KotlinCommonCompilation = target.project.objects.newInstance( - KotlinCommonCompilation::class.java, MetadataCompilationDetails(target, name, getOrCreateDefaultSourceSet(name)) - ) -} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMetadataTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMetadataTarget.kt index 97cca515603..c3dea279ec6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMetadataTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMetadataTarget.kt @@ -6,14 +6,16 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.Project -import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType +import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent import org.jetbrains.kotlin.gradle.targets.metadata.KotlinMetadataTargetConfigurator import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled import javax.inject.Inject abstract class KotlinMetadataTarget @Inject constructor( project: Project -) : KotlinOnlyTarget>(project, KotlinPlatformType.common) { +) : KotlinOnlyTarget */ KotlinCompilation<*>>(project, KotlinPlatformType.common) { override val artifactsTaskName: String // The IDE import looks at this task name to determine the artifact and register the path to the artifact; diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationDependencyAssociation.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationDependencyAssociation.kt index 85cd069391f..cba72f52f11 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationDependencyAssociation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationDependencyAssociation.kt @@ -7,9 +7,11 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl import org.gradle.api.Project import org.gradle.api.artifacts.Dependency -import org.gradle.api.tasks.SourceSet import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.mpp.InternalKotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.mpp.isMain +import org.jetbrains.kotlin.gradle.plugin.mpp.isTest +import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.gradle.utils.filesProvider internal fun interface KotlinCompilationAssociator { @@ -70,7 +72,7 @@ internal object DefaultKotlinCompilationAssociator : KotlinCompilationAssociator } } -internal object KotlinNativeCompilationAssociator : KotlinCompilationAssociator { +internal object NativeKotlinCompilationAssociator : KotlinCompilationAssociator { override fun associate(target: KotlinTarget, first: InternalKotlinCompilation<*>, second: InternalKotlinCompilation<*>) { target.project.kotlinCompilationModuleManager.unionModules(first.compilationModule, second.compilationModule) @@ -83,12 +85,14 @@ internal object KotlinNativeCompilationAssociator : KotlinCompilationAssociator } } -internal object KotlinJvmWithJavaCompilationAssociator : KotlinCompilationAssociator { +internal object JvmKotlinCompilationAssociator : KotlinCompilationAssociator { override fun associate(target: KotlinTarget, first: InternalKotlinCompilation<*>, second: InternalKotlinCompilation<*>) { target.project.kotlinCompilationModuleManager.unionModules(first.compilationModule, second.compilationModule) - if (first.compilationName != SourceSet.TEST_SOURCE_SET_NAME || second.compilationName != SourceSet.MAIN_SOURCE_SET_NAME) { - DefaultKotlinCompilationAssociator.associate(target, first, second) - } // otherwise, do nothing: the Java Gradle plugin adds these dependencies for us, we don't need to add them to the classpath + + /* Main to Test association handled already by java plugin */ + if (target is KotlinJvmTarget && target.withJavaEnabled && first.isMain() && second.isTest()) { + return + } else DefaultKotlinCompilationAssociator.associate(target, first, second) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationDependencyConfigurationsContainer.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationDependencyConfigurationsContainer.kt index 421087e5dda..90497e13fcf 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationDependencyConfigurationsContainer.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationDependencyConfigurationsContainer.kt @@ -8,9 +8,12 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl import org.gradle.api.Action import org.gradle.api.Project import org.gradle.api.artifacts.Configuration -import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies -import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler +import org.gradle.api.attributes.Category +import org.gradle.api.attributes.Usage +import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinDependencyHandler +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages +import org.jetbrains.kotlin.gradle.utils.* internal interface KotlinCompilationDependencyConfigurationsContainer { val apiConfiguration: Configuration diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationFriendPathsResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationFriendPathsResolver.kt index 23b4440bcd5..6e124cc4b15 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationFriendPathsResolver.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationFriendPathsResolver.kt @@ -11,31 +11,82 @@ import org.gradle.api.tasks.bundling.AbstractArchiveTask import org.jetbrains.kotlin.gradle.plugin.mpp.InternalKotlinCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithClosure import org.jetbrains.kotlin.gradle.plugin.mpp.isMain +import org.jetbrains.kotlin.gradle.plugin.sources.getVisibleSourceSetsFromAssociateCompilations +import org.jetbrains.kotlin.gradle.plugin.sources.internal +import org.jetbrains.kotlin.gradle.targets.metadata.getMetadataCompilationForSourceSet import org.jetbrains.kotlin.gradle.utils.filesProvider internal interface KotlinCompilationFriendPathsResolver { fun resolveFriendPaths(compilation: InternalKotlinCompilation<*>): Iterable } -internal object DefaultKotlinCompilationFriendPathsResolver : KotlinCompilationFriendPathsResolver { +internal class DefaultKotlinCompilationFriendPathsResolver( + private val friendArtifactResolver: FriendArtifactResolver = DefaultFriendArtifactResolver +) : KotlinCompilationFriendPathsResolver { + + override fun resolveFriendPaths(compilation: InternalKotlinCompilation<*>): Iterable { - return mutableListOf().also { allCollections -> - compilation.associateWithClosure.forEach { allCollections.add(it.output.classesDirs) } - allCollections.add(resolveFriendArtifacts(compilation)) + return mutableListOf().apply { + compilation.associateWithClosure.forEach { add(it.output.classesDirs) } + add(friendArtifactResolver.resolveFriendArtifacts(compilation)) } } - private fun resolveFriendArtifacts(compilation: InternalKotlinCompilation<*>): FileCollection { - return with(compilation.project) { - val friendArtifactsTaskProvider = resolveFriendArtifactsTask(compilation) ?: return files() - filesProvider { friendArtifactsTaskProvider.flatMap { it.archiveFile } } + /* Resolution of friend artifacts */ + + interface FriendArtifactResolver { + fun resolveFriendArtifacts(compilation: InternalKotlinCompilation<*>): FileCollection + + companion object { + fun composite(vararg resolvers: FriendArtifactResolver?): FriendArtifactResolver { + return CompositeFriendArtifactResolver(listOfNotNull(*resolvers)) + } } } - private fun resolveFriendArtifactsTask(compilation: InternalKotlinCompilation<*>): TaskProvider? { - if (compilation.associateWithClosure.none { it.isMain() }) return null - val archiveTasks = compilation.project.tasks.withType(AbstractArchiveTask::class.java) - if (compilation.target.artifactsTaskName !in archiveTasks.names) return null - return archiveTasks.named(compilation.target.artifactsTaskName) + class CompositeFriendArtifactResolver( + private val resolvers: List + ) : FriendArtifactResolver { + override fun resolveFriendArtifacts(compilation: InternalKotlinCompilation<*>): FileCollection { + return compilation.project.files(resolvers.map { resolver -> resolver.resolveFriendArtifacts(compilation) }) + } + } + + object DefaultFriendArtifactResolver : FriendArtifactResolver { + override fun resolveFriendArtifacts(compilation: InternalKotlinCompilation<*>): FileCollection { + return with(compilation.project) { + val friendArtifactsTaskProvider = resolveFriendArtifactsTask(compilation) ?: return files() + filesProvider { friendArtifactsTaskProvider.flatMap { it.archiveFile } } + } + } + + private fun resolveFriendArtifactsTask(compilation: InternalKotlinCompilation<*>): TaskProvider? { + if (compilation.associateWithClosure.none { it.isMain() }) return null + val archiveTasks = compilation.project.tasks.withType(AbstractArchiveTask::class.java) + if (compilation.target.artifactsTaskName !in archiveTasks.names) return null + return archiveTasks.named(compilation.target.artifactsTaskName) + } + } + + object AdditionalMetadataFriendArtifactResolver : FriendArtifactResolver { + override fun resolveFriendArtifacts(compilation: InternalKotlinCompilation<*>): FileCollection { + val friendSourceSets = getVisibleSourceSetsFromAssociateCompilations(compilation.defaultSourceSet) + return compilation.project.files( + friendSourceSets.mapNotNull { compilation.target.compilations.findByName(it.name)?.output?.classesDirs } + ) + } + } + + object AdditionalSharedNativeMetadataFriendArtifactResolver : FriendArtifactResolver { + override fun resolveFriendArtifacts(compilation: InternalKotlinCompilation<*>): FileCollection { + // TODO: implement proper dependsOn/refines compiler args for Kotlin/Native and pass the dependsOn klibs separately; + // But for now, those dependencies don't have any special semantics, so passing all them as friends works, too + val friendSourceSets = getVisibleSourceSetsFromAssociateCompilations(compilation.defaultSourceSet) + + compilation.defaultSourceSet.internal.dependsOnClosure + + return compilation.project.files( + friendSourceSets.mapNotNull { compilation.project.getMetadataCompilationForSourceSet(it)?.output?.classesDirs } + ) + } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationImpl.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationImpl.kt index 1544d4e566c..d843cfc8073 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationImpl.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationImpl.kt @@ -21,6 +21,8 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.internal import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask import org.jetbrains.kotlin.gradle.tasks.locateTask import org.jetbrains.kotlin.gradle.utils.ObservableSet +import org.jetbrains.kotlin.tooling.core.MutableExtras +import org.jetbrains.kotlin.tooling.core.mutableExtrasOf import javax.inject.Inject @@ -35,7 +37,7 @@ internal class KotlinCompilationImpl @Inject constructor( val compilationModule: KotlinCompilationModuleManager.CompilationModule, val sourceSets: KotlinCompilationSourceSetsContainer, val dependencyConfigurations: KotlinCompilationDependencyConfigurationsContainer, - val compilationTaskNames: KotlinCompilationTaskNameContainer, + val compilationTaskNames: KotlinCompilationTaskNamesContainer, val processResourcesTaskName: String?, val output: KotlinCompilationOutput, val compilerOptions: HasCompilerOptions<*>, @@ -55,6 +57,8 @@ internal class KotlinCompilationImpl @Inject constructor( override val target: KotlinTarget get() = params.target + override val extras: MutableExtras = mutableExtrasOf() + val sourceSets get() = params.sourceSets val dependencyConfigurations: KotlinCompilationDependencyConfigurationsContainer diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationSourceSetInclusion.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationSourceSetInclusion.kt index 08ebf8d3276..4675e5249f7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationSourceSetInclusion.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationSourceSetInclusion.kt @@ -15,16 +15,17 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.addSourcesToKotlinCompileTask import org.jetbrains.kotlin.gradle.plugin.mpp.addSourcesToKotlinNativeCompileTask import org.jetbrains.kotlin.gradle.plugin.sources.defaultSourceSetLanguageSettingsChecker import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation +import org.jetbrains.kotlin.tooling.core.extrasKeyOf +import org.jetbrains.kotlin.tooling.core.getOrPut internal interface KotlinCompilationSourceSetInclusion { fun include(compilation: InternalKotlinCompilation<*>, sourceSet: KotlinSourceSet) } internal class DefaultKotlinCompilationSourceSetInclusion( - private val addSourcesToCompileTask: AddSourcesToCompileTask + private val addSourcesToCompileTask: AddSourcesToCompileTask = AddSourcesToCompileTask.Default ) : KotlinCompilationSourceSetInclusion { - interface AddSourcesToCompileTask { fun addSources(compilation: KotlinCompilation<*>, sourceSet: KotlinSourceSet, addAsCommonSources: Lazy) @@ -51,10 +52,9 @@ internal class DefaultKotlinCompilationSourceSetInclusion( } } - private val processedSourceSets = hashSetOf() - override fun include(compilation: InternalKotlinCompilation<*>, sourceSet: KotlinSourceSet) { - if (!processedSourceSets.add(sourceSet)) return + /* Check if the source set was already included */ + if (!compilation.includedSourceSets.add(sourceSet)) return addSourcesToCompileTask.addSources( compilation, sourceSet, @@ -97,4 +97,17 @@ internal class DefaultKotlinCompilationSourceSetInclusion( defaultSourceSetLanguageSettingsChecker.runAllChecks(compilation.defaultSourceSet, sourceSet) } } + + private companion object { + /** + * Key used to store already processed source sets on the compilation instance itself + * to avoid re-processing of unnecessary source sets! + */ + private val includedSourceSetsKey = extrasKeyOf>( + DefaultKotlinCompilationSourceSetInclusion::class.java.name + ) + + val InternalKotlinCompilation<*>.includedSourceSets: MutableSet + get() = extras.getOrPut(includedSourceSetsKey, { hashSetOf() }) + } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationTaskContainer.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationTaskContainer.kt index 553ae8ad72c..7cfd7dcbe9b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationTaskContainer.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationTaskContainer.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl -data class KotlinCompilationTaskNameContainer( +internal data class KotlinCompilationTaskNamesContainer( val compileTaskName: String, val compileAllTaskName: String ) \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultCompilationModuleFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultCompilationModuleFactory.kt new file mode 100644 index 00000000000..1ab4a2082cd --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultCompilationModuleFactory.kt @@ -0,0 +1,27 @@ +/* + * 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.plugin.mpp.compilationImpl.factory + +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager +import org.jetbrains.kotlin.gradle.plugin.mpp.filterModuleName +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.archivesName + +internal object DefaultCompilationModuleFactory : KotlinCompilationImplFactory.CompilationModuleFactory { + override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationModuleManager.CompilationModule = + KotlinCompilationModuleManager.CompilationModule( + compilationName = compilationName, + ownModuleName = target.project.provider { + val baseName = target.project.archivesName.orNull + ?: target.project.name + val suffix = if (compilationName == KotlinCompilation.MAIN_COMPILATION_NAME) "" else "_$compilationName" + filterModuleName("$baseName$suffix") + }, + type = if (compilationName == KotlinCompilation.MAIN_COMPILATION_NAME) KotlinCompilationModuleManager.CompilationModule.Type.Main + else KotlinCompilationModuleManager.CompilationModule.Type.Auxiliary + ) +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultKotlinCompilationDependencyConfigurationsFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultKotlinCompilationDependencyConfigurationsFactory.kt new file mode 100644 index 00000000000..3ddd1283daa --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultKotlinCompilationDependencyConfigurationsFactory.kt @@ -0,0 +1,130 @@ +/* + * 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.plugin.mpp.compilationImpl.factory + +import org.gradle.api.attributes.Category +import org.gradle.api.attributes.Usage +import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationDependencyConfigurationsContainer +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationDependencyConfigurationsContainer +import org.jetbrains.kotlin.gradle.utils.* + +internal sealed class DefaultKotlinCompilationDependencyConfigurationsFactory : + KotlinCompilationImplFactory.KotlinCompilationDependencyConfigurationsFactory { + + object WithRuntime : DefaultKotlinCompilationDependencyConfigurationsFactory() { + override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationDependencyConfigurationsContainer { + return KotlinCompilationDependencyConfigurationsContainer(target, compilationName, withRuntime = true) + } + } + + object WithoutRuntime : DefaultKotlinCompilationDependencyConfigurationsFactory() { + override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationDependencyConfigurationsContainer { + return KotlinCompilationDependencyConfigurationsContainer(target, compilationName, withRuntime = false) + } + } +} + +internal object NativeKotlinCompilationDependencyConfigurationsFactory : + KotlinCompilationImplFactory.KotlinCompilationDependencyConfigurationsFactory { + + override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationDependencyConfigurationsContainer { + return KotlinCompilationDependencyConfigurationsContainer( + target, compilationName, withRuntime = false, compileClasspathConfigurationSuffix = "compileKlibraries" + ) + } +} + +private fun KotlinCompilationDependencyConfigurationsContainer( + target: KotlinTarget, compilationName: String, withRuntime: Boolean, + compileClasspathConfigurationSuffix: String = "compileClasspath", + runtimeClasspathConfigurationSuffix: String = "runtimeClasspath" +): KotlinCompilationDependencyConfigurationsContainer { + val compilation = "${target.disambiguationClassifier}/$compilationName" + val prefix = lowerCamelCaseName( + target.disambiguationClassifier, + compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, + "compilation" + ) + + val apiConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, API)).apply { + isVisible = false + isCanBeConsumed = false + isCanBeResolved = false + description = "API dependencies for $compilation" + } + + val implementationConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, IMPLEMENTATION)).apply { + extendsFrom(apiConfiguration) + isVisible = false + isCanBeConsumed = false + isCanBeResolved = false + description = "Implementation only dependencies for $compilation." + } + + val compileOnlyConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, COMPILE_ONLY)).apply { + isCanBeConsumed = false + setupAsLocalTargetSpecificConfigurationIfSupported(target) + attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) + isVisible = false + isCanBeResolved = false + description = "Compile only dependencies for $compilation." + } + + val runtimeOnlyConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, RUNTIME_ONLY)).apply { + isVisible = false + isCanBeConsumed = false + isCanBeResolved = false + description = "Runtime only dependencies for $compilation." + } + + val compileDependencyConfiguration = target.project.configurations.maybeCreate( + lowerCamelCaseName( + target.disambiguationClassifier, + compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, + compileClasspathConfigurationSuffix + ) + ).apply { + extendsFrom(compileOnlyConfiguration, implementationConfiguration) + usesPlatformOf(target) + isVisible = false + isCanBeConsumed = false + attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target)) + if (target.platformType != KotlinPlatformType.androidJvm) { + attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) + } + description = "Compile classpath for $compilation." + } + + val runtimeDependencyConfiguration = if (withRuntime) target.project.configurations.maybeCreate( + lowerCamelCaseName( + target.disambiguationClassifier, + compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, + runtimeClasspathConfigurationSuffix + ) + ).apply { + extendsFrom(runtimeOnlyConfiguration, implementationConfiguration) + usesPlatformOf(target) + isVisible = false + isCanBeConsumed = false + isCanBeResolved = true + attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target)) + if (target.platformType != KotlinPlatformType.androidJvm) { + attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY)) + } + description = "Runtime classpath of $compilation." + } else null + + return DefaultKotlinCompilationDependencyConfigurationsContainer( + apiConfiguration = apiConfiguration, + implementationConfiguration = implementationConfiguration, + compileOnlyConfiguration = compileOnlyConfiguration, + runtimeOnlyConfiguration = runtimeOnlyConfiguration, + compileDependencyConfiguration = compileDependencyConfiguration, + runtimeDependencyConfiguration = runtimeDependencyConfiguration + ) +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultKotlinCompilationOutputFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultKotlinCompilationOutputFactory.kt new file mode 100644 index 00000000000..e055a9ecf80 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultKotlinCompilationOutputFactory.kt @@ -0,0 +1,17 @@ +/* + * 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.plugin.mpp.compilationImpl.factory + +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinCompilationOutput +import java.util.concurrent.Callable + +internal object DefaultKotlinCompilationOutputFactory : KotlinCompilationImplFactory.KotlinCompilationOutputFactory { + override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationOutput = DefaultKotlinCompilationOutput( + target.project, Callable { target.project.buildDir.resolve("processedResources/${target.targetName}/$compilationName") } + ) +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultKotlinCompilationSourceSetsContainerFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultKotlinCompilationSourceSetsContainerFactory.kt new file mode 100644 index 00000000000..387acb7db6f --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultKotlinCompilationSourceSetsContainerFactory.kt @@ -0,0 +1,38 @@ +/* + * 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.plugin.mpp.compilationImpl.factory + +import org.jetbrains.kotlin.gradle.dsl.kotlinExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationSourceSetsContainer +import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName + +internal class DefaultKotlinCompilationSourceSetsContainerFactory( + private val defaultSourceSetNaming: DefaultSourceSetNaming = DefaultDefaultSourceSetNaming +) : KotlinCompilationImplFactory.KotlinCompilationSourceSetsContainerFactory { + + fun interface DefaultSourceSetNaming { + fun defaultSourceSetName(target: KotlinTarget, compilationName: String): String + } + + object DefaultDefaultSourceSetNaming : DefaultSourceSetNaming { + override fun defaultSourceSetName(target: KotlinTarget, compilationName: String): String = lowerCamelCaseName( + target.disambiguationClassifier.takeIf { target !is KotlinMetadataTarget }, + if (compilationName == KotlinCompilation.MAIN_COMPILATION_NAME && target is KotlinMetadataTarget) + KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME + else compilationName + ) + } + + override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationSourceSetsContainer { + val defaultSourceSetName = defaultSourceSetNaming.defaultSourceSetName(target, compilationName) + val defaultSourceSet = target.project.kotlinExtension.sourceSets.maybeCreate(defaultSourceSetName) + return KotlinCompilationSourceSetsContainer(defaultSourceSet) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultKotlinCompilationTaskNamesContainerFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultKotlinCompilationTaskNamesContainerFactory.kt new file mode 100644 index 00000000000..1ee7d10d3d6 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultKotlinCompilationTaskNamesContainerFactory.kt @@ -0,0 +1,21 @@ +/* + * 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.plugin.mpp.compilationImpl.factory + +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationTaskNamesContainer +import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName + +internal object DefaultKotlinCompilationTaskNamesContainerFactory : + KotlinCompilationImplFactory.KotlinCompilationTaskNamesContainerFactory { + override fun create(target: KotlinTarget, compilationName: String) = KotlinCompilationTaskNamesContainer( + compileTaskName = lowerCamelCaseName( + "compile", compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, "Kotlin", target.targetName + ), + compileAllTaskName = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "classes") + ) +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultProcessResourcesTaskNameFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultProcessResourcesTaskNameFactory.kt new file mode 100644 index 00000000000..b8d1275fb48 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/DefaultProcessResourcesTaskNameFactory.kt @@ -0,0 +1,18 @@ +/* + * 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.plugin.mpp.compilationImpl.factory + +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName + +internal object DefaultProcessResourcesTaskNameFactory : KotlinCompilationImplFactory.ProcessResourcesTaskNameFactory { + override fun create(target: KotlinTarget, compilationName: String): String = lowerCamelCaseName( + target.disambiguationClassifier, + compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, + "processResources" + ) +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/JvmCompilerOptionsFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/JvmCompilerOptionsFactory.kt new file mode 100644 index 00000000000..5e3d399e755 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/JvmCompilerOptionsFactory.kt @@ -0,0 +1,23 @@ +package org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory + +import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptions +import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptionsDefault +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions +import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget + +internal object JvmCompilerOptionsFactory : KotlinCompilationImplFactory.CompilerOptionsFactory { + override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationImplFactory.CompilerOptionsFactory.Options { + val compilerOptions = object : HasCompilerOptions { + override val options: CompilerJvmOptions = + target.project.objects.newInstance(CompilerJvmOptionsDefault::class.java) + } + + val kotlinOptions = object : KotlinJvmOptions { + override val options: CompilerJvmOptions + get() = compilerOptions.options + } + + return KotlinCompilationImplFactory.CompilerOptionsFactory.Options(compilerOptions, kotlinOptions) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/KotlinCompilationImplFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/KotlinCompilationImplFactory.kt new file mode 100644 index 00000000000..98736370c66 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/KotlinCompilationImplFactory.kt @@ -0,0 +1,94 @@ +/* + * 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.plugin.mpp.compilationImpl.factory + +import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions +import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.* +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule + +internal class KotlinCompilationImplFactory( + private val compilerOptionsFactory: CompilerOptionsFactory, + + private val compilationModuleFactory: CompilationModuleFactory = + DefaultCompilationModuleFactory, + + private val compilationSourceSetsContainerFactory: KotlinCompilationSourceSetsContainerFactory = + DefaultKotlinCompilationSourceSetsContainerFactory(), + + private val compilationDependencyConfigurationsFactory: KotlinCompilationDependencyConfigurationsFactory = + DefaultKotlinCompilationDependencyConfigurationsFactory.WithRuntime, + + private val compilationAssociator: KotlinCompilationAssociator = + DefaultKotlinCompilationAssociator, + + private val compilationFriendPathsResolver: KotlinCompilationFriendPathsResolver = + DefaultKotlinCompilationFriendPathsResolver(), + + private val compilationSourceSetInclusion: KotlinCompilationSourceSetInclusion = + DefaultKotlinCompilationSourceSetInclusion(), + + private val compilationOutputFactory: KotlinCompilationOutputFactory = + DefaultKotlinCompilationOutputFactory, + + private val compilationTaskNamesContainerFactory: KotlinCompilationTaskNamesContainerFactory = + DefaultKotlinCompilationTaskNamesContainerFactory, + + private val processResourcesTaskNameFactory: ProcessResourcesTaskNameFactory = + DefaultProcessResourcesTaskNameFactory +) { + fun interface CompilationModuleFactory { + fun create(target: KotlinTarget, compilationName: String): CompilationModule + } + + fun interface KotlinCompilationSourceSetsContainerFactory { + fun create(target: KotlinTarget, compilationName: String): KotlinCompilationSourceSetsContainer + } + + fun interface KotlinCompilationTaskNamesContainerFactory { + fun create(target: KotlinTarget, compilationName: String): KotlinCompilationTaskNamesContainer + } + + fun interface ProcessResourcesTaskNameFactory { + fun create(target: KotlinTarget, compilationName: String): String? + } + + fun interface KotlinCompilationDependencyConfigurationsFactory { + fun create(target: KotlinTarget, compilationName: String): KotlinCompilationDependencyConfigurationsContainer + } + + fun interface KotlinCompilationOutputFactory { + fun create(target: KotlinTarget, compilationName: String): KotlinCompilationOutput + } + + fun interface CompilerOptionsFactory { + data class Options(val compilerOptions: HasCompilerOptions<*>, val kotlinOptions: KotlinCommonOptions) + + fun create(target: KotlinTarget, compilationName: String): Options + } + + fun create(target: KotlinTarget, compilationName: String): KotlinCompilationImpl { + val options = compilerOptionsFactory.create(target, compilationName) + return KotlinCompilationImpl( + KotlinCompilationImpl.Params( + target = target, + compilationModule = compilationModuleFactory.create(target, compilationName), + sourceSets = compilationSourceSetsContainerFactory.create(target, compilationName), + dependencyConfigurations = compilationDependencyConfigurationsFactory.create(target, compilationName), + compilationTaskNames = compilationTaskNamesContainerFactory.create(target, compilationName), + processResourcesTaskName = processResourcesTaskNameFactory.create(target, compilationName), + output = compilationOutputFactory.create(target, compilationName), + compilerOptions = options.compilerOptions, + kotlinOptions = options.kotlinOptions, + compilationAssociator = compilationAssociator, + compilationFriendPathsResolver = compilationFriendPathsResolver, + compilationSourceSetInclusion = compilationSourceSetInclusion + ) + ) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/NativeCompilerOptionsFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/NativeCompilerOptionsFactory.kt new file mode 100644 index 00000000000..f1988273f18 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/NativeCompilerOptionsFactory.kt @@ -0,0 +1,23 @@ +/* + * 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.plugin.mpp.compilationImpl.factory + +import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.targets.native.NativeCompilerOptions + +internal object NativeCompilerOptionsFactory : KotlinCompilationImplFactory.CompilerOptionsFactory { + + override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationImplFactory.CompilerOptionsFactory.Options { + val compilerOptions = NativeCompilerOptions(target.project) + + val kotlinOptions = object : KotlinCommonOptions { + override val options get() = compilerOptions.options + } + + return KotlinCompilationImplFactory.CompilerOptionsFactory.Options(compilerOptions, kotlinOptions) + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/NativeKotlinCompilationTaskNamesContainerFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/NativeKotlinCompilationTaskNamesContainerFactory.kt new file mode 100644 index 00000000000..fd097ca5906 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/NativeKotlinCompilationTaskNamesContainerFactory.kt @@ -0,0 +1,16 @@ +/* + * 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.plugin.mpp.compilationImpl.factory + +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName + +internal object NativeKotlinCompilationTaskNamesContainerFactory : + KotlinCompilationImplFactory.KotlinCompilationTaskNamesContainerFactory { + override fun create(target: KotlinTarget, compilationName: String) = + DefaultKotlinCompilationTaskNamesContainerFactory.create(target, compilationName) + .copy(compileAllTaskName = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "klibrary")) +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmCompilationTaskConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmCompilationTaskConfigurator.kt index 36c90a662f8..d2467c548c7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmCompilationTaskConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmCompilationTaskConfigurator.kt @@ -51,7 +51,9 @@ open class GradleKpmCompilationTaskConfigurator( compilationData: KotlinNativeCompilationData<*>, configure: KotlinNativeCompile.() -> Unit ): TaskProvider { - val compileTask = KotlinNativeTargetConfigurator.createKlibCompilationTask(compilationData) + val compileTask = KotlinNativeTargetConfigurator.createKlibCompilationTask( + KotlinCompilationProjection.KPM(compilationData), compilationData.konanTarget + ) val allSources = getSourcesForFragmentCompilation(fragment) val commonSources = getCommonSourcesForFragmentCompilation(fragment) @@ -66,9 +68,9 @@ open class GradleKpmCompilationTaskConfigurator( } fun createKotlinNativeCompilationTask( - variant: GradleKpmVariant, + variant: GradleKpmNativeVariantInternal, compilationData: KotlinNativeCompilationData<*> ): TaskProvider = createKotlinNativeCompilationTask(variant, compilationData) { kotlinPluginData = project.compilerPluginProviderForPlatformCompilation(variant, compilationData) } - } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmNativeVariantCompilationData.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmNativeVariantCompilationData.kt index 673db25a1fb..ae85d96cd90 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmNativeVariantCompilationData.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmNativeVariantCompilationData.kt @@ -28,10 +28,7 @@ internal class GradleKpmNativeVariantCompilationData( override val owner: GradleKpmNativeVariant get() = variant - override val compilerOptions: HasCompilerOptions = NativeCompilerOptions( - project, - variant.languageSettings - ) + override val compilerOptions: HasCompilerOptions = NativeCompilerOptions(project) @Suppress("DEPRECATION") @Deprecated("Replaced with compilerOptions.options", replaceWith = ReplaceWith("compilerOptions.options")) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmNativeVariantInternal.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmNativeVariantInternal.kt index 6da3baf4e08..9ba705c88c1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmNativeVariantInternal.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/GradleKpmNativeVariantInternal.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 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.GradleKpmDefaultCInteropSettingsFactory import org.jetbrains.kotlin.gradle.plugin.mpp.publishedConfigurationName import org.jetbrains.kotlin.konan.target.KonanTarget @@ -35,8 +36,10 @@ abstract class GradleKpmNativeVariantInternal( override val gradleVariantNames: Set get() = listOf(apiElementsConfiguration.name).flatMap { listOf(it, publishedConfigurationName(it)) }.toSet() - val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName -> - project.objects.newInstance(DefaultCInteropSettings::class.java, project, cinteropName, compilationData) + val cinterops by lazy { + project.container( + DefaultCInteropSettings::class.java, GradleKpmDefaultCInteropSettingsFactory(compilationData) + ) } override val compilationData by lazy { GradleKpmNativeVariantCompilationData(this) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinMetadataCompilationData.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinMetadataCompilationData.kt index 53f2e82b1b3..cf47ef95db8 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinMetadataCompilationData.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinMetadataCompilationData.kt @@ -177,10 +177,7 @@ internal open class KotlinNativeFragmentMetadataCompilationDataImpl( override val isActive: Boolean get() = fragment.isNativeShared() && fragment.containingVariants.count() > 1 - override val compilerOptions: HasCompilerOptions = NativeCompilerOptions( - project, - languageSettings - ) + override val compilerOptions: HasCompilerOptions = NativeCompilerOptions(project) @Suppress("DEPRECATION") @Deprecated("Replaced with compilerOptions.options", replaceWith = ReplaceWith("compilerOptions.options")) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultLanguageSettingsBuilder.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultLanguageSettingsBuilder.kt index 71c2d16ade9..0a262ddac05 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultLanguageSettingsBuilder.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/sources/DefaultLanguageSettingsBuilder.kt @@ -79,7 +79,7 @@ internal class DefaultLanguageSettingsBuilder : LanguageSettingsBuilder { val pluginOptionsTask = compilerPluginOptionsTask.value ?: return null return when (pluginOptionsTask) { is AbstractKotlinCompile<*> -> pluginOptionsTask.pluginOptions.toSingleCompilerPluginOptions() - is AbstractKotlinNativeCompile<*, *, *> -> pluginOptionsTask.compilerPluginOptions + is AbstractKotlinNativeCompile<*, *> -> pluginOptionsTask.compilerPluginOptions else -> error("Unexpected task: $pluginOptionsTask") }.arguments } @@ -89,7 +89,7 @@ internal class DefaultLanguageSettingsBuilder : LanguageSettingsBuilder { val pluginClasspathTask = compilerPluginOptionsTask.value ?: return null return when (pluginClasspathTask) { is AbstractKotlinCompile<*> -> pluginClasspathTask.pluginClasspath - is AbstractKotlinNativeCompile<*, *, *> -> pluginClasspathTask.compilerPluginClasspath ?: pluginClasspathTask.project.files() + is AbstractKotlinNativeCompile<*, *> -> pluginClasspathTask.compilerPluginClasspath ?: pluginClasspathTask.project.files() else -> error("Unexpected task: $pluginClasspathTask") } } @@ -106,16 +106,16 @@ internal fun applyLanguageSettingsToCompilerOptions( ) = with(compilerOptions) { languageVersion.convention(languageSettingsBuilder.languageVersion?.let { KotlinVersion.fromVersion(it) }) apiVersion.convention(languageSettingsBuilder.apiVersion?.let { KotlinVersion.fromVersion(it) }) - + val freeArgs = mutableListOf().apply { if (languageSettingsBuilder.progressiveMode) { add("-progressive") } - + languageSettingsBuilder.enabledLanguageFeatures.forEach { featureName -> add("-XXLanguage:+$featureName") } - + languageSettingsBuilder.optInAnnotationsInUse.forEach { annotationName -> add("-opt-in=$annotationName") } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetConfigurator.kt index f0ed1bb493e..ae1b5c67be6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/KotlinJsTargetConfigurator.kt @@ -65,7 +65,11 @@ open class KotlinJsTargetConfigurator : compilation.source(compilation.defaultSourceSet) - configureResourceProcessing(compilation, project.files(Callable { compilation.allKotlinSourceSets.map { it.resources } })) + configureResourceProcessing( + compilation, + compilation.processResourcesTaskName, + project.files(Callable { compilation.allKotlinSourceSets.map { it.resources } }) + ) createLifecycleTaskInternal(compilation) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt index d5d039d38d9..080feb2076a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilation.kt @@ -70,56 +70,16 @@ open class KotlinJvmCompilation @Inject internal constructor( get() = compilation.relatedConfigurationNames } - -private inline fun InternalKotlinCompilation<*>.castKotlinOptionsType(): InternalKotlinCompilation { +//TODO SEB: Find a good spot for this function +internal inline fun InternalKotlinCompilation<*>.castKotlinOptionsType(): InternalKotlinCompilation { this.kotlinOptions as T @Suppress("UNCHECKED_CAST") return this as InternalKotlinCompilation } -private inline fun HasCompilerOptions<*>.castCompilerOptionsType(): HasCompilerOptions { +//TODO SEB: Find home for function +internal inline fun HasCompilerOptions<*>.castCompilerOptionsType(): HasCompilerOptions { this.options as T @Suppress("UNCHECKED_CAST") return this as HasCompilerOptions } - - -abstract class oKotlinJvmCompilation @Inject constructor( - compilationDetails: CompilationDetailsWithRuntime, -) : AbstractKotlinCompilationToRunnableFiles(compilationDetails), - KotlinCompilationWithResources { - override val target: KotlinJvmTarget get() = compilationDetails.target as KotlinJvmTarget - - @Suppress("UNCHECKED_CAST") - override val compilerOptions: HasCompilerOptions - get() = super.compilerOptions as HasCompilerOptions - - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - @Deprecated("Replaced with compileTaskProvider", replaceWith = ReplaceWith("compileTaskProvider")) - @Suppress("UNCHECKED_CAST", "DEPRECATION") - override val compileKotlinTaskProvider: TaskProvider - get() = super.compileKotlinTaskProvider as TaskProvider - - @Suppress("DEPRECATION") - @Deprecated("Accessing task instance directly is deprecated", replaceWith = ReplaceWith("compileTaskProvider")) - override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile - get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile - - @Suppress("UNCHECKED_CAST") - override val compileTaskProvider: TaskProvider> - get() = super.compileTaskProvider as TaskProvider> - - val compileJavaTaskProvider: TaskProvider? - get() = if (target.withJavaEnabled) { - val project = target.project - val javaSourceSets = - project.gradle.variantImplementationFactory() - .getInstance(project) - .sourceSets - val javaSourceSet = javaSourceSets.getByName(compilationPurpose) - project.tasks.withType(JavaCompile::class.java).named(javaSourceSet.compileJavaTaskName) - } else null -} - diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilationFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilationFactory.kt index 281c3230e50..d5757936fba 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilationFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/jvm/KotlinJvmCompilationFactory.kt @@ -6,172 +6,25 @@ @file:Suppress("PackageDirectoryMismatch") // Old package for compatibility package org.jetbrains.kotlin.gradle.plugin.mpp -import org.gradle.api.attributes.Category -import org.gradle.api.attributes.Usage -import org.gradle.api.provider.Provider -import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptions -import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptionsDefault -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.* -import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule.Type.Auxiliary -import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule.Type.Main -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.archivesName +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.JvmCompilerOptionsFactory +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget import org.jetbrains.kotlin.gradle.utils.* -import java.util.concurrent.Callable -open class KotlinJvmCompilationFactory( - override val target: KotlinJvmTarget +open class KotlinJvmCompilationFactory internal constructor( + override val target: KotlinJvmTarget, + private val compilationImplFactory: KotlinCompilationImplFactory = + KotlinCompilationImplFactory( + compilerOptionsFactory = JvmCompilerOptionsFactory, + compilationAssociator = JvmKotlinCompilationAssociator + ), ) : KotlinCompilationFactory { override val itemClass: Class get() = KotlinJvmCompilation::class.java override fun create(name: String): KotlinJvmCompilation { - val compilerOptions = createCompilerOptions() - - val params = KotlinCompilationImpl.Params( - target = target, - compilationModule = KotlinCompilationModuleManager.CompilationModule( - compilationName = name, - ownModuleName = ownModuleName(target, name), - type = if (name == KotlinCompilation.MAIN_COMPILATION_NAME) Main else Auxiliary - ), - sourceSets = KotlinCompilationSourceSetsContainer(getOrCreateDefaultSourceSet(name)), - dependencyConfigurations = createDependencyConfigurations(name), - compilationTaskNames = KotlinCompilationTaskNameContainer( - compileTaskName = lowerCamelCaseName( - "compile", name.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, "Kotlin", target.targetName - ), - compileAllTaskName = lowerCamelCaseName(target.disambiguationClassifier, name, "classes") - ), - processResourcesTaskName = lowerCamelCaseName( - target.disambiguationClassifier, - name.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - "processResources" - ), - output = DefaultKotlinCompilationOutput( - project, Callable { target.project.buildDir.resolve("processedResources/${target.targetName}/$name") } - ), - compilerOptions = compilerOptions, - kotlinOptions = compilerOptions.asKotlinJvmOptions(), - compilationAssociator = if (target.withJavaEnabled) KotlinJvmWithJavaCompilationAssociator else - DefaultKotlinCompilationAssociator, - compilationFriendPathsResolver = DefaultKotlinCompilationFriendPathsResolver, - compilationSourceSetInclusion = DefaultKotlinCompilationSourceSetInclusion( - DefaultKotlinCompilationSourceSetInclusion.AddSourcesToCompileTask.Default - ) - ) - - return target.project.objects.newInstance(KotlinJvmCompilation::class.java, KotlinCompilationImpl(params)) - } - - private fun createDependencyConfigurations( - compilationName: String - ): KotlinCompilationDependencyConfigurationsContainer { - val compilation = "${target.disambiguationClassifier}/$compilationName" - val prefix = lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - "compilation" - ) - - val apiConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, API)).apply { - isVisible = false - isCanBeConsumed = false - isCanBeResolved = false - description = "API dependencies for $compilation" - } - - val implementationConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, IMPLEMENTATION)).apply { - extendsFrom(apiConfiguration) - isVisible = false - isCanBeConsumed = false - isCanBeResolved = false - description = "Implementation only dependencies for $compilation." - } - - val compileOnlyConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, COMPILE_ONLY)).apply { - isCanBeConsumed = false - setupAsLocalTargetSpecificConfigurationIfSupported(target) - attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) - isVisible = false - isCanBeResolved = false - description = "Compile only dependencies for $compilation." - } - - val runtimeOnlyConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, RUNTIME_ONLY)).apply { - isVisible = false - isCanBeConsumed = false - isCanBeResolved = false - description = "Runtime only dependencies for $compilation." - } - - val compileDependencyConfiguration = target.project.configurations.maybeCreate( - lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - "compileClasspath" - ) - ).apply { - extendsFrom(compileOnlyConfiguration, implementationConfiguration) - usesPlatformOf(target) - isVisible = false - isCanBeConsumed = false - attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target)) - if (target.platformType != KotlinPlatformType.androidJvm) { - attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) - } - description = "Compile classpath for $compilation." - } - - val runtimeDependencyConfiguration = target.project.configurations.maybeCreate( - lowerCamelCaseName( - target.disambiguationClassifier, - compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - "runtimeClasspath" - ) - ).apply { - extendsFrom(runtimeOnlyConfiguration, implementationConfiguration) - usesPlatformOf(target) - isVisible = false - isCanBeConsumed = false - isCanBeResolved = true - attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target)) - if (target.platformType != KotlinPlatformType.androidJvm) { - attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY)) - } - description = "Runtime classpath of $compilation." - } - - return DefaultKotlinCompilationDependencyConfigurationsContainer( - apiConfiguration = apiConfiguration, - implementationConfiguration = implementationConfiguration, - compileOnlyConfiguration = compileOnlyConfiguration, - runtimeOnlyConfiguration = runtimeOnlyConfiguration, - compileDependencyConfiguration = compileDependencyConfiguration, - runtimeDependencyConfiguration = runtimeDependencyConfiguration - ) - } - - private fun createCompilerOptions(): HasCompilerOptions { - return object : HasCompilerOptions { - override val options: CompilerJvmOptions = - target.project.objects.newInstance(CompilerJvmOptionsDefault::class.java) - } - } - - private fun HasCompilerOptions.asKotlinJvmOptions(): KotlinJvmOptions { - return object : KotlinJvmOptions { - override val options: CompilerJvmOptions - get() = this@asKotlinJvmOptions.options - } + return target.project.objects.newInstance(KotlinJvmCompilation::class.java, compilationImplFactory.create(target, name)) } } - -private fun ownModuleName(target: KotlinTarget, compilationName: String): Provider = target.project.provider { - val baseName = target.project.archivesName.orNull - ?: target.project.name - val suffix = if (compilationName == KotlinCompilation.MAIN_COMPILATION_NAME) "" else "_$compilationName" - filterModuleName("$baseName$suffix") -} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt index cd955012d10..df5ca2c258e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt @@ -20,7 +20,6 @@ import org.gradle.api.tasks.bundling.Zip 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.compilationDetailsImpl.DefaultCompilationDetails import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.* import org.jetbrains.kotlin.gradle.plugin.sources.* import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService @@ -54,7 +53,7 @@ internal val Project.isCompatibilityMetadataVariantEnabled: Boolean get() = PropertiesProvider(this).enableCompatibilityMetadataVariant == true class KotlinMetadataTargetConfigurator : - KotlinOnlyTargetConfigurator, KotlinMetadataTarget>(createTestCompilation = false) { + KotlinOnlyTargetConfigurator, KotlinMetadataTarget>(createTestCompilation = false) { companion object { internal const val ALL_METADATA_JAR_NAME = "allMetadataJar" @@ -115,7 +114,7 @@ class KotlinMetadataTargetConfigurator : super.setupCompilationDependencyFiles(compilation) } - override fun buildCompilationProcessor(compilation: AbstractKotlinCompilation<*>): KotlinCompilationProcessor<*> = when (compilation) { + override fun buildCompilationProcessor(compilation: KotlinCompilation<*>): KotlinCompilationProcessor<*> = when (compilation) { is KotlinCommonCompilation -> { val tasksProvider = KotlinTasksProvider() KotlinCommonSourceSetProcessor(KotlinCompilationProjection(compilation), tasksProvider) @@ -181,7 +180,7 @@ class KotlinMetadataTargetConfigurator : val publishedCommonSourceSets: Set = getCommonSourceSetsForMetadataCompilation(project) val hostSpecificSourceSets: Set = getHostSpecificSourceSets(project).toSet() - val sourceSetsWithMetadataCompilations: Map> = publishedCommonSourceSets + val sourceSetsWithMetadataCompilations: Map> = publishedCommonSourceSets .associateWith { sourceSet -> createMetadataCompilation(target, sourceSet, allMetadataJar, sourceSet in hostSpecificSourceSets) } @@ -236,7 +235,7 @@ class KotlinMetadataTargetConfigurator : } private fun exportDependenciesForPublishing( - compilation: AbstractKotlinCompilation<*> + compilation: KotlinCompilation<*> ) { val sourceSet = compilation.defaultSourceSet val isSharedNativeCompilation = compilation is KotlinSharedNativeCompilation @@ -290,7 +289,7 @@ class KotlinMetadataTargetConfigurator : sourceSet: KotlinSourceSet, allMetadataJar: TaskProvider, isHostSpecific: Boolean - ): AbstractKotlinCompilation<*> { + ): KotlinCompilation<*> { val project = target.project val compilationName = sourceSet.name @@ -300,10 +299,11 @@ class KotlinMetadataTargetConfigurator : val isNativeSourceSet = isNativeSourceSet(sourceSet) - val compilationFactory: KotlinCompilationFactory> = when { + val compilationFactory: KotlinCompilationFactory> = when { isNativeSourceSet -> KotlinSharedNativeCompilationFactory( - target, - platformCompilations.map { (it as AbstractKotlinNativeCompilation).konanTarget } + target = target, + konanTargets = platformCompilations.map { (it as AbstractKotlinNativeCompilation).konanTarget }.toSet(), + defaultSourceSet = sourceSet ) else -> KotlinCommonCompilationFactory(target) @@ -312,8 +312,6 @@ class KotlinMetadataTargetConfigurator : return compilationFactory.create(compilationName).apply { target.compilations.add(this@apply) - (compilationDetails as DefaultCompilationDetails<*, *>).addExactSourceSetEagerly(sourceSet) - configureMetadataDependenciesForCompilation(this@apply) if (!isHostSpecific) { @@ -334,7 +332,7 @@ class KotlinMetadataTargetConfigurator : } } - private fun configureMetadataDependenciesForCompilation(compilation: AbstractKotlinCompilation<*>) { + private fun configureMetadataDependenciesForCompilation(compilation: KotlinCompilation<*>) { val project = compilation.target.project val sourceSet = compilation.defaultSourceSet @@ -342,7 +340,8 @@ class KotlinMetadataTargetConfigurator : transformGranularMetadataTaskName(compilation.name), listOf(sourceSet) ) { - it.description = "Generates serialized dependencies metadata for compilation '${compilation.name}' of target '${compilation.target.name}' (for tooling)" + it.description = + "Generates serialized dependencies metadata for compilation '${compilation.name}' of target '${compilation.target.name}' (for tooling)" } compilation.compileDependencyFiles += createMetadataDependencyTransformationClasspath( @@ -436,7 +435,7 @@ class KotlinMetadataTargetConfigurator : private fun createMetadataDependencyTransformationClasspath( fromFiles: Configuration, - compilation: AbstractKotlinCompilation<*> + compilation: KotlinCompilation<*> ): FileCollection { val project = compilation.target.project @@ -486,11 +485,11 @@ class KotlinMetadataTargetConfigurator : } internal class NativeSharedCompilationProcessor( - private val kotlinCompilation: KotlinSharedNativeCompilation -) : KotlinCompilationProcessor(KotlinCompilationProjection(kotlinCompilation)) { + private val compilation: KotlinSharedNativeCompilation +) : KotlinCompilationProcessor(KotlinCompilationProjection(compilation)) { override val kotlinTask: TaskProvider = - KotlinNativeTargetConfigurator.createKlibCompilationTask(kotlinCompilation) + KotlinNativeTargetConfigurator.createKlibCompilationTask(compilationProjection, compilation.konanTarget) override fun run() = Unit } @@ -633,6 +632,6 @@ internal fun Project.filesWithUnpackedArchives(from: FileCollection, extensions: } }).builtBy(from) -internal fun Project.getMetadataCompilationForSourceSet(sourceSet: KotlinSourceSet): AbstractKotlinCompilation<*>? { +internal fun Project.getMetadataCompilationForSourceSet(sourceSet: KotlinSourceSet): KotlinMetadataCompilation<*>? { return multiplatformExtension.metadata().compilations.findByName(sourceSet.name) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetPreset.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetPreset.kt index e32da749df3..7e67017f76e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetPreset.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetPreset.kt @@ -14,17 +14,17 @@ import org.jetbrains.kotlin.gradle.targets.metadata.KotlinMetadataTargetConfigur class KotlinMetadataTargetPreset( project: Project -) : KotlinOnlyTargetPreset>(project) { +) : KotlinOnlyTargetPreset>(project) { override fun getName(): String = PRESET_NAME override fun createCompilationFactory( forTarget: KotlinMetadataTarget - ): KotlinCompilationFactory> = - object : KotlinCompilationFactory> { + ): KotlinCompilationFactory> = + object : KotlinCompilationFactory> { override val target: KotlinTarget = forTarget - override val itemClass: Class> - get() = AbstractKotlinCompilation::class.java + override val itemClass: Class> + get() = KotlinCompilation::class.java override fun create(name: String): AbstractKotlinCompilation<*> = when (name) { KotlinCompilation.MAIN_COMPILATION_NAME -> KotlinCommonCompilationFactory(forTarget).create(name) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt index a69d6f28665..2adb4079f08 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/DefaultCInteropSettings.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp import org.gradle.api.Action +import org.gradle.api.NamedDomainObjectFactory import org.gradle.api.file.FileCollection import org.gradle.api.file.ProjectLayout import org.gradle.api.internal.file.FileOperations @@ -17,26 +18,36 @@ import org.gradle.api.provider.ProviderFactory import org.jetbrains.kotlin.gradle.plugin.CInteropSettings import org.jetbrains.kotlin.gradle.plugin.CInteropSettings.IncludeDirectories import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeCompilationData import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmNativeVariantCompilationData 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 org.jetbrains.kotlin.gradle.utils.newInstance import org.jetbrains.kotlin.gradle.utils.property import java.io.File import javax.inject.Inject -abstract class DefaultCInteropSettings @Inject constructor( - private val name: String, - @Transient - override val compilation: KotlinNativeCompilationData<*>, - private val providerFactory: ProviderFactory, - private val objectFactory: ObjectFactory, - private val projectLayout: ProjectLayout, - private val fileOperations: FileOperations, - ) : CInteropSettings { - private fun files() = objectFactory.fileCollection() - private fun files(vararg paths: Any) = objectFactory.fileCollection().from(*paths) +abstract class DefaultCInteropSettings @Inject internal constructor( + private val params: Params +) : CInteropSettings { + + internal data class Params( + val name: String, + val identifier: CInteropIdentifier, + val dependencyConfigurationName: String, + val interopProcessingTaskName: String, + val services: Services + ) { + open class Services @Inject constructor( + val providerFactory: ProviderFactory, + val objectFactory: ObjectFactory, + val projectLayout: ProjectLayout, + val fileOperations: FileOperations, + ) + } + + private fun files() = params.services.objectFactory.fileCollection() + private fun files(vararg paths: Any) = params.services.objectFactory.fileCollection().from(*paths) inner class DefaultIncludeDirectories : IncludeDirectories { var allHeadersDirs: FileCollection = files() @@ -53,29 +64,19 @@ abstract class DefaultCInteropSettings @Inject constructor( } } - override fun getName(): String = name + override fun getName(): String = params.name - internal val identifier: CInteropIdentifier - get() = CInteropIdentifier(CInteropIdentifier.Scope.create(compilation), name) - - val target: KotlinNativeTarget? - get() = (compilation as? KotlinNativeCompilation?)?.target + internal val identifier = params.identifier override val dependencyConfigurationName: String - get() = compilation.disambiguateName("${name.capitalize()}CInterop") + get() = params.dependencyConfigurationName override var dependencyFiles: FileCollection = files() - val interopProcessingTaskName: String - get() = lowerCamelCaseName( - "cinterop", - compilation.compilationPurpose.takeIf { it != "main" }.orEmpty(), - name, - target?.disambiguationClassifier ?: compilation.compilationClassifier - ) + val interopProcessingTaskName get() = params.interopProcessingTaskName - val defFileProperty: Property = objectFactory.property().value( - projectLayout.projectDirectory.file("src/nativeInterop/cinterop/$name.def").asFile + val defFileProperty: Property = params.services.objectFactory.property().value( + params.services.projectLayout.projectDirectory.file("src/nativeInterop/cinterop/$name.def").asFile ) var defFile: File @@ -90,18 +91,18 @@ abstract class DefaultCInteropSettings @Inject constructor( _packageNameProp.set(value) } - internal val _packageNameProp: Property = objectFactory.property(String::class.java) + internal val _packageNameProp: Property = params.services.objectFactory.property(String::class.java) val compilerOpts = mutableListOf() val linkerOpts = mutableListOf() var extraOpts: List get() = _extraOptsProp.get() set(value) { - _extraOptsProp = objectFactory.listProperty(String::class.java) + _extraOptsProp = params.services.objectFactory.listProperty(String::class.java) extraOpts(value) } - internal var _extraOptsProp: ListProperty = objectFactory.listProperty(String::class.java) + internal var _extraOptsProp: ListProperty = params.services.objectFactory.listProperty(String::class.java) val includeDirs = DefaultIncludeDirectories() var headers: FileCollection = files() @@ -109,7 +110,7 @@ abstract class DefaultCInteropSettings @Inject constructor( // DSL methods. override fun defFile(file: Any) { - defFileProperty.set(fileOperations.file(file)) + defFileProperty.set(params.services.fileOperations.file(file)) } override fun packageName(value: String) { @@ -138,16 +139,46 @@ abstract class DefaultCInteropSettings @Inject constructor( override fun extraOpts(vararg values: Any) = extraOpts(values.toList()) override fun extraOpts(values: List) { - _extraOptsProp.addAll(providerFactory.provider { values.map { it.toString() } }) + _extraOptsProp.addAll(params.services.providerFactory.provider { values.map { it.toString() } }) } } -private fun KotlinNativeCompilationData<*>.disambiguateName(simpleName: String): String = when (this) { - is AbstractKotlinNativeCompilation -> (this as AbstractKotlinCompilation<*>).disambiguateName(simpleName) - is GradleKpmNativeVariantCompilationData -> owner.disambiguateName(simpleName) - else -> lowerCamelCaseName( - this.compilationClassifier, - this.compilationPurpose.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, - simpleName - ) +internal class DefaultCInteropSettingsFactory(private val compilation: KotlinCompilation<*>) : + NamedDomainObjectFactory { + override fun create(name: String): DefaultCInteropSettings { + val params = DefaultCInteropSettings.Params( + name = name, + identifier = CInteropIdentifier(CInteropIdentifier.Scope.create(compilation), name), + dependencyConfigurationName = compilation.disambiguateName("${name.capitalize()}CInterop"), + interopProcessingTaskName = lowerCamelCaseName( + "cinterop", + compilation.name.takeIf { it != "main" }.orEmpty(), + name, + compilation.target.disambiguationClassifier + ), + services = compilation.project.objects.newInstance() + ) + + return compilation.project.objects.newInstance(params) + } +} + +internal class GradleKpmDefaultCInteropSettingsFactory(private val compilation: GradleKpmNativeVariantCompilationData) : + NamedDomainObjectFactory { + override fun create(name: String): DefaultCInteropSettings { + val params = DefaultCInteropSettings.Params( + name = name, + identifier = CInteropIdentifier(CInteropIdentifier.Scope.create(compilation), name), + dependencyConfigurationName = compilation.owner.disambiguateName("${name.capitalize()}CInterop"), + interopProcessingTaskName = lowerCamelCaseName( + "cinterop", + compilation.compilationPurpose.takeIf { it != "main" }.orEmpty(), + name, + compilation.compilationClassifier + ), + services = compilation.project.objects.newInstance() + ) + + return compilation.project.objects.newInstance(params) + } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilation.kt index 5b9067e823c..438b1c1df64 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilation.kt @@ -11,11 +11,8 @@ import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.tasks.TaskProvider import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions -import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions -import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationWithResources import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeCompilationData -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeFragmentMetadataCompilationData +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationImpl import org.jetbrains.kotlin.gradle.targets.native.NativeCompilerOptions import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName @@ -24,39 +21,69 @@ import java.io.File import java.util.concurrent.Callable import javax.inject.Inject -abstract class AbstractKotlinNativeCompilation( - override val konanTarget: KonanTarget, - compilationDetails: CompilationDetails -) : AbstractKotlinCompilation( - compilationDetails -), - KotlinNativeCompilationData { +abstract class AbstractKotlinNativeCompilation internal constructor( + private val compilation: KotlinCompilationImpl, + val konanTarget: KonanTarget +) : InternalKotlinCompilation by compilation.castKotlinOptionsType() { @Suppress("DEPRECATION") @Deprecated("Accessing task instance directly is deprecated", replaceWith = ReplaceWith("compileTaskProvider")) override val compileKotlinTask: KotlinNativeCompile - get() = super.compileKotlinTask as KotlinNativeCompile + get() = compilation.compileKotlinTask as KotlinNativeCompile @Suppress("UNCHECKED_CAST", "DEPRECATION") @Deprecated("Replaced with compileTaskProvider", replaceWith = ReplaceWith("compileTaskProvider")) override val compileKotlinTaskProvider: TaskProvider - get() = super.compileKotlinTaskProvider as TaskProvider + get() = compilation.compileKotlinTaskProvider as TaskProvider @Suppress("UNCHECKED_CAST") override val compileTaskProvider: TaskProvider - get() = super.compileTaskProvider as TaskProvider + get() = compilation.compileTaskProvider as TaskProvider internal val useGenericPluginArtifact: Boolean get() = project.nativeUseEmbeddableCompilerJar // Endorsed library controller. @Deprecated("Please declare explicit dependency on kotlinx-cli. This option is scheduled to be removed in 1.9.0") - override var enableEndorsedLibs: Boolean = false + var enableEndorsedLibs: Boolean = false } +open class KotlinNativeCompilation @Inject internal constructor( + konanTarget: KonanTarget, private val compilation: KotlinCompilationImpl, +) : AbstractKotlinNativeCompilation(compilation, konanTarget) { + + final override val target: KotlinNativeTarget + get() = compilation.target as KotlinNativeTarget + + override val compilerOptions: NativeCompilerOptions + get() = super.compilerOptions as NativeCompilerOptions + + // Interop DSL. + val cinterops = compilation.project.container(DefaultCInteropSettings::class.java, DefaultCInteropSettingsFactory(compilation)) + + fun cinterops(action: Action>) = action.execute(cinterops) + + // Naming + final override val processResourcesTaskName: String + get() = disambiguateName("processResources") + + val binariesTaskName: String + get() = lowerCamelCaseName(target.disambiguationClassifier, compilation.compilationName, "binaries") +} + +open class KotlinSharedNativeCompilation @Inject internal constructor( + val konanTargets: List, + compilation: KotlinCompilationImpl +) : AbstractKotlinNativeCompilation(compilation, konanTargets.find { it.enabledOnCurrentHost } ?: konanTargets.first()), + KotlinMetadataCompilation { + override val target: KotlinMetadataTarget = compilation.target as KotlinMetadataTarget +} + +// TODO SEB: Find home internal val Project.nativeUseEmbeddableCompilerJar: Boolean get() = PropertiesProvider(this).nativeUseEmbeddableCompilerJar +//TODO SEB: Find home for fuctnion internal fun addSourcesToKotlinNativeCompileTask( project: Project, taskName: String, @@ -68,50 +95,4 @@ internal fun addSourcesToKotlinNativeCompileTask( task.commonSources.from(project.files(Callable { if (addAsCommonSources.value) sourceFiles() else emptyList() })) } -} - -abstract class KotlinNativeCompilation @Inject constructor( - konanTarget: KonanTarget, - details: CompilationDetails -) : AbstractKotlinNativeCompilation(konanTarget, details), - KotlinCompilationWithResources { - - override val target: KotlinNativeTarget - get() = super.target as KotlinNativeTarget - - override val compilerOptions: NativeCompilerOptions - get() = super.compilerOptions as NativeCompilerOptions - - // Interop DSL. - val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName -> - project.objects.newInstance(DefaultCInteropSettings::class.java, cinteropName, this) - } - - fun cinterops(action: Action>) = action.execute(cinterops) - - // Naming - override val processResourcesTaskName: String - get() = disambiguateName("processResources") - - val binariesTaskName: String - get() = lowerCamelCaseName(target.disambiguationClassifier, compilationPurpose, "binaries") -} - -abstract class KotlinSharedNativeCompilation @Inject constructor( - 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(), - compilationDetails - ), - KotlinMetadataCompilation { - - override val target: KotlinMetadataTarget get() = super.target as KotlinMetadataTarget - - override val isActive: Boolean - get() = true // old plugin only creates necessary compilations -} +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilationFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilationFactory.kt index c0f0299028d..de86cefa3ab 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilationFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeCompilationFactory.kt @@ -6,81 +6,33 @@ @file:Suppress("PackageDirectoryMismatch") // Old package for compatibility package org.jetbrains.kotlin.gradle.plugin.mpp -import org.jetbrains.kotlin.gradle.dsl.CompilerCommonOptions -import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions -import org.jetbrains.kotlin.gradle.plugin.mpp.compilationDetailsImpl.NativeCompilationDetails -import org.jetbrains.kotlin.gradle.plugin.mpp.compilationDetailsImpl.SharedNativeCompilationDetails -import org.jetbrains.kotlin.gradle.targets.native.NativeCompilerOptions -import org.jetbrains.kotlin.konan.target.KonanTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationSourceSetInclusion +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.NativeKotlinCompilationAssociator +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.NativeCompilerOptionsFactory +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.NativeKotlinCompilationDependencyConfigurationsFactory +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.NativeKotlinCompilationTaskNamesContainerFactory -open class KotlinNativeCompilationFactory( - override val target: KotlinNativeTarget +open class KotlinNativeCompilationFactory internal constructor( + override val target: KotlinNativeTarget, + private val compilationImplFactory: KotlinCompilationImplFactory = + KotlinCompilationImplFactory( + compilationTaskNamesContainerFactory = NativeKotlinCompilationTaskNamesContainerFactory, + compilationDependencyConfigurationsFactory = NativeKotlinCompilationDependencyConfigurationsFactory, + compilerOptionsFactory = NativeCompilerOptionsFactory, + compilationAssociator = NativeKotlinCompilationAssociator, + compilationSourceSetInclusion = DefaultKotlinCompilationSourceSetInclusion( + DefaultKotlinCompilationSourceSetInclusion.AddSourcesToCompileTask.Native + ), + ) ) : KotlinCompilationFactory { override val itemClass: Class get() = KotlinNativeCompilation::class.java - @Suppress("DEPRECATION") override fun create(name: String): KotlinNativeCompilation { - // TODO: Validate compilation free args using the [CompilationFreeArgsValidator] - // when the compilation and the link args are separated (see KT-33717). - // Note: such validation should be done in the whenEvaluate block because - // a user can change args during project configuration. - - val defaultSourceSet = getOrCreateDefaultSourceSet(name) return target.project.objects.newInstance( - KotlinNativeCompilation::class.java, - target.konanTarget, - NativeCompilationDetails( - target, - name, - defaultSourceSet, - { - NativeCompilerOptions( - target.project, - defaultSourceSet.languageSettings - ) - }, - { - object : KotlinCommonOptions { - override val options: CompilerCommonOptions - get() = compilerOptions.options - } - } - ) + KotlinNativeCompilation::class.java, target.konanTarget, compilationImplFactory.create(target, name) ) } } - -class KotlinSharedNativeCompilationFactory( - override val target: KotlinMetadataTarget, - val konanTargets: List -) : KotlinCompilationFactory { - override val itemClass: Class - get() = KotlinSharedNativeCompilation::class.java - - override fun create(name: String): KotlinSharedNativeCompilation { - val defaultSourceSet = getOrCreateDefaultSourceSet(name) - return target.project.objects.newInstance( - KotlinSharedNativeCompilation::class.java, - konanTargets, - SharedNativeCompilationDetails( - target, - name, - defaultSourceSet, - { - NativeCompilerOptions( - target.project, - defaultSourceSet.languageSettings - ) - }, - { - object : KotlinCommonOptions { - override val options: CompilerCommonOptions - get() = compilerOptions.options - } - } - ) - ) - } -} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt index d58f7aa81e3..cc5883e0cc1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt @@ -26,6 +26,7 @@ import org.gradle.api.tasks.Exec import org.gradle.api.tasks.TaskProvider import org.gradle.language.base.plugins.LifecycleBasePlugin import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPILATION_NAME +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationProjection.KPM import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.KOTLIN_NATIVE_IGNORE_INCORRECT_DEPENDENCIES import org.jetbrains.kotlin.gradle.plugin.mpp.* import org.jetbrains.kotlin.gradle.plugin.mpp.apple.registerEmbedAndSignAppleFrameworkTask @@ -43,8 +44,6 @@ import org.jetbrains.kotlin.gradle.testing.internal.configureConventions import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry import org.jetbrains.kotlin.gradle.testing.testTaskName import org.jetbrains.kotlin.gradle.utils.* -import org.jetbrains.kotlin.gradle.utils.Xcode -import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget import java.io.File @@ -88,7 +87,7 @@ open class KotlinNativeTargetConfigurator : AbstractKotl private fun Project.syncLanguageSettingsToLinkTask(binary: NativeBinary) { tasks.named(binary.linkTaskName, KotlinNativeLink::class.java).configure { // We propagate compilation free args to the link task for now (see KT-33717). - val defaultLanguageSettings = binary.compilation.languageSettings as? DefaultLanguageSettingsBuilder + val defaultLanguageSettings = binary.compilation.defaultSourceSet.languageSettings as? DefaultLanguageSettingsBuilder if (defaultLanguageSettings != null) { it.toolOptions.freeCompilerArgs.addAll( defaultLanguageSettings.freeCompilerArgs @@ -210,12 +209,26 @@ open class KotlinNativeTargetConfigurator : AbstractKotl compilation: KotlinNativeCompilation, cinterops: NamedDomainObjectCollection ) { + val compilationProjection = KotlinCompilationProjection(compilation) cinterops.all { interop -> - val interopTask = registerTask(interop.interopProcessingTaskName, listOf(interop)) { - it.destinationDir = provider { klibOutputDirectory(compilation).resolve("cinterop") } + + val params = CInteropProcess.Params( + settings = interop, + targetName = compilation.target.name, + compilationName = compilation.name, + konanTarget = compilation.konanTarget, + baseKlibName = run { + val compilationPrefix = if (compilation.isMain()) project.name else compilation.name + "$compilationPrefix-cinterop-${interop.name}" + }, + services = objects.newInstance() + ) + + val interopTask = registerTask(interop.interopProcessingTaskName, listOf(params)) { + it.destinationDir = provider { klibOutputDirectory(compilationProjection).resolve("cinterop") } it.group = INTEROP_GROUP it.description = "Generates Kotlin/Native interop library '${interop.name}' " + - "for compilation '${compilation.compilationPurpose}'" + + "for compilation '${compilation.compilationName}'" + "of target '${it.konanTarget.name}'." it.enabled = compilation.konanTarget.enabledOnCurrentHost } @@ -233,11 +246,12 @@ open class KotlinNativeTargetConfigurator : AbstractKotl project.dependencies.add(target.apiElementsConfigurationName, interopOutput) // Add interop library to special CInteropApiElements configuration - createCInteropApiElementsKlibArtifact(interop, interopTask) + createCInteropApiElementsKlibArtifact(compilation.target, interop, interopTask) // Add the interop library in publication. createKlibArtifact( - compilation = interop.compilation, + compilationProjection = compilationProjection, + konanTarget = konanTarget, artifactFile = interopTask.map { it.outputFile }, classifier = "cinterop-${interop.name}", producingTask = interopTask, @@ -280,7 +294,7 @@ open class KotlinNativeTargetConfigurator : AbstractKotl it.group = BasePlugin.BUILD_GROUP it.description = "Assembles outputs for target '${target.name}'." } - target.compilations.all { createKlibCompilationTask(it) } + target.compilations.all { createKlibCompilationTask(KotlinCompilationProjection(it), it.konanTarget) } val apiElements = configurations.getByName(target.apiElementsConfigurationName) @@ -325,7 +339,7 @@ open class KotlinNativeTargetConfigurator : AbstractKotl } project.runOnceAfterEvaluated("Sync native compilation language settings to compiler options") { target.compilations.all { compilation -> - compilation.compilerOptions.syncLanguageSettings() + compilation.compilerOptions.syncLanguageSettings(compilation.defaultSourceSet.languageSettings) } } @@ -459,50 +473,55 @@ open class KotlinNativeTargetConfigurator : AbstractKotl const val RUN_GROUP = "run" internal fun createKlibCompilationTask( - compilation: KotlinNativeCompilationData<*> + compilationProjection: KotlinCompilationProjection, + konanTarget: KonanTarget ): TaskProvider { - val project = compilation.project + val project = compilationProjection.project val compileTaskProvider = project.registerTask( - compilation.compileKotlinTaskName, - listOf(compilation) + compilationProjection.compileKotlinTaskName, + listOf(compilationProjection) ) { it.group = BasePlugin.BUILD_GROUP - it.description = "Compiles a klibrary from the '${compilation.compilationPurpose}' " + - "compilation for target '${compilation.platformType.name}'." - it.enabled = compilation.konanTarget.enabledOnCurrentHost + it.description = "Compiles a klibrary from the '${compilationProjection.compilationName}' " + + "compilation for target '${compilationProjection.platformType.name}'." + it.enabled = konanTarget.enabledOnCurrentHost - it.destinationDirectory.set(project.klibOutputDirectory(compilation).resolve("klib")) + it.destinationDirectory.set(project.klibOutputDirectory(compilationProjection).resolve("klib")) } - compilation.output.classesDirs.from(compileTaskProvider.map { it.outputFile }) + compilationProjection.classesDirs.from(compileTaskProvider.map { it.outputFile }) - project.project.tasks.named(compilation.compileAllTaskName).dependsOn(compileTaskProvider) + project.project.tasks.named(compilationProjection.compileAllTaskName).dependsOn(compileTaskProvider) - if (compilation.isMainCompilationData()) { - if (compilation is KotlinNativeCompilation) { - project.project.tasks.named(compilation.target.artifactsTaskName).dependsOn(compileTaskProvider) + if (compilationProjection.isMain) { + if (compilationProjection is KotlinCompilationProjection.TCS && compilationProjection.compilation is KotlinNativeCompilation) { + project.project.tasks.named(compilationProjection.compilation.target.artifactsTaskName).dependsOn(compileTaskProvider) } project.project.tasks.named(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(compileTaskProvider) } - val shouldAddCompileOutputsToElements = compilation.owner is GradleKpmVariant || compilation.isMainCompilationData() + val shouldAddCompileOutputsToElements = + (compilationProjection is KPM && compilationProjection.compilationData.owner is GradleKpmVariant) || + compilationProjection.isMain + + if (shouldAddCompileOutputsToElements) { - createRegularKlibArtifact(compilation, compileTaskProvider) + createRegularKlibArtifact(compilationProjection, konanTarget, compileTaskProvider) } - if (compilation is AbstractKotlinNativeCompilation) { + if (compilationProjection is KotlinCompilationProjection.TCS && compilationProjection.compilation is AbstractKotlinNativeCompilation) { // FIXME: support compiler plugins for PM20 - addCompilerPlugins(compilation) + addCompilerPlugins(compilationProjection.compilation) } return compileTaskProvider } private fun Project.klibOutputDirectory( - compilation: KotlinCompilationData<*> + compilation: KotlinCompilationProjection ): File { - val targetSubDirectory = compilation.compilationClassifier?.let { "$it/" }.orEmpty() - return buildDir.resolve("classes/kotlin/$targetSubDirectory${compilation.compilationPurpose}") + val targetSubDirectory = compilation.targetDisambiguationClassifier?.let { "$it/" }.orEmpty() + return buildDir.resolve("classes/kotlin/$targetSubDirectory${compilation.compilationName}") } private fun addCompilerPlugins(compilation: AbstractKotlinNativeCompilation) { @@ -522,30 +541,37 @@ open class KotlinNativeTargetConfigurator : AbstractKotl } internal fun createRegularKlibArtifact( - compilation: KotlinNativeCompilationData<*>, + compilation: KotlinCompilationProjection, + konanTarget: KonanTarget, compileTask: TaskProvider - ) = createKlibArtifact(compilation, compileTask.map { it.outputFile.get() }, null, compileTask) + ) = createKlibArtifact(compilation, konanTarget, compileTask.map { it.outputFile.get() }, null, compileTask) private fun createKlibArtifact( - compilation: KotlinNativeCompilationData<*>, + compilationProjection: KotlinCompilationProjection, + konanTarget: KonanTarget, artifactFile: Provider, classifier: String?, producingTask: TaskProvider<*>, copy: Boolean = false ) { - val project = compilation.project - if (!compilation.konanTarget.enabledOnCurrentHost) { + val project = compilationProjection.project + if (!konanTarget.enabledOnCurrentHost) { return } - val apiElements = project.configurations.getByName(compilation.apiElementsConfigurationName) + val apiElementsName = when (compilationProjection) { + is KPM -> (compilationProjection.compilationData.owner as GradleKpmVariant).apiElementsConfiguration.name + is KotlinCompilationProjection.TCS -> compilationProjection.compilation.target.apiElementsConfigurationName + } + + val apiElements = project.configurations.getByName(apiElementsName) val realProducingTask: TaskProvider<*> // TODO: Someone remove this HACK PLEASE! val realArtifactFile = if (copy) { realProducingTask = project.project.registerTask("copy${producingTask.name.capitalize()}") { - val targetSubDirectory = compilation.compilationClassifier?.let { "$it/" }.orEmpty() - it.destinationDir = project.project.buildDir.resolve("libs/$targetSubDirectory${compilation.compilationPurpose}") + val targetSubDirectory = compilationProjection.targetDisambiguationClassifier?.let { "$it/" }.orEmpty() + it.destinationDir = project.project.buildDir.resolve("libs/$targetSubDirectory${compilationProjection.compilationName}") it.from(artifactFile) it.dependsOn(producingTask) } @@ -557,7 +583,7 @@ open class KotlinNativeTargetConfigurator : AbstractKotl with(apiElements) { val klibArtifact = project.project.artifacts.add(apiElements.name, realArtifactFile) { artifact -> - artifact.name = compilation.compilationPurpose + artifact.name = compilationProjection.compilationName artifact.extension = "klib" artifact.type = "klib" artifact.classifier = classifier @@ -568,13 +594,6 @@ open class KotlinNativeTargetConfigurator : AbstractKotl attributes.attribute(ArtifactAttributes.ARTIFACT_FORMAT, NativeArtifactFormat.KLIB) } } - - private val KotlinNativeCompilationData<*>.apiElementsConfigurationName: String - get() = when (val dataOwner = owner) { - is GradleKpmVariant -> dataOwner.apiElementsConfiguration.name - is KotlinTarget -> dataOwner.apiElementsConfigurationName - else -> error("unexpected owner of $this") - } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinSharedNativeCompilationFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinSharedNativeCompilationFactory.kt new file mode 100644 index 00000000000..a417cfe6ae3 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinSharedNativeCompilationFactory.kt @@ -0,0 +1,59 @@ +/* + * 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. + */ + +@file:Suppress("PackageDirectoryMismatch") // Old package for compatibility +package org.jetbrains.kotlin.gradle.plugin.mpp + +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationFriendPathsResolver +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationSourceSetInclusion +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationSourceSetsContainer +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.NativeKotlinCompilationAssociator +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.DefaultKotlinCompilationDependencyConfigurationsFactory +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory +import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.NativeCompilerOptionsFactory +import org.jetbrains.kotlin.konan.target.KonanTarget + +open class KotlinSharedNativeCompilationFactory internal constructor( + override val target: KotlinMetadataTarget, + private val konanTargets: Set, + private val defaultSourceSet: KotlinSourceSet, + private val compilationImplFactory: KotlinCompilationImplFactory = + KotlinCompilationImplFactory( + compilationDependencyConfigurationsFactory = DefaultKotlinCompilationDependencyConfigurationsFactory.WithoutRuntime, + compilerOptionsFactory = NativeCompilerOptionsFactory, + compilationAssociator = NativeKotlinCompilationAssociator, + + compilationSourceSetInclusion = DefaultKotlinCompilationSourceSetInclusion( + DefaultKotlinCompilationSourceSetInclusion.AddSourcesToCompileTask.Native + ), + + compilationFriendPathsResolver = DefaultKotlinCompilationFriendPathsResolver( + friendArtifactResolver = DefaultKotlinCompilationFriendPathsResolver.FriendArtifactResolver.composite( + DefaultKotlinCompilationFriendPathsResolver.DefaultFriendArtifactResolver, + DefaultKotlinCompilationFriendPathsResolver.AdditionalSharedNativeMetadataFriendArtifactResolver + ) + ), + + /* + Metadata compilations are created *because* of a pre-existing SourceSet. + We therefore can create the container inline + */ + compilationSourceSetsContainerFactory = KotlinCompilationImplFactory.KotlinCompilationSourceSetsContainerFactory { _, _ -> + KotlinCompilationSourceSetsContainer(defaultSourceSet) + } + ) +) : KotlinCompilationFactory { + + override val itemClass: Class + get() = KotlinSharedNativeCompilation::class.java + + @Suppress("DEPRECATION") + override fun create(name: String): KotlinSharedNativeCompilation { + return target.project.objects.newInstance( + itemClass, konanTargets.toList(), compilationImplFactory.create(target, name) + ) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/NativeCompilerOptions.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/NativeCompilerOptions.kt index e2654716c5c..4abb59662e1 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/NativeCompilerOptions.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/NativeCompilerOptions.kt @@ -6,23 +6,22 @@ package org.jetbrains.kotlin.gradle.targets.native import org.gradle.api.Project -import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptions -import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptionsDefault +import org.jetbrains.kotlin.gradle.dsl.CompilerCommonOptions +import org.jetbrains.kotlin.gradle.dsl.CompilerCommonOptionsDefault import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToCompilerOptions import org.jetbrains.kotlin.project.model.LanguageSettings -class NativeCompilerOptions( - project: Project, - private val nativeLanguageSettings: LanguageSettings -) : HasCompilerOptions { - override val options: KotlinCommonCompilerOptions = project.objects - .newInstance(KotlinCommonCompilerOptionsDefault::class.java) +class NativeCompilerOptions(project: Project) : HasCompilerOptions { + + override val options: CompilerCommonOptions = project.objects + .newInstance(CompilerCommonOptionsDefault::class.java) .apply { useK2.finalizeValue() } - fun syncLanguageSettings() { - applyLanguageSettingsToCompilerOptions(nativeLanguageSettings, options) + internal fun syncLanguageSettings(languageSettings: LanguageSettings) { + applyLanguageSettingsToCompilerOptions(languageSettings, options) } + } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerTask.kt index 9ad45eac9e7..f549d79d2bc 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerTask.kt @@ -19,6 +19,8 @@ import org.jetbrains.kotlin.compilerRunner.GradleCliCommonizer import org.jetbrains.kotlin.compilerRunner.KotlinNativeCommonizerToolRunner import org.jetbrains.kotlin.compilerRunner.KotlinToolRunner import org.jetbrains.kotlin.compilerRunner.konanHome +import org.jetbrains.kotlin.gradle.dsl.kotlinExtension +import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet @@ -283,7 +285,10 @@ private fun CInteropProcess.toGist(): CInteropGist { identifier = settings.identifier, konanTarget = konanTarget, // FIXME support cinterop with PM20 - sourceSets = project.provider { (settings.compilation as? KotlinCompilation<*>)?.kotlinSourceSets }, + sourceSets = project.provider { + project.multiplatformExtension.targets.getByName(targetName) + .compilations.getByName(compilationName).kotlinSourceSets + }, libraryFile = outputFileProvider, dependencies = libraries ) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropConfigurations.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropConfigurations.kt index 651c1c03aa7..aefd58d1e07 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropConfigurations.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropConfigurations.kt @@ -10,20 +10,25 @@ import org.gradle.api.artifacts.Configuration import org.gradle.api.attributes.* import org.gradle.api.internal.artifacts.ArtifactAttributes import org.gradle.api.tasks.TaskProvider -import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.CInteropSettings import org.jetbrains.kotlin.gradle.plugin.KotlinNativeTargetConfigurator.NativeArtifactFormat +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.plugin.categoryByName import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultCInteropSettings import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages +import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements.cinteropKlibLibraryElements import org.jetbrains.kotlin.gradle.tasks.CInteropProcess internal fun createCInteropApiElementsKlibArtifact( + target: KotlinNativeTarget, settings: DefaultCInteropSettings, interopTask: TaskProvider ) { - val project = settings.compilation.project - val configurationName = cInteropApiElementsConfigurationName(settings.target ?: return) + val project = target.project + val configurationName = cInteropApiElementsConfigurationName(target) val configuration = project.configurations.getByName(configurationName) project.artifacts.add(configuration.name, interopTask.map { it.outputFile }) { artifact -> artifact.extension = "klib" diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropIdentifier.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropIdentifier.kt index c552d7344de..54d2ab1dd91 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropIdentifier.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropIdentifier.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.gradle.targets.native.internal import org.gradle.api.tasks.Input +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData import org.jetbrains.kotlin.tooling.core.UnsafeApi import java.io.Serializable @@ -19,6 +20,11 @@ internal data class CInteropIdentifier internal constructor( ) : Serializable { class Scope @UnsafeApi internal constructor(val name: String) : Serializable { companion object { + @OptIn(UnsafeApi::class) + fun create(compilation: KotlinCompilation<*>): Scope { + return Scope("compilation/${compilation.compileKotlinTaskName}") + } + @OptIn(UnsafeApi::class) fun create(compilation: KotlinCompilationData<*>): Scope { return Scope("compilation/${compilation.compileKotlinTaskName}") diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeLink.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeLink.kt index 9c88c00b6f6..31ec1231b50 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeLink.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeLink.kt @@ -107,7 +107,7 @@ constructor( @Suppress("DEPRECATION") @Deprecated("Use toolOptions to configure the task") @get:Internal - val languageSettings: LanguageSettings = compilation.languageSettings + val languageSettings: LanguageSettings = compilation.defaultSourceSet.languageSettings @Suppress("unused") @get:Input diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt index 0e3779f9b58..6e653384b52 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/KotlinNativeTasks.kt @@ -14,11 +14,7 @@ import org.gradle.api.artifacts.component.ModuleComponentIdentifier import org.gradle.api.artifacts.component.ModuleComponentSelector import org.gradle.api.artifacts.result.DependencyResult import org.gradle.api.artifacts.result.ResolvedDependencyResult -import org.gradle.api.file.ConfigurableFileCollection -import org.gradle.api.file.FileCollection -import org.gradle.api.file.FileTree -import org.gradle.api.file.ProjectLayout -import org.gradle.api.file.RegularFile +import org.gradle.api.file.* import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.Provider import org.gradle.api.provider.ProviderFactory @@ -34,12 +30,13 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinCompile import org.jetbrains.kotlin.gradle.internal.ensureParentDirsCreated import org.jetbrains.kotlin.gradle.internal.isInIdeaSync import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationProjection import org.jetbrains.kotlin.gradle.plugin.cocoapods.asValidFrameworkName import org.jetbrains.kotlin.gradle.plugin.mpp.* +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinMetadataCompilationData import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeCompilationData -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeFragmentMetadataCompilationData -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.isMainCompilationData import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder +import org.jetbrains.kotlin.gradle.plugin.tcsOrNull import org.jetbrains.kotlin.gradle.targets.native.KonanPropertiesBuildService import org.jetbrains.kotlin.gradle.targets.native.internal.isAllowCommonizer import org.jetbrains.kotlin.gradle.targets.native.tasks.* @@ -58,6 +55,42 @@ import java.io.File import java.nio.file.Files import java.nio.file.Path import javax.inject.Inject +import kotlin.collections.Collection +import kotlin.collections.Iterable +import kotlin.collections.List +import kotlin.collections.Map +import kotlin.collections.MutableList +import kotlin.collections.MutableMap +import kotlin.collections.MutableSet +import kotlin.collections.Set +import kotlin.collections.any +import kotlin.collections.asSequence +import kotlin.collections.associateBy +import kotlin.collections.component1 +import kotlin.collections.component2 +import kotlin.collections.emptyList +import kotlin.collections.filter +import kotlin.collections.filterIsInstance +import kotlin.collections.flatMap +import kotlin.collections.forEach +import kotlin.collections.getOrPut +import kotlin.collections.getValue +import kotlin.collections.isNotEmpty +import kotlin.collections.joinToString +import kotlin.collections.listOf +import kotlin.collections.listOfNotNull +import kotlin.collections.map +import kotlin.collections.mapNotNull +import kotlin.collections.minus +import kotlin.collections.mutableListOf +import kotlin.collections.mutableMapOf +import kotlin.collections.mutableSetOf +import kotlin.collections.orEmpty +import kotlin.collections.plus +import kotlin.collections.plusAssign +import kotlin.collections.set +import kotlin.collections.sortedBy +import kotlin.collections.toMutableSet import org.jetbrains.kotlin.konan.file.File as KFile import org.jetbrains.kotlin.utils.ResolvedDependencies as KResolvedDependencies import org.jetbrains.kotlin.utils.ResolvedDependenciesSupport as KResolvedDependenciesSupport @@ -127,7 +160,6 @@ internal fun FileCollection.filterKlibsPassedToCompiler(): FileCollection = filt // endregion abstract class AbstractKotlinNativeCompile< T : KotlinCommonToolOptions, - K : KotlinNativeCompilationData<*>, M : CommonToolArguments > @Inject constructor( @@ -138,7 +170,7 @@ abstract class AbstractKotlinNativeCompile< protected abstract val projectLayout: ProjectLayout @get:Internal - abstract val compilation: K + internal abstract val compilation: KotlinCompilationProjection // region inputs/outputs @get:Input @@ -155,24 +187,30 @@ abstract class AbstractKotlinNativeCompile< @get:Internal protected val konanTarget by project.provider { - compilation.konanTarget + when (val compilation = compilation) { + is KotlinCompilationProjection.KPM -> (compilation.compilationData as KotlinNativeCompilationData<*>).konanTarget + is KotlinCompilationProjection.TCS -> (compilation.compilation as AbstractKotlinNativeCompilation).konanTarget + } } + @get:Classpath - override val libraries: ConfigurableFileCollection = objectFactory.fileCollection().from({ - // Avoid resolving these dependencies during task graph construction when we can't build the target: - if (konanTarget.enabledOnCurrentHost) - objectFactory.fileCollection().from( - compilation.compileDependencyFiles.filterOutPublishableInteropLibs(project) - ) - else objectFactory.fileCollection() - }) + override val libraries: ConfigurableFileCollection = objectFactory.fileCollection().from( + { + // Avoid resolving these dependencies during task graph construction when we can't build the target: + if (konanTarget.enabledOnCurrentHost) + objectFactory.fileCollection().from( + compilation.compileDependencyFiles.filterOutPublishableInteropLibs(project) + ) + else objectFactory.fileCollection() + } + ) @get:Classpath protected val friendModule: FileCollection = project.files({ compilation.friendPaths }) @get:Input - val target: String by project.provider { compilation.konanTarget.name } + val target: String by project.provider { konanTarget.name } // region Compiler options. @Deprecated( @@ -210,7 +248,9 @@ abstract class AbstractKotlinNativeCompile< @Deprecated("Please declare explicit dependency on kotlinx-cli. This option is scheduled to be removed in 1.9.0") @get:Input - val enableEndorsedLibs: Boolean by project.provider { compilation.enableEndorsedLibs } + val enableEndorsedLibs: Boolean by project.provider { + compilation.tcsOrNull?.compilation?.run { this as? KotlinNativeCompilation }?.enableEndorsedLibs ?: false + } @get:Input val kotlinNativeVersion: String @@ -229,8 +269,10 @@ abstract class AbstractKotlinNativeCompile< when { outputKind == FRAMEWORK -> it.asValidFrameworkName() + outputKind in listOf(STATIC, DYNAMIC) || outputKind == PROGRAM && konanTarget == KonanTarget.WASM32 -> it.replace('-', '_') + else -> it } } @@ -286,6 +328,7 @@ abstract class AbstractKotlinNativeCompile< @get:Internal internal val manifestFile: Provider get() = projectLayout.buildDirectory.file("tmp/$name/inputManifest") + } // Remove it once actual K2NativeCompilerArguments will be available without 'kotlin.native.enabled = true' flag @@ -297,14 +340,14 @@ class StubK2NativeCompilerArguments : CommonCompilerArguments() @CacheableTask abstract class KotlinNativeCompile @Inject -constructor( - @Internal +internal constructor( + @get:Internal @Transient // can't be serialized for Gradle configuration cache - final override val compilation: KotlinNativeCompilationData<*>, + final override val compilation: KotlinCompilationProjection, private val objectFactory: ObjectFactory, private val providerFactory: ProviderFactory, private val execOperations: ExecOperations -) : AbstractKotlinNativeCompile, StubK2NativeCompilerArguments>(objectFactory), +) : AbstractKotlinNativeCompile(objectFactory), KotlinCompile, KotlinCompilationTask { @@ -319,9 +362,8 @@ constructor( @get:Internal override val baseName: String by lazy { - if (compilation.isMainCompilationData()) - project.name - else "${project.name}_${compilation.compilationPurpose}" + if (compilation.isMain) project.name + else "${project.name}_${compilation.compilationName}" } // Store as an explicit provider in order to allow Gradle Instant Execution to capture the state @@ -373,7 +415,7 @@ constructor( // endregion. // region Kotlin options. - override val compilerOptions: KotlinCommonCompilerOptions = compilation.compilerOptions.options + override val compilerOptions: CompilerCommonOptions = compilation.compilerOptions.options @Deprecated( message = "Replaced with compilerOptions", @@ -409,11 +451,10 @@ constructor( replaceWith = ReplaceWith("compilerOptions.freeCompilerArgs") ) @get:Input - override val additionalCompilerOptions: Provider> get() = compilerOptions - .freeCompilerArgs - .map { - it + (languageSettings as DefaultLanguageSettingsBuilder).freeCompilerArgs - } + override val additionalCompilerOptions: Provider> + get() = compilerOptions + .freeCompilerArgs + .map { it + (languageSettings as DefaultLanguageSettingsBuilder).freeCompilerArgs } private val runnerSettings = KotlinNativeCompilerRunner.Settings.fromProject(project) private val isAllowCommonizer: Boolean by lazy { project.isAllowCommonizer() } @@ -441,24 +482,26 @@ constructor( ) } + private fun createSharedCompilationDataOrNull(): SharedCompilationData? { + when (compilation) { + is KotlinCompilationProjection.KPM -> if (compilation.compilationData !is KotlinMetadataCompilationData<*>) return null + is KotlinCompilationProjection.TCS -> if (compilation.compilation !is KotlinMetadataCompilation<*>) return null + } + + val manifestFile: File = manifestFile.get().asFile + manifestFile.ensureParentDirsCreated() + val properties = java.util.Properties() + properties[KLIB_PROPERTY_NATIVE_TARGETS] = konanTargetsForManifest + properties.saveToFile(org.jetbrains.kotlin.konan.file.File(manifestFile.toPath())) + + return SharedCompilationData(manifestFile, isAllowCommonizer) + } + @TaskAction fun compile() { val output = outputFile.get() output.parentFile.mkdirs() - var sharedCompilationData: SharedCompilationData? = null - if (compilation is KotlinNativeFragmentMetadataCompilationData) { - val manifestFile: File = manifestFile.get().asFile - manifestFile.ensureParentDirsCreated() - val properties = java.util.Properties() - properties[KLIB_PROPERTY_NATIVE_TARGETS] = konanTargetsForManifest - properties.saveToFile(org.jetbrains.kotlin.konan.file.File(manifestFile.toPath())) - - sharedCompilationData = SharedCompilationData( - manifestFile, - isAllowCommonizer - ) - } val plugins = listOfNotNull( compilerPluginClasspath?.let { CompilerPluginData(it, compilerPluginOptions) }, @@ -478,7 +521,7 @@ constructor( moduleName, shortModuleName, friendModule, - sharedCompilationData, + createSharedCompilationDataOrNull(), sources.asFileTree, commonSourcesTree ) @@ -681,12 +724,13 @@ internal class CacheBuilder( val toolOptions: KotlinCommonCompilerToolOptions, val externalDependenciesArgs: List ) { - val rootCacheDirectory get() = getRootCacheDirectory( - File(runnerSettings.parent.konanHome), - konanTarget, - binary.debuggable, - konanCacheKind - ) + val rootCacheDirectory + get() = getRootCacheDirectory( + File(runnerSettings.parent.konanHome), + konanTarget, + binary.debuggable, + konanCacheKind + ) companion object { fun createWithProject( @@ -939,36 +983,54 @@ internal class CacheBuilder( } @CacheableTask -open class CInteropProcess -@Inject constructor( +open class CInteropProcess @Inject internal constructor(params: Params) : DefaultTask() { + + internal class Params( + val settings: DefaultCInteropSettings, + val targetName: String, + val compilationName: String, + val konanTarget: KonanTarget, + val baseKlibName: String, + val services: Services + ) { + internal open class Services @Inject constructor( + val objectFactory: ObjectFactory, + val execOperations: ExecOperations + ) + } + + private val objectFactory: ObjectFactory = params.services.objectFactory + + private val execOperations: ExecOperations = params.services.execOperations + + @get:Internal + internal val targetName: String = params.targetName + + @get:Internal + internal val compilationName: String = params.compilationName + @Internal - val settings: DefaultCInteropSettings, - private val objectFactory: ObjectFactory, - private val execOperations: ExecOperations -) : DefaultTask() { + val settings: DefaultCInteropSettings = params.settings @Internal // Taken into account in the outputFileProvider property lateinit var destinationDir: Provider @get:Input - val konanTarget: KonanTarget = settings.compilation.konanTarget + val konanTarget: KonanTarget = params.konanTarget @get:Input val konanVersion: CompilerVersion = project.konanVersion + @Suppress("unused") @get:Input - val interopName: String = settings.name + val interopName: String = params.settings.name @get:Input - val baseKlibName: String = run { - val compilationPrefix = settings.compilation.let { - if (it.isMainCompilationData()) project.name else it.compilationPurpose - } - "$compilationPrefix-cinterop-$interopName" - } + val baseKlibName: String = params.baseKlibName + @get:Internal - val outputFileName: String = with(CompilerOutputKind.LIBRARY) { + val outputFileName: String = with(LIBRARY) { "$baseKlibName${suffix(konanTarget)}" } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index afdc2e4073e..4f348930002 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -533,7 +533,7 @@ internal inline val T.thisTaskProvider: TaskProvider @CacheableTask abstract class KotlinCompile @Inject constructor( - override val compilerOptions: KotlinJvmCompilerOptions, + final override val compilerOptions: CompilerJvmOptions, workerExecutor: WorkerExecutor, objectFactory: ObjectFactory ) : AbstractKotlinCompile(objectFactory, workerExecutor), diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt index 5695bf991d7..1f27d953e7a 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt @@ -76,9 +76,8 @@ internal open class BaseKotlinCompileConfig : AbstractKotl task.associatedJavaCompileTaskSources.from(javaTaskProvider.map { it.source }) task.associatedJavaCompileTaskName.value(javaTaskProvider.name) } - task.ownModuleName.value( - (compilationProjection.compilerOptions.options as CompilerJvmOptions).moduleName.convention(compilationProjection.ownModuleName) - ) + + task.ownModuleName.value(compilationProjection.ownModuleName) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/MultiplatformExtensionTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/MultiplatformExtensionTest.kt index a0afef98130..77d3edf8af9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/MultiplatformExtensionTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/MultiplatformExtensionTest.kt @@ -13,6 +13,7 @@ import org.gradle.api.internal.project.ProjectInternal import org.gradle.api.plugins.ExtraPropertiesExtension import org.gradle.testfixtures.ProjectBuilder import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_CINTEROP_COMMONIZATION @@ -20,7 +21,6 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLI import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_STDLIB_DEFAULT_DEPENDENCY import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerDependent import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropIdentifier import org.jetbrains.kotlin.gradle.targets.native.internal.from @@ -78,7 +78,7 @@ abstract class MultiplatformExtensionTest { return compilations.getByName("test").cinteropIdentifier(name) } - internal fun KotlinCompilationData<*>.cinteropIdentifier(name: String): CInteropIdentifier { + internal fun KotlinCompilation<*>.cinteropIdentifier(name: String): CInteropIdentifier { return CInteropIdentifier(CInteropIdentifier.Scope.create(this), name) } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/mpp/CompilationSpecificPluginPath.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/mpp/CompilationSpecificPluginPath.kt index d78afbcf0ac..298470ace81 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/mpp/CompilationSpecificPluginPath.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/mpp/CompilationSpecificPluginPath.kt @@ -14,7 +14,9 @@ import org.jetbrains.kotlin.gradle.buildProject import org.jetbrains.kotlin.gradle.buildProjectWithMPP import org.jetbrains.kotlin.gradle.kotlin import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.tasks.* +import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile +import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinNativeCompile +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import kotlin.test.* internal class CompilationSpecificPluginPath { @@ -292,7 +294,7 @@ internal class CompilationSpecificPluginPath { .getByName(taskName) .let { when (it) { - is AbstractKotlinNativeCompile<*, *, *> -> it.compilerPluginClasspath + is AbstractKotlinNativeCompile<*, *> -> it.compilerPluginClasspath is AbstractKotlinCompile<*> -> it.pluginClasspath.from.single() else -> error("Unexpected task type with name $taskName. Is it kotlin compile task?") } diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/mpp/KpmCompilerPluginTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/mpp/KpmCompilerPluginTest.kt index 0cd43f02f6d..fd9758fa1fd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/mpp/KpmCompilerPluginTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/mpp/KpmCompilerPluginTest.kt @@ -17,7 +17,10 @@ import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinNativeCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerPluginData import org.jetbrains.kotlin.project.model.* -import kotlin.test.* +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue class KpmCompilerPluginTest { @Test @@ -146,7 +149,7 @@ class KpmCompilerPluginTest { .let { when (it) { is AbstractKotlinCompile<*> -> it.kotlinPluginData - is AbstractKotlinNativeCompile<*, *, *> -> it.kotlinPluginData + is AbstractKotlinNativeCompile<*, *> -> it.kotlinPluginData else -> error("Unknown task type: $it") } } diff --git a/libraries/tools/kotlin-tooling-core/src/main/kotlin/org/jetbrains/kotlin/tooling/core/ExtrasUtils.kt b/libraries/tools/kotlin-tooling-core/src/main/kotlin/org/jetbrains/kotlin/tooling/core/ExtrasUtils.kt index 178d9c98b55..71cbc157144 100644 --- a/libraries/tools/kotlin-tooling-core/src/main/kotlin/org/jetbrains/kotlin/tooling/core/ExtrasUtils.kt +++ b/libraries/tools/kotlin-tooling-core/src/main/kotlin/org/jetbrains/kotlin/tooling/core/ExtrasUtils.kt @@ -54,3 +54,6 @@ operator fun Extras.plus(entry: Extras.Entry<*>): Extras = ImmutableExtrasImpl(t operator fun Extras.plus(entries: Iterable>): Extras = ImmutableExtrasImpl(this.entries + entries) +inline fun MutableExtras.getOrPut(key: Extras.Key, defaultValue: () -> T): T { + return this[key] ?: defaultValue().also { this[key] = it } +} \ No newline at end of file