From f15feb644bf565b8068b00bc50206891f3a9ec40 Mon Sep 17 00:00:00 2001 From: Sebastian Sellmair Date: Tue, 24 Jan 2023 14:50:49 +0100 Subject: [PATCH] [Gradle] Ensure cinterop* configurations contain target/compilation attributes ^KT-56115 Verification Pending --- .../native/internal/CInteropConfigurations.kt | 30 +++-- .../KT56143CinteropConfigurationAttributes.kt | 113 ++++++++++++++++++ 2 files changed, 133 insertions(+), 10 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/regressionTests/KT56143CinteropConfigurationAttributes.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropConfigurations.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropConfigurations.kt index c74a73f7154..765c4636e7f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropConfigurations.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/CInteropConfigurations.kt @@ -14,7 +14,9 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinNativeTargetConfigurator.NativeA import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.categoryByName import org.jetbrains.kotlin.gradle.plugin.mpp.* +import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.copyAttributes import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf +import org.jetbrains.kotlin.gradle.plugin.whenEvaluated import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements.cinteropKlibLibraryElements import org.jetbrains.kotlin.gradle.tasks.CInteropProcess @@ -48,11 +50,15 @@ internal fun Project.locateOrCreateCInteropDependencyConfiguration( isCanBeResolved = true isCanBeConsumed = false - usesPlatformOf(compilation.target) - 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)) - description = "CInterop dependencies for compilation '${compilation.name}')." + /* Deferring attributes to wait for compilation.attributes to be configured by user*/ + whenEvaluated { + 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)) + description = "CInterop dependencies for compilation '${compilation.name}')." + } } } @@ -67,11 +73,15 @@ internal fun Project.locateOrCreateCInteropApiElementsConfiguration(target: Kotl isCanBeResolved = false isCanBeConsumed = true - usesPlatformOf(target) - 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(ArtifactAttributes.ARTIFACT_FORMAT, NativeArtifactFormat.KLIB) + /* Deferring attributes to wait for target.attributes to be configured by user */ + whenEvaluated { + 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(ArtifactAttributes.ARTIFACT_FORMAT, NativeArtifactFormat.KLIB) + } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/regressionTests/KT56143CinteropConfigurationAttributes.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/regressionTests/KT56143CinteropConfigurationAttributes.kt new file mode 100644 index 00000000000..1e954ec7cc5 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/regressionTests/KT56143CinteropConfigurationAttributes.kt @@ -0,0 +1,113 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +@file:Suppress("FunctionName") + +package org.jetbrains.kotlin.gradle.regressionTests + +import org.gradle.api.artifacts.Configuration +import org.gradle.api.attributes.Attribute +import org.gradle.api.attributes.Category +import org.gradle.api.attributes.LibraryElements +import org.gradle.api.attributes.Usage +import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension +import org.jetbrains.kotlin.gradle.plugin.categoryByName +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages +import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements.cinteropKlibLibraryElements +import org.jetbrains.kotlin.gradle.targets.native.internal.locateOrCreateCInteropApiElementsConfiguration +import org.jetbrains.kotlin.gradle.targets.native.internal.locateOrCreateCInteropDependencyConfiguration +import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP +import org.jetbrains.kotlin.gradle.util.kotlin +import org.jetbrains.kotlin.gradle.util.main +import org.junit.Test +import kotlin.test.assertEquals + +class KT56143CinteropConfigurationAttributes { + + private val targetAttribute = Attribute.of("for.target", String::class.java) + private val compilationAttribute = Attribute.of("for.compilation", String::class.java) + + private val project = buildProjectWithMPP { + kotlin { + linuxX64("variantA") { + attributes.attribute(targetAttribute, "a") + compilations.main.attributes.attribute(compilationAttribute, "compilation:a") + } + + linuxX64("variantB") { + attributes.attribute(targetAttribute, "b") + compilations.main.attributes.attribute(compilationAttribute, "compilation:b") + } + } + } + + private val variantA = project.multiplatformExtension.linuxX64("variantA") + + private val variantB = project.multiplatformExtension.linuxX64("variantB") + + @Test + fun `test - cinteropApiElements - contains target attributes`() { + project.evaluate() + + val variantAElements = project.locateOrCreateCInteropApiElementsConfiguration(variantA) + assertEquals("a", variantAElements.attributes.getAttribute(targetAttribute)) + + val variantBElements = project.locateOrCreateCInteropApiElementsConfiguration(variantB) + assertEquals("b", variantBElements.attributes.getAttribute(targetAttribute)) + } + + @Test + fun `test - cinteropDependencies - contains target and compilation attributes`() { + project.evaluate() + + val variantADependencies = project.locateOrCreateCInteropDependencyConfiguration( + variantA.compilations.main as KotlinNativeCompilation + ) + assertEquals("a", variantADependencies.attributes.getAttribute(targetAttribute)) + assertEquals("compilation:a", variantADependencies.attributes.getAttribute(compilationAttribute)) + + val variantBDependencies = project.locateOrCreateCInteropDependencyConfiguration( + variantB.compilations.main as KotlinNativeCompilation + ) + assertEquals("b", variantBDependencies.attributes.getAttribute(targetAttribute)) + assertEquals("compilation:b", variantBDependencies.attributes.getAttribute(compilationAttribute)) + } + + @Test + fun `test - all cinterop configurations contain default attributes`() { + project.evaluate() + + fun checkConfigurationAttributes(configuration: Configuration) { + assertEquals( + project.cinteropKlibLibraryElements(), + configuration.attributes.getAttribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE), + "Expected cinterop klib library elements on ${configuration.name}" + ) + + assertEquals( + project.objects.named(Usage::class.java, KotlinUsages.KOTLIN_CINTEROP), + configuration.attributes.getAttribute(Usage.USAGE_ATTRIBUTE), + "Expected kotlin cinterop usage on ${configuration.name}" + ) + + assertEquals( + project.categoryByName(Category.LIBRARY), + configuration.attributes.getAttribute(Category.CATEGORY_ATTRIBUTE), + "Expected library category on ${configuration.name}" + ) + } + + project.multiplatformExtension.targets.forEach { target -> + val cinteropApiElements = project.locateOrCreateCInteropApiElementsConfiguration(target) + checkConfigurationAttributes(cinteropApiElements) + + target.compilations.forEach { compilation -> + if (compilation is KotlinNativeCompilation) + checkConfigurationAttributes(project.locateOrCreateCInteropDependencyConfiguration(compilation)) + } + } + } +}