diff --git a/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/AndroidTargetPrototype.kt b/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/AndroidTargetPrototype.kt index c4cd3fd6ccc..1cfdf798af4 100644 --- a/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/AndroidTargetPrototype.kt +++ b/libraries/tools/kotlin-gradle-plugin-tcs-android/src/main/kotlin/org/jetbrains/kotlin/gradle/android/AndroidTargetPrototype.kt @@ -9,7 +9,6 @@ package org.jetbrains.kotlin.gradle.android import com.android.build.gradle.AppExtension import com.android.build.gradle.internal.publishing.AndroidArtifacts -import org.gradle.api.attributes.Usage import org.gradle.api.attributes.java.TargetJvmEnvironment import org.gradle.api.attributes.java.TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE import org.gradle.kotlin.dsl.getByType @@ -46,8 +45,22 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge val androidTarget = createExternalKotlinTarget { targetName = "android" platformType = KotlinPlatformType.jvm - targetFactory = TargetFactory { delegate -> - PrototypeAndroidTarget(delegate, PrototypeAndroidDsl(31)) + targetFactory = TargetFactory { delegate -> PrototypeAndroidTarget(delegate, PrototypeAndroidDsl(31)) } + + apiElements.configure { _, configuration -> + configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) + } + + runtimeElements.configure { _, configuration -> + configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) + } + + apiElementsPublished.configure { _, configuration -> + configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) + } + + runtimeElementsPublished.configure { _, configuration -> + configuration.attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) } } @@ -111,44 +124,30 @@ fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarge /* Setup apiElements configuration: - Usage: JAVA_API - jvmEnvironment: Android variants: - classes (provides access to the compiled .class files) artifactType: CLASSES_JAR */ - project.configurations.getByName(androidTarget.apiElementsConfigurationName).apply { - attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_API)) - attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) - outgoing.variants.create("classes").let { variant -> - variant.attributes.attribute(AndroidArtifacts.ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type) - variant.artifact(mainCompilation.output.classesDirs.singleFile) { - it.builtBy(mainCompilation.output.classesDirs) - } + androidTarget.apiElementsConfiguration.outgoing.variants.create("classes").let { variant -> + variant.attributes.attribute(AndroidArtifacts.ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type) + variant.artifact(mainCompilation.output.classesDirs.singleFile) { + it.builtBy(mainCompilation.output.classesDirs) } } - /* Setup runtimeElements configuration: - Usage: JAVA_RUNTIME - jvmEnvironment: Android variants: - classes (provides access to the compiled .class files) artifactType: CLASSES_JAR */ - project.configurations.getByName(androidTarget.runtimeElementsConfigurationName).apply { - attributes.attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage.JAVA_RUNTIME)) - attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID)) - outgoing.variants.create("classes").let { variant -> - variant.attributes.attribute(AndroidArtifacts.ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type) - variant.artifact(mainCompilation.output.classesDirs.singleFile) { - it.builtBy(mainCompilation.output.classesDirs) - } + androidTarget.runtimeElementsConfiguration.outgoing.variants.create("classes").let { variant -> + variant.attributes.attribute(AndroidArtifacts.ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type) + variant.artifact(mainCompilation.output.classesDirs.singleFile) { + it.builtBy(mainCompilation.output.classesDirs) } } - /* "Disable" configurations from plain Android plugin This hack will not be necessary in the final implementation diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/DecoratedExternalKotlinTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/DecoratedExternalKotlinTarget.kt index b6a04066e8c..70589e2482f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/DecoratedExternalKotlinTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/DecoratedExternalKotlinTarget.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.external +import org.gradle.api.artifacts.Configuration import org.gradle.api.logging.Logger import org.gradle.api.logging.Logging import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi @@ -18,5 +19,9 @@ abstract class DecoratedExternalKotlinTarget internal constructor( class Delegate internal constructor(internal val impl: ExternalKotlinTargetImpl) + val apiElementsConfiguration: Configuration = delegate.apiElementsConfiguration + + val runtimeElementsConfiguration: Configuration = delegate.runtimeElementsConfiguration + internal val logger: Logger = Logging.getLogger("${ExternalKotlinTargetImpl::class.qualifiedName}: $name") } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetConfigurationDescriptor.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetConfigurationDescriptor.kt new file mode 100644 index 00000000000..0a7e9b25279 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetConfigurationDescriptor.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2010-2022 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.external + +import org.gradle.api.artifacts.Configuration +import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi + +@ExternalKotlinTargetApi +interface ExternalKotlinTargetConfigurationDescriptor { + val configure: ((target: T, configuration: Configuration) -> Unit)? +} + +@ExternalKotlinTargetApi +class ExternalKotlinTargetConfigurationDescriptorBuilder internal constructor() { + + var configure: ((target: T, configuration: Configuration) -> Unit)? = null + + fun configure(action: (target: T, configuration: Configuration) -> Unit) = apply { + val configure = this.configure + if (configure == null) this.configure = action + else this.configure = { target, configuration -> + configure(target, configuration) + action(target, configuration) + } + } + + internal fun build(): ExternalKotlinTargetConfigurationDescriptor { + return ExternalKotlinTargetConfigurationDescriptorImpl(configure) + } +} + +private data class ExternalKotlinTargetConfigurationDescriptorImpl( + override val configure: ((target: T, configuration: Configuration) -> Unit)? +) : ExternalKotlinTargetConfigurationDescriptor diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetDescriptor.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetDescriptor.kt index 1488ff7a191..a37b3b9d271 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetDescriptor.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/ExternalKotlinTargetDescriptor.kt @@ -20,50 +20,63 @@ interface ExternalKotlinTargetDescriptor { val targetName: String val platformType: KotlinPlatformType val targetFactory: TargetFactory - val configure: ((T) -> Unit)? -} -@ExternalKotlinTargetApi -interface ExternalKotlinTargetDescriptorBuilder { - var targetName: String - var platformType: KotlinPlatformType - var targetFactory: TargetFactory - var configure: ((T) -> Unit)? - fun configure(action: (T) -> Unit) = apply { - val configure = this.configure - if (configure == null) this.configure = action - else this.configure = { configure(it); action(it) } - } + val configure: ((T) -> Unit)? + + val apiElements: ExternalKotlinTargetConfigurationDescriptor + val runtimeElements: ExternalKotlinTargetConfigurationDescriptor + val apiElementsPublished: ExternalKotlinTargetConfigurationDescriptor + val runtimeElementsPublished: ExternalKotlinTargetConfigurationDescriptor } @ExternalKotlinTargetApi fun ExternalKotlinTargetDescriptor( configure: ExternalKotlinTargetDescriptorBuilder.() -> Unit ): ExternalKotlinTargetDescriptor { - return ExternalKotlinTargetDescriptorBuilderImpl().also(configure).build() + return ExternalKotlinTargetDescriptorBuilder().also(configure).build() } @ExternalKotlinTargetApi -private class ExternalKotlinTargetDescriptorBuilderImpl : ExternalKotlinTargetDescriptorBuilder { - override var targetName: String by Delegates.notNull() - override var platformType: KotlinPlatformType by Delegates.notNull() - override var targetFactory: TargetFactory by Delegates.notNull() - override var configure: ((T) -> Unit)? = null +class ExternalKotlinTargetDescriptorBuilder internal constructor() { + var targetName: String by Delegates.notNull() + var platformType: KotlinPlatformType by Delegates.notNull() + var targetFactory: TargetFactory by Delegates.notNull() - fun build(): ExternalKotlinTargetDescriptorImpl = ExternalKotlinTargetDescriptorImpl( + val apiElements: ExternalKotlinTargetConfigurationDescriptorBuilder = + ExternalKotlinTargetConfigurationDescriptorBuilder() + + val runtimeElements: ExternalKotlinTargetConfigurationDescriptorBuilder = + ExternalKotlinTargetConfigurationDescriptorBuilder() + + val apiElementsPublished: ExternalKotlinTargetConfigurationDescriptorBuilder = + ExternalKotlinTargetConfigurationDescriptorBuilder() + + val runtimeElementsPublished: ExternalKotlinTargetConfigurationDescriptorBuilder = + ExternalKotlinTargetConfigurationDescriptorBuilder() + + var configure: ((T) -> Unit)? = null + + internal fun build(): ExternalKotlinTargetDescriptor = ExternalKotlinTargetDescriptorImpl( targetName = targetName, platformType = platformType, targetFactory = targetFactory, + apiElements = apiElements.build(), + runtimeElements = runtimeElements.build(), + apiElementsPublished = apiElementsPublished.build(), + runtimeElementsPublished = runtimeElementsPublished.build(), configure = configure ) } -@ExternalKotlinTargetApi private data class ExternalKotlinTargetDescriptorImpl( override val targetName: String, override val platformType: KotlinPlatformType, override val targetFactory: TargetFactory, - override val configure: ((T) -> Unit)? + override val apiElements: ExternalKotlinTargetConfigurationDescriptor, + override val runtimeElements: ExternalKotlinTargetConfigurationDescriptor, + override val apiElementsPublished: ExternalKotlinTargetConfigurationDescriptor, + override val runtimeElementsPublished: ExternalKotlinTargetConfigurationDescriptor, + override val configure: ((T) -> Unit)?, ) : ExternalKotlinTargetDescriptor diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/createExternalKotlinTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/createExternalKotlinTarget.kt index 19635bc0f5a..8c2c7333cde 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/createExternalKotlinTarget.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/external/createExternalKotlinTarget.kt @@ -7,11 +7,16 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.external +import org.gradle.api.attributes.Category +import org.gradle.api.attributes.Usage import org.gradle.jvm.tasks.Jar import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages +import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName +import org.jetbrains.kotlin.gradle.utils.named @ExternalKotlinTargetApi fun KotlinMultiplatformExtension.createExternalKotlinTarget( @@ -20,6 +25,7 @@ fun KotlinMultiplatformExtension.createExter val defaultConfiguration = project.configurations.maybeCreate(lowerCamelCaseName(descriptor.targetName, "default")) val apiElementsConfiguration = project.configurations.maybeCreate(lowerCamelCaseName(descriptor.targetName, "apiElements")) val runtimeElementsConfiguration = project.configurations.maybeCreate(lowerCamelCaseName(descriptor.targetName, "runtimeElements")) + val artifactsTaskLocator = ExternalKotlinTargetImpl.ArtifactsTaskLocator { target -> target.project.locateOrRegisterTask(lowerCamelCaseName(descriptor.targetName, "jar")) } @@ -36,9 +42,21 @@ fun KotlinMultiplatformExtension.createExter artifactsTaskLocator = artifactsTaskLocator ) + apiElementsConfiguration.usesPlatformOf(target) + apiElementsConfiguration.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target)) + apiElementsConfiguration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) + + runtimeElementsConfiguration.usesPlatformOf(target) + runtimeElementsConfiguration.attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(target)) + runtimeElementsConfiguration.attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) + val decorated = descriptor.targetFactory.create(DecoratedExternalKotlinTarget.Delegate(target)) target.onCreated() + descriptor.configure?.invoke(decorated) + descriptor.apiElements.configure?.invoke(decorated, apiElementsConfiguration) + descriptor.runtimeElements.configure?.invoke(decorated, runtimeElementsConfiguration) + targets.add(decorated) decorated.logger.info("Created ${descriptor.platformType} target") return decorated