From 261934d881d6474602b67f42404795373ec09238 Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Wed, 10 Mar 2021 16:56:08 +0100 Subject: [PATCH] Implement CopyCommonizeCInteropForIdeTask to survive build folder cleaning --- .../gradle/CInteropCommonizerTaskTest.kt | 12 ++--- .../KotlinMetadataTargetConfigurator.kt | 12 +++-- .../AbstractCInteropCommonizerTask.kt | 44 +++++++++++++++++++ .../native/internal/CInteropCommonizerTask.kt | 28 ++---------- .../native/internal/CommonizerTasks.kt | 17 +++++++ ...yCInteropCommonizerTaskOutputForIdeTask.kt | 42 ++++++++++++++++++ 6 files changed, 121 insertions(+), 34 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/AbstractCInteropCommonizerTask.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CopyCInteropCommonizerTaskOutputForIdeTask.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/CInteropCommonizerTaskTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/CInteropCommonizerTaskTest.kt index c75b13ffcfb..3391fee3a13 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/CInteropCommonizerTaskTest.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/CInteropCommonizerTaskTest.kt @@ -61,7 +61,7 @@ class CInteropCommonizerTaskTest { CInteropCommonizationParameters( CommonizerTarget(LINUX_X64, MACOS_X64), setOf(linuxInterop.identifier, macosInterop.identifier) ), - task.findSupportingCommonizationParameters(nativeMainCompilation) + task.getCommonizationParameters(nativeMainCompilation) ) } @@ -85,7 +85,7 @@ class CInteropCommonizerTaskTest { .single { it.defaultSourceSet == nativeMain } assertNull( - task.findSupportingCommonizationParameters(nativeMainCompilation), + task.getCommonizationParameters(nativeMainCompilation), "Expected no CInteropCommonizerTarget from nativeMain, since one target has not defined any cinterop" ) } @@ -119,19 +119,19 @@ class CInteropCommonizerTaskTest { CInteropCommonizationParameters( SharedCommonizerTarget(CommonizerTarget(IOS_X64, IOS_ARM64), CommonizerTarget(MACOS_X64), CommonizerTarget(LINUX_X64)), setOf(linuxInterop, macosInterop, iosX64Interop, iosArm64Interop) - ), task.findSupportingCommonizationParameters(sharedNativeCompilation(nativeMain)) + ), task.getCommonizationParameters(sharedNativeCompilation(nativeMain)) ) assertEquals( CInteropCommonizationParameters( SharedCommonizerTarget(CommonizerTarget(IOS_X64, IOS_ARM64), CommonizerTarget(MACOS_X64), CommonizerTarget(LINUX_X64)), setOf(linuxInterop, macosInterop, iosX64Interop, iosArm64Interop) - ), task.findSupportingCommonizationParameters(sharedNativeCompilation(iosMain)) + ), task.getCommonizationParameters(sharedNativeCompilation(iosMain)) ) assertTrue( - task.findSupportingCommonizationParameters(sharedNativeCompilation(iosMain))!! in - task.findSupportingCommonizationParameters(sharedNativeCompilation(nativeMain))!!, + task.getCommonizationParameters(sharedNativeCompilation(iosMain))!! in + task.getCommonizationParameters(sharedNativeCompilation(nativeMain))!!, "Expected CInteropCommonizerTarget of iosMain to be fully contained in nativeMain" ) } 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 65ced4fda5c..a708449d0de 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 @@ -24,6 +24,8 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.CompilationSourceSetUtil.compilati import org.jetbrains.kotlin.gradle.plugin.sources.* import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService import org.jetbrains.kotlin.gradle.targets.native.internal.commonizeCInteropTask +import org.jetbrains.kotlin.gradle.targets.native.internal.copyCommonizeCInteropForIdeTask +import org.jetbrains.kotlin.gradle.targets.native.internal.getLibraries import org.jetbrains.kotlin.gradle.tasks.* import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName @@ -322,11 +324,13 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) : } if (this is KotlinSharedNativeCompilation) { - project.commonizeCInteropTask?.let { commonizeCInteropTask -> - val commonizerOutput = project.files(commonizeCInteropTask.map { it.getLibraries(this) }) - compileDependencyFiles = compileDependencyFiles.plus(commonizerOutput) + project.commonizeCInteropTask?.let { task -> + compileDependencyFiles = compileDependencyFiles.plus(task.getLibraries(this)) + } + project.copyCommonizeCInteropForIdeTask?.let { task -> + val libraries = task.getLibraries(this) kotlinSourceSetsIncludingDefault.forEach { sourceSet -> - project.dependencies.add(sourceSet.implementationMetadataConfigurationName, commonizerOutput) + project.dependencies.add(sourceSet.implementationMetadataConfigurationName, libraries) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/AbstractCInteropCommonizerTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/AbstractCInteropCommonizerTask.kt new file mode 100644 index 00000000000..a591865aa6d --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/AbstractCInteropCommonizerTask.kt @@ -0,0 +1,44 @@ +/* + * 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.targets.native.internal + +import org.gradle.api.DefaultTask +import org.gradle.api.file.FileCollection +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskProvider +import org.jetbrains.kotlin.descriptors.commonizer.HierarchicalCommonizerOutputLayout +import org.jetbrains.kotlin.descriptors.commonizer.prettyName +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation +import java.io.File + +internal abstract class AbstractCInteropCommonizerTask : DefaultTask() { + @get:OutputDirectory + abstract val outputDirectory: File + + internal fun outputDirectory(parameters: CInteropCommonizationParameters): File { + return outputDirectory + .resolve(parameters.commonizerTarget.prettyName) + .resolve(parameters.interops.map { it.interopName }.distinct().joinToString("-")) + } + + internal abstract fun getCommonizationParameters(compilation: KotlinSharedNativeCompilation): CInteropCommonizationParameters? + + internal fun getLibraries(compilation: KotlinSharedNativeCompilation): FileCollection { + val fileProvider = project.provider> { + val parameters = getCommonizationParameters(compilation) ?: return@provider emptySet() + HierarchicalCommonizerOutputLayout.getTargetDirectory(outputDirectory(parameters), parameters.commonizerTarget) + .listFiles().orEmpty().toSet() + } + + return project.files(fileProvider) { fileCollection -> + fileCollection.builtBy(this) + } + } +} + +internal fun TaskProvider.getLibraries(compilation: KotlinSharedNativeCompilation): FileCollection { + return compilation.target.project.files(map { it.getLibraries(compilation) }) +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerTask.kt index b6df11ec542..a9065f1d237 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropCommonizerTask.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.gradle.targets.native.internal -import org.gradle.api.DefaultTask import org.gradle.api.Project import org.gradle.api.file.FileCollection import org.gradle.api.provider.Provider @@ -14,9 +13,7 @@ import org.gradle.workers.WorkParameters import org.jetbrains.kotlin.compilerRunner.GradleCliCommonizer import org.jetbrains.kotlin.compilerRunner.konanHome import org.jetbrains.kotlin.descriptors.commonizer.CommonizerTarget -import org.jetbrains.kotlin.descriptors.commonizer.HierarchicalCommonizerOutputLayout import org.jetbrains.kotlin.descriptors.commonizer.SharedCommonizerTarget -import org.jetbrains.kotlin.descriptors.commonizer.prettyName import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull import org.jetbrains.kotlin.gradle.plugin.CInteropSettings import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation @@ -31,7 +28,7 @@ import org.jetbrains.kotlin.gradle.tasks.CInteropProcess import org.jetbrains.kotlin.konan.target.KonanTarget import java.io.File -internal open class CInteropCommonizerTask : DefaultTask() { +internal open class CInteropCommonizerTask : AbstractCInteropCommonizerTask() { internal data class CInteropGist( @get:Input val identifier: CInteropIdentifier, @@ -45,6 +42,8 @@ internal open class CInteropCommonizerTask : DefaultTask() { val allSourceSetNames: Provider> = sourceSets.map { it.resolveAllDependsOnSourceSets().map(Any::toString) } } + override val outputDirectory: File = project.buildDir.resolve("classes/kotlin/commonizer") + @get:Nested internal var cinterops = setOf() private set @@ -98,25 +97,6 @@ internal open class CInteropCommonizerTask : DefaultTask() { ) } - private fun outputDirectory(parameters: CInteropCommonizationParameters): File { - return project.buildDir.resolve("classes/kotlin/commonizer") - .resolve(parameters.commonizerTarget.prettyName) - .resolve(parameters.interops.map { it.interopName }.distinct().joinToString("-")) - } - - internal fun getLibraries(compilation: KotlinSharedNativeCompilation): FileCollection { - val fileProvider = project.provider> { - val parameters = findSupportingCommonizationParameters(compilation) ?: return@provider emptySet() - HierarchicalCommonizerOutputLayout - .getTargetDirectory(outputDirectory(parameters), parameters.commonizerTarget) - .listFiles().orEmpty().toSet() - } - - return project.files(fileProvider) { fileCollection -> - fileCollection.builtBy(this) - } - } - @Nested internal fun getCommonizationParameters(): Set { val sharedNativeCompilations = (project.multiplatformExtensionOrNull ?: return emptySet()) @@ -140,7 +120,7 @@ internal open class CInteropCommonizerTask : DefaultTask() { .run(::removeRedundantParameters) } - internal fun findSupportingCommonizationParameters(compilation: KotlinSharedNativeCompilation): CInteropCommonizationParameters? { + override fun getCommonizationParameters(compilation: KotlinSharedNativeCompilation): CInteropCommonizationParameters? { val supportedParameters = getCommonizationParameters().filter { parameters -> parameters.supports(compilation) } if (supportedParameters.isEmpty()) return null assert(supportedParameters.size == 1) { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CommonizerTasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CommonizerTasks.kt index 229ec9629dd..6a79827b352 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CommonizerTasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CommonizerTasks.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.targets.native.internal import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.tasks.TaskProvider +import org.jetbrains.kotlin.gradle.internal.isInIdeaSync import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.tasks.dependsOn import org.jetbrains.kotlin.gradle.tasks.locateTask @@ -55,6 +56,22 @@ internal val Project.commonizeCInteropTask: TaskProvider return null } +internal val Project.copyCommonizeCInteropForIdeTask: TaskProvider? + get() { + if (isCInteropCommonizationEnabled) { + return locateOrRegisterTask( + "copyCommonizeCInteropForIde", + invokeWhenRegistered = { if (isInIdeaSync) commonizeTask.dependsOn(this) }, + configureTask = { + group = "interop" + description = "Copies the output of ${commonizeCInteropTask?.get()?.name} into " + + "the root projects .gradle folder for the IDE" + } + ) + } + return null + } + internal val Project.commonizeNativeDistributionTask: TaskProvider get() = locateOrRegisterTask( "commonizeNativeDistribution", diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CopyCInteropCommonizerTaskOutputForIdeTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CopyCInteropCommonizerTaskOutputForIdeTask.kt new file mode 100644 index 00000000000..baf1ba8c4f6 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CopyCInteropCommonizerTaskOutputForIdeTask.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.targets.native.internal + +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.* +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation +import java.io.File + +internal open class CopyCommonizeCInteropForIdeTask : AbstractCInteropCommonizerTask() { + + private val commonizeCInteropTask: TaskProvider + get() = project.commonizeCInteropTask ?: throw IllegalStateException("Missing commonizeCInteropTask") + + @get:InputFiles + @get:PathSensitive(PathSensitivity.ABSOLUTE) + val cInteropCommonizerTaskOutputDirectories: Provider> = + commonizeCInteropTask.map { it.getAllOutputDirectories() } + + @get:OutputDirectory + override val outputDirectory: File = project.rootDir.resolve(".gradle/kotlin/commonizer") + .resolve(project.path.removePrefix(":").replace(":", "/")) + + override fun getCommonizationParameters(compilation: KotlinSharedNativeCompilation): CInteropCommonizationParameters? { + return commonizeCInteropTask.get().getCommonizationParameters(compilation) + } + + @TaskAction + protected fun copy() { + outputDirectory.mkdirs() + for (parameters in commonizeCInteropTask.get().getCommonizationParameters()) { + val source = commonizeCInteropTask.get().outputDirectory(parameters) + if (!source.exists()) continue + val target = outputDirectory(parameters) + if (target.exists()) target.deleteRecursively() + source.copyRecursively(target, true) + } + } +}