[Gradle] Create archive tasks for custom compilations
This change is needed for kotlin-test in order to support correct project dependencies in kotlin.git repository. ^KT-62943 Verification Pending
This commit is contained in:
committed by
Space Team
parent
e747793e62
commit
f2ddae533e
+6
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType.Companion.jsCompi
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_ABI_SNAPSHOT
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_ABI_SNAPSHOT
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_COMPILER_KEEP_INCREMENTAL_COMPILATION_CACHES_IN_MEMORY
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_COMPILER_KEEP_INCREMENTAL_COMPILATION_CACHES_IN_MEMORY
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_COMPILER_USE_PRECISE_COMPILATION_RESULTS_BACKUP
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_COMPILER_USE_PRECISE_COMPILATION_RESULTS_BACKUP
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_CREATE_ARCHIVE_TASKS_FOR_CUSTOM_COMPILATIONS
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_CREATE_DEFAULT_MULTIPLATFORM_PUBLICATIONS
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_CREATE_DEFAULT_MULTIPLATFORM_PUBLICATIONS
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_EXPERIMENTAL_TRY_K2
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_EXPERIMENTAL_TRY_K2
|
||||||
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_INTERNAL_DIAGNOSTICS_SHOW_STACKTRACE
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_INTERNAL_DIAGNOSTICS_SHOW_STACKTRACE
|
||||||
@@ -477,6 +478,9 @@ internal class PropertiesProvider private constructor(private val project: Proje
|
|||||||
val createDefaultMultiplatformPublications: Boolean
|
val createDefaultMultiplatformPublications: Boolean
|
||||||
get() = booleanProperty(KOTLIN_CREATE_DEFAULT_MULTIPLATFORM_PUBLICATIONS) ?: true
|
get() = booleanProperty(KOTLIN_CREATE_DEFAULT_MULTIPLATFORM_PUBLICATIONS) ?: true
|
||||||
|
|
||||||
|
val createArchiveTasksForCustomCompilations: Boolean
|
||||||
|
get() = booleanProperty(KOTLIN_CREATE_ARCHIVE_TASKS_FOR_CUSTOM_COMPILATIONS) ?: false
|
||||||
|
|
||||||
val runKotlinCompilerViaBuildToolsApi: Boolean
|
val runKotlinCompilerViaBuildToolsApi: Boolean
|
||||||
get() = booleanProperty(KOTLIN_RUN_COMPILER_VIA_BUILD_TOOLS_API) ?: false
|
get() = booleanProperty(KOTLIN_RUN_COMPILER_VIA_BUILD_TOOLS_API) ?: false
|
||||||
|
|
||||||
@@ -636,6 +640,8 @@ internal class PropertiesProvider private constructor(private val project: Proje
|
|||||||
val KOTLIN_INTERNAL_DIAGNOSTICS_SHOW_STACKTRACE = property("$KOTLIN_INTERNAL_NAMESPACE.diagnostics.showStacktrace")
|
val KOTLIN_INTERNAL_DIAGNOSTICS_SHOW_STACKTRACE = property("$KOTLIN_INTERNAL_NAMESPACE.diagnostics.showStacktrace")
|
||||||
val KOTLIN_SUPPRESS_GRADLE_PLUGIN_ERRORS = property("$KOTLIN_INTERNAL_NAMESPACE.suppressGradlePluginErrors")
|
val KOTLIN_SUPPRESS_GRADLE_PLUGIN_ERRORS = property("$KOTLIN_INTERNAL_NAMESPACE.suppressGradlePluginErrors")
|
||||||
val MPP_13X_FLAGS_SET_BY_PLUGIN = property("$KOTLIN_INTERNAL_NAMESPACE.mpp.13X.flags.setByPlugin")
|
val MPP_13X_FLAGS_SET_BY_PLUGIN = property("$KOTLIN_INTERNAL_NAMESPACE.mpp.13X.flags.setByPlugin")
|
||||||
|
val KOTLIN_CREATE_ARCHIVE_TASKS_FOR_CUSTOM_COMPILATIONS =
|
||||||
|
property("$KOTLIN_INTERNAL_NAMESPACE.mpp.createArchiveTasksForCustomCompilations")
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
+5
@@ -27,6 +27,11 @@ internal interface InternalKotlinCompilation<out T : KotlinCommonOptions> : Kotl
|
|||||||
val configurations: KotlinCompilationConfigurationsContainer
|
val configurations: KotlinCompilationConfigurationsContainer
|
||||||
val friendPaths: Iterable<FileCollection>
|
val friendPaths: Iterable<FileCollection>
|
||||||
val processResourcesTaskName: String?
|
val processResourcesTaskName: String?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see [org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationArchiveTasks]
|
||||||
|
*/
|
||||||
|
val archiveTaskName: String?
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val <T : KotlinCommonOptions> KotlinCompilation<T>.internal: InternalKotlinCompilation<T>
|
internal val <T : KotlinCommonOptions> KotlinCompilation<T>.internal: InternalKotlinCompilation<T>
|
||||||
|
|||||||
+2
@@ -164,6 +164,8 @@ internal class KotlinCompilationImpl constructor(
|
|||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
override val archiveTaskName: String?
|
||||||
|
get() = project.kotlinCompilationArchiveTasksOrNull?.getArchiveTaskOrNull(this)?.name
|
||||||
|
|
||||||
//region CompilerOptions & KotlinOptions
|
//region CompilerOptions & KotlinOptions
|
||||||
|
|
||||||
|
|||||||
+139
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.tasks.TaskProvider
|
||||||
|
import org.gradle.api.tasks.bundling.AbstractArchiveTask
|
||||||
|
import org.gradle.api.tasks.bundling.Jar
|
||||||
|
import org.gradle.api.tasks.bundling.Zip
|
||||||
|
import org.jetbrains.kotlin.gradle.InternalKotlinGradlePluginApi
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinProjectSetupAction
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.disambiguateName
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.isTest
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.CurrentBuildIdentifier
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.currentBuild
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.libsDirectory
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **WARNING!** This is internal Kotlin Gradle Plugin API, it is not supported outside JetBrains.
|
||||||
|
*
|
||||||
|
* Extension DSL to access Archive Tasks for custom compilations
|
||||||
|
* These archive tasks can be exported as artifacts via consumable configuration.
|
||||||
|
* And IDE will correctly import them.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* ```kotlin
|
||||||
|
* // project :lib
|
||||||
|
* kotlin {
|
||||||
|
* jvm {
|
||||||
|
* val customCompilation by compilations.creating
|
||||||
|
* val archiveTask = kotlinCompilationArchiveTasks
|
||||||
|
* .getArchiveTaskOrNull(customCompilation)!!
|
||||||
|
*
|
||||||
|
* val jvmCustomApiElements by configurations.creating {
|
||||||
|
* isCanBeConsumed = true
|
||||||
|
* }
|
||||||
|
* project.artifacts.add(jvmCustomApiElements.name, archiveTask)
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // project :app
|
||||||
|
* kotlin {
|
||||||
|
* jvm()
|
||||||
|
* sourceSets {
|
||||||
|
* jvmMain {
|
||||||
|
* dependencies {
|
||||||
|
* // This dependency will be correctly resolved in IDE
|
||||||
|
* // as Module dependency to `lib.jvmCustom` source set
|
||||||
|
* compileOnly(project(":lib", configuration = "jvmCustomApiElements"))
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
@InternalKotlinGradlePluginApi
|
||||||
|
interface KotlinCompilationArchiveTasks {
|
||||||
|
/**
|
||||||
|
* Returns archive task associated with [kotlinCompilation] instance.
|
||||||
|
*
|
||||||
|
* This method searches via Identity class (Project path, target and compilation names) of Compilations not by reference.
|
||||||
|
* So it is safe to pass decorated or wrapped instances.
|
||||||
|
*/
|
||||||
|
fun getArchiveTaskOrNull(kotlinCompilation: KotlinCompilation<*>): TaskProvider<out AbstractArchiveTask>?
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val KotlinRegisterCompilationArchiveTasksExtension = KotlinProjectSetupAction {
|
||||||
|
if (!project.kotlinPropertiesProvider.createArchiveTasksForCustomCompilations) return@KotlinProjectSetupAction
|
||||||
|
project.extensions.add(
|
||||||
|
KotlinCompilationArchiveTasks::class.java,
|
||||||
|
"kotlinCompilationsArchiveTasks",
|
||||||
|
KotlinCompilationArchiveTasksImpl(project.currentBuild)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val Project.kotlinCompilationArchiveTasksImplOrNull: KotlinCompilationArchiveTasksImpl?
|
||||||
|
get() = extensions.findByName("kotlinCompilationsArchiveTasks") as? KotlinCompilationArchiveTasksImpl?
|
||||||
|
|
||||||
|
internal val Project.kotlinCompilationArchiveTasksOrNull: KotlinCompilationArchiveTasks? get() = kotlinCompilationArchiveTasksImplOrNull
|
||||||
|
|
||||||
|
private class KotlinCompilationArchiveTasksImpl(
|
||||||
|
private val currentBuild: CurrentBuildIdentifier
|
||||||
|
) : KotlinCompilationArchiveTasks {
|
||||||
|
private val tasksMap: MutableMap<Key, TaskProvider<out AbstractArchiveTask>> = mutableMapOf()
|
||||||
|
|
||||||
|
private data class Key(
|
||||||
|
val targetName: String,
|
||||||
|
val compilationName: String
|
||||||
|
) {
|
||||||
|
constructor(kotlinCompilation: KotlinCompilation<*>) : this(
|
||||||
|
targetName = kotlinCompilation.target.targetName,
|
||||||
|
compilationName = kotlinCompilation.compilationName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun store(kotlinCompilation: KotlinCompilation<*>, task: TaskProvider<out AbstractArchiveTask>) {
|
||||||
|
require(kotlinCompilation.project in currentBuild) { "Compilation $kotlinCompilation is not from current project" }
|
||||||
|
tasksMap[Key(kotlinCompilation)] = task
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getArchiveTaskOrNull(kotlinCompilation: KotlinCompilation<*>): TaskProvider<out AbstractArchiveTask>? {
|
||||||
|
if (kotlinCompilation.project !in currentBuild) return null
|
||||||
|
return tasksMap[Key(kotlinCompilation)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val KotlinCreateCompilationArchivesTask = KotlinCompilationSideEffect { compilation ->
|
||||||
|
if (compilation.isMain() || compilation.isTest()) return@KotlinCompilationSideEffect
|
||||||
|
if (compilation.target is KotlinMetadataTarget) return@KotlinCompilationSideEffect
|
||||||
|
// Pessimistically exclude Android target to avoid any conflicts
|
||||||
|
if (compilation.target.platformType == KotlinPlatformType.androidJvm) return@KotlinCompilationSideEffect
|
||||||
|
|
||||||
|
val project = compilation.project
|
||||||
|
if (!project.kotlinPropertiesProvider.createArchiveTasksForCustomCompilations) return@KotlinCompilationSideEffect
|
||||||
|
|
||||||
|
val archiveTask = if (compilation.target.platformType == KotlinPlatformType.jvm) {
|
||||||
|
project.tasks.register(compilation.disambiguateName("jar"), Jar::class.java) { task ->
|
||||||
|
task.from(compilation.output.allOutputs)
|
||||||
|
task.archiveBaseName.convention(compilation.target.disambiguateName(compilation.name))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
project.tasks.register(compilation.disambiguateName("klib"), Zip::class.java) { task ->
|
||||||
|
task.from(compilation.output.allOutputs)
|
||||||
|
task.archiveBaseName.convention(compilation.target.disambiguateName(compilation.name))
|
||||||
|
task.destinationDirectory.convention(project.libsDirectory)
|
||||||
|
task.archiveExtension.set("klib")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project.kotlinCompilationArchiveTasksImplOrNull?.store(compilation, archiveTask)
|
||||||
|
}
|
||||||
+2
@@ -109,6 +109,7 @@ internal fun Project.registerKotlinPluginExtensions() {
|
|||||||
register(project, CInteropCommonizedCInteropApiElementsConfigurationsSetupAction)
|
register(project, CInteropCommonizedCInteropApiElementsConfigurationsSetupAction)
|
||||||
register(project, AddBuildListenerForXCodeSetupAction)
|
register(project, AddBuildListenerForXCodeSetupAction)
|
||||||
register(project, CreateFatFrameworksSetupAction)
|
register(project, CreateFatFrameworksSetupAction)
|
||||||
|
register(project, KotlinRegisterCompilationArchiveTasksExtension)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +133,7 @@ internal fun Project.registerKotlinPluginExtensions() {
|
|||||||
register(project, KotlinCreateNativeCompileTasksSideEffect)
|
register(project, KotlinCreateNativeCompileTasksSideEffect)
|
||||||
register(project, KotlinCompilationProcessorSideEffect)
|
register(project, KotlinCompilationProcessorSideEffect)
|
||||||
register(project, KotlinCreateNativeCInteropTasksSideEffect)
|
register(project, KotlinCreateNativeCInteropTasksSideEffect)
|
||||||
|
register(project, KotlinCreateCompilationArchivesTask)
|
||||||
}
|
}
|
||||||
|
|
||||||
KotlinTargetArtifact.extensionPoint.apply {
|
KotlinTargetArtifact.extensionPoint.apply {
|
||||||
|
|||||||
+114
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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("FunctionName")
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.unitTests
|
||||||
|
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_CREATE_ARCHIVE_TASKS_FOR_CUSTOM_COMPILATIONS
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationArchiveTasks
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.internal
|
||||||
|
import org.jetbrains.kotlin.gradle.util.*
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNotNull
|
||||||
|
import kotlin.test.fail
|
||||||
|
|
||||||
|
class KotlinCompilationArchiveTasksTest {
|
||||||
|
private fun Project.enableKotlinCompilationArchiveTasksCreation(enabled: Boolean = true) {
|
||||||
|
propertiesExtension.set(KOTLIN_CREATE_ARCHIVE_TASKS_FOR_CUSTOM_COMPILATIONS, enabled.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
private val Project.kotlinCompilationsArchiveTasks: KotlinCompilationArchiveTasks
|
||||||
|
get() = extensions.getByName("kotlinCompilationsArchiveTasks") as KotlinCompilationArchiveTasks
|
||||||
|
|
||||||
|
val testProject: Project = buildProject {
|
||||||
|
enableKotlinCompilationArchiveTasksCreation()
|
||||||
|
applyMultiplatformPlugin()
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
linuxX64()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `custom jvm compilation has archive task`() {
|
||||||
|
testProject.kotlin {
|
||||||
|
jvm {
|
||||||
|
val customCompilation = compilations.create("custom")
|
||||||
|
val archiveTaskProvider = project.kotlinCompilationsArchiveTasks.getArchiveTaskOrNull(customCompilation)
|
||||||
|
assertNotNull(archiveTaskProvider)
|
||||||
|
val archiveFile = archiveTaskProvider.get().archiveFile.get().asFile
|
||||||
|
if (!archiveFile.endsWith("libs/jvmCustom.jar")) fail("Unexpected archive file for compilation $customCompilation")
|
||||||
|
|
||||||
|
assertEquals(archiveTaskProvider.name, customCompilation.internal.archiveTaskName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `custom native compilation has archive`() {
|
||||||
|
testProject.kotlin {
|
||||||
|
linuxX64 {
|
||||||
|
val customCompilation = compilations.create("custom")
|
||||||
|
val archiveTaskProvider = project.kotlinCompilationsArchiveTasks.getArchiveTaskOrNull(customCompilation)
|
||||||
|
assertNotNull(archiveTaskProvider)
|
||||||
|
val archiveFile = archiveTaskProvider.get().archiveFile.get().asFile
|
||||||
|
if (!archiveFile.endsWith("libs/linuxX64Custom.klib"))
|
||||||
|
fail("Unexpected archive file for compilation $customCompilation: $archiveFile")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `main and test compilations should not have archive task`() {
|
||||||
|
testProject.multiplatformExtension.targets.flatMap { it.compilations }.forEach { compilation ->
|
||||||
|
if (compilation.internal.archiveTaskName != null)
|
||||||
|
fail("Archive tasks should not be created for default compilations, but $compilation has it")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `archive tasks should not be created for custom compilation when feature flag is not set`() {
|
||||||
|
val project = buildProject {
|
||||||
|
enableKotlinCompilationArchiveTasksCreation(enabled = false)
|
||||||
|
applyMultiplatformPlugin()
|
||||||
|
kotlin {
|
||||||
|
jvm().compilations.create("custom")
|
||||||
|
linuxX64().compilations.create("custom")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
project.multiplatformExtension.targets.flatMap { it.compilations }.forEach { compilation ->
|
||||||
|
if (compilation.internal.archiveTaskName != null)
|
||||||
|
fail("Archive tasks should not be created")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `archive tasks should not be created for any android compilation`() {
|
||||||
|
val project = buildProject {
|
||||||
|
enableKotlinCompilationArchiveTasksCreation()
|
||||||
|
applyMultiplatformPlugin()
|
||||||
|
androidLibrary {
|
||||||
|
compileSdk = 33
|
||||||
|
productFlavors {
|
||||||
|
create("customFlavor")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kotlin {
|
||||||
|
linuxX64()
|
||||||
|
androidTarget()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project.multiplatformExtension.androidTarget().compilations.forEach { compilation ->
|
||||||
|
if (compilation.internal.archiveTaskName != null)
|
||||||
|
fail("Archive tasks should not be created for $compilation")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user