[Gradle] Replace 'configureArchivesAndComponent' with KotlinTargetArtifact
KT-61634
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/MppCompositeBuildIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/MppCompositeBuildIT.kt
index 753da1a..7cded6a 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/MppCompositeBuildIT.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/MppCompositeBuildIT.kt
@@ -176,6 +176,8 @@
buildGradleKts.replaceText("<kgp_version>", KOTLIN_VERSION)
projectPath.resolve("included-build/build.gradle.kts").replaceText("<kgp_version>", KOTLIN_VERSION)
+ makeSnapshotTo("/Users/sebastiansellmair/tmp")
+
build("assemble") {
assertTasksExecuted(":compileCommonMainKotlinMetadata")
assertTasksExecuted(":compileKotlinJvm")
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 37ebd10..1a3d8b4 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
@@ -9,20 +9,15 @@
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
-import org.gradle.api.artifacts.Dependency
-import org.gradle.api.artifacts.PublishArtifact
import org.gradle.api.artifacts.type.ArtifactTypeDefinition
import org.gradle.api.attributes.*
-import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.bundling.Jar
import org.gradle.api.tasks.bundling.Zip
-import org.jetbrains.kotlin.gradle.plugin.internal.artifactTypeAttribute
import org.jetbrains.kotlin.gradle.plugin.mpp.*
-import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationSideEffect
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.runKotlinCompilationSideEffects
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute
import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetAttribute
@@ -39,14 +34,12 @@
fun configureTarget(
target: KotlinTargetType,
) {
- target.runKotlinTargetSideEffects()
target.runKotlinCompilationSideEffects()
- configureArchivesAndComponent(target)
+ target.runKotlinTargetSideEffects()
configureBuild(target)
configurePlatformSpecificModel(target)
}
- fun configureArchivesAndComponent(target: KotlinTargetType)
fun configureBuild(target: KotlinTargetType)
fun configurePlatformSpecificModel(target: KotlinTargetType) = Unit
}
@@ -95,68 +88,7 @@
abstract class KotlinOnlyTargetConfigurator<KotlinCompilationType : KotlinCompilation<*>, KotlinTargetType : KotlinOnlyTarget<KotlinCompilationType>>(
createTestCompilation: Boolean,
-) : AbstractKotlinTargetConfigurator<KotlinTargetType>(createTestCompilation) {
- open val archiveType: String = ArtifactTypeDefinition.JAR_TYPE
-
- open val archiveTaskType: Class<out Zip>
- get() = Jar::class.java
-
- /** The implementations are expected to create a [Zip] task under the name [KotlinTarget.artifactsTaskName] of the [target]. */
- protected open fun createArchiveTasks(target: KotlinTargetType): TaskProvider<out Zip> {
- return target.project.registerTask(
- target.artifactsTaskName,
- archiveTaskType
- ) {
- it.description = "Assembles an archive containing the main classes."
- it.group = BasePlugin.BUILD_GROUP
- it.from(target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME).output.allOutputs)
- it.isPreserveFileTimestamps = false
- it.isReproducibleFileOrder = true
-
- target.disambiguationClassifier?.let { classifier ->
- it.archiveAppendix.set(classifier.toLowerCaseAsciiOnly())
- }
- }
- }
-
- override fun configureArchivesAndComponent(target: KotlinTargetType) {
- val project = target.project
-
- val mainCompilation = target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME)
-
- val task = createArchiveTasks(target)
-
- // Workaround: adding the artifact during configuration seems to interfere with the Java plugin, which results into missing
- // task dependency 'assemble -> jar' if the Java plugin is applied after this steps
- project.afterEvaluate {
- project.artifacts.add(Dependency.ARCHIVES_CONFIGURATION, task) { jarArtifact ->
- jarArtifact.builtBy(task)
- jarArtifact.type = archiveType
-
- val apiElementsConfiguration = project.configurations.getByName(target.apiElementsConfigurationName)
- // If the target adds its own artifact to this configuration until this happens, don't add another one:
- addJarIfNoArtifactsPresent(project, apiElementsConfiguration, jarArtifact)
-
- if (mainCompilation is KotlinCompilationToRunnableFiles<*>) {
- val runtimeConfiguration = mainCompilation.internal.configurations.deprecatedRuntimeConfiguration
- val runtimeElementsConfiguration = project.configurations.getByName(target.runtimeElementsConfigurationName)
- runtimeConfiguration?.let { addJarIfNoArtifactsPresent(project, runtimeConfiguration, jarArtifact) }
- addJarIfNoArtifactsPresent(project, runtimeElementsConfiguration, jarArtifact)
- }
- }
- }
- }
-
- private fun addJarIfNoArtifactsPresent(project: Project, configuration: Configuration, jarArtifact: PublishArtifact) {
- if (configuration.artifacts.isEmpty()) {
- val publications = configuration.outgoing
-
- // Configure an implicit variant
- publications.artifacts.add(jarArtifact)
- publications.attributes.attribute(project.artifactTypeAttribute, archiveType)
- }
- }
-}
+) : AbstractKotlinTargetConfigurator<KotlinTargetType>(createTestCompilation)
internal interface KotlinTargetWithTestsConfigurator<R : KotlinTargetTestRun<*>, T : KotlinTargetWithTests<*, R>>
: KotlinTargetConfigurator<T> {
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationProcessorSideEffect.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationProcessorSideEffect.kt
index 40b0a2d..59cf531 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationProcessorSideEffect.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCompilationProcessorSideEffect.kt
@@ -11,18 +11,15 @@
import org.jetbrains.kotlin.gradle.plugin.KotlinJsIrSourceSetProcessor
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCommonCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation
-import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation
-import org.jetbrains.kotlin.gradle.targets.metadata.NativeSharedCompilationProcessor
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
internal val KotlinCompilationProcessorSideEffect = KotlinCompilationSideEffect { compilation ->
val processor = when (compilation) {
is KotlinCommonCompilation -> KotlinCommonSourceSetProcessor(KotlinCompilationInfo(compilation), KotlinTasksProvider())
- is KotlinSharedNativeCompilation -> NativeSharedCompilationProcessor(compilation)
is KotlinJvmCompilation -> Kotlin2JvmSourceSetProcessor(KotlinTasksProvider(), KotlinCompilationInfo(compilation))
is KotlinJsIrCompilation -> KotlinJsIrSourceSetProcessor(KotlinTasksProvider(), KotlinCompilationInfo(compilation))
else -> null
}
processor?.run()
-}
\ No newline at end of file
+}
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCreateNativeCompileTasksSideEffect.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCreateNativeCompileTasksSideEffect.kt
new file mode 100644
index 0000000..797e8fb
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/KotlinCreateNativeCompileTasksSideEffect.kt
@@ -0,0 +1,79 @@
+/*
+ * 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.plugins.BasePlugin
+import org.gradle.language.base.plugins.LifecycleBasePlugin
+import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
+import org.jetbrains.kotlin.gradle.dsl.topLevelExtension
+import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationInfo
+import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
+import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
+import org.jetbrains.kotlin.gradle.plugin.SubpluginEnvironment
+import org.jetbrains.kotlin.gradle.plugin.launchInStage
+import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinNativeCompilation
+import org.jetbrains.kotlin.gradle.plugin.mpp.enabledOnCurrentHost
+import org.jetbrains.kotlin.gradle.targets.klibOutputDirectory
+import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
+import org.jetbrains.kotlin.gradle.tasks.dependsOn
+import org.jetbrains.kotlin.gradle.tasks.registerTask
+
+/**
+ * Will register (and configure) the corresponding [KotlinNativeCompile] task for a given
+ * [AbstractKotlinNativeCompilation] (which includes shared native metadata and 'platform compilations')
+ */
+internal val KotlinCreateNativeCompileTasksSideEffect = KotlinCompilationSideEffect<AbstractKotlinNativeCompilation> { compilation ->
+ val project = compilation.project
+ val extension = project.topLevelExtension
+ val compilationInfo = KotlinCompilationInfo(compilation)
+
+ val kotlinNativeCompile = project.registerTask<KotlinNativeCompile>(
+ compilation.compileKotlinTaskName,
+ listOf(compilationInfo, compilation.compilerOptions.options)
+ ) { task ->
+ task.group = BasePlugin.BUILD_GROUP
+ task.description = "Compiles a klibrary from the '${compilationInfo.compilationName}' " +
+ "compilation in target '${compilationInfo.targetDisambiguationClassifier}'."
+ task.enabled = compilation.konanTarget.enabledOnCurrentHost
+
+ task.destinationDirectory.set(project.klibOutputDirectory(compilationInfo).dir("klib"))
+ if (project.kotlinPropertiesProvider.useK2 == true) {
+ task.compilerOptions.useK2.set(true)
+ }
+ task.runViaBuildToolsApi.value(false).disallowChanges() // K/N is not yet supported
+
+ task.explicitApiMode.value(
+ project.providers.provider {
+ // Plugin explicitly does not configures 'explicitApi' mode for test sources
+ // compilation, as test sources are not published
+ if (compilationInfo.isMain) {
+ extension.explicitApi
+ } else {
+ ExplicitApiMode.Disabled
+ }
+ }
+ ).finalizeValueOnRead()
+ }
+
+ compilationInfo.classesDirs.from(kotlinNativeCompile.map { it.outputFile })
+ project.tasks.named(compilation.compileAllTaskName).dependsOn(kotlinNativeCompile)
+ project.tasks.named(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(kotlinNativeCompile)
+ compilation.addCompilerPlugins()
+}
+
+private fun AbstractKotlinNativeCompilation.addCompilerPlugins() {
+ val project = target.project
+
+ project.launchInStage(KotlinPluginLifecycle.Stage.AfterEvaluateBuildscript) {
+ SubpluginEnvironment
+ .loadSubplugins(project)
+ .addSubpluginOptions(project, this@addCompilerPlugins)
+
+ compileTaskProvider.configure {
+ it.compilerPluginClasspath = this@addCompilerPlugins.configurations.pluginConfiguration
+ }
+ }
+}
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt
index de246978..2a55170 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/registerKotlinPluginExtensions.kt
@@ -49,10 +49,12 @@
import org.jetbrains.kotlin.gradle.plugin.sources.LanguageSettingsSetupAction
import org.jetbrains.kotlin.gradle.plugin.statistics.MultiplatformBuildStatsReportSetupAction
import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubpluginSetupAction
+import org.jetbrains.kotlin.gradle.targets.*
+import org.jetbrains.kotlin.gradle.targets.CreateArtifactsSideEffect
import org.jetbrains.kotlin.gradle.targets.CreateDefaultCompilationsSideEffect
import org.jetbrains.kotlin.gradle.targets.CreateTargetConfigurationsSideEffect
-import org.jetbrains.kotlin.gradle.targets.NativeForwardImplementationToApiElementsSideEffect
import org.jetbrains.kotlin.gradle.targets.KotlinTargetSideEffect
+import org.jetbrains.kotlin.gradle.targets.NativeForwardImplementationToApiElementsSideEffect
import org.jetbrains.kotlin.gradle.targets.js.npm.AddNpmDependencyExtensionProjectSetupAction
import org.jetbrains.kotlin.gradle.targets.metadata.KotlinMetadataTargetSetupAction
import org.jetbrains.kotlin.gradle.targets.native.CreateFatFrameworksSetupAction
@@ -100,15 +102,26 @@
register(project, CreateDefaultCompilationsSideEffect)
register(project, CreateTargetConfigurationsSideEffect)
register(project, NativeForwardImplementationToApiElementsSideEffect)
+ register(project, CreateArtifactsSideEffect)
}
KotlinCompilationSideEffect.extensionPoint.apply {
register(project, KotlinCreateSourcesJarTaskSideEffect)
register(project, KotlinCreateResourcesTaskSideEffect)
register(project, KotlinCreateLifecycleTasksSideEffect)
+ register(project, KotlinCreateNativeCompileTasksSideEffect)
register(project, KotlinCompilationProcessorSideEffect)
}
+ KotlinTargetArtifact.extensionPoint.apply {
+ register(project, KotlinTargetMetadataArtifact)
+ register(project, KotlinLegacyCompatibilityMetadataArtifact)
+ register(project, KotlinJvmJarTargetArtifact)
+ register(project, KotlinJsKlibTargetArtifact)
+ register(project, KotlinNativeKlibTargetArtifact)
+ register(project, KotlinNativeHostSpecificMetadataArtifact)
+ }
+
KotlinGradleProjectChecker.extensionPoint.apply {
register(project, CommonMainOrTestWithDependsOnChecker)
register(project, DeprecatedKotlinNativeTargetsChecker)
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/CreateArtifactsSideEffect.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/CreateArtifactsSideEffect.kt
new file mode 100644
index 0000000..7fe6cc8
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/CreateArtifactsSideEffect.kt
@@ -0,0 +1,23 @@
+/*
+ * 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.targets
+
+import org.jetbrains.kotlin.gradle.plugin.launch
+
+
+/**
+ * Creates target level artifacts (and exposes them in the 'apiElements' and 'runtimeElements' configurations)
+ * The corresponding task for jvm would be called 'jvmJar'
+ */
+internal val CreateArtifactsSideEffect = KotlinTargetSideEffect { target ->
+ val apiElements = target.project.configurations.getByName(target.apiElementsConfigurationName)
+ val runtimeElements = target.project.configurations.findByName(target.runtimeElementsConfigurationName)
+ KotlinTargetArtifact.extensionPoint[target.project].forEach { artifact ->
+ target.project.launch {
+ artifact.createArtifact(target, apiElements, runtimeElements)
+ }
+ }
+}
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinJsKlibTargetArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinJsKlibTargetArtifact.kt
new file mode 100644
index 0000000..8d4b94c
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinJsKlibTargetArtifact.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.targets
+
+import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
+import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
+import org.jetbrains.kotlin.gradle.targets.js.ir.KLIB_TYPE
+import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
+import org.jetbrains.kotlin.gradle.targets.js.ir.wasmDecamelizedDefaultNameOrNull
+import org.jetbrains.kotlin.gradle.utils.decamelize
+import org.jetbrains.kotlin.gradle.utils.libsDirectory
+
+internal val KotlinJsKlibTargetArtifact = KotlinTargetArtifact { target, apiElements, runtimeElements ->
+ if (target !is KotlinJsIrTarget) return@KotlinTargetArtifact
+
+ val jsKlibTask = target.createArtifactsTask {
+ it.from(target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME).output.allOutputs)
+ it.archiveExtension.set(KLIB_TYPE)
+ it.destinationDirectory.set(target.project.libsDirectory)
+
+ if (target.platformType == KotlinPlatformType.wasm) {
+ if (target.wasmDecamelizedDefaultNameOrNull() != null) {
+ target.disambiguationClassifier?.let { classifier ->
+ it.archiveAppendix.set(classifier.decamelize())
+ }
+ }
+ }
+ }
+
+ target.createPublishArtifact(jsKlibTask, KLIB_TYPE, apiElements, runtimeElements)
+}
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinJvmJarTargetArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinJvmJarTargetArtifact.kt
new file mode 100644
index 0000000..9225315
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinJvmJarTargetArtifact.kt
@@ -0,0 +1,21 @@
+/*
+ * 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.targets
+
+import org.gradle.api.artifacts.type.ArtifactTypeDefinition.JAR_TYPE
+import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
+import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
+
+internal val KotlinJvmJarTargetArtifact = KotlinTargetArtifact { target, apiElements, runtimeElements ->
+ if (target !is KotlinJvmTarget) return@KotlinTargetArtifact
+ val mainCompilation = target.compilations.getByName(MAIN_COMPILATION_NAME)
+
+ val jvmJarTask = target.createArtifactsTask { jar ->
+ jar.from(mainCompilation.output.allOutputs)
+ }
+
+ target.createPublishArtifact(jvmJarTask, JAR_TYPE, apiElements, runtimeElements)
+}
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinLegacyCompatibilityMetadataArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinLegacyCompatibilityMetadataArtifact.kt
new file mode 100644
index 0000000..b682517
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinLegacyCompatibilityMetadataArtifact.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.targets
+
+import org.gradle.api.artifacts.type.ArtifactTypeDefinition.JAR_TYPE
+import org.gradle.api.tasks.bundling.Jar
+import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget
+import org.jetbrains.kotlin.gradle.targets.metadata.isCompatibilityMetadataVariantEnabled
+import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
+import org.jetbrains.kotlin.gradle.tasks.registerTask
+
+internal val KotlinLegacyCompatibilityMetadataArtifact = KotlinTargetArtifact { target, apiElements, _ ->
+ if (target !is KotlinMetadataTarget) return@KotlinTargetArtifact
+ if (!target.project.isKotlinGranularMetadataEnabled) return@KotlinTargetArtifact
+ if (!target.project.isCompatibilityMetadataVariantEnabled) return@KotlinTargetArtifact
+
+ val legacyJar = target.project.registerTask<Jar>(target.legacyArtifactsTaskName)
+ legacyJar.configure {
+ // Capture it here to use in onlyIf spec. Direct usage causes serialization of target attempt when configuration cache is enabled
+ it.description = "Assembles an archive containing the Kotlin metadata of the commonMain source set."
+ it.from(target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME).output.allOutputs)
+ }
+
+ target.createPublishArtifact(legacyJar, JAR_TYPE, apiElements)
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinMetadataTargetArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinMetadataTargetArtifact.kt
new file mode 100644
index 0000000..9ea1e9b
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinMetadataTargetArtifact.kt
@@ -0,0 +1,55 @@
+/*
+ * 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.targets
+
+import org.gradle.api.artifacts.Dependency.ARCHIVES_CONFIGURATION
+import org.gradle.api.artifacts.type.ArtifactTypeDefinition.JAR_TYPE
+import org.gradle.api.attributes.Category
+import org.gradle.api.attributes.Usage
+import org.jetbrains.kotlin.gradle.plugin.categoryByName
+import org.jetbrains.kotlin.gradle.plugin.internal.artifactTypeAttribute
+import org.jetbrains.kotlin.gradle.plugin.mpp.*
+import org.jetbrains.kotlin.gradle.plugin.usageByName
+import org.jetbrains.kotlin.gradle.targets.metadata.createGenerateProjectStructureMetadataTask
+import org.jetbrains.kotlin.gradle.targets.metadata.filesWithUnpackedArchives
+import org.jetbrains.kotlin.gradle.targets.metadata.isCompatibilityMetadataVariantEnabled
+import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
+import org.jetbrains.kotlin.gradle.targets.native.internal.includeCommonizedCInteropMetadata
+
+internal val KotlinTargetMetadataArtifact = KotlinTargetArtifact { target, apiElements, _ ->
+ if (target !is KotlinMetadataTarget || !target.project.isKotlinGranularMetadataEnabled) return@KotlinTargetArtifact
+
+ apiElements.attributes.attribute(Usage.USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA))
+ apiElements.attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
+
+ val metadataJarTask = target.createArtifactsTask { jar ->
+ jar.description = "Assembles a jar archive containing the metadata for all Kotlin source sets."
+ if (target.project.isCompatibilityMetadataVariantEnabled) {
+ jar.archiveClassifier.set("all")
+ }
+ }
+
+ /* Include 'KotlinProjectStructureMetadata' file */
+ val generateMetadata = target.project.createGenerateProjectStructureMetadataTask()
+ metadataJarTask.configure { jar ->
+ jar.from(generateMetadata.map { it.resultFile }) { spec ->
+ spec.into("META-INF").rename { MULTIPLATFORM_PROJECT_METADATA_JSON_FILE_NAME }
+ }
+ }
+
+ /* Include output of metadata compilations into metadata jar (including commonizer output if available */
+ val hostSpecificSourceSets = getHostSpecificSourceSets(target.project)
+ target.compilations.all { compilation ->
+ if (compilation.defaultSourceSet in hostSpecificSourceSets) return@all
+ val metadataContent = target.project.filesWithUnpackedArchives(compilation.output.allOutputs, setOf("klib"))
+ metadataJarTask.configure { it.from(metadataContent) { spec -> spec.into(compilation.defaultSourceSet.name) } }
+ if (compilation is KotlinSharedNativeCompilation) {
+ target.project.includeCommonizedCInteropMetadata(metadataJarTask, compilation)
+ }
+ }
+
+ target.createPublishArtifact(metadataJarTask, JAR_TYPE, apiElements)
+}
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinNativeHostSpecificMetadataArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinNativeHostSpecificMetadataArtifact.kt
new file mode 100644
index 0000000..eef8498
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinNativeHostSpecificMetadataArtifact.kt
@@ -0,0 +1,74 @@
+/*
+ * 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.targets
+
+import org.gradle.api.artifacts.Dependency
+import org.gradle.api.attributes.Usage
+import org.gradle.api.plugins.BasePlugin
+import org.gradle.jvm.tasks.Jar
+import org.jetbrains.kotlin.gradle.plugin.launch
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
+import org.jetbrains.kotlin.gradle.plugin.mpp.getHostSpecificSourceSets
+import org.jetbrains.kotlin.gradle.plugin.usageByName
+import org.jetbrains.kotlin.gradle.targets.metadata.filesWithUnpackedArchives
+import org.jetbrains.kotlin.gradle.targets.metadata.findMetadataCompilation
+import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
+import org.jetbrains.kotlin.gradle.targets.native.internal.includeCommonizedCInteropMetadata
+import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
+import org.jetbrains.kotlin.gradle.utils.copyAttributes
+import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
+
+internal val KotlinNativeHostSpecificMetadataArtifact = KotlinTargetArtifact { target, apiElements, _ ->
+ if (target !is KotlinNativeTarget) return@KotlinTargetArtifact
+ if (!target.project.isKotlinGranularMetadataEnabled) return@KotlinTargetArtifact
+ val project = target.project
+
+ target.project.configurations.create(target.hostSpecificMetadataElementsConfigurationName) { configuration ->
+ configuration.isCanBeConsumed = true
+ configuration.isCanBeResolved = false
+
+ configuration.extendsFrom(*apiElements.extendsFrom.toTypedArray())
+
+ copyAttributes(from = apiElements.attributes, to = configuration.attributes)
+ configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA))
+ }
+
+ val hostSpecificSourceSets = getHostSpecificSourceSets(target.project)
+ if (hostSpecificSourceSets.isEmpty()) return@KotlinTargetArtifact
+
+ val hostSpecificMetadataJar = project.locateOrRegisterTask<Jar>(target.hostSpecificMetadataElementsConfigurationName) { metadataJar ->
+ metadataJar.archiveAppendix.set(project.provider { target.disambiguationClassifier.orEmpty().toLowerCaseAsciiOnly() })
+ metadataJar.archiveClassifier.set("metadata")
+ metadataJar.group = BasePlugin.BUILD_GROUP
+ metadataJar.description = "Assembles Kotlin metadata of target '${target.name}'."
+
+ val publishable = target.publishable
+ metadataJar.onlyIf { publishable }
+
+ project.launch {
+ val metadataCompilations = hostSpecificSourceSets.mapNotNull {
+ project.findMetadataCompilation(it)
+ }
+
+ metadataCompilations.forEach { compilation ->
+ metadataJar.from(project.filesWithUnpackedArchives(compilation.output.allOutputs, setOf("klib"))) { spec ->
+ spec.into(compilation.name)
+ }
+ metadataJar.dependsOn(compilation.output.classesDirs)
+
+ if (compilation is KotlinSharedNativeCompilation) {
+ project.includeCommonizedCInteropMetadata(metadataJar, compilation)
+ }
+ }
+ }
+ }
+ project.artifacts.add(Dependency.ARCHIVES_CONFIGURATION, hostSpecificMetadataJar)
+ project.artifacts.add(target.hostSpecificMetadataElementsConfigurationName, hostSpecificMetadataJar) { artifact ->
+ artifact.classifier = "metadata"
+ }
+}
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinNativeKlibTargetArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinNativeKlibTargetArtifact.kt
new file mode 100644
index 0000000..c7c648f
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinNativeKlibTargetArtifact.kt
@@ -0,0 +1,82 @@
+/*
+ * 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.targets
+
+import org.gradle.api.DefaultTask
+import org.gradle.api.Project
+import org.gradle.api.file.DirectoryProperty
+import org.gradle.api.internal.plugins.DefaultArtifactPublicationSet
+import org.gradle.api.plugins.BasePlugin
+import org.gradle.api.provider.Provider
+import org.gradle.api.tasks.TaskProvider
+import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
+import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
+import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationInfo
+import org.jetbrains.kotlin.gradle.plugin.KotlinNativeTargetConfigurator.NativeArtifactFormat
+import org.jetbrains.kotlin.gradle.plugin.internal.artifactTypeAttribute
+import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinNativeCompilation
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
+import org.jetbrains.kotlin.gradle.plugin.mpp.enabledOnCurrentHost
+import org.jetbrains.kotlin.gradle.tasks.dependsOn
+import org.jetbrains.kotlin.gradle.tasks.registerTask
+import java.io.File
+
+internal val KotlinNativeKlibTargetArtifact = KotlinTargetArtifact { target, apiElements, _ ->
+ if (target !is KotlinNativeTarget) return@KotlinTargetArtifact
+ /* Just registering a dummy placeholder that other tasks can use as umbrella */
+ val artifactsTask = target.project.registerTask<DefaultTask>(target.artifactsTaskName) {
+ it.group = BasePlugin.BUILD_GROUP
+ it.description = "Assembles outputs for target '${target.name}'."
+ }
+
+ apiElements.outgoing.attributes.attribute(target.project.artifactTypeAttribute, NativeArtifactFormat.KLIB)
+
+ target.compilations.getByName(MAIN_COMPILATION_NAME).let { mainCompilation ->
+ artifactsTask.dependsOn(mainCompilation.compileTaskProvider)
+ createRegularKlibArtifact(mainCompilation)
+ }
+}
+
+internal fun createRegularKlibArtifact(compilation: AbstractKotlinNativeCompilation) = createKlibArtifact(
+ compilation = compilation,
+ artifactFile = compilation.compileTaskProvider.map { it.outputFile.get() },
+ classifier = null,
+ producingTask = compilation.compileTaskProvider
+)
+
+internal fun createKlibArtifact(
+ compilation: AbstractKotlinNativeCompilation,
+ artifactFile: Provider<File>,
+ classifier: String?,
+ producingTask: TaskProvider<*>,
+) {
+ if (!compilation.konanTarget.enabledOnCurrentHost) {
+ return
+ }
+
+ val apiElementsName = compilation.target.apiElementsConfigurationName
+ with(compilation.project.configurations.getByName(apiElementsName)) {
+ val klibArtifact = compilation.project.artifacts.add(name, artifactFile) { artifact ->
+ artifact.name = compilation.compilationName
+ artifact.extension = "klib"
+ artifact.type = "klib"
+ artifact.classifier = classifier
+ artifact.builtBy(producingTask)
+ }
+ compilation.project.extensions.getByType(DefaultArtifactPublicationSet::class.java).addCandidate(klibArtifact)
+ artifacts.add(klibArtifact)
+ attributes.attribute(compilation.project.artifactTypeAttribute, NativeArtifactFormat.KLIB)
+ }
+}
+
+internal fun Project.klibOutputDirectory(
+ compilation: KotlinCompilationInfo,
+): DirectoryProperty {
+ val targetSubDirectory = compilation.targetDisambiguationClassifier?.let { "$it/" }.orEmpty()
+ return project.objects.directoryProperty().value(
+ layout.buildDirectory.dir("classes/kotlin/$targetSubDirectory${compilation.compilationName}")
+ )
+}
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinTargetArtifact.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinTargetArtifact.kt
new file mode 100644
index 0000000..f77255f
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/KotlinTargetArtifact.kt
@@ -0,0 +1,59 @@
+/*
+ * 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.targets
+
+import org.gradle.api.artifacts.Configuration
+import org.gradle.api.artifacts.Dependency.ARCHIVES_CONFIGURATION
+import org.gradle.api.artifacts.PublishArtifact
+import org.gradle.api.plugins.BasePlugin
+import org.gradle.api.tasks.TaskProvider
+import org.gradle.jvm.tasks.Jar
+import org.jetbrains.kotlin.gradle.plugin.KotlinGradlePluginExtensionPoint
+import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
+import org.jetbrains.kotlin.gradle.plugin.internal.artifactTypeAttribute
+import org.jetbrains.kotlin.gradle.tasks.registerTask
+import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
+
+internal fun interface KotlinTargetArtifact {
+ suspend fun createArtifact(target: KotlinTarget, apiElements: Configuration, runtimeElements: Configuration?)
+
+ companion object {
+ val extensionPoint = KotlinGradlePluginExtensionPoint<KotlinTargetArtifact>()
+ }
+}
+
+internal fun KotlinTarget.createArtifactsTask(configure: (Jar) -> Unit = {}): TaskProvider<Jar> {
+ return project.registerTask<Jar>(artifactsTaskName) { jar ->
+ jar.description = "Assembles an archive containing the main classes."
+ jar.group = BasePlugin.BUILD_GROUP
+ jar.isPreserveFileTimestamps = false
+ jar.isReproducibleFileOrder = true
+
+ disambiguationClassifier?.let { classifier ->
+ jar.archiveAppendix.set(classifier.toLowerCaseAsciiOnly())
+ }
+
+ configure(jar)
+ }
+}
+
+internal fun KotlinTarget.createPublishArtifact(
+ artifactTask: TaskProvider<*>,
+ artifactType: String,
+ vararg elementsConfiguration: Configuration?,
+): PublishArtifact {
+ val artifact = project.artifacts.add(ARCHIVES_CONFIGURATION, artifactTask) { artifact ->
+ artifact.builtBy(artifactTask)
+ artifact.type = artifactType
+ }
+
+ elementsConfiguration.filterNotNull().forEach { configuration ->
+ configuration.outgoing.artifacts.add(artifact)
+ configuration.outgoing.attributes.attribute(project.artifactTypeAttribute, artifactType)
+ }
+
+ return artifact
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt
index fba7b8f..c3a6d68 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt
@@ -5,9 +5,6 @@
package org.jetbrains.kotlin.gradle.targets.js.ir
-import org.gradle.api.tasks.TaskProvider
-import org.gradle.api.tasks.bundling.Jar
-import org.gradle.api.tasks.bundling.Zip
import org.jetbrains.kotlin.gradle.dsl.JsModuleKind
import org.jetbrains.kotlin.gradle.dsl.JsSourceMapEmbedMode
import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompilerOptions
@@ -17,8 +14,6 @@
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsReportAggregatingTestRun
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
import org.jetbrains.kotlin.gradle.testing.testTaskName
-import org.jetbrains.kotlin.gradle.utils.decamelize
-import org.jetbrains.kotlin.gradle.utils.libsDirectory
open class KotlinJsIrTargetConfigurator :
KotlinOnlyTargetConfigurator<KotlinJsIrCompilation, KotlinJsIrTarget>(true),
@@ -28,12 +23,6 @@
override val testRunClass: Class<KotlinJsReportAggregatingTestRun> get() = KotlinJsReportAggregatingTestRun::class.java
- override val archiveType: String
- get() = KLIB_TYPE
-
- override val archiveTaskType: Class<out Zip>
- get() = Jar::class.java
-
override fun createTestRun(
name: String,
target: KotlinJsIrTarget
@@ -61,24 +50,6 @@
return result
}
- override fun createArchiveTasks(target: KotlinJsIrTarget): TaskProvider<out Zip> {
- val libsDirectory = target.project.libsDirectory
- return super.createArchiveTasks(target).apply {
- configure {
- it.archiveExtension.set(KLIB_TYPE)
- it.destinationDirectory.set(libsDirectory)
-
- if (target.platformType == KotlinPlatformType.wasm) {
- if (target.wasmDecamelizedDefaultNameOrNull() != null) {
- target.disambiguationClassifier?.let { classifier ->
- it.archiveAppendix.set(classifier.decamelize())
- }
- }
- }
- }
- }
- }
-
internal companion object {
internal fun KotlinJsCompilerOptions.configureJsDefaultOptions(
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinCompilationNpmResolver.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinCompilationNpmResolver.kt
index 88c7d28..4e4ad64 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinCompilationNpmResolver.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/npm/resolver/KotlinCompilationNpmResolver.kt
@@ -92,9 +92,10 @@
if (compilation.isMain()) {
project.tasks
.withType(Zip::class.java)
- .named(npmProject.target.artifactsTaskName)
- .configure {
- it.dependsOn(packageJsonTask)
+ .configureEach {
+ if (it.name == npmProject.target.artifactsTaskName) {
+ it.dependsOn(packageJsonTask)
+ }
}
val publicPackageJsonConfiguration = createPublicPackageJsonConfiguration()
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 b5d493a..73d2935 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
@@ -12,12 +12,9 @@
import org.gradle.api.attributes.Category.CATEGORY_ATTRIBUTE
import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE
import org.gradle.api.file.FileCollection
-import org.gradle.api.plugins.BasePlugin
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.bundling.Jar
-import org.gradle.api.tasks.bundling.Zip
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
-import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.dsl.metadataTarget
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
@@ -28,14 +25,10 @@
import org.jetbrains.kotlin.gradle.targets.native.internal.createCInteropMetadataDependencyClasspath
import org.jetbrains.kotlin.gradle.targets.native.internal.includeCommonizedCInteropMetadata
import org.jetbrains.kotlin.gradle.targets.native.internal.sharedCommonizerTarget
-import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
-import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
import org.jetbrains.kotlin.gradle.tasks.registerTask
-import org.jetbrains.kotlin.gradle.utils.whenEvaluated
import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import org.jetbrains.kotlin.tooling.core.extrasLazyProperty
-import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
internal const val COMMON_MAIN_ELEMENTS_CONFIGURATION_NAME = "commonMainMetadataElements"
@@ -90,22 +83,10 @@
compileKotlinTaskProvider.configure { it.onlyIf { isCompatibilityMetadataVariantEnabled } }
}
- val allMetadataJar = target.project.tasks.named<Jar>(ALL_METADATA_JAR_NAME)
- createMetadataCompilationsForCommonSourceSets(target, allMetadataJar)
-
- configureProjectStructureMetadataGeneration(target.project, allMetadataJar)
+ createMetadataCompilationsForCommonSourceSets(target)
configureMetadataDependenciesConfigurationsForCommonSourceSets(target)
- target.project.configurations.getByName(target.apiElementsConfigurationName).run {
- attributes.attribute(USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA))
- attributes.attribute(CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
- /** Note: to add this artifact here is enough to avoid duplicate artifacts in this configuration: the default artifact
- * won't be added (later) if there's already an artifact in the configuration, see
- * [KotlinOnlyTargetConfigurator.configureArchivesAndComponent] */
- target.project.artifacts.add(target.apiElementsConfigurationName, allMetadataJar)
- }
-
if (target.project.isCompatibilityMetadataVariantEnabled) {
createCommonMainElementsConfiguration(target)
}
@@ -115,47 +96,6 @@
}
}
- override fun createArchiveTasks(target: KotlinMetadataTarget): TaskProvider<out Zip> {
- if (!target.project.isKotlinGranularMetadataEnabled)
- return super.createArchiveTasks(target)
-
- val result = target.project.registerTask<Jar>(target.artifactsTaskName) {
- it.group = BasePlugin.BUILD_GROUP
- it.isReproducibleFileOrder = true
- it.isPreserveFileTimestamps = false
- /** The content is added to this JAR in [KotlinMetadataTargetConfigurator.configureTarget]. */
- }
-
- result.configure { allMetadataJar ->
- allMetadataJar.description = "Assembles a jar archive containing the metadata for all Kotlin source sets."
- allMetadataJar.group = BasePlugin.BUILD_GROUP
-
- if (target.project.isCompatibilityMetadataVariantEnabled) {
- allMetadataJar.archiveClassifier.set("all")
- }
-
- target.disambiguationClassifier?.let { classifier ->
- allMetadataJar.archiveAppendix.set(classifier.toLowerCaseAsciiOnly())
- }
- }
-
- if (target.project.isCompatibilityMetadataVariantEnabled) {
- val legacyJar = target.project.registerTask<Jar>(target.legacyArtifactsTaskName)
- legacyJar.configure {
- // Capture it here to use in onlyIf spec. Direct usage causes serialization of target attempt when configuration cache is enabled
- val isCompatibilityMetadataVariantEnabled = target.project.isCompatibilityMetadataVariantEnabled
- it.description = "Assembles an archive containing the Kotlin metadata of the commonMain source set."
- if (!isCompatibilityMetadataVariantEnabled) {
- it.archiveClassifier.set("commonMain")
- }
- it.onlyIf { isCompatibilityMetadataVariantEnabled }
- it.from(target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME).output.allOutputs)
- }
- }
-
- return result
- }
-
private fun configureMetadataDependenciesConfigurationsForCommonSourceSets(target: KotlinMetadataTarget) {
target.project.whenEvaluated {
kotlinExtension.sourceSets.all { sourceSet ->
@@ -169,7 +109,6 @@
private fun createMetadataCompilationsForCommonSourceSets(
target: KotlinMetadataTarget,
- allMetadataJar: TaskProvider<out Jar>,
) = target.project.launchInStage(KotlinPluginLifecycle.Stage.AfterFinaliseDsl) {
withRestrictedStages(KotlinPluginLifecycle.Stage.upTo(KotlinPluginLifecycle.Stage.FinaliseCompilations)) {
// Do this after all targets are configured by the user build script
@@ -179,7 +118,7 @@
val sourceSetsWithMetadataCompilations: Map<KotlinSourceSet, KotlinCompilation<*>> = publishedCommonSourceSets
.associateWith { sourceSet ->
- createMetadataCompilation(target, sourceSet, allMetadataJar, sourceSet in hostSpecificSourceSets)
+ createMetadataCompilation(target, sourceSet, sourceSet in hostSpecificSourceSets)
}
.onEach { (sourceSet, compilation) ->
if (!isMetadataCompilationSupported(sourceSet)) {
@@ -224,16 +163,6 @@
return true
}
- private fun configureProjectStructureMetadataGeneration(project: Project, allMetadataJar: TaskProvider<out Jar>) {
- val generateMetadata = project.createGenerateProjectStructureMetadataTask()
-
- allMetadataJar.configure {
- it.from(generateMetadata.map { it.resultFile }) { spec ->
- spec.into("META-INF").rename { MULTIPLATFORM_PROJECT_METADATA_JSON_FILE_NAME }
- }
- }
- }
-
private fun exportDependenciesForPublishing(
compilation: KotlinCompilation<*>,
) {
@@ -274,7 +203,6 @@
private suspend fun createMetadataCompilation(
target: KotlinMetadataTarget,
sourceSet: KotlinSourceSet,
- allMetadataJar: TaskProvider<out Jar>,
isHostSpecific: Boolean,
): KotlinCompilation<*> {
val project = target.project
@@ -300,13 +228,7 @@
configureMetadataDependenciesForCompilation(this@apply)
- if (!isHostSpecific) {
- val metadataContent = project.filesWithUnpackedArchives(this@apply.output.allOutputs, setOf("klib"))
- allMetadataJar.configure { it.from(metadataContent) { spec -> spec.into(this@apply.defaultSourceSet.name) } }
- if (this is KotlinSharedNativeCompilation) {
- project.includeCommonizedCInteropMetadata(allMetadataJar, this)
- }
- } else {
+ if (isHostSpecific) {
if (platformCompilations.filterIsInstance<KotlinNativeCompilation>().none { it.konanTarget.enabledOnCurrentHost }) {
// Then we don't have any platform module to put this compiled source set to, so disable the compilation task:
compileKotlinTaskProvider.configure { it.enabled = false }
@@ -365,15 +287,6 @@
}
}
-internal class NativeSharedCompilationProcessor(
- private val compilation: KotlinSharedNativeCompilation,
-) : KotlinCompilationProcessor<KotlinNativeCompile>(KotlinCompilationInfo(compilation)) {
-
- override val kotlinTask: TaskProvider<out KotlinNativeCompile> =
- KotlinNativeTargetConfigurator.createKlibCompilationTask(compilationInfo, compilation.konanTarget)
-
- override fun run() = Unit
-}
internal fun Project.createGenerateProjectStructureMetadataTask(): TaskProvider<GenerateProjectStructureMetadata> =
project.registerTask(lowerCamelCaseName("generateProjectStructureMetadata")) { task ->
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTarget.kt
index de7828f..f2c8168 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTarget.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTarget.kt
@@ -36,7 +36,7 @@
abstract class KotlinNativeTarget @Inject constructor(
project: Project,
- val konanTarget: KonanTarget
+ val konanTarget: KonanTarget,
) : KotlinTargetWithBinaries<KotlinNativeCompilation, KotlinNativeBinaryContainer>(
project,
KotlinPlatformType.native
@@ -64,44 +64,11 @@
.intersect(mainCompilation.allKotlinSourceSets)
if (hostSpecificSourceSets.isNotEmpty()) {
- val hostSpecificMetadataJar = project.locateOrRegisterTask<Jar>(hostSpecificMetadataJarTaskName) { metadataJar ->
- metadataJar.archiveAppendix.set(project.provider { disambiguationClassifier.orEmpty().toLowerCaseAsciiOnly() })
- metadataJar.archiveClassifier.set("metadata")
- metadataJar.group = BasePlugin.BUILD_GROUP
- metadataJar.description = "Assembles Kotlin metadata of target '${name}'."
-
- val publishable = this@KotlinNativeTarget.publishable
- metadataJar.onlyIf { publishable }
-
- launch {
- val metadataCompilations = hostSpecificSourceSets.mapNotNull {
- project.findMetadataCompilation(it)
- }
-
- metadataCompilations.forEach { compilation ->
- metadataJar.from(project.filesWithUnpackedArchives(compilation.output.allOutputs, setOf("klib"))) { spec ->
- spec.into(compilation.name)
- }
- metadataJar.dependsOn(compilation.output.classesDirs)
-
- if (compilation is KotlinSharedNativeCompilation) {
- project.includeCommonizedCInteropMetadata(metadataJar, compilation)
- }
- }
- }
- }
- project.artifacts.add(Dependency.ARCHIVES_CONFIGURATION, hostSpecificMetadataJar)
-
- val metadataConfiguration = project.configurations.getByName(hostSpecificMetadataElementsConfigurationName)
- project.artifacts.add(metadataConfiguration.name, hostSpecificMetadataJar) { artifact ->
- artifact.classifier = "metadata"
- }
-
mutableUsageContexts.add(
DefaultKotlinUsageContext(
mainCompilation,
KotlinUsageContext.MavenScope.COMPILE,
- metadataConfiguration.name,
+ hostSpecificMetadataElementsConfigurationName,
includeIntoProjectStructureMetadata = false
)
)
@@ -196,7 +163,7 @@
private suspend fun <T> getHostSpecificElements(
fragments: Iterable<T>,
isNativeShared: suspend (T) -> Boolean,
- getKonanTargets: suspend (T) -> Set<KonanTarget>
+ getKonanTargets: suspend (T) -> Set<KonanTarget>,
): Set<T> = fragments.filterTo(mutableSetOf()) { isNativeShared(it) && isHostSpecificKonanTargetsSet(getKonanTargets(it)) }
internal suspend fun getHostSpecificSourceSets(project: Project): Set<KotlinSourceSet> {
@@ -234,7 +201,7 @@
abstract class KotlinNativeTargetWithTests<T : KotlinNativeBinaryTestRun>(
project: Project,
- konanTarget: KonanTarget
+ konanTarget: KonanTarget,
) : KotlinNativeTarget(project, konanTarget), KotlinTargetWithTests<NativeBinaryTestRunSource, T> {
override lateinit var testRuns: NamedDomainObjectContainer<T>
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 f44e404..c58efcfe 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
@@ -32,6 +32,8 @@
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XcodeVersionTask
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.registerEmbedAndSignAppleFrameworkTask
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.version
+import org.jetbrains.kotlin.gradle.targets.createKlibArtifact
+import org.jetbrains.kotlin.gradle.targets.klibOutputDirectory
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
import org.jetbrains.kotlin.gradle.targets.native.*
import org.jetbrains.kotlin.gradle.targets.native.internal.*
@@ -150,8 +152,7 @@
// Add the interop library in publication.
createKlibArtifact(
- compilationInfo = compilationInfo,
- konanTarget = konanTarget,
+ compilation,
artifactFile = interopTask.map { it.outputFile },
classifier = "cinterop-${interop.name}",
producingTask = interopTask,
@@ -187,30 +188,6 @@
}
}
- override fun configureArchivesAndComponent(target: T): Unit = with(target.project) {
- registerTask<DefaultTask>(target.artifactsTaskName) {
- it.group = BasePlugin.BUILD_GROUP
- it.description = "Assembles outputs for target '${target.name}'."
- }
- target.compilations.all { createKlibCompilationTask(KotlinCompilationInfo(it), it.konanTarget) }
-
- val apiElements = configurations.getByName(target.apiElementsConfigurationName)
-
- apiElements.outgoing.attributes.attribute(artifactTypeAttribute, NativeArtifactFormat.KLIB)
-
- if (project.isKotlinGranularMetadataEnabled) {
- project.configurations.create(target.hostSpecificMetadataElementsConfigurationName) { configuration ->
- configuration.isCanBeConsumed = true
- configuration.isCanBeResolved = false
-
- configuration.extendsFrom(*apiElements.extendsFrom.toTypedArray())
-
- copyAttributes(from = apiElements.attributes, to = configuration.attributes)
- configuration.attributes.attribute(USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_METADATA))
- }
- }
- }
-
protected fun configureCInterops(target: KotlinNativeTarget): Unit = with(target.project) {
locateOrCreateCInteropApiElementsConfiguration(target)
target.compilations.all { compilation ->
@@ -352,130 +329,7 @@
const val INTEROP_GROUP = "interop"
const val RUN_GROUP = "run"
- internal fun createKlibCompilationTask(
- compilationInfo: KotlinCompilationInfo,
- konanTarget: KonanTarget,
- ): TaskProvider<KotlinNativeCompile> {
- val project = compilationInfo.project
- val ext = project.topLevelExtension
- val compileTaskProvider = project.registerTask<KotlinNativeCompile>(
- compilationInfo.compileKotlinTaskName,
- listOf(
- compilationInfo,
- compilationInfo.compilerOptions.options as KotlinNativeCompilerOptions
- )
- ) {
- it.group = BasePlugin.BUILD_GROUP
- it.description = "Compiles a klibrary from the '${compilationInfo.compilationName}' " +
- "compilation in target '${compilationInfo.targetDisambiguationClassifier}'."
- it.enabled = konanTarget.enabledOnCurrentHost
- it.destinationDirectory.set(project.klibOutputDirectory(compilationInfo).dir("klib"))
- val propertiesProvider = PropertiesProvider(project)
- if (propertiesProvider.useK2 == true) {
- it.compilerOptions.useK2.set(true)
- }
- it.runViaBuildToolsApi.value(false).disallowChanges() // K/N is not yet supported
-
- it.explicitApiMode
- .value(
- project.providers.provider {
- // Plugin explicitly does not configures 'explicitApi' mode for test sources
- // compilation, as test sources are not published
- if (compilationInfo.isMain) {
- ext.explicitApi
- } else {
- ExplicitApiMode.Disabled
- }
- }
- )
- .finalizeValueOnRead()
-
- }
-
- compilationInfo.classesDirs.from(compileTaskProvider.map { it.outputFile })
-
- project.project.tasks.named(compilationInfo.compileAllTaskName).dependsOn(compileTaskProvider)
-
- if (compilationInfo.isMain) {
- if (compilationInfo is KotlinCompilationInfo.TCS && compilationInfo.compilation is KotlinNativeCompilation) {
- project.project.tasks.named(compilationInfo.compilation.target.artifactsTaskName).dependsOn(compileTaskProvider)
- }
-
- project.project.tasks.named(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(compileTaskProvider)
- }
-
- val shouldAddCompileOutputsToElements = compilationInfo.isMain
- if (shouldAddCompileOutputsToElements) {
- createRegularKlibArtifact(compilationInfo, konanTarget, compileTaskProvider)
- }
-
- if (compilationInfo is KotlinCompilationInfo.TCS && compilationInfo.compilation is AbstractKotlinNativeCompilation) {
- // FIXME: support compiler plugins for PM20
- addCompilerPlugins(compilationInfo.compilation)
- }
-
- return compileTaskProvider
- }
-
- private fun Project.klibOutputDirectory(
- compilation: KotlinCompilationInfo,
- ): DirectoryProperty {
- val targetSubDirectory = compilation.targetDisambiguationClassifier?.let { "$it/" }.orEmpty()
- return project.objects.directoryProperty().value(
- layout.buildDirectory.dir("classes/kotlin/$targetSubDirectory${compilation.compilationName}")
- )
- }
-
- private fun addCompilerPlugins(compilation: AbstractKotlinNativeCompilation) {
- val project = compilation.target.project
-
- project.whenEvaluated {
- SubpluginEnvironment
- .loadSubplugins(project)
- .addSubpluginOptions(project, compilation)
-
- compilation.compileKotlinTaskProvider.configure {
- it.compilerPluginClasspath = compilation.configurations.pluginConfiguration
- }
- }
- }
-
- internal fun createRegularKlibArtifact(
- compilation: KotlinCompilationInfo,
- konanTarget: KonanTarget,
- compileTask: TaskProvider<out KotlinNativeCompile>,
- ) = createKlibArtifact(compilation, konanTarget, compileTask.map { it.outputFile.get() }, null, compileTask)
-
- private fun createKlibArtifact(
- compilationInfo: KotlinCompilationInfo,
- konanTarget: KonanTarget,
- artifactFile: Provider<File>,
- classifier: String?,
- producingTask: TaskProvider<*>,
- ) {
- val project = compilationInfo.project
- if (!konanTarget.enabledOnCurrentHost) {
- return
- }
-
- val apiElementsName = when (compilationInfo) {
- is KotlinCompilationInfo.TCS -> compilationInfo.compilation.target.apiElementsConfigurationName
- }
-
- with(project.configurations.getByName(apiElementsName)) {
- val klibArtifact = project.project.artifacts.add(name, artifactFile) { artifact ->
- artifact.name = compilationInfo.compilationName
- artifact.extension = "klib"
- artifact.type = "klib"
- artifact.classifier = classifier
- artifact.builtBy(producingTask)
- }
- project.project.extensions.getByType(DefaultArtifactPublicationSet::class.java).addCandidate(klibArtifact)
- artifacts.add(klibArtifact)
- attributes.attribute(project.artifactTypeAttribute, NativeArtifactFormat.KLIB)
- }
- }
}
}
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/createKotlinKlibCompilationTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/createKotlinKlibCompilationTask.kt
new file mode 100644
index 0000000..894a2dc
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/createKotlinKlibCompilationTask.kt
@@ -0,0 +1,32 @@
+/*
+ * 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.targets.native
+
+import org.gradle.api.Project
+import org.gradle.api.file.DirectoryProperty
+import org.gradle.api.internal.plugins.DefaultArtifactPublicationSet
+import org.gradle.api.plugins.BasePlugin
+import org.gradle.api.provider.Provider
+import org.gradle.api.tasks.TaskProvider
+import org.gradle.language.base.plugins.LifecycleBasePlugin
+import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
+import org.jetbrains.kotlin.gradle.dsl.KotlinNativeCompilerOptions
+import org.jetbrains.kotlin.gradle.dsl.topLevelExtension
+import org.jetbrains.kotlin.gradle.plugin.*
+import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationInfo
+import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterEvaluateBuildscript
+import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
+import org.jetbrains.kotlin.gradle.plugin.internal.artifactTypeAttribute
+import org.jetbrains.kotlin.gradle.plugin.launchInStage
+import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinNativeCompilation
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
+import org.jetbrains.kotlin.gradle.plugin.mpp.enabledOnCurrentHost
+import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
+import org.jetbrains.kotlin.gradle.tasks.dependsOn
+import org.jetbrains.kotlin.gradle.tasks.registerTask
+import org.jetbrains.kotlin.konan.target.KonanTarget
+import java.io.File
+