From 3be2734c639a5873436d6b63bdc5469bafaffb3f Mon Sep 17 00:00:00 2001 From: Sergey Igushkin Date: Mon, 22 Mar 2021 19:21:04 +0300 Subject: [PATCH] Refactor the setup of compilation in the PM20 implementation prototype --- .../gradle/plugin/mpp/kotlinCompilations.kt | 15 +- .../plugin/mpp/pm20/KotlinJvmVariant.kt | 1 + .../plugin/mpp/pm20/KotlinNativeVariant.kt | 10 +- .../mpp/pm20/KotlinNativeVariantFactory.kt | 34 +-- .../plugin/mpp/pm20/VariantSourcesProvider.kt | 42 +++ .../plugin/mpp/pm20/abstractVariants.kt | 2 + .../mpp/pm20/fragmentsMetadataCompilation.kt | 4 +- .../gradle/plugin/mpp/pm20/modelClasses.kt | 33 +-- .../KotlinMetadataTargetConfigurator.kt | 2 +- .../targets/native/KotlinNativeTarget.kt | 2 +- .../native/KotlinNativeTargetConfigurator.kt | 249 +++++++++--------- 11 files changed, 209 insertions(+), 185 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/VariantSourcesProvider.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt index 6d4a407c416..e504e3d8679 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/kotlinCompilations.kt @@ -112,9 +112,8 @@ abstract class AbstractKotlinCompilation( project, compileKotlinTaskName, sourceSet.customSourceFilesExtensions, - { sourceSet.kotlin }, addAsCommonSources - ) + ) { sourceSet.kotlin } internal fun addExactSourceSetsEagerly(sourceSets: Set) { with(target.project) { @@ -307,12 +306,20 @@ abstract class AbstractKotlinCompilation( get() = ownModuleName() } +internal fun addCommonSourcesToKotlinCompileTask( + project: Project, + taskName: String, + sourceFileExtensions: Iterable, + sources: () -> Iterable +) = addSourcesToKotlinCompileTask(project, taskName, sourceFileExtensions, lazyOf(true), sources) + +// FIXME this function dangerously ignores an incorrect type of the task (e.g. if the actual task is a K/N one); consider reporting a failure internal fun addSourcesToKotlinCompileTask( project: Project, taskName: String, sourceFileExtensions: Iterable, - sources: () -> Iterable, - addAsCommonSources: Lazy + addAsCommonSources: Lazy = lazyOf(false), + sources: () -> Iterable ) { fun AbstractKotlinCompile<*>.configureAction() { source(project.files(Callable { sources() })) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariant.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariant.kt index 9b776094eb0..eb3128092be 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariant.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinJvmVariant.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.filterModuleName open class KotlinJvmVariant(containingModule: KotlinGradleModule, fragmentName: String) : KotlinGradlePublishedVariantWithRuntime(containingModule, fragmentName) { + override val compilationData: KotlinJvmVariantCompilationData by lazy { KotlinJvmVariantCompilationData(this) } override val platformType: KotlinPlatformType get() = KotlinPlatformType.jvm diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinNativeVariant.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinNativeVariant.kt index 9eb56346d28..88dda8c4718 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinNativeVariant.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinNativeVariant.kt @@ -5,15 +5,17 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 +import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultCInteropSettings import org.jetbrains.kotlin.gradle.plugin.mpp.NativeCompileOptions +import org.jetbrains.kotlin.gradle.plugin.mpp.isHostSpecificKonanTargetsSet import org.jetbrains.kotlin.gradle.plugin.mpp.publishedConfigurationName import org.jetbrains.kotlin.konan.target.KonanTarget import javax.inject.Inject -open class KotlinNativeVariantInternal( +abstract class KotlinNativeVariantInternal( containingModule: KotlinGradleModule, fragmentName: String, val konanTarget: KonanTarget @@ -33,7 +35,7 @@ open class KotlinNativeVariantInternal( DefaultCInteropSettings(project, cinteropName, compilationData) } - internal val compilationData by lazy { KotlinNativeVariantCompilationData(this) } + override val compilationData by lazy { KotlinNativeVariantCompilationData(this) } } internal val KotlinNativeVariantInternal.includesHostSpecificMetadata: Boolean @@ -55,10 +57,6 @@ open class KotlinIosX64Variant @Inject constructor(containingModule: KotlinGradl open class KotlinIosArm64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) : KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.IOS_ARM64) - -internal val KotlinNativeVariant.hostSpecificMetadataConfigurationName - get() = disambiguateName("MetadataElements") - interface KotlinNativeCompilationData : KotlinCompilationData { val konanTarget: KonanTarget val enableEndorsedLibs: Boolean diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinNativeVariantFactory.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinNativeVariantFactory.kt index 76ab8247090..1c2f5dfcfd6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinNativeVariantFactory.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/KotlinNativeVariantFactory.kt @@ -7,30 +7,18 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Dependency -import org.gradle.api.artifacts.ModuleDependency import org.gradle.api.attributes.Usage -import org.gradle.api.component.AdhocComponentWithVariants -import org.gradle.api.component.SoftwareComponentFactory -import org.gradle.api.internal.project.ProjectInternal -import org.gradle.api.publish.PublishingExtension -import org.gradle.api.publish.maven.MavenPublication -import org.gradle.api.publish.maven.internal.publication.DefaultMavenPublication import org.gradle.jvm.tasks.Jar import org.jetbrains.kotlin.gradle.dsl.pm20Extension import org.jetbrains.kotlin.gradle.plugin.KotlinNativeTargetConfigurator import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages -import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.CalculatedCapability -import org.jetbrains.kotlin.gradle.plugin.mpp.publishedConfigurationName import org.jetbrains.kotlin.gradle.plugin.usageByName import org.jetbrains.kotlin.gradle.targets.metadata.filesWithUnpackedArchives import org.jetbrains.kotlin.gradle.tasks.registerTask -import org.jetbrains.kotlin.gradle.utils.dashSeparatedName import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION import org.jetbrains.kotlin.project.model.refinesClosure -import org.jetbrains.kotlin.project.model.utils.variantsContainingFragment -import java.util.concurrent.Callable import kotlin.reflect.KClass open class KotlinNativeVariantFactory( @@ -55,25 +43,13 @@ open class KotlinNativeVariantFactory( override fun configureKotlinCompilation(fragment: T) { val compilationData = fragment.compilationData + LifecycleTasksManager(project).registerClassesTask(compilationData) - //FIXME: deduplicate with KotlinJvmVariantFactory - val classesTaskName = compilationData.compileAllTaskName - project.tasks.register(classesTaskName) { classesTask -> - classesTask.dependsOn(fragment.compilationOutputs.allOutputs) - } + val compileTask = KotlinNativeTargetConfigurator.createKlibCompilationTask(compilationData) - //FIXME: needs refactoring so as not to create the configurator - val compileTask = with(KotlinNativeTargetConfigurator(project.getKotlinPluginVersion()!!)) { - project.createKlibCompilationTask(compilationData) - } - - // FIXME: duplication with KotlinJvmVariantFactory - val allSources = { project.files(Callable { fragment.refinesClosure.map { it.kotlinSourceRoots } }) } - val commonSources = { - project.files(Callable { - fragment.refinesClosure.filter { module.variantsContainingFragment(it).count() > 1 }.map { it.kotlinSourceRoots } - }) - } + val sources = VariantSourcesProvider() + val allSources = sources.getSourcesFromRefinesClosure(fragment) + val commonSources = sources.getSourcesFromRefinesClosure(fragment) compileTask.configure { it.source(allSources) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/VariantSourcesProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/VariantSourcesProvider.kt new file mode 100644 index 00000000000..3c69b133387 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/VariantSourcesProvider.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 + +import org.gradle.api.Project +import org.gradle.api.file.FileCollection +import org.gradle.language.base.plugins.LifecycleBasePlugin +import org.jetbrains.kotlin.project.model.refinesClosure +import org.jetbrains.kotlin.project.model.utils.variantsContainingFragment + +open class VariantSourcesProvider { + open fun getSourcesFromRefinesClosure(variant: KotlinGradleVariant): FileCollection { + val project = variant.containingModule.project + return project.files(project.provider { + variant.refinesClosure.map { it.kotlinSourceRoots } + }) + } + + open fun getCommonSourcesFromRefinesClosure(variant: KotlinGradleVariant): FileCollection { + val containingModule = variant.containingModule + val project = containingModule.project + return project.files(project.provider { + variant.refinesClosure.filter { + // Every fragment refined by some other fragment should be considered common, even if it is included in just one variant + containingModule.variantsContainingFragment(it).toSet() != setOf(it) + }.map { it.kotlinSourceRoots } + }) + } +} + +open class LifecycleTasksManager(private val project: Project) { + open fun registerClassesTask(compilationData: KotlinCompilationData<*>) = with(project) { + val classesTaskName = compilationData.compileAllTaskName + val classesTask = project.tasks.register(classesTaskName) { classesTask -> + classesTask.dependsOn(compilationData.output.allOutputs) + } + project.tasks.named(LifecycleBasePlugin.BUILD_TASK_NAME).configure { it.dependsOn(classesTask) } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariants.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariants.kt index bf53c119a9f..195cd73e735 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariants.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/abstractVariants.kt @@ -39,6 +39,8 @@ abstract class KotlinGradleVariantInternal( override lateinit var compileDependencyFiles: FileCollection + internal abstract val compilationData: KotlinVariantCompilationDataInternal<*> + // TODO rewrite using our own artifacts API? override val compilationOutputs: KotlinCompilationOutput = DefaultKotlinCompilationOutput( diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentsMetadataCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentsMetadataCompilation.kt index b155fb50246..c518e23e0b3 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentsMetadataCompilation.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/fragmentsMetadataCompilation.kt @@ -202,8 +202,8 @@ private fun addSourcesToMetadataCompileTask(compilationData: AbstractKotlinFragm compilationData.project, compilationData.compileKotlinTaskName, /*FIXME*/ emptyList(), - sources, - lazyOf(true) + lazyOf(true), + sources ) is KotlinNativeFragmentMetadataCompilationData -> addSourcesToKotlinNativeCompileTask( compilationData.project, diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/modelClasses.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/modelClasses.kt index 0896df4deb9..3e94ebe9e5d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/modelClasses.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/pm20/modelClasses.kt @@ -7,15 +7,14 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20 import org.gradle.api.tasks.TaskProvider import org.gradle.jvm.tasks.Jar +import org.gradle.language.base.plugins.LifecycleBasePlugin import org.jetbrains.kotlin.gradle.plugin.Kotlin2JvmSourceSetProcessor import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion +import org.jetbrains.kotlin.gradle.plugin.mpp.addCommonSourcesToKotlinCompileTask import org.jetbrains.kotlin.gradle.plugin.mpp.addSourcesToKotlinCompileTask import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask import org.jetbrains.kotlin.gradle.utils.dashSeparatedName -import org.jetbrains.kotlin.project.model.refinesClosure -import org.jetbrains.kotlin.project.model.utils.variantsContainingFragment -import java.util.concurrent.Callable open class KotlinJvmVariantFactory(module: KotlinGradleModule) : AbstractKotlinGradleRuntimePublishedVariantFactory(module) { @@ -38,30 +37,18 @@ open class KotlinJvmVariantFactory(module: KotlinGradleModule) : } override fun configureKotlinCompilation(fragment: KotlinJvmVariant) { - val compilationData = KotlinJvmVariantCompilationData(fragment) - - val classesTaskName = compilationData.compileAllTaskName - project.tasks.register(classesTaskName) { classesTask -> - classesTask.dependsOn(fragment.compilationOutputs.allOutputs) - } + val compilationData = fragment.compilationData + LifecycleTasksManager(project).registerClassesTask(compilationData) Kotlin2JvmSourceSetProcessor(KotlinTasksProvider(), compilationData, project.getKotlinPluginVersion() ?: "unknown"/*TODO*/).run() - val allSources = { project.files(Callable { fragment.refinesClosure.map { it.kotlinSourceRoots } }) } - val commonSources = { - project.files(Callable { - fragment.refinesClosure.filter { module.variantsContainingFragment(it).count() > 1 }.map { it.kotlinSourceRoots } - }) - } + val sources = VariantSourcesProvider() + val allSources = sources.getSourcesFromRefinesClosure(fragment) + val commonSources = sources.getCommonSourcesFromRefinesClosure(fragment) - addSourcesToKotlinCompileTask( - project, compilationData.compileKotlinTaskName, /*FIXME*/ emptyList(), allSources, - addAsCommonSources = lazyOf(false) - ) - addSourcesToKotlinCompileTask( - project, compilationData.compileKotlinTaskName, /*FIXME*/ emptyList(), commonSources, - addAsCommonSources = lazyOf(true) - ) + // FIXME support custom source file extensions in the two calls below + addSourcesToKotlinCompileTask(project, compilationData.compileKotlinTaskName, emptyList()) { allSources } + addCommonSourcesToKotlinCompileTask(project, compilationData.compileKotlinTaskName, emptyList()) { commonSources } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt index 5defce6ca75..cd887cefab7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/metadata/KotlinMetadataTargetConfigurator.kt @@ -483,7 +483,7 @@ internal class NativeSharedCompilationProcessor( override val kotlinTask: TaskProvider = with(nativeTargetConfigurator) { - project.createKlibCompilationTask(kotlinCompilation) + KotlinNativeTargetConfigurator.createKlibCompilationTask(kotlinCompilation) } override fun run() = Unit diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTarget.kt index c6a0e3f0f13..fa0ac3dffec 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTarget.kt @@ -139,7 +139,7 @@ open class KotlinNativeTarget @Inject constructor( private val hostManager by lazy { HostManager() } -private fun isHostSpecificKonanTargetsSet(konanTargets: Iterable): Boolean { +internal fun isHostSpecificKonanTargetsSet(konanTargets: Iterable): Boolean { val enabledByHost = hostManager.enabledByHost val allHosts = enabledByHost.keys fun canBeBuiltOnHosts(konanTarget: KonanTarget) = enabledByHost.filterValues { konanTarget in it }.keys diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt index c74357e27b0..8961e4e7909 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetConfigurator.kt @@ -52,87 +52,18 @@ open class KotlinNativeTargetConfigurator( createDefaultSourceSets = true, createTestCompilation = true ) { - private fun Project.klibOutputDirectory( - compilation: KotlinCompilationData<*> - ): File { - val targetSubDirectory = compilation.compilationClassifier?.let { "$it/" }.orEmpty() - return buildDir.resolve("classes/kotlin/$targetSubDirectory${compilation.compilationPurpose}") - } - private fun addCompilerPlugins(compilation: AbstractKotlinNativeCompilation) { - val project = compilation.target.project - - project.whenEvaluated { - SubpluginEnvironment - .loadSubplugins(project, kotlinPluginVersion) - .addSubpluginOptions(project, compilation) - - compilation.compileKotlinTaskProvider.configure { - it.compilerPluginClasspath = project - .configurations - .getByName(compilation.pluginConfigurationName) - } - } - } - - private val KotlinNativeCompilationData<*>.apiElementsConfigurationName: String - get() = when (val dataOwner = owner) { - is KotlinGradleVariant -> dataOwner.apiElementsConfigurationName - is KotlinTarget -> dataOwner.apiElementsConfigurationName - else -> error("unexpected owner of $this") - } - - internal fun Project.createRegularKlibArtifact( - compilation: KotlinNativeCompilationData<*>, - compileTask: TaskProvider - ) = createKlibArtifact(compilation, compileTask.map { it.outputFile.get() }, null, compileTask) - - internal fun Project.createCInteropKlibArtifact( + private fun createCInteropKlibArtifact( interop: DefaultCInteropSettings, interopTask: TaskProvider - ) = createKlibArtifact(interop.compilation, interopTask.map { it.outputFile }, "cinterop-${interop.name}", interopTask, copy = true) + ) = createKlibArtifact( + interop.compilation, + interopTask.map { it.outputFile }, + "cinterop-${interop.name}", + interopTask, + copy = true + ) - private fun Project.createKlibArtifact( - compilation: KotlinNativeCompilationData<*>, - artifactFile: Provider, - classifier: String?, - producingTask: TaskProvider<*>, - copy: Boolean = false - ) { - if (!compilation.konanTarget.enabledOnCurrentHost) { - return - } - - val apiElements = configurations.getByName(compilation.apiElementsConfigurationName) - - val realProducingTask: TaskProvider<*> - // TODO: Someone remove this HACK PLEASE! - val realArtifactFile = if (copy) { - realProducingTask = project.registerTask("copy${producingTask.name.capitalize()}") { - val targetSubDirectory = compilation.compilationClassifier?.let { "$it/" }.orEmpty() - it.destinationDir = project.buildDir.resolve("libs/$targetSubDirectory${compilation.compilationPurpose}") - it.from(artifactFile) - it.dependsOn(producingTask) - } - realProducingTask.map { (it as Copy).destinationDir.resolve(artifactFile.get().name) } - } else { - realProducingTask = producingTask - artifactFile - } - - with(apiElements) { - val klibArtifact = project.artifacts.add(apiElements.name, realArtifactFile) { artifact -> - artifact.name = compilation.compilationPurpose - artifact.extension = "klib" - artifact.type = "klib" - artifact.classifier = classifier - artifact.builtBy(realProducingTask) - } - project.extensions.getByType(DefaultArtifactPublicationSet::class.java).addCandidate(klibArtifact) - artifacts.add(klibArtifact) - attributes.attribute(ArtifactAttributes.ARTIFACT_FORMAT, NativeArtifactFormat.KLIB) - } - } // region Task creation. private fun Project.createLinkTask(binary: NativeBinary) { val result = registerTask( @@ -264,45 +195,6 @@ open class KotlinNativeTargetConfigurator( } } - internal fun Project.createKlibCompilationTask(compilation: KotlinNativeCompilationData<*>): TaskProvider { - val compileTaskProvider = registerTask( - compilation.compileKotlinTaskName, listOf(compilation) - ) { - 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.destinationDir = klibOutputDirectory(compilation).resolve("klib") - } - - - compilation.output.addClassesDir { - project.files(compileTaskProvider.map { it.outputFile }) - } - - project.tasks.getByName(compilation.compileAllTaskName).dependsOn(compileTaskProvider) - - if (compilation.isMainCompilationData()) { - if (compilation is KotlinNativeCompilation) { - project.tasks.getByName(compilation.target.artifactsTaskName).apply { - dependsOn(compileTaskProvider) - } - } - - project.tasks.getByName(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).apply { - dependsOn(compileTaskProvider) - } - createRegularKlibArtifact(compilation, compileTaskProvider) - } - if (compilation is AbstractKotlinNativeCompilation) { - // FIXME: support compiler plugins for PM20 - addCompilerPlugins(compilation) - } - - return compileTaskProvider - } - // FIXME support creating interop tasks for PM20 private fun Project.createCInteropTasks( compilation: KotlinNativeCompilation, @@ -363,9 +255,7 @@ open class KotlinNativeTargetConfigurator( override fun configureArchivesAndComponent(target: T): Unit = with(target.project) { registerTask(target.artifactsTaskName) { } - target.compilations.all { - createKlibCompilationTask(it) - } + target.compilations.all { createKlibCompilationTask(it) } val apiElements = configurations.getByName(target.apiElementsConfigurationName) @@ -551,6 +441,127 @@ open class KotlinNativeTargetConfigurator( description = "Dependencies for cinterop '${cinterop.name}' (compilation '${compilation.name}')." } } + + internal fun createKlibCompilationTask( + compilation: KotlinNativeCompilationData<*> + ): TaskProvider { + val project = compilation.project + val compileTaskProvider = project.registerTask( + compilation.compileKotlinTaskName, + listOf(compilation) + ) { + 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.destinationDir = project.klibOutputDirectory(compilation).resolve("klib") + } + + + compilation.output.addClassesDir { + project.project.files(compileTaskProvider.map { it.outputFile }) + } + + project.project.tasks.getByName(compilation.compileAllTaskName).dependsOn(compileTaskProvider) + + if (compilation.isMainCompilationData()) { + if (compilation is KotlinNativeCompilation) { + project.project.tasks.getByName(compilation.target.artifactsTaskName).apply { + dependsOn(compileTaskProvider) + } + } + + project.project.tasks.getByName(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).apply { + dependsOn(compileTaskProvider) + } + createRegularKlibArtifact(compilation, compileTaskProvider) + } + if (compilation is AbstractKotlinNativeCompilation) { + // FIXME: support compiler plugins for PM20 + addCompilerPlugins(compilation) + } + + return compileTaskProvider + } + + private fun Project.klibOutputDirectory( + compilation: KotlinCompilationData<*> + ): File { + val targetSubDirectory = compilation.compilationClassifier?.let { "$it/" }.orEmpty() + return buildDir.resolve("classes/kotlin/$targetSubDirectory${compilation.compilationPurpose}") + } + + private fun addCompilerPlugins(compilation: AbstractKotlinNativeCompilation) { + val project = compilation.target.project + + project.whenEvaluated { + SubpluginEnvironment + .loadSubplugins(project, project.getKotlinPluginVersion() ?: "unspecified" /* TODO */) + .addSubpluginOptions(project, compilation) + + compilation.compileKotlinTaskProvider.configure { + it.compilerPluginClasspath = project + .configurations + .getByName(compilation.pluginConfigurationName) + } + } + } + + internal fun createRegularKlibArtifact( + compilation: KotlinNativeCompilationData<*>, + compileTask: TaskProvider + ) = createKlibArtifact(compilation, compileTask.map { it.outputFile.get() }, null, compileTask) + + private fun createKlibArtifact( + compilation: KotlinNativeCompilationData<*>, + artifactFile: Provider, + classifier: String?, + producingTask: TaskProvider<*>, + copy: Boolean = false + ) { + val project = compilation.project + if (!compilation.konanTarget.enabledOnCurrentHost) { + return + } + + val apiElements = project.configurations.getByName(compilation.apiElementsConfigurationName) + + 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}") + it.from(artifactFile) + it.dependsOn(producingTask) + } + realProducingTask.map { (it as Copy).destinationDir.resolve(artifactFile.get().name) } + } else { + realProducingTask = producingTask + artifactFile + } + + with(apiElements) { + val klibArtifact = project.project.artifacts.add(apiElements.name, realArtifactFile) { artifact -> + artifact.name = compilation.compilationPurpose + artifact.extension = "klib" + artifact.type = "klib" + artifact.classifier = classifier + artifact.builtBy(realProducingTask) + } + project.project.extensions.getByType(DefaultArtifactPublicationSet::class.java).addCandidate(klibArtifact) + artifacts.add(klibArtifact) + attributes.attribute(ArtifactAttributes.ARTIFACT_FORMAT, NativeArtifactFormat.KLIB) + } + } + + private val KotlinNativeCompilationData<*>.apiElementsConfigurationName: String + get() = when (val dataOwner = owner) { + is KotlinGradleVariant -> dataOwner.apiElementsConfigurationName + is KotlinTarget -> dataOwner.apiElementsConfigurationName + else -> error("unexpected owner of $this") + } } }