[Gradle] Fix eager task realization due to attributes querying

Gradle 8.3+ starts triggering JVM eager tasks creating via eagerly
configured attributes that we copy over from the Gradle JVM plugin for
Kotlin compilation. The fix is to migrate to '.attributeProvider()' API
to configure the attribute.

^KT-60664 In Progress
This commit is contained in:
Yahor Berdnikau
2023-12-21 22:18:33 +01:00
committed by Space Team
parent 2da6946ac2
commit dbd77fc785
58 changed files with 563 additions and 222 deletions
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.gradle
import org.gradle.api.logging.configuration.WarningMode
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.testbase.*
import org.junit.jupiter.api.DisplayName
@@ -27,7 +26,8 @@ class ConfigurationAvoidanceIT : KGPBaseTest() {
@JvmGradlePluginTests
@GradleTestVersions(
additionalVersions = [TestVersions.Gradle.G_7_3]
additionalVersions = [TestVersions.Gradle.G_7_3],
maxVersion = TestVersions.Gradle.G_8_3
)
@DisplayName("KGP/Jvm does not eagerly configure any tasks")
@GradleTest
@@ -648,7 +648,7 @@ class KotlinGradleIT : KGPBaseTest() {
subProject("projB").buildGradle.appendText("\nkotlin.target.attributes.attribute(targetAttribute, \"bar\")")
buildAndFail(":projB:compileKotlin") {
when {
gradleVersion < GradleVersion.version("6.8.4") -> {
gradleVersion <= GradleVersion.version(TestVersions.Gradle.G_6_8) -> {
assertOutputContains(
"No matching variant of project :projA was found. The consumer was configured to find an API of a library " +
"compatible with Java 8, preferably in the form of class files, " +
@@ -659,14 +659,19 @@ class KotlinGradleIT : KGPBaseTest() {
)
}
else -> {
assertOutputContains(
"No matching variant of project :projA was found. The consumer was configured to find a library for use during compile-time, " +
"compatible with Java 8, preferably in the form of class files, " +
"preferably optimized for standard JVMs, and its dependencies declared externally, " +
"as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm', " +
"attribute 'com.example.compilation' with value 'foo', " +
"attribute 'com.example.target' with value 'bar' but:"
)
// Attributes may come in random order
val attributeMatchingString = output.lineSequence().find {
it.trimStart().startsWith(
"> No matching variant of project :projA was found. " +
"The consumer was configured to find a library for use during compile-time, " +
"compatible with Java 8, preferably in the form of class files, " +
"preferably optimized for standard JVMs, and its dependencies declared externally, "
)
}
assertNotNull(attributeMatchingString, "Expected variant mismatch string is not found")
assertTrue(attributeMatchingString.contains("attribute 'com.example.compilation' with value 'foo'"))
assertTrue(attributeMatchingString.contains("attribute 'com.example.target' with value 'bar'"))
assertTrue(attributeMatchingString.contains("attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'"))
}
}
}
@@ -681,7 +686,7 @@ class KotlinGradleIT : KGPBaseTest() {
)
buildAndFail(":projB:compileKotlin") {
when {
gradleVersion < GradleVersion.version("6.8.4") -> {
gradleVersion <= GradleVersion.version(TestVersions.Gradle.G_6_8) -> {
assertOutputContains(
"No matching variant of project :projA was found. The consumer was configured to find an API of a library " +
"compatible with Java 8, preferably in the form of class files, and its dependencies declared externally, " +
@@ -691,14 +696,19 @@ class KotlinGradleIT : KGPBaseTest() {
)
}
else -> {
assertOutputContains(
"No matching variant of project :projA was found. The consumer was configured to find a library for use during compile-time, " +
"compatible with Java 8, preferably in the form of class files, preferably optimized for standard JVMs, " +
"and its dependencies declared externally, " +
"as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm', " +
"attribute 'com.example.compilation' with value 'bar', " +
"attribute 'com.example.target' with value 'foo' but:"
)
// Attributes may come in random order
val attributeMatchingString = output.lineSequence().find {
it.contains(
"No matching variant of project :projA was found. " +
"The consumer was configured to find a library for use during compile-time, " +
"compatible with Java 8, preferably in the form of class files, " +
"preferably optimized for standard JVMs, and its dependencies declared externally, "
)
}
assertNotNull(attributeMatchingString, "Expected variant mismatch string is not found")
assertTrue(attributeMatchingString.contains("attribute 'com.example.compilation' with value 'bar'"))
assertTrue(attributeMatchingString.contains("attribute 'com.example.target' with value 'foo'"))
assertTrue(attributeMatchingString.contains("attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'"))
}
}
}
@@ -52,8 +52,14 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge
In this example we hardcoded AGP version 7.4.0-beta02 as demo
*/
apiElements.configure { _, configuration ->
configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID))
configuration.attributes.attribute(AgpVersionAttr.ATTRIBUTE, project.objects.named("7.4.0-beta02")) /* For demo */
configuration.attributes.attributeProvider(
TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.provider { project.objects.named(TargetJvmEnvironment.ANDROID) }
)
configuration.attributes.attributeProvider(
AgpVersionAttr.ATTRIBUTE,
project.provider { project.objects.named("7.4.0-beta02") } /* For demo */
)
}
/*
@@ -61,8 +67,14 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge
In this example we hardcoded AGP version 7.4.0-beta02 as demo
*/
runtimeElements.configure { _, configuration ->
configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID))
configuration.attributes.attribute(AgpVersionAttr.ATTRIBUTE, project.objects.named("7.4.0-beta02")) /* For demo */
configuration.attributes.attributeProvider(
TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.provider { project.objects.named(TargetJvmEnvironment.ANDROID) }
)
configuration.attributes.attributeProvider(
AgpVersionAttr.ATTRIBUTE,
project.provider { project.objects.named("7.4.0-beta02") } /* For demo */
)
}
/*
@@ -70,8 +82,16 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge
In this example we hardcoded AGP version 7.4.0-beta02 as demo
*/
sourcesElements.configure { _, configuration ->
configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID))
configuration.attributes.attribute(AgpVersionAttr.ATTRIBUTE, project.objects.named("7.4.0-beta02")) /* For demo */
configuration.attributes.attributeProvider(
TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.provider { project.objects.named(TargetJvmEnvironment.ANDROID) }
)
configuration.attributes.attributeProvider(
AgpVersionAttr.ATTRIBUTE,
project.provider {
project.objects.named("7.4.0-beta02") /* For demo */
}
)
}
/*
@@ -80,14 +100,30 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge
*/
apiElementsPublished.configure { _, configuration ->
/* TODO w/ Google: Find a way to deprecate this attribute */
configuration.attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.androidJvm)
configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID))
configuration.attributes.attributeProvider(
KotlinPlatformType.attribute,
project.provider { KotlinPlatformType.androidJvm }
)
configuration.attributes.attributeProvider(
TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.provider {
project.objects.named(TargetJvmEnvironment.ANDROID)
}
)
}
runtimeElementsPublished.configure { _, configuration ->
/* TODO w/ Google: Find a way to deprecate this attribute */
configuration.attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.androidJvm)
configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID))
configuration.attributes.attributeProvider(
KotlinPlatformType.attribute,
project.provider { KotlinPlatformType.androidJvm }
)
configuration.attributes.attributeProvider(
TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.provider {
project.objects.named(TargetJvmEnvironment.ANDROID)
}
)
}
configureIdeImport {
@@ -165,7 +201,10 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge
artifactType: CLASSES_JAR
*/
androidTarget.apiElementsConfiguration.outgoing.variants.create("classes").let { variant ->
variant.attributes.attribute(AndroidArtifacts.ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type)
variant.attributes.attributeProvider(
AndroidArtifacts.ARTIFACT_TYPE,
project.provider { AndroidArtifacts.ArtifactType.CLASSES_JAR.type }
)
variant.artifact(mainCompilation.output.classesDirs.singleFile) {
it.builtBy(mainCompilation.output.classesDirs)
}
@@ -178,7 +217,10 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge
artifactType: CLASSES_JAR
*/
androidTarget.runtimeElementsConfiguration.outgoing.variants.create("classes").let { variant ->
variant.attributes.attribute(AndroidArtifacts.ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type)
variant.attributes.attributeProvider(
AndroidArtifacts.ARTIFACT_TYPE,
project.provider { AndroidArtifacts.ArtifactType.CLASSES_JAR.type }
)
variant.artifact(mainCompilation.output.classesDirs.singleFile) {
it.builtBy(mainCompilation.output.classesDirs)
}
@@ -41,14 +41,26 @@ internal fun PrototypeAndroidTarget.createAndroidCompilation(name: String): Prot
configure { compilation ->
/* Setup attributes for the compile dependencies */
compilation.configurations.compileDependencyConfiguration.apply {
attributes.attribute(ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type)
attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID))
attributes.attributeProvider(
ARTIFACT_TYPE,
project.provider { AndroidArtifacts.ArtifactType.CLASSES_JAR.type }
)
attributes.attributeProvider(
TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.provider { project.objects.named(TargetJvmEnvironment.ANDROID) }
)
}
/* Setup attributes for the runtime dependencies */
compilation.configurations.runtimeDependencyConfiguration?.apply {
attributes.attribute(ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type)
attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID))
attributes.attributeProvider(
ARTIFACT_TYPE,
project.provider { AndroidArtifacts.ArtifactType.CLASSES_JAR.type }
)
attributes.attributeProvider(
TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.provider { project.objects.named(TargetJvmEnvironment.ANDROID) }
)
}
}
}
@@ -20,22 +20,23 @@ import org.jetbrains.kotlin.gradle.plugin.usageByName
import org.jetbrains.kotlin.gradle.utils.createResolvable
import org.jetbrains.kotlin.gradle.utils.findResolvable
import org.jetbrains.kotlin.gradle.utils.named
import org.jetbrains.kotlin.gradle.utils.setAttribute
private const val KOTLIN_KLIB_COMMONIZER_EMBEDDABLE = "kotlin-klib-commonizer-embeddable"
internal fun GradleCliCommonizer(commonizerToolRunner: KotlinNativeCommonizerToolRunner): CliCommonizer {
return CliCommonizer(CliCommonizer.Executor { arguments ->
return CliCommonizer { arguments ->
commonizerToolRunner.run(arguments)
})
}
}
internal fun Project.maybeCreateCommonizerClasspathConfiguration(): Configuration {
return configurations.findResolvable(KLIB_COMMONIZER_CLASSPATH_CONFIGURATION_NAME)
?: project.configurations.createResolvable(KLIB_COMMONIZER_CLASSPATH_CONFIGURATION_NAME)
.run {
attributes.attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY))
attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR))
attributes.attribute(Usage.USAGE_ATTRIBUTE, usageByName(Usage.JAVA_RUNTIME))
attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY))
attributes.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR))
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, usageByName(Usage.JAVA_RUNTIME))
defaultDependencies { dependencies ->
dependencies.add(
project.dependencies.create("$KOTLIN_MODULE_GROUP:$KOTLIN_KLIB_COMMONIZER_EMBEDDABLE:${getKotlinPluginVersion()}")
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.gradle.targets.metadata.isCompatibilityMetadataVaria
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.createConsumable
import org.jetbrains.kotlin.gradle.utils.setAttribute
internal val KotlinLegacyCompatibilityMetadataArtifact = KotlinTargetArtifact { target, _, _ ->
if (target !is KotlinMetadataTarget) return@KotlinTargetArtifact
@@ -39,8 +40,8 @@ internal val KotlinLegacyCompatibilityMetadataArtifact = KotlinTargetArtifact {
target.project.configurations.createConsumable(COMMON_MAIN_ELEMENTS_CONFIGURATION_NAME).apply {
usesPlatformOf(target)
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target))
attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
val commonMainApiConfiguration = target.project.configurations.sourceSetDependencyConfigurationByScope(
target.project.kotlinExtension.sourceSets.getByName(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME),
@@ -15,12 +15,13 @@ import org.jetbrains.kotlin.gradle.targets.metadata.createGenerateProjectStructu
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
import org.jetbrains.kotlin.gradle.utils.setAttribute
internal val KotlinMetadataArtifact = 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))
apiElements.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA))
apiElements.attributes.setAttribute(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."
@@ -21,8 +21,9 @@ 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.gradle.utils.copyAttributesTo
import org.jetbrains.kotlin.gradle.utils.createConsumable
import org.jetbrains.kotlin.gradle.utils.setAttribute
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
internal val KotlinNativeHostSpecificMetadataArtifact = KotlinTargetArtifact { target, apiElements, _ ->
@@ -34,8 +35,14 @@ internal val KotlinNativeHostSpecificMetadataArtifact = KotlinTargetArtifact { t
configuration.extendsFrom(*apiElements.extendsFrom.toTypedArray())
target.project.launchInStage(AfterFinaliseDsl) {
copyAttributes(from = apiElements.attributes, to = configuration.attributes)
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA))
apiElements.copyAttributesTo(
target.project,
dest = configuration.attributes
)
configuration.setAttribute(
Usage.USAGE_ATTRIBUTE,
target.project.usageByName(KotlinUsages.KOTLIN_METADATA)
)
}
}
@@ -21,6 +21,7 @@ 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 org.jetbrains.kotlin.gradle.utils.setAttribute
import java.io.File
internal val KotlinNativeKlibArtifact = KotlinTargetArtifact { target, apiElements, _ ->
@@ -31,7 +32,7 @@ internal val KotlinNativeKlibArtifact = KotlinTargetArtifact { target, apiElemen
it.description = "Assembles outputs for target '${target.name}'."
}
apiElements.outgoing.attributes.attribute(target.project.artifactTypeAttribute, NativeArtifactFormat.KLIB)
apiElements.outgoing.attributes.setAttribute(target.project.artifactTypeAttribute, NativeArtifactFormat.KLIB)
target.compilations.getByName(MAIN_COMPILATION_NAME).let { mainCompilation ->
artifactsTask.dependsOn(mainCompilation.compileTaskProvider)
@@ -67,7 +68,7 @@ internal fun createKlibArtifact(
}
compilation.project.extensions.getByType(DefaultArtifactPublicationSet::class.java).addCandidate(klibArtifact)
artifacts.add(klibArtifact)
attributes.attribute(compilation.project.artifactTypeAttribute, NativeArtifactFormat.KLIB)
attributes.setAttribute(compilation.project.artifactTypeAttribute, NativeArtifactFormat.KLIB)
}
}
@@ -15,6 +15,7 @@ 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.gradle.utils.setAttribute
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
internal fun interface KotlinTargetArtifact {
@@ -52,8 +53,8 @@ internal fun KotlinTarget.createPublishArtifact(
elementsConfiguration.filterNotNull().forEach { configuration ->
configuration.outgoing.artifacts.add(artifact)
configuration.outgoing.attributes.attribute(project.artifactTypeAttribute, artifactType)
configuration.outgoing.attributes.setAttribute(project.artifactTypeAttribute, artifactType)
}
return artifact
}
}
@@ -151,7 +151,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
project.configurations.findResolvable(configurationName)?.let { return it }
val aptConfiguration = project.configurations.createResolvable(configurationName).apply {
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, Usage.JAVA_RUNTIME))
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME))
}
if (aptConfiguration.name != MAIN_KAPT_CONFIGURATION_NAME) {
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.gradle.tasks.locateTask
import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.whenEvaluated
import org.jetbrains.kotlin.gradle.utils.archivePathCompatible
import org.jetbrains.kotlin.gradle.utils.setAttribute
const val PLUGIN_CLASSPATH_CONFIGURATION_NAME = "kotlinCompilerPluginClasspath"
const val NATIVE_COMPILER_PLUGIN_CLASSPATH_CONFIGURATION_NAME = "kotlinNativeCompilerPluginClasspath"
@@ -270,14 +271,14 @@ internal abstract class AbstractKotlinPlugin(
// platform-specific modules
if (kotlinTarget.platformType != KotlinPlatformType.common) {
project.configurations.getByName(kotlinTarget.apiElementsConfigurationName).run {
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(kotlinTarget))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(kotlinTarget))
attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
usesPlatformOf(kotlinTarget)
}
project.configurations.getByName(kotlinTarget.runtimeElementsConfigurationName).run {
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(kotlinTarget))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(kotlinTarget))
attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
usesPlatformOf(kotlinTarget)
}
}
@@ -181,6 +181,11 @@ abstract class DefaultKotlinBasePlugin : KotlinBasePlugin {
SourceSetCompatibilityHelper.SourceSetCompatibilityHelperVariantFactory::class,
DefaultSourceSetCompatibilityHelperVariantFactory()
)
factories.putIfAbsent(
AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory::class,
DefaultAttributeConfigurationHelperVariantFactory()
)
}
protected fun setupAttributeMatchingStrategy(
@@ -9,6 +9,9 @@ import org.gradle.api.Named
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.attributes.*
import org.gradle.api.attributes.java.TargetJvmEnvironment
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.runKotlinCompilationSideEffects
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute
@@ -53,7 +56,7 @@ internal inline fun <reified T : Named> Project.attributeValueByName(attributeVa
objects.named(T::class.java, attributeValueName)
fun Configuration.usesPlatformOf(target: KotlinTarget): Configuration {
attributes.attribute(KotlinPlatformType.attribute, target.platformType)
attributes.setAttribute(KotlinPlatformType.attribute, target.platformType)
when (target.platformType) {
KotlinPlatformType.jvm -> setJavaTargetEnvironmentAttributeIfSupported(target.project, "standard-jvm")
@@ -72,33 +75,31 @@ fun Configuration.usesPlatformOf(target: KotlinTarget): Configuration {
else -> setJavaTargetEnvironmentAttributeIfSupported(target.project, "non-jvm")
}
val publishJsCompilerAttribute = PropertiesProvider(target.project).publishJsCompilerAttribute
val publishJsCompilerAttribute = target.project.kotlinPropertiesProvider.publishJsCompilerAttribute
if (publishJsCompilerAttribute && target is KotlinJsIrTarget) {
if (target.platformType == KotlinPlatformType.js) {
attributes.attribute(KotlinJsCompilerAttribute.jsCompilerAttribute, KotlinJsCompilerAttribute.ir)
attributes.setAttribute(KotlinJsCompilerAttribute.jsCompilerAttribute, KotlinJsCompilerAttribute.ir)
} else {
attributes.attribute(KotlinWasmTargetAttribute.wasmTargetAttribute, target.wasmTargetType!!.toAttribute())
attributes.setAttributeProvider<KotlinWasmTargetAttribute>(
target.project,
KotlinWasmTargetAttribute.wasmTargetAttribute,
) { target.wasmTargetType!!.toAttribute() }
}
}
// TODO: Provide an universal way to copy attributes from the target.
if (target is KotlinNativeTarget) {
attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.konanTarget.name)
attributes.setAttribute(KotlinNativeTarget.konanTargetAttribute, target.konanTarget.name)
}
return this
}
private fun Configuration.setJavaTargetEnvironmentAttributeIfSupported(project: Project, value: String) {
if (isGradleVersionAtLeast(7, 0)) {
@Suppress("UNCHECKED_CAST")
val attributeClass = Class.forName("org.gradle.api.attributes.java.TargetJvmEnvironment") as Class<out Named>
@Suppress("UNCHECKED_CAST")
val attributeKey = attributeClass.getField("TARGET_JVM_ENVIRONMENT_ATTRIBUTE").get(null) as Attribute<Named>
val attributeValue = project.objects.named(attributeClass, value)
attributes.attribute(attributeKey, attributeValue)
if (GradleVersion.current() >= GradleVersion.version("7.0")) {
attributes.setAttribute(
TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.objects.named(value)
)
}
}
@@ -9,7 +9,6 @@ package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
import org.gradle.api.Project
import org.gradle.api.artifacts.DependencySubstitutions
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.artifacts.component.ModuleComponentSelector
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.attributes.Category
@@ -23,6 +22,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.ide.IdeDependencyResolver
import org.jetbrains.kotlin.gradle.plugin.usageByName
import org.jetbrains.kotlin.gradle.utils.named
import org.jetbrains.kotlin.gradle.utils.setAttribute
/**
* Resolves dependencies of jvm and Android source sets from the perspective jvm
@@ -32,10 +32,10 @@ internal fun IdeJvmAndAndroidPlatformBinaryDependencyResolver(project: Project):
binaryType = IdeaKotlinBinaryDependency.KOTLIN_COMPILE_BINARY_TYPE,
artifactResolutionStrategy = IdeBinaryDependencyResolver.ArtifactResolutionStrategy.PlatformLikeSourceSet(
setupPlatformResolutionAttributes = {
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(Usage.JAVA_API))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.jvm)
attributes.attribute(
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.usageByName(Usage.JAVA_API))
attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
attributes.setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.jvm)
attributes.setAttribute(
TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE,
project.objects.named(TargetJvmEnvironment.STANDARD_JVM)
)
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.gradle.plugin.ide.dependencyResolvers
import org.gradle.api.Project
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.attributes.Attribute
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinBinaryDependency
import org.jetbrains.kotlin.gradle.idea.tcs.IdeaKotlinDependency
@@ -28,7 +27,8 @@ import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.sources.android.AndroidVariantType
import org.jetbrains.kotlin.gradle.plugin.sources.android.type
import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.utils.copyAttributes
import org.jetbrains.kotlin.gradle.utils.setAttribute
import org.jetbrains.kotlin.gradle.utils.setAttributeProvider
import org.jetbrains.kotlin.gradle.utils.toMap
/**
@@ -112,7 +112,10 @@ internal object IdeJvmAndAndroidSourceDependencyResolver : IdeDependencyResolver
.map { attributes -> attributes.toMap().toList().toSet() }
.reduceOrNull { acc, next -> acc intersect next }
.orEmpty()
.forEach { (key, value) -> @Suppress("UNCHECKED_CAST") attribute(key as Attribute<Any>, value as Any) }
.forEach { (key, value) ->
@Suppress("UNCHECKED_CAST")
setAttributeProvider(sourceSet.project, key as Attribute<Any>) { value as Any }
}
},
componentFilter = { id -> id is ProjectComponentIdentifier }
)
@@ -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.plugin.internal
import org.gradle.api.Project
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.HasAttributes
import org.gradle.api.provider.ProviderFactory
import org.jetbrains.kotlin.gradle.plugin.VariantImplementationFactories
import org.jetbrains.kotlin.gradle.plugin.variantImplementationFactory
/**
* Gradle 7.4 introduced a way of configuring attribute values using a [org.gradle.api.provider.Provider].
* In Gradle 8.3+ using a non-Provider value caused eager task realization (see KT-60664).
*/
internal interface AttributesConfigurationHelper {
fun <T : Any> setAttribute(
attributesContainer: HasAttributes,
key: Attribute<T>,
value: () -> T
)
interface AttributeConfigurationHelperVariantFactory : VariantImplementationFactories.VariantImplementationFactory {
fun getInstance(providerFactory: ProviderFactory): AttributesConfigurationHelper
}
}
internal class DefaultAttributesConfigurationHelper(
private val providerFactory: ProviderFactory
) : AttributesConfigurationHelper {
override fun <T : Any> setAttribute(
attributesContainer: HasAttributes,
key: Attribute<T>,
value: () -> T
) {
attributesContainer.attributes.attributeProvider(
key,
providerFactory.provider { value() }
)
}
}
internal class DefaultAttributeConfigurationHelperVariantFactory :
AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory {
override fun getInstance(
providerFactory: ProviderFactory
): AttributesConfigurationHelper = DefaultAttributesConfigurationHelper(providerFactory)
}
internal val Project.attributesConfigurationHelper
get() = variantImplementationFactory<AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory>()
.getInstance(providers)
@@ -50,11 +50,11 @@ class HierarchyAttributeContainer(
override fun isEmpty(): Boolean = lazyAttributesMap.isEmpty() &&
attributesMap.isEmpty() &&
(parent?.keySet().orEmpty().filter(filterParentAttributes).isEmpty())
(parent?.keySet().orEmpty().toSet().none(filterParentAttributes))
override fun keySet(): Set<Attribute<*>> = lazyAttributesMap.keys +
attributesMap.keys +
parent?.keySet().orEmpty().filter(filterParentAttributes)
parent?.keySet().orEmpty().toSet().filter(filterParentAttributes)
override fun <T : Any> attribute(key: Attribute<T>, value: T): AttributeContainer {
val checkedValue = requireNotNull(value as Any?) { "null values for attributes are not supported" }
@@ -208,13 +208,11 @@ class DefaultKotlinUsageContext(
*/
val result = project.configurations.detachedResolvable().attributes
// Capture type parameter T:
fun <T> copyAttribute(attribute: Attribute<T>, from: AttributeContainer, to: AttributeContainer) {
to.attribute<T>(attribute, from.getAttribute(attribute)!!)
}
filterOutNonPublishableAttributes(configurationAttributes.keySet())
.forEach { copyAttribute(it, configurationAttributes, result) }
configurationAttributes.copyAttributesTo(
project,
dest = result,
keys = filterOutNonPublishableAttributes(configurationAttributes.keySet())
)
return result
}
@@ -16,7 +16,7 @@ import org.gradle.api.internal.project.ProjectInternal
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent
import org.jetbrains.kotlin.gradle.plugin.launchInStage
import org.jetbrains.kotlin.gradle.utils.copyAttributes
import org.jetbrains.kotlin.gradle.utils.copyAttributesTo
import org.jetbrains.kotlin.gradle.utils.createDependencyScope
import org.jetbrains.kotlin.gradle.utils.findDependencyScope
import org.jetbrains.kotlin.tooling.core.UnsafeApi
@@ -39,7 +39,14 @@ internal fun KotlinTargetSoftwareComponent(
publishedConfiguration.isVisible = false
publishedConfiguration.extendsFrom(project.configurations.getByName(kotlinUsageContext.dependencyConfigurationName))
publishedConfiguration.artifacts.addAll(kotlinUsageContext.artifacts)
copyAttributes(from = kotlinUsageContext.attributes, to = publishedConfiguration.attributes)
// KT-64789: workaround for missing 'org.gradle.libraryelements' attribute on the kotlinUsageContext returned keys Set
// So far I don't know the reason why it appears only on the second call to `keySet()`
// Test failing without it - KotlinAndroidMppIT#testMppAndroidLibFlavorsPublication
kotlinUsageContext.attributes.keySet()
kotlinUsageContext.copyAttributesTo(
project,
dest = publishedConfiguration
)
}
adhocVariant.addVariantsFromConfiguration(configuration) { configurationVariantDetails ->
@@ -168,12 +168,12 @@ internal fun Configuration.configureSourcesPublicationAttributes(target: KotlinT
// to be either JAVA_RUNTIME (for jvm) or KOTLIN_RUNTIME (for other targets)
// the latter isn't a strong requirement since there is no tooling that consume kotlin sources through gradle variants at the moment
// so consistency with Java Gradle Plugin seemed most desirable choice.
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(target))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.attributeValueByName(Category.DOCUMENTATION))
attributes.attribute(DocsType.DOCS_TYPE_ATTRIBUTE, project.attributeValueByName(DocsType.SOURCES))
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(target))
attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.attributeValueByName(Category.DOCUMENTATION))
attributes.setAttribute(DocsType.DOCS_TYPE_ATTRIBUTE, project.attributeValueByName(DocsType.SOURCES))
// Bundling attribute is about component dependencies, external means that they are provided as separate components
// source variants doesn't have any dependencies (at least at the moment) so there is not much sense to use this attribute
// however for Java Gradle Plugin compatibility and in order to prevent weird Variant Resolution errors we include this attribute
attributes.attribute(Bundling.BUNDLING_ATTRIBUTE, project.attributeValueByName(Bundling.EXTERNAL))
attributes.setAttribute(Bundling.BUNDLING_ATTRIBUTE, project.attributeValueByName(Bundling.EXTERNAL))
usesPlatformOf(target)
}
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.Stage.AfterEvalu
import org.jetbrains.kotlin.gradle.plugin.KotlinProjectSetupCoroutine
import org.jetbrains.kotlin.gradle.plugin.await
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation
import org.jetbrains.kotlin.gradle.utils.copyAttributes
import org.jetbrains.kotlin.gradle.utils.copyAttributesTo
import org.jetbrains.kotlin.gradle.utils.forAllTargets
@@ -25,22 +25,31 @@ internal val UserDefinedAttributesSetupAction = KotlinProjectSetupCoroutine {
kotlinExtension.forAllTargets { target ->
target.internal.kotlinComponents.flatMap { it.internal.usages }.forEach { usage ->
val dependencyConfiguration = target.project.configurations.findByName(usage.dependencyConfigurationName) ?: return@forEach
copyAttributes(usage.compilation.attributes, dependencyConfiguration.attributes)
usage.compilation.copyAttributesTo(
this@KotlinProjectSetupCoroutine,
dest = dependencyConfiguration.attributes
)
}
target.compilations.all { compilation ->
val compilationAttributes = compilation.attributes
compilation.allOwnedConfigurationsNames
.mapNotNull { configurationName -> project.configurations.findByName(configurationName) }
.forEach { configuration -> copyAttributes(compilationAttributes, configuration.attributes) }
.forEach { configuration ->
compilation.copyAttributesTo(
this@KotlinProjectSetupCoroutine,
dest = configuration
)
}
}
// Copy to host-specific metadata elements configurations
if (target is KotlinNativeTarget) {
val hostSpecificMetadataElements = project.configurations.findByName(target.hostSpecificMetadataElementsConfigurationName)
if (hostSpecificMetadataElements != null) {
copyAttributes(from = target.attributes, to = hostSpecificMetadataElements.attributes)
target.copyAttributesTo(
this@KotlinProjectSetupCoroutine,
dest = hostSpecificMetadataElements
)
}
}
}
@@ -138,7 +138,7 @@ private fun KotlinCompilationDependencyConfigurationsContainer(
val compileOnlyConfiguration = target.project.configurations
.maybeCreateDependencyScope(compileOnlyConfigurationName).apply {
setupAsLocalTargetSpecificConfigurationIfSupported(target)
attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
isVisible = false
description = "Compile only dependencies for $compilationCoordinates."
}
@@ -153,9 +153,9 @@ private fun KotlinCompilationDependencyConfigurationsContainer(
extendsFrom(compileOnlyConfiguration, implementationConfiguration)
usesPlatformOf(target)
isVisible = false
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target))
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target))
if (target.platformType != KotlinPlatformType.androidJvm) {
attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
}
description = "Compile classpath for $compilationCoordinates."
}
@@ -166,9 +166,9 @@ private fun KotlinCompilationDependencyConfigurationsContainer(
deprecatedRuntimeConfiguration?.let { extendsFrom(it) }
usesPlatformOf(target)
isVisible = false
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target))
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target))
if (target.platformType != KotlinPlatformType.androidJvm) {
attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
}
description = "Runtime classpath of $compilationCoordinates."
} else null
@@ -178,10 +178,11 @@ private fun KotlinCompilationDependencyConfigurationsContainer(
isVisible = false
description = "Host-specific Metadata dependencies for $compilationCoordinates"
extendsFrom(compileDependencyConfiguration)
copyAttributes(from = compileDependencyConfiguration.attributes, to = attributes)
attributes {
it.attribute(Usage.USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA))
}
compileDependencyConfiguration.copyAttributesTo(
target.project,
dest = this
)
setAttribute(Usage.USAGE_ATTRIBUTE, target.project.usageByName(KotlinUsages.KOTLIN_METADATA))
} else null
val pluginConfiguration = target.project.configurations.maybeCreateResolvable(pluginConfigurationName).apply {
@@ -128,14 +128,14 @@ fun <T : DecoratedExternalKotlinTarget> KotlinMultiplatformExtension.createExter
private fun ExternalKotlinTargetImpl.setupApiElements(configuration: Configuration) {
configuration.usesPlatformOf(this)
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(this))
configuration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
configuration.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(this))
configuration.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
}
private fun ExternalKotlinTargetImpl.setupRuntimeElements(configuration: Configuration) {
configuration.usesPlatformOf(this)
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(this))
configuration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
configuration.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(this))
configuration.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
}
private fun ExternalKotlinTargetImpl.setupSourcesElements(configuration: Configuration) {
@@ -60,7 +60,10 @@ internal val InternalKotlinSourceSet.resolvableMetadataConfiguration: Configurat
/* Ensure consistent dependency resolution result within the whole module */
configuration.shouldResolveConsistentlyWith(allCompileMetadataConfiguration)
copyAttributes(allCompileMetadataConfiguration.attributes, configuration.attributes)
allCompileMetadataConfiguration.copyAttributesTo(
project,
dest = configuration
)
configureMetadataDependenciesConfigurations(configuration)
@@ -96,8 +99,8 @@ private val Project.allCompileMetadataConfiguration
get(): Configuration = configurations.findResolvable("allSourceSetsCompileDependenciesMetadata")
?: configurations.createResolvable("allSourceSetsCompileDependenciesMetadata").also { configuration ->
configuration.usesPlatformOf(multiplatformExtension.metadata())
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA))
configuration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
configuration.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA))
configuration.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
kotlinExtension.sourceSets.all { sourceSet ->
configuration.extendsFrom(configurations.getByName(sourceSet.apiConfigurationName))
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnab
import org.jetbrains.kotlin.gradle.utils.createResolvable
import org.jetbrains.kotlin.gradle.utils.maybeCreateDependencyScope
import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable
import org.jetbrains.kotlin.gradle.utils.setAttribute
import java.io.File
internal abstract class KotlinSourceSetFactory<T : KotlinSourceSet> internal constructor(
@@ -98,9 +99,9 @@ internal class DefaultKotlinSourceSetFactory(
dependencyConfigurationWithMetadata.forEach { (configurationName, metadataName) ->
project.configurations.maybeCreateResolvable(metadataName).apply {
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.common)
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_API))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
attributes.setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.common)
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_API))
attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
isVisible = false
if (configurationName != null) {
@@ -108,7 +109,7 @@ internal class DefaultKotlinSourceSetFactory(
}
if (project.isKotlinGranularMetadataEnabled) {
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA))
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.usageByName(KotlinUsages.KOTLIN_METADATA))
}
}
}
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.gradle.scripting.ScriptingExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.utils.maybeCreateDependencyScope
import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable
import org.jetbrains.kotlin.gradle.utils.setAttribute
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
private const val SCRIPTING_LOG_PREFIX = "kotlin scripting plugin:"
@@ -113,7 +114,7 @@ private fun configureDiscoveryTransformation(
discoveryResultsConfigurationName: String
) {
project.configurations.maybeCreateResolvable(discoveryResultsConfigurationName).apply {
attributes.attribute(artifactType, scriptFilesExtensions)
attributes.setAttribute(artifactType, scriptFilesExtensions)
extendsFrom(discoveryConfiguration)
}
val classLoadersCachingService = ClassLoadersCachingBuildService.registerIfAbsent(project)
@@ -161,14 +162,14 @@ private fun DependencyHandler.registerDiscoverScriptExtensionsTransform(
parameters.compilerClasspath.from(compilerClasspath)
}
registerTransform(DiscoverScriptExtensionsTransformAction::class.java) { transformSpec ->
transformSpec.from.attribute(artifactType, "jar")
transformSpec.to.attribute(artifactType, scriptFilesExtensions)
transformSpec.from.setAttribute(artifactType, "jar")
transformSpec.to.setAttribute(artifactType, scriptFilesExtensions)
transformSpec.configureCommonParameters()
}
registerTransform(DiscoverScriptExtensionsTransformAction::class.java) { transformSpec ->
transformSpec.from.attribute(artifactType, "classes")
transformSpec.to.attribute(artifactType, scriptFilesExtensions)
transformSpec.from.setAttribute(artifactType, "classes")
transformSpec.to.setAttribute(artifactType, scriptFilesExtensions)
transformSpec.configureCommonParameters()
}
}
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.isSourcesPublishableFuture
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
import org.jetbrains.kotlin.gradle.utils.maybeCreateConsumable
import org.jetbrains.kotlin.gradle.utils.maybeCreateDependencyScope
import org.jetbrains.kotlin.gradle.utils.setAttribute
internal val CreateTargetConfigurationsSideEffect = KotlinTargetSideEffect { target ->
val project = target.project
@@ -36,8 +37,8 @@ internal val CreateTargetConfigurationsSideEffect = KotlinTargetSideEffect { tar
configurations.maybeCreateConsumable(target.apiElementsConfigurationName).apply {
description = "API elements for main."
isVisible = false
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target))
attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
extendsFrom(configurations.maybeCreateDependencyScope(mainCompilation.apiConfigurationName))
if (mainCompilation is KotlinCompilationToRunnableFiles) {
val runtimeConfiguration = mainCompilation.internal.configurations.deprecatedRuntimeConfiguration
@@ -50,8 +51,8 @@ internal val CreateTargetConfigurationsSideEffect = KotlinTargetSideEffect { tar
configurations.maybeCreateConsumable(target.runtimeElementsConfigurationName).apply {
description = "Elements of runtime for main."
isVisible = false
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(target))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(target))
attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
val runtimeConfiguration = mainCompilation.internal.configurations.deprecatedRuntimeConfiguration
extendsFrom(implementationConfiguration)
if (runtimeOnlyConfiguration != null)
@@ -94,8 +95,8 @@ internal val CreateTargetConfigurationsSideEffect = KotlinTargetSideEffect { tar
).apply {
description = "Common Fake API elements for main."
isVisible = false
attributes.attribute<Usage>(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target))
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.common)
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target))
attributes.setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.common)
}
}
}
@@ -335,7 +335,10 @@ internal class AndroidProjectHandler(
val buildTypeAttrValue = project.objects.named<BuildTypeAttr>(variant.buildType.name)
listOf(compilation.compileDependencyConfigurationName, compilation.runtimeDependencyConfigurationName).forEach {
project.configurations.findByName(it)?.attributes?.attribute(Attribute.of(BuildTypeAttr::class.java), buildTypeAttrValue)
project.configurations.findByName(it)?.attributes?.setAttribute(
Attribute.of(BuildTypeAttr::class.java),
buildTypeAttrValue
)
}
// TODO this code depends on the convention that is present in the Android plugin as there's no public API
@@ -355,7 +358,7 @@ internal class AndroidProjectHandler(
listOf(apiElementsConfigurationName, runtimeElementsConfigurationName).forEach { outputConfigurationName ->
project.configurations.findByName(outputConfigurationName)?.let { configuration ->
configuration.usesPlatformOf(compilation.target)
configuration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
configuration.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
}
}
}
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.gradle.dsl.HasConfigurableCompilerOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptionsDefault
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.internal.attributesConfigurationHelper
import org.jetbrains.kotlin.gradle.tasks.DefaultKotlinJavaToolchain
import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
@@ -299,7 +300,7 @@ abstract class KotlinAndroidTarget @Inject constructor(
description = "Source files of Android ${variantName}."
isVisible = false
copyAttributes(apiElementsConfiguration.attributes, attributes)
apiElementsConfiguration.copyAttributesTo(project, dest = this)
configureSourcesPublicationAttributes(this@KotlinAndroidTarget)
}
}
@@ -135,9 +135,9 @@ class KotlinCompilationNpmResolver(
val all = project.configurations.createResolvable(compilation.npmAggregatedConfigurationName)
all.usesPlatformOf(target)
all.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target))
all.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
all.attributes.attribute(publicPackageJsonAttribute, PUBLIC_PACKAGE_JSON_ATTR_VALUE)
all.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target))
all.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
all.attributes.setAttribute(publicPackageJsonAttribute, PUBLIC_PACKAGE_JSON_ATTR_VALUE)
all.isVisible = false
all.description = "NPM configuration for $compilation."
@@ -163,9 +163,9 @@ class KotlinCompilationNpmResolver(
val all = project.configurations.createConsumable(compilation.publicPackageJsonConfigurationName)
all.usesPlatformOf(target)
all.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target))
all.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
all.attributes.attribute(publicPackageJsonAttribute, PUBLIC_PACKAGE_JSON_ATTR_VALUE)
all.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target))
all.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
all.attributes.setAttribute(publicPackageJsonAttribute, PUBLIC_PACKAGE_JSON_ATTR_VALUE)
all.isVisible = false
return all
@@ -324,7 +324,7 @@ abstract class KotlinJvmTarget @Inject constructor(
).mapNotNull {
project.configurations.findByName(it)
}.forEach { configuration ->
copyAttributes(attributes, configuration.attributes)
copyAttributesTo(project, dest = configuration)
}
}
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf
import org.jetbrains.kotlin.gradle.targets.KotlinTargetSideEffect
import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable
import org.jetbrains.kotlin.gradle.utils.setAttribute
internal val ConfigureFrameworkExportSideEffect = KotlinTargetSideEffect<KotlinNativeTarget> { target ->
val project = target.project
@@ -23,9 +24,9 @@ internal val ConfigureFrameworkExportSideEffect = KotlinTargetSideEffect<KotlinN
isVisible = false
isTransitive = false
usesPlatformOf(target)
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
description = "Dependenceis to be exported in framework ${framework.name} for target ${target.targetName}"
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target))
attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
description = "Dependencies to be exported in framework ${framework.name} for target ${target.targetName}"
}
}
}
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.gradle.targets.native.KotlinNativeSimulatorTestRunFa
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
import org.jetbrains.kotlin.gradle.utils.klibModuleName
import org.jetbrains.kotlin.gradle.utils.newInstance
import org.jetbrains.kotlin.gradle.utils.setAttribute
import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
@@ -40,7 +41,7 @@ abstract class KotlinNativeTarget @Inject constructor(
) {
init {
attributes.attribute(konanTargetAttribute, konanTarget.name)
attributes.setAttribute(konanTargetAttribute, konanTarget.name)
}
private val hostSpecificMetadataJarTaskName get() = disambiguateName("MetadataJar")
@@ -19,6 +19,7 @@ import org.gradle.api.tasks.AbstractExecTask
import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink
import org.jetbrains.kotlin.gradle.utils.attributeOf
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable
import org.jetbrains.kotlin.konan.target.KonanTarget
@@ -321,9 +322,8 @@ class Framework(
}
companion object {
val frameworkTargets: Attribute<Set<*>> = Attribute.of(
"org.jetbrains.kotlin.native.framework.targets",
Set::class.java
val frameworkTargets: Attribute<Set<String>> = attributeOf<Set<String>>(
"org.jetbrains.kotlin.native.framework.targets"
)
}
}
@@ -45,7 +45,7 @@ internal fun Project.createFrameworkArtifact(binaryFramework: Framework, linkTas
?: configurations.createConsumable(binaryFramework.binaryFrameworkConfigurationName).also {
it.applyBinaryFrameworkGroupAttributes(project, binaryFramework.frameworkGroupDescription, listOf(binaryFramework.target))
project.launchInStage(KotlinPluginLifecycle.Stage.FinaliseDsl) {
copyAttributes(binaryFramework.attributes, it.attributes)
binaryFramework.copyAttributesTo(project, dest = it)
}
}
@@ -78,11 +78,13 @@ private fun Configuration.applyBinaryFrameworkGroupAttributes(
targets: List<KotlinNativeTarget>,
) {
with(attributes) {
attribute(KotlinPlatformType.attribute, KotlinPlatformType.native)
attribute(project.artifactTypeAttribute, KotlinNativeTargetConfigurator.NativeArtifactFormat.FRAMEWORK)
attribute(KotlinNativeTarget.kotlinNativeBuildTypeAttribute, frameworkDescription.buildType.name)
attribute(KotlinNativeTarget.kotlinNativeFrameworkNameAttribute, frameworkDescription.frameworkName)
attribute(Framework.frameworkTargets, targets.map { it.konanTarget.name }.toSet())
setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.native)
setAttribute(project.artifactTypeAttribute, KotlinNativeTargetConfigurator.NativeArtifactFormat.FRAMEWORK)
setAttribute(KotlinNativeTarget.kotlinNativeBuildTypeAttribute, frameworkDescription.buildType.name)
setAttribute(KotlinNativeTarget.kotlinNativeFrameworkNameAttribute, frameworkDescription.frameworkName)
setAttributeProvider(project, Framework.frameworkTargets) {
targets.map { it.konanTarget.name }.toSet()
}
}
}
@@ -18,6 +18,7 @@ import org.gradle.api.tasks.PathSensitivity
import org.gradle.work.DisableCachingByDefault
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerArtifactTypeAttribute.KLIB
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerArtifactTypeAttribute.KLIB_COLLECTION_DIR
import org.jetbrains.kotlin.gradle.utils.setAttribute
/**
* Commonized CInterop artifacts can come in two shapes:
@@ -52,16 +53,16 @@ internal object CInteropCommonizerArtifactTypeAttribute {
*/
fun setupTransform(project: Project) {
project.dependencies.artifactTypes.maybeCreate(KLIB_COLLECTION_DIR).also { artifactType ->
artifactType.attributes.attribute(attribute, KLIB_COLLECTION_DIR)
artifactType.attributes.setAttribute(attribute, KLIB_COLLECTION_DIR)
}
project.dependencies.artifactTypes.maybeCreate(KLIB).also { artifactType ->
artifactType.attributes.attribute(attribute, KLIB)
artifactType.attributes.setAttribute(attribute, KLIB)
}
project.dependencies.registerTransform(KlibCollectionDirTransform::class.java) { transform ->
transform.from.attribute(attribute, KLIB_COLLECTION_DIR)
transform.to.attribute(attribute, KLIB)
transform.from.setAttribute(attribute, KLIB_COLLECTION_DIR)
transform.to.setAttribute(attribute, KLIB)
}
}
@@ -21,8 +21,10 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.resolvableMetadataConfiguration
import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.targets.metadata.awaitMetadataCompilationsCreated
import org.jetbrains.kotlin.gradle.targets.metadata.findMetadataCompilation
import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.gradle.utils.createConsumable
import org.jetbrains.kotlin.gradle.utils.createResolvable
import org.jetbrains.kotlin.gradle.utils.setAttribute
import org.jetbrains.kotlin.tooling.core.UnsafeApi
/* Elements configuration */
@@ -113,7 +115,10 @@ internal suspend fun Project.locateOrCreateCommonizedCInteropDependencyConfigura
* If artifacts are added using [CInteropCommonizerArtifactTypeAttribute.KLIB_COLLECTION_DIR] then a transformation
* has to happen that will resolve the exact list of klibs.
*/
configuration.attributes.attribute(CInteropCommonizerArtifactTypeAttribute.attribute, CInteropCommonizerArtifactTypeAttribute.KLIB)
configuration.attributes.setAttribute(
CInteropCommonizerArtifactTypeAttribute.attribute,
CInteropCommonizerArtifactTypeAttribute.KLIB
)
description = "Commonized CInterop dependencies for $sourceSet with targets: '$commonizerTarget'."
}
@@ -124,7 +129,7 @@ private fun Project.setupBasicCommonizedCInteropConfigurationAttributes(
configuration: Configuration,
commonizerTarget: SharedCommonizerTarget,
) {
configuration.attributes.attribute(CommonizerTargetAttribute.attribute, commonizerTarget.identityString)
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_COMMONIZED_CINTEROP))
configuration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
configuration.attributes.setAttribute(CommonizerTargetAttribute.attribute, commonizerTarget.identityString)
configuration.attributes.setAttribute(Usage.USAGE_ATTRIBUTE, objects.named(KotlinUsages.KOTLIN_COMMONIZED_CINTEROP))
configuration.attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
}
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.gradle.targets.KotlinTargetSideEffect
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements.cinteropKlibLibraryElements
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.gradle.utils.copyAttributes
import org.jetbrains.kotlin.gradle.utils.createConsumable
import org.jetbrains.kotlin.gradle.utils.findConsumable
@@ -57,10 +56,10 @@ internal fun Project.locateOrCreateCInteropDependencyConfiguration(
/* Deferring attributes to wait for compilation.attributes to be configured by user*/
launchInStage(AfterFinaliseDsl) {
usesPlatformOf(compilation.target)
copyAttributes(compilation.attributes, attributes)
attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements())
attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_CINTEROP))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
compilation.copyAttributesTo(project, dest = attributes)
attributes.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements())
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, objects.named(KotlinUsages.KOTLIN_CINTEROP))
attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
description = "CInterop dependencies for compilation '${compilation.name}')."
}
}
@@ -81,11 +80,11 @@ internal fun Project.locateOrCreateCInteropApiElementsConfiguration(target: Kotl
/* Deferring attributes to wait for target.attributes to be configured by user */
launchInStage(AfterFinaliseDsl) {
usesPlatformOf(target)
copyAttributes(target.attributes, attributes)
attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements())
attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_CINTEROP))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
attributes.attribute(artifactTypeAttribute, NativeArtifactFormat.KLIB)
target.copyAttributesTo(project, dest = attributes)
attributes.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, cinteropKlibLibraryElements())
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, objects.named(KotlinUsages.KOTLIN_CINTEROP))
attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
attributes.setAttribute(artifactTypeAttribute, NativeArtifactFormat.KLIB)
/* Expose api dependencies */
target.compilations.findByName(MAIN_COMPILATION_NAME)?.let { compilation ->
@@ -194,8 +194,8 @@ constructor(
val apiConfiguration = project.configurations.getByName(compilation.apiConfigurationName)
dependencies.addAll(apiConfiguration.allDependencies)
usesPlatformOf(compilation.target)
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(compilation.target))
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(compilation.target))
attributes.setAttribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
}.filterKlibsPassedToCompiler()
@get:Optional
@@ -15,6 +15,8 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.gradle.utils.maybeCreateResolvable
import org.jetbrains.kotlin.gradle.utils.named
import org.jetbrains.kotlin.gradle.utils.setAttribute
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.target.presetName
@@ -76,9 +78,9 @@ internal fun Project.registerLibsDependencies(target: KonanTarget, artifactName:
configurations.maybeCreateResolvable(librariesConfigurationName).apply {
isVisible = false
isTransitive = true
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native)
attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.name)
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, KotlinUsages.KOTLIN_API))
attributes.setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.native)
attributes.setAttribute(KotlinNativeTarget.konanTargetAttribute, target.name)
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.objects.named(KotlinUsages.KOTLIN_API))
}
deps.forEach { dependencies.add(librariesConfigurationName, it) }
return librariesConfigurationName
@@ -89,9 +91,9 @@ internal fun Project.registerExportDependencies(target: KonanTarget, artifactNam
configurations.maybeCreateResolvable(exportConfigurationName).apply {
isVisible = false
isTransitive = false
attributes.attribute(KotlinPlatformType.attribute, KotlinPlatformType.native)
attributes.attribute(KotlinNativeTarget.konanTargetAttribute, target.name)
attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class.java, KotlinUsages.KOTLIN_API))
attributes.setAttribute(KotlinPlatformType.attribute, KotlinPlatformType.native)
attributes.setAttribute(KotlinNativeTarget.konanTargetAttribute, target.name)
attributes.setAttribute(Usage.USAGE_ATTRIBUTE, project.objects.named(KotlinUsages.KOTLIN_API))
}
deps.forEach { dependencies.add(exportConfigurationName, it) }
return exportConfigurationName
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.gradle.internal.kapt.incremental.StructureTransformL
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.tasks.toCompilerPluginOptions
import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.gradle.utils.createDependencyScope
import org.jetbrains.kotlin.gradle.utils.detachedResolvable
import org.jetbrains.kotlin.gradle.utils.listProperty
import java.io.File
@@ -101,7 +100,7 @@ internal open class KaptConfig<TASK : KaptTask>(
// the attributes that are potentially needed to resolve dependencies on MPP modules, and the classpath configuration does.
classStructureConfiguration.dependencies.add(project.dependencies.create(project.files(project.provider { taskProvider.get().classpath })))
classStructureConfiguration.incoming.artifactView { viewConfig ->
viewConfig.attributes.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
viewConfig.attributes.setAttribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
}.files
} else null
}
@@ -114,13 +113,13 @@ internal open class KaptConfig<TASK : KaptTask>(
else
StructureTransformLegacyAction::class.java
project.dependencies.registerTransform(transformActionClass) { transformSpec ->
transformSpec.from.attribute(artifactType, "jar")
transformSpec.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
transformSpec.from.setAttribute(artifactType, "jar")
transformSpec.to.setAttribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
}
project.dependencies.registerTransform(transformActionClass) { transformSpec ->
transformSpec.from.attribute(artifactType, "directory")
transformSpec.to.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
transformSpec.from.setAttribute(artifactType, "directory")
transformSpec.to.setAttribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
}
project.extensions.extraProperties["KaptStructureTransformAdded"] = true
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.gradle.tasks.DefaultKotlinJavaToolchain
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.utils.detachedResolvable
import org.jetbrains.kotlin.gradle.utils.providerWithLazyConvention
import org.jetbrains.kotlin.gradle.utils.setAttribute
internal typealias KotlinCompileConfig = BaseKotlinCompileConfig<KotlinCompile>
@@ -71,7 +72,7 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
task.classpathSnapshotProperties.useClasspathSnapshot.value(useClasspathSnapshot).disallowChanges()
if (useClasspathSnapshot) {
val classpathEntrySnapshotFiles = classpathConfiguration!!.incoming.artifactView {
it.attributes.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE)
it.attributes.setAttribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE)
}.files
task.classpathSnapshotProperties.classpathSnapshot.from(classpathEntrySnapshotFiles).disallowChanges()
task.classpathSnapshotProperties.classpathSnapshotDir.value(getClasspathSnapshotDir(task)).disallowChanges()
@@ -185,14 +186,14 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
val kgpVersion = project.getKotlinPluginVersion()
val suppressVersionInconsistencyChecks = project.kotlinPropertiesProvider.suppressBuildToolsApiVersionConsistencyChecks
project.dependencies.registerTransform(BuildToolsApiClasspathEntrySnapshotTransform::class.java) {
it.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, JAR_ARTIFACT_TYPE)
it.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE)
it.from.setAttribute(ARTIFACT_TYPE_ATTRIBUTE, JAR_ARTIFACT_TYPE)
it.to.setAttribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE)
it.configureCommonParameters(kgpVersion, classLoadersCachingService, classpath, jvmToolchain, runKotlinCompilerViaBuildToolsApi, suppressVersionInconsistencyChecks)
it.setupTransformActionToolingDiagnostics(project)
}
project.dependencies.registerTransform(BuildToolsApiClasspathEntrySnapshotTransform::class.java) {
it.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, DIRECTORY_ARTIFACT_TYPE)
it.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE)
it.from.setAttribute(ARTIFACT_TYPE_ATTRIBUTE, DIRECTORY_ARTIFACT_TYPE)
it.to.setAttribute(ARTIFACT_TYPE_ATTRIBUTE, CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE)
it.configureCommonParameters(kgpVersion, classLoadersCachingService, classpath, jvmToolchain, runKotlinCompilerViaBuildToolsApi, suppressVersionInconsistencyChecks)
it.setupTransformActionToolingDiagnostics(project)
}
@@ -5,8 +5,11 @@
package org.jetbrains.kotlin.gradle.utils
import org.gradle.api.Project
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.AttributeContainer
import org.gradle.api.attributes.HasAttributes
import org.jetbrains.kotlin.gradle.plugin.internal.attributesConfigurationHelper
/**
* KGP's internal analog of [org.gradle.api.internal.attributes.AttributeContainerInternal.asMap]
@@ -21,15 +24,47 @@ internal fun AttributeContainer.toMap(): Map<Attribute<*>, Any?> {
return result
}
internal fun <T : Any> HasAttributes.setAttributeProvider(
project: Project,
key: Attribute<T>,
value: () -> T
) {
project.attributesConfigurationHelper.setAttribute(this, key, value)
}
internal fun copyAttributes(from: AttributeContainer, to: AttributeContainer, keys: Iterable<Attribute<*>> = from.keySet()) {
// capture type argument T
fun <T : Any> copyOneAttribute(from: AttributeContainer, to: AttributeContainer, key: Attribute<T>) {
val value = checkNotNull(from.getAttribute(key))
to.attribute(key, value)
}
for (key in keys) {
copyOneAttribute(from, to, key)
/**
* Should only be used to configure simple attributes values!
*
* When in doubt, prefer lazy method overload.
*/
internal fun <T : Any> HasAttributes.setAttribute(
key: Attribute<T>,
value: T
) {
attributes.attribute(key, value)
}
internal fun <T : Any> HasAttributes.copyAttributeTo(
project: Project,
dest: HasAttributes,
key: Attribute<T>,
) {
dest.setAttributeProvider(project, key) {
attributes.getAttribute(key)
?: throw IllegalStateException("Failed to copy attribute. Source container is missing $key (named ${key.name}).")
}
}
internal fun HasAttributes.copyAttributesTo(
project: Project,
dest: HasAttributes,
keys: Iterable<Attribute<*>> = attributes.keySet(),
) {
for (key in keys) {
copyAttributeTo(project, dest, key)
}
}
internal inline fun <reified T> attributeOf(
name: String
): Attribute<T> = Attribute.of(name, T::class.java)
@@ -34,13 +34,13 @@ internal fun Configuration.addGradlePluginMetadataAttributes(
project: Project
) {
attributes {
it.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
it.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME))
it.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
it.setAttribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
it.setAttribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME))
it.setAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
if (GradleVersion.current() >= GradleVersion.version("7.0")) {
it.attribute(
it.setAttribute(
GradlePluginApiVersion.GRADLE_PLUGIN_API_VERSION_ATTRIBUTE,
project.objects.named(GradlePluginApiVersion::class.java, GradleVersion.current().version)
project.objects.named(GradleVersion.current().version)
)
}
}
@@ -21,7 +21,7 @@ class BinaryFrameworksCustomAttributesTest {
val project = buildProjectWithMPP {
kotlin {
iosArm64("ios") {
attributes.attribute(disambiguationAttribute1, "someValue")
attributes.attributeProvider(disambiguationAttribute1, provider { "someValue" })
binaries {
framework("main")
framework("custom") {
@@ -29,7 +29,7 @@ class BinaryFrameworksCustomAttributesTest {
linkerOpts = mutableListOf("-L.")
freeCompilerArgs = mutableListOf("-Xtime")
isStatic = true
attributes.attribute(disambiguationAttribute2, "someValue2")
attributes.attributeProvider(disambiguationAttribute2, provider { "someValue2" })
}
}
}
@@ -33,13 +33,13 @@ class KT56143CinteropConfigurationAttributes {
private val project = buildProjectWithMPP {
kotlin {
linuxX64("variantA") {
attributes.attribute(targetAttribute, "a")
compilations.main.attributes.attribute(compilationAttribute, "compilation:a")
attributes.attributeProvider(targetAttribute, provider { "a" })
compilations.main.attributes.attributeProvider(compilationAttribute, provider { "compilation:a" })
}
linuxX64("variantB") {
attributes.attribute(targetAttribute, "b")
compilations.main.attributes.attribute(compilationAttribute, "compilation:b")
attributes.attributeProvider(targetAttribute, provider { "b" })
compilations.main.attributes.attributeProvider(compilationAttribute, provider { "compilation:b" })
}
}
}
@@ -34,7 +34,10 @@ class CInteropCommonizerArtifactTypeAttributeTest {
/* Create consumable elements configuration */
project.configurations.createConsumable("testElements").also { configuration ->
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named("test"))
configuration.attributes.attributeProvider(
Usage.USAGE_ATTRIBUTE,
project.provider { project.objects.named("test") }
)
/* Add klibCollectionDir as artifact */
configuration.outgoing.artifact(klibCollectionDir) { artifact ->
@@ -45,9 +48,13 @@ class CInteropCommonizerArtifactTypeAttributeTest {
/* Create resolvable configuration */
val resolvable = project.configurations.createResolvable("testDependencies").also { configuration ->
configuration.attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named("test"))
configuration.attributes.attribute(
CInteropCommonizerArtifactTypeAttribute.attribute, CInteropCommonizerArtifactTypeAttribute.KLIB
configuration.attributes.attributeProvider(
Usage.USAGE_ATTRIBUTE,
project.provider { project.objects.named("test") }
)
configuration.attributes.attributeProvider(
CInteropCommonizerArtifactTypeAttribute.attribute,
project.provider { CInteropCommonizerArtifactTypeAttribute.KLIB }
)
}
@@ -180,12 +180,12 @@ class ExternalKotlinTargetApiTests {
defaults()
sourcesElements.configure { target, configuration ->
assertEquals(target.sourcesElementsConfiguration, configuration)
configuration.attributes.attribute(testAttribute, "sourcesElements")
configuration.attributes.attributeProvider(testAttribute, provider { "sourcesElements" })
}
sourcesElementsPublished.configure { target, configuration ->
assertEquals(target.sourcesElementsPublishedConfiguration, configuration)
configuration.attributes.attribute(testAttribute, "sourcesElements-published")
configuration.attributes.attributeProvider(testAttribute, provider { "sourcesElements-published" })
}
}
target.createCompilation<FakeCompilation> { defaults(kotlin) }
@@ -306,7 +306,7 @@ class ExternalKotlinTargetApiTests {
val target = kotlin.createExternalKotlinTarget<FakeTarget> { defaults() }
target.createCompilation<FakeCompilation> { defaults(kotlin) }
target.attributes.attribute(userAttribute, "foo")
target.attributes.attributeProvider(userAttribute, target.project.provider { "foo" })
project.evaluate()
@@ -23,8 +23,14 @@ class IdeaKotlinBinaryAttributesFactoryTest {
val dummyConfiguration = project.configurations.create("dummy")
val container = dummyConfiguration.attributes
container.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_API))
container.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.DOCUMENTATION))
container.attributeProvider(
Usage.USAGE_ATTRIBUTE,
project.provider { project.objects.named(Usage.JAVA_API) }
)
container.attributeProvider(
Category.CATEGORY_ATTRIBUTE,
project.provider { project.objects.named(Category.DOCUMENTATION) }
)
assertEquals(
mapOf(
@@ -10,7 +10,6 @@ import org.gradle.api.Named
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project
import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.model.ObjectFactory
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.jetbrains.kotlin.gradle.plugin.internal.*
import org.jetbrains.kotlin.gradle.plugin.internal.BasePluginConfigurationG70
@@ -155,4 +154,5 @@ private fun Project.registerVariantImplementations() {
factories[UnameExecutor.UnameExecutorVariantFactory::class] =
UnameExecutorG70.UnameExecutorVariantFactoryG70()
factories[ConfigurationCacheStartParameterAccessor.Factory::class] = ConfigurationCacheStartParameterAccessorG70.Factory()
factories[AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory::class] = AttributeConfigurationHelperVariantFactoryG70()
}
@@ -0,0 +1,26 @@
/*
* 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.internal
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.HasAttributes
import org.gradle.api.provider.ProviderFactory
internal class AttributesConfigurationHelperG70 : AttributesConfigurationHelper {
override fun <T : Any> setAttribute(
attributesContainer: HasAttributes,
key: Attribute<T>,
value: () -> T
) {
attributesContainer.attributes.attribute(key, value())
}
}
internal class AttributeConfigurationHelperVariantFactoryG70 : AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory {
override fun getInstance(
providerFactory: ProviderFactory
): AttributesConfigurationHelper = AttributesConfigurationHelperG70()
}
@@ -10,7 +10,6 @@ import org.gradle.api.Named
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project
import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.model.ObjectFactory
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.jetbrains.kotlin.gradle.plugin.internal.*
import org.jetbrains.kotlin.gradle.plugin.internal.ConfigurationTimePropertiesAccessorG71
@@ -156,4 +155,5 @@ private fun Project.registerVariantImplementations() {
factories[UnameExecutor.UnameExecutorVariantFactory::class] =
UnameExecutorG71.UnameExecutorVariantFactoryG71()
factories[ConfigurationCacheStartParameterAccessor.Factory::class] = ConfigurationCacheStartParameterAccessorG71.Factory()
factories[AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory::class] = AttributeConfigurationHelperVariantFactoryG71()
}
@@ -0,0 +1,26 @@
/*
* 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.internal
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.HasAttributes
import org.gradle.api.provider.ProviderFactory
internal class AttributesConfigurationHelperG71 : AttributesConfigurationHelper {
override fun <T : Any> setAttribute(
attributesContainer: HasAttributes,
key: Attribute<T>,
value: () -> T
) {
attributesContainer.attributes.attribute(key, value())
}
}
internal class AttributeConfigurationHelperVariantFactoryG71 : AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory {
override fun getInstance(
providerFactory: ProviderFactory
): AttributesConfigurationHelper = AttributesConfigurationHelperG71()
}
@@ -145,4 +145,6 @@ private fun Project.registerVariantImplementations() {
factories[UnameExecutor.UnameExecutorVariantFactory::class] =
UnameExecutorG74.UnameExecutorVariantFactoryG74()
factories[ConfigurationCacheStartParameterAccessor.Factory::class] = ConfigurationCacheStartParameterAccessorG74.Factory()
factories[AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory::class] =
AttributeConfigurationHelperVariantFactoryG74()
}
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2024 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.internal
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.AttributeContainer
import org.gradle.api.attributes.HasAttributes
import org.gradle.api.provider.ProviderFactory
/**
* While Gradle 7.4 already has [AttributeContainer.attributeProvider] method available,
* Gradle itself has a bug in mixed attributes (eager + provider) case leading to the false-positive
* deprecation message:
* ```
* Consumable configurations with identical capabilities within a project must have unique attributes, ...
* ```
*/
internal class AttributesConfigurationHelperG74 : AttributesConfigurationHelper {
override fun <T : Any> setAttribute(
attributesContainer: HasAttributes,
key: Attribute<T>,
value: () -> T
) {
attributesContainer.attributes.attribute(key, value())
}
}
internal class AttributeConfigurationHelperVariantFactoryG74 : AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory {
override fun getInstance(
providerFactory: ProviderFactory
): AttributesConfigurationHelper = AttributesConfigurationHelperG74()
}
@@ -162,4 +162,5 @@ private fun Project.registerVariantImplementations() {
factories[ConfigurationCacheStartParameterAccessor.Factory::class] = ConfigurationCacheStartParameterAccessorG6.Factory()
factories[SourceSetCompatibilityHelper.SourceSetCompatibilityHelperVariantFactory::class] =
SourceSetCompatibilityHelperG6VariantFactory()
factories[AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory::class] = AttributeConfigurationHelperVariantFactoryG6()
}
@@ -0,0 +1,26 @@
/*
* 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.internal
import org.gradle.api.attributes.Attribute
import org.gradle.api.attributes.HasAttributes
import org.gradle.api.provider.ProviderFactory
internal class AttributesConfigurationHelperG6 : AttributesConfigurationHelper {
override fun <T : Any> setAttribute(
attributesContainer: HasAttributes,
key: Attribute<T>,
value: () -> T
) {
attributesContainer.attributes.attribute(key, value())
}
}
internal class AttributeConfigurationHelperVariantFactoryG6 : AttributesConfigurationHelper.AttributeConfigurationHelperVariantFactory {
override fun getInstance(
providerFactory: ProviderFactory
): AttributesConfigurationHelper = AttributesConfigurationHelperG6()
}