[Gradle] Initial 'externalTargetApi' w/ compilable Android prototype
^KT-54766 Verification Pending
This commit is contained in:
committed by
Space Team
parent
33adebe5bf
commit
9599c16d95
+12
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
@RequiresOptIn(
|
||||
message = "This API is intended to be used by Google to maintain KotlinTargets outside of kotlin.git",
|
||||
level = RequiresOptIn.Level.ERROR
|
||||
)
|
||||
annotation class ExternalKotlinTargetApi
|
||||
@@ -9,9 +9,16 @@ dependencies {
|
||||
compileOnly(project(":kotlin-gradle-plugin"))
|
||||
}
|
||||
|
||||
/* This module is just for local development / prototyping and demos */
|
||||
if (!kotlinBuildProperties.isTeamcityBuild) {
|
||||
tasks.register("install") {
|
||||
dependsOn(tasks.named("publishToMavenLocal"))
|
||||
configureKotlinCompileTasksGradleCompatibility()
|
||||
|
||||
kotlin {
|
||||
sourceSets.all {
|
||||
languageSettings.optIn("org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi")
|
||||
}
|
||||
}
|
||||
|
||||
/* This module is just for local development / prototyping and demos */
|
||||
if (!kotlinBuildProperties.isTeamcityBuild) {
|
||||
publish()
|
||||
standardPublicJars()
|
||||
}
|
||||
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("DEPRECATION", "DuplicatedCode")
|
||||
|
||||
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
|
||||
import org.gradle.kotlin.dsl.named
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.kpm.external.ExternalVariantApi
|
||||
import org.jetbrains.kotlin.gradle.kpm.external.project
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinTargetDescriptor.DecoratedExternalTargetFactory
|
||||
|
||||
@OptIn(ExternalVariantApi::class)
|
||||
fun KotlinMultiplatformExtension.androidTargetPrototype(): PrototypeAndroidTarget {
|
||||
val project = this.project
|
||||
val androidExtension = project.extensions.getByType<AppExtension>()
|
||||
|
||||
/*
|
||||
Set a variant filter and only allow 'debug'.
|
||||
Reason: This prototype will not deal w/ buildTypes or flavors.
|
||||
Only 'debug' will be supported. As of agreed w/ AGP team, this is the initial goal
|
||||
for the APIs.
|
||||
*/
|
||||
androidExtension.variantFilter { variant ->
|
||||
if (variant.name != "debug") {
|
||||
variant.ignore = true
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Create our 'AndroidTarget':
|
||||
This uses the 'KotlinPlatformType.jvm' instead of androidJvm, since from the perspective of
|
||||
Kotlin, this is just another 'jvm' like target (using the jvm compiler)
|
||||
*/
|
||||
val androidTarget = createExternalKotlinTarget<PrototypeAndroidTarget> {
|
||||
targetName = "android"
|
||||
platformType = KotlinPlatformType.jvm
|
||||
decoratedExternalTargetFactory = DecoratedExternalTargetFactory { externalTarget ->
|
||||
PrototypeAndroidTarget(externalTarget, PrototypeAndroidDsl(31))
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Whilst using the .all hook, we only expect the single 'debug' variant to be available through this API.
|
||||
*/
|
||||
androidExtension.applicationVariants.all { applicationVariant ->
|
||||
project.logger.quiet("Setting up applicationVariant: ${applicationVariant.name}")
|
||||
|
||||
/*
|
||||
Create Compilations: main, unitTest and instrumentedTest
|
||||
(as proposed in the new Multiplatform/Android SourceSetLayout v2)
|
||||
*/
|
||||
val mainCompilation = androidTarget.createAndroidCompilation("main")
|
||||
val unitTestCompilation = androidTarget.createAndroidCompilation("unitTest")
|
||||
val instrumentedTestCompilation = androidTarget.createAndroidCompilation("instrumentedTest")
|
||||
|
||||
/*
|
||||
Associate unitTest/instrumentedTest compilations with main
|
||||
*/
|
||||
unitTestCompilation.associateWith(mainCompilation)
|
||||
instrumentedTestCompilation.associateWith(mainCompilation)
|
||||
|
||||
/*
|
||||
Setup dependsOn edges as in Multiplatform/Android SourceSetLayout v2:
|
||||
android/main dependsOn commonMain
|
||||
android/unitTest dependsOn commonTest
|
||||
android/instrumentedTest *does not depend on a common SourceSet*
|
||||
*/
|
||||
mainCompilation.defaultSourceSet.dependsOn(sourceSets.getByName("commonMain"))
|
||||
unitTestCompilation.defaultSourceSet.dependsOn(sourceSets.getByName("commonTest"))
|
||||
|
||||
/*
|
||||
Wire the Kotlin Compilations output (.class files) into the Android artifacts
|
||||
by using the 'registerPreJavacGeneratedBytecode' function
|
||||
*/
|
||||
applicationVariant.registerPreJavacGeneratedBytecode(mainCompilation.output.classesDirs)
|
||||
applicationVariant.unitTestVariant.registerPreJavacGeneratedBytecode(unitTestCompilation.output.classesDirs)
|
||||
applicationVariant.testVariant.registerPreJavacGeneratedBytecode(instrumentedTestCompilation.output.classesDirs)
|
||||
|
||||
|
||||
/*
|
||||
Add dependencies coming from Kotlin to Android by adding all dependencies from Kotlin to the variants
|
||||
compileConfiguration or runtimeConfiguration
|
||||
*/
|
||||
applicationVariant.compileConfiguration.extendsFrom(mainCompilation.configurations.compileDependencyConfiguration)
|
||||
applicationVariant.runtimeConfiguration.extendsFrom(mainCompilation.configurations.runtimeDependencyConfiguration)
|
||||
applicationVariant.unitTestVariant.compileConfiguration.extendsFrom(unitTestCompilation.configurations.compileDependencyConfiguration)
|
||||
applicationVariant.unitTestVariant.runtimeConfiguration.extendsFrom(unitTestCompilation.configurations.runtimeDependencyConfiguration)
|
||||
applicationVariant.testVariant.compileConfiguration.extendsFrom(instrumentedTestCompilation.configurations.compileDependencyConfiguration)
|
||||
applicationVariant.testVariant.runtimeConfiguration.extendsFrom(instrumentedTestCompilation.configurations.runtimeDependencyConfiguration)
|
||||
|
||||
|
||||
/*
|
||||
Add the 'android boot classpath' to the compilation dependencies to compile against
|
||||
*/
|
||||
mainCompilation.configurations.compileDependencyConfiguration.dependencies.add(
|
||||
project.dependencies.create(project.androidBootClasspath())
|
||||
)
|
||||
|
||||
|
||||
/*
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
"Disable" configurations from plain Android plugin
|
||||
This hack will not be necessary in the final implementation
|
||||
*/
|
||||
project.configurations.findByName("${applicationVariant.name}ApiElements")?.isCanBeConsumed = false
|
||||
project.configurations.findByName("${applicationVariant.name}RuntimeElements")?.isCanBeConsumed = false
|
||||
}
|
||||
|
||||
return androidTarget
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("DEPRECATION", "OVERRIDE_DEPRECATION")
|
||||
|
||||
package org.jetbrains.kotlin.gradle.android
|
||||
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
|
||||
import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilation
|
||||
|
||||
class PrototypeAndroidCompilation(delegate: Delegate) : ExternalKotlinCompilation(delegate) {
|
||||
override val kotlinOptions: KotlinCommonOptions
|
||||
get() = super.kotlinOptions as KotlinJvmOptions
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override val compilerOptions: HasCompilerOptions<KotlinJvmCompilerOptions>
|
||||
get() = super.compilerOptions as HasCompilerOptions<KotlinJvmCompilerOptions>
|
||||
|
||||
var androidCompilationSpecificStuff = 10
|
||||
}
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.android
|
||||
|
||||
import org.gradle.api.NamedDomainObjectContainer
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.DecoratedExternalKotlinTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinTarget
|
||||
|
||||
data class PrototypeAndroidDsl(
|
||||
var compileSdk: Int
|
||||
)
|
||||
|
||||
class PrototypeAndroidTarget(
|
||||
private val target: ExternalKotlinTarget,
|
||||
val androidDsl: PrototypeAndroidDsl
|
||||
) : DecoratedExternalKotlinTarget(target) {
|
||||
internal val kotlin = target.project.extensions.getByType<KotlinMultiplatformExtension>()
|
||||
|
||||
@Suppress("unchecked_cast")
|
||||
override val compilations: NamedDomainObjectContainer<PrototypeAndroidCompilation>
|
||||
get() = target.compilations as NamedDomainObjectContainer<PrototypeAndroidCompilation>
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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.android
|
||||
|
||||
import com.android.build.gradle.BaseExtension
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
internal fun Project.androidBootClasspath(): FileCollection {
|
||||
return project.files(Callable { project.extensions.getByType<BaseExtension>().bootClasspath })
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.android
|
||||
|
||||
import com.android.build.gradle.internal.publishing.AndroidArtifacts
|
||||
import org.gradle.api.attributes.java.TargetJvmEnvironment
|
||||
import org.gradle.kotlin.dsl.named
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilationDescriptor
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilationDescriptor.DecoratedKotlinCompilationFactory
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.createCompilation
|
||||
|
||||
internal fun PrototypeAndroidTarget.createAndroidCompilation(name: String): PrototypeAndroidCompilation {
|
||||
return createCompilation {
|
||||
compilationName = name
|
||||
defaultSourceSet = kotlin.sourceSets.maybeCreate(camelCase("prototype", targetName, name))
|
||||
decoratedKotlinCompilationFactory = DecoratedKotlinCompilationFactory(::PrototypeAndroidCompilation)
|
||||
compileTaskName = camelCase("prototype", "compile", targetName, name)
|
||||
|
||||
/*
|
||||
Replace Kotlin's compilation association (main <-> test) with noop,
|
||||
since Android goes through adding a dependency on the project itself
|
||||
*/
|
||||
compilationAssociator = ExternalKotlinCompilationDescriptor.CompilationAssociator { first, second ->
|
||||
first.configurations.compileDependencyConfiguration.extendsFrom(
|
||||
second.configurations.apiConfiguration,
|
||||
second.configurations.implementationConfiguration,
|
||||
second.configurations.compileOnlyConfiguration
|
||||
)
|
||||
}
|
||||
|
||||
/* Configure the compilation before it is accessible for user code */
|
||||
configure { compilation ->
|
||||
/* Setup attributes for the compile dependencies */
|
||||
compilation.configurations.compileDependencyConfiguration.apply {
|
||||
attributes.attribute(AndroidArtifacts.ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type)
|
||||
attributes.attribute(TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID))
|
||||
}
|
||||
|
||||
/* Setup attributes for the runtime dependencies */
|
||||
compilation.configurations.runtimeDependencyConfiguration?.apply {
|
||||
attributes.attribute(AndroidArtifacts.ARTIFACT_TYPE, AndroidArtifacts.ArtifactType.CLASSES_JAR.type)
|
||||
attributes.attribute(TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, project.objects.named(TargetJvmEnvironment.ANDROID))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("DEPRECATION")
|
||||
|
||||
package org.jetbrains.kotlin.gradle.android
|
||||
|
||||
fun camelCase(vararg parts: String): String {
|
||||
if (parts.isEmpty()) return ""
|
||||
return parts.joinToString("") { it.capitalize() }.decapitalize()
|
||||
}
|
||||
+2
-1
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsCompilerAttribute
|
||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
|
||||
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
||||
import org.jetbrains.kotlin.gradle.utils.*
|
||||
@@ -143,7 +144,7 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
|
||||
compilation.compileKotlinTaskProvider.map { it.outputs.files }
|
||||
})
|
||||
|
||||
if (compilation is KotlinJvmCompilation && compilation.target.withJavaEnabled) {
|
||||
if (compilation is KotlinJvmCompilation && (compilation.target as? KotlinJvmTarget)?.withJavaEnabled == true) {
|
||||
it.inputs.files({ compilation.compileJavaTaskProvider?.map { it.outputs.files } })
|
||||
}
|
||||
|
||||
|
||||
+54
-62
@@ -20,16 +20,9 @@ import org.gradle.api.internal.component.SoftwareComponentInternal
|
||||
import org.gradle.api.internal.component.UsageContext
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsSubTargetContainerDsl
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsSubTargetDsl
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
|
||||
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
|
||||
import org.jetbrains.kotlin.gradle.tasks.dependsOn
|
||||
import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
|
||||
@@ -84,61 +77,7 @@ abstract class AbstractKotlinTarget(
|
||||
}
|
||||
|
||||
override val components: Set<SoftwareComponent> by lazy {
|
||||
buildAdhocComponentsFromKotlinVariants(kotlinComponents)
|
||||
}
|
||||
|
||||
private fun buildAdhocComponentsFromKotlinVariants(kotlinVariants: Set<KotlinTargetComponent>): Set<SoftwareComponent> {
|
||||
val softwareComponentFactoryClass = SoftwareComponentFactory::class.java
|
||||
// TODO replace internal API access with injection (not possible until we have this class on the compile classpath)
|
||||
val softwareComponentFactory = (project as ProjectInternal).services.get(softwareComponentFactoryClass)
|
||||
|
||||
return kotlinVariants.map { kotlinVariant ->
|
||||
val adhocVariant = softwareComponentFactory.adhoc(kotlinVariant.name)
|
||||
|
||||
project.whenEvaluated {
|
||||
(kotlinVariant as SoftwareComponentInternal).usages.filterIsInstance<KotlinUsageContext>().forEach { kotlinUsageContext ->
|
||||
val publishedConfigurationName = publishedConfigurationName(kotlinUsageContext.name)
|
||||
val configuration = project.configurations.findByName(publishedConfigurationName)
|
||||
?: project.configurations.create(publishedConfigurationName).also { configuration ->
|
||||
configuration.isCanBeConsumed = false
|
||||
configuration.isCanBeResolved = false
|
||||
configuration.extendsFrom(project.configurations.getByName(kotlinUsageContext.dependencyConfigurationName))
|
||||
configuration.artifacts.addAll(kotlinUsageContext.artifacts)
|
||||
|
||||
val attributes = kotlinUsageContext.attributes
|
||||
attributes.keySet().forEach {
|
||||
// capture type parameter T
|
||||
fun <T> copyAttribute(key: Attribute<T>, from: AttributeContainer, to: AttributeContainer) {
|
||||
to.attribute(key, from.getAttribute(key)!!)
|
||||
}
|
||||
copyAttribute(it, attributes, configuration.attributes)
|
||||
}
|
||||
}
|
||||
|
||||
adhocVariant.addVariantsFromConfiguration(configuration) { configurationVariantDetails ->
|
||||
val mavenScope = when (kotlinUsageContext.usage.name) {
|
||||
"java-api-jars" -> "compile"
|
||||
"java-runtime-jars" -> "runtime"
|
||||
else -> error("unexpected usage value '${kotlinUsageContext.usage.name}'")
|
||||
}
|
||||
configurationVariantDetails.mapToMavenScope(mavenScope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
adhocVariant as SoftwareComponent
|
||||
|
||||
object : ComponentWithVariants, ComponentWithCoordinates, SoftwareComponentInternal {
|
||||
override fun getCoordinates() =
|
||||
(kotlinVariant as? ComponentWithCoordinates)?.coordinates ?: error("kotlinVariant is not ComponentWithCoordinates")
|
||||
|
||||
override fun getVariants(): Set<SoftwareComponent> =
|
||||
(kotlinVariant as? KotlinVariantWithMetadataVariant)?.variants.orEmpty()
|
||||
|
||||
override fun getName(): String = adhocVariant.name
|
||||
override fun getUsages(): MutableSet<out UsageContext> = (adhocVariant as SoftwareComponentInternal).usages
|
||||
}
|
||||
}.toSet()
|
||||
project.buildAdhocComponentsFromKotlinVariants(kotlinComponents)
|
||||
}
|
||||
|
||||
protected open fun createKotlinVariant(
|
||||
@@ -228,3 +167,56 @@ internal fun KotlinTarget.disambiguateName(simpleName: String) =
|
||||
|
||||
internal fun javaApiUsageForMavenScoping() = "java-api-jars"
|
||||
|
||||
internal fun Project.buildAdhocComponentsFromKotlinVariants(kotlinVariants: Set<KotlinTargetComponent>): Set<SoftwareComponent> {
|
||||
val softwareComponentFactoryClass = SoftwareComponentFactory::class.java
|
||||
// TODO replace internal API access with injection (not possible until we have this class on the compile classpath)
|
||||
val softwareComponentFactory = (project as ProjectInternal).services.get(softwareComponentFactoryClass)
|
||||
|
||||
return kotlinVariants.map { kotlinVariant ->
|
||||
val adhocVariant = softwareComponentFactory.adhoc(kotlinVariant.name)
|
||||
|
||||
project.whenEvaluated {
|
||||
(kotlinVariant as SoftwareComponentInternal).usages.filterIsInstance<KotlinUsageContext>().forEach { kotlinUsageContext ->
|
||||
val publishedConfigurationName = publishedConfigurationName(kotlinUsageContext.name)
|
||||
val configuration = project.configurations.findByName(publishedConfigurationName)
|
||||
?: project.configurations.create(publishedConfigurationName).also { configuration ->
|
||||
configuration.isCanBeConsumed = false
|
||||
configuration.isCanBeResolved = false
|
||||
configuration.extendsFrom(project.configurations.getByName(kotlinUsageContext.dependencyConfigurationName))
|
||||
configuration.artifacts.addAll(kotlinUsageContext.artifacts)
|
||||
|
||||
val attributes = kotlinUsageContext.attributes
|
||||
attributes.keySet().forEach {
|
||||
// capture type parameter T
|
||||
fun <T> copyAttribute(key: Attribute<T>, from: AttributeContainer, to: AttributeContainer) {
|
||||
to.attribute(key, from.getAttribute(key)!!)
|
||||
}
|
||||
copyAttribute(it, attributes, configuration.attributes)
|
||||
}
|
||||
}
|
||||
|
||||
adhocVariant.addVariantsFromConfiguration(configuration) { configurationVariantDetails ->
|
||||
val mavenScope = when (kotlinUsageContext.usage.name) {
|
||||
"java-api-jars" -> "compile"
|
||||
"java-runtime-jars" -> "runtime"
|
||||
else -> error("unexpected usage value '${kotlinUsageContext.usage.name}'")
|
||||
}
|
||||
configurationVariantDetails.mapToMavenScope(mavenScope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
adhocVariant as SoftwareComponent
|
||||
|
||||
object : ComponentWithVariants, ComponentWithCoordinates, SoftwareComponentInternal {
|
||||
override fun getCoordinates() =
|
||||
(kotlinVariant as? ComponentWithCoordinates)?.coordinates ?: error("kotlinVariant is not ComponentWithCoordinates")
|
||||
|
||||
override fun getVariants(): Set<SoftwareComponent> =
|
||||
(kotlinVariant as? KotlinVariantWithMetadataVariant)?.variants.orEmpty()
|
||||
|
||||
override fun getName(): String = adhocVariant.name
|
||||
override fun getUsages(): MutableSet<out UsageContext> = (adhocVariant as SoftwareComponentInternal).usages
|
||||
}
|
||||
}.toSet()
|
||||
}
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinDependencyHandler
|
||||
|
||||
internal interface KotlinCompilationConfigurationsContainer {
|
||||
interface KotlinCompilationConfigurationsContainer {
|
||||
val deprecatedCompileConfiguration: Configuration?
|
||||
val deprecatedRuntimeConfiguration: Configuration?
|
||||
val apiConfiguration: Configuration
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ internal class DefaultKotlinCompilationFriendPathsResolver(
|
||||
|
||||
/* Resolution of friend artifacts */
|
||||
|
||||
interface FriendArtifactResolver {
|
||||
fun interface FriendArtifactResolver {
|
||||
fun resolveFriendArtifacts(compilation: InternalKotlinCompilation<*>): FileCollection
|
||||
|
||||
companion object {
|
||||
|
||||
+1
-3
@@ -25,10 +25,8 @@ import org.jetbrains.kotlin.gradle.tasks.locateTask
|
||||
import org.jetbrains.kotlin.gradle.utils.ObservableSet
|
||||
import org.jetbrains.kotlin.tooling.core.MutableExtras
|
||||
import org.jetbrains.kotlin.tooling.core.mutableExtrasOf
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
internal class KotlinCompilationImpl @Inject constructor(
|
||||
internal class KotlinCompilationImpl constructor(
|
||||
private val params: Params
|
||||
) : InternalKotlinCompilation<KotlinCommonOptions> {
|
||||
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* 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.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
abstract class DecoratedExternalKotlinTarget(
|
||||
internal val delegate: ExternalKotlinTarget
|
||||
) : KotlinTarget by delegate
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("DEPRECATION")
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin.mpp.external
|
||||
|
||||
import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.DecoratedKotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationImpl
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
abstract class ExternalKotlinCompilation(delegate: Delegate) :
|
||||
DecoratedKotlinCompilation<KotlinCommonOptions>(delegate.compilation) {
|
||||
class Delegate internal constructor(internal val compilation: KotlinCompilationImpl)
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.file.FileCollection
|
||||
import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.DecoratedKotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilationDescriptor.*
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
interface ExternalKotlinCompilationDescriptor<T : ExternalKotlinCompilation> {
|
||||
fun interface DecoratedKotlinCompilationFactory<T : DecoratedKotlinCompilation<*>> {
|
||||
fun create(delegate: ExternalKotlinCompilation.Delegate): T
|
||||
}
|
||||
|
||||
fun interface FriendArtifactResolver<T : ExternalKotlinCompilation> {
|
||||
fun resolveFriendPaths(compilation: T): FileCollection
|
||||
}
|
||||
|
||||
fun interface CompilationAssociator<T : ExternalKotlinCompilation> {
|
||||
fun associate(compilation: T, main: ExternalKotlinCompilation)
|
||||
}
|
||||
|
||||
val compilationName: String
|
||||
val compileTaskName: String?
|
||||
val compileAllTaskName: String?
|
||||
val defaultSourceSet: KotlinSourceSet
|
||||
val decoratedKotlinCompilationFactory: DecoratedKotlinCompilationFactory<T>
|
||||
val friendArtifactResolver: FriendArtifactResolver<T>?
|
||||
val compilationAssociator: CompilationAssociator<T>?
|
||||
val configure: ((T) -> Unit)?
|
||||
}
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
fun <T : ExternalKotlinCompilation> ExternalKotlinCompilationDescriptor(
|
||||
configure: ExternalKotlinCompilationDescriptorBuilder<T>.() -> Unit
|
||||
): ExternalKotlinCompilationDescriptor<T> {
|
||||
return ExternalKotlinCompilationDescriptorBuilderImpl<T>().also(configure).run {
|
||||
ExternalKotlinCompilationDescriptorImpl(
|
||||
compilationName = compilationName,
|
||||
compileTaskName = compileTaskName,
|
||||
compileAllTaskName = compileAllTaskName,
|
||||
defaultSourceSet = defaultSourceSet,
|
||||
decoratedKotlinCompilationFactory = decoratedKotlinCompilationFactory,
|
||||
friendArtifactResolver = friendArtifactResolver,
|
||||
compilationAssociator = compilationAssociator,
|
||||
configure = this.configure
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
interface ExternalKotlinCompilationDescriptorBuilder<T : ExternalKotlinCompilation> {
|
||||
var compilationName: String
|
||||
var compileTaskName: String?
|
||||
var compileAllTaskName: String?
|
||||
var defaultSourceSet: KotlinSourceSet
|
||||
var decoratedKotlinCompilationFactory: DecoratedKotlinCompilationFactory<T>
|
||||
var friendArtifactResolver: FriendArtifactResolver<T>?
|
||||
var compilationAssociator: CompilationAssociator<T>?
|
||||
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) }
|
||||
}
|
||||
}
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
private class ExternalKotlinCompilationDescriptorBuilderImpl<T : ExternalKotlinCompilation> :
|
||||
ExternalKotlinCompilationDescriptorBuilder<T> {
|
||||
override var compilationName: String by Delegates.notNull()
|
||||
override var compileTaskName: String? = null
|
||||
override var compileAllTaskName: String? = null
|
||||
override var defaultSourceSet: KotlinSourceSet by Delegates.notNull()
|
||||
override var decoratedKotlinCompilationFactory: DecoratedKotlinCompilationFactory<T> by Delegates.notNull()
|
||||
override var friendArtifactResolver: FriendArtifactResolver<T>? = null
|
||||
override var compilationAssociator: CompilationAssociator<T>? = null
|
||||
override var configure: ((T) -> Unit)? = null
|
||||
}
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
private data class ExternalKotlinCompilationDescriptorImpl<T : ExternalKotlinCompilation>(
|
||||
override val compilationName: String,
|
||||
override val compileTaskName: String?,
|
||||
override val compileAllTaskName: String?,
|
||||
override val defaultSourceSet: KotlinSourceSet,
|
||||
override val decoratedKotlinCompilationFactory: DecoratedKotlinCompilationFactory<T>,
|
||||
override val friendArtifactResolver: FriendArtifactResolver<T>?,
|
||||
override val compilationAssociator: CompilationAssociator<T>?,
|
||||
override val configure: ((T) -> Unit)?
|
||||
) : ExternalKotlinCompilationDescriptor<T>
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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.Action
|
||||
import org.gradle.api.NamedDomainObjectContainer
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.attributes.AttributeContainer
|
||||
import org.gradle.api.component.SoftwareComponent
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.buildAdhocComponentsFromKotlinVariants
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
class ExternalKotlinTarget internal constructor(
|
||||
override val project: Project,
|
||||
override val targetName: String,
|
||||
override val platformType: KotlinPlatformType,
|
||||
val defaultConfiguration: Configuration,
|
||||
val apiElementsConfiguration: Configuration,
|
||||
val runtimeElementsConfiguration: Configuration,
|
||||
override val publishable: Boolean,
|
||||
internal val kotlinComponents: Set<KotlinTargetComponent>,
|
||||
private val artifactsTaskLocator: ArtifactsTaskLocator,
|
||||
) : KotlinTarget {
|
||||
|
||||
fun interface ArtifactsTaskLocator {
|
||||
fun locate(target: ExternalKotlinTarget): TaskProvider<out Task>
|
||||
}
|
||||
|
||||
val kotlin = project.multiplatformExtension
|
||||
|
||||
override val useDisambiguationClassifierAsSourceSetNamePrefix: Boolean = true
|
||||
|
||||
override val overrideDisambiguationClassifierOnIdeImport: String? = null
|
||||
|
||||
val artifactsTask: TaskProvider<out Task> by lazy {
|
||||
artifactsTaskLocator.locate(this)
|
||||
}
|
||||
|
||||
override val artifactsTaskName: String
|
||||
get() = artifactsTask.name
|
||||
|
||||
override val defaultConfigurationName: String
|
||||
get() = defaultConfiguration.name
|
||||
|
||||
override val apiElementsConfigurationName: String
|
||||
get() = apiElementsConfiguration.name
|
||||
|
||||
override val runtimeElementsConfigurationName: String
|
||||
get() = runtimeElementsConfiguration.name
|
||||
|
||||
override val components: Set<SoftwareComponent> by lazy {
|
||||
project.buildAdhocComponentsFromKotlinVariants(kotlinComponents)
|
||||
}
|
||||
|
||||
override val compilations: NamedDomainObjectContainer<ExternalKotlinCompilation> by lazy {
|
||||
project.container(ExternalKotlinCompilation::class.java)
|
||||
}
|
||||
|
||||
override fun mavenPublication(action: Action<MavenPublication>) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override val preset: Nothing? = null
|
||||
|
||||
override fun getAttributes(): AttributeContainer {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
internal fun onCreated() {
|
||||
artifactsTask
|
||||
components
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinTargetDescriptor.DecoratedExternalTargetFactory
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
interface ExternalKotlinTargetDescriptor<T : DecoratedExternalKotlinTarget> {
|
||||
|
||||
fun interface DecoratedExternalTargetFactory<T : DecoratedExternalKotlinTarget> {
|
||||
fun create(target: ExternalKotlinTarget): T
|
||||
}
|
||||
|
||||
val targetName: String
|
||||
val platformType: KotlinPlatformType
|
||||
val decoratedExternalTargetFactory: DecoratedExternalTargetFactory<T>
|
||||
val configure: ((T) -> Unit)?
|
||||
}
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
interface ExternalKotlinTargetDescriptorBuilder<T : DecoratedExternalKotlinTarget> {
|
||||
var targetName: String
|
||||
var platformType: KotlinPlatformType
|
||||
var decoratedExternalTargetFactory: DecoratedExternalTargetFactory<T>
|
||||
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) }
|
||||
}
|
||||
}
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
fun <T : DecoratedExternalKotlinTarget> ExternalKotlinTargetDescriptor(
|
||||
configure: ExternalKotlinTargetDescriptorBuilder<T>.() -> Unit
|
||||
): ExternalKotlinTargetDescriptor<T> {
|
||||
return ExternalKotlinTargetDescriptorBuilderImpl<T>().also(configure).build()
|
||||
}
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
private class ExternalKotlinTargetDescriptorBuilderImpl<T : DecoratedExternalKotlinTarget> : ExternalKotlinTargetDescriptorBuilder<T> {
|
||||
override var targetName: String by Delegates.notNull()
|
||||
override var platformType: KotlinPlatformType by Delegates.notNull()
|
||||
override var decoratedExternalTargetFactory: DecoratedExternalTargetFactory<T> by Delegates.notNull()
|
||||
override var configure: ((T) -> Unit)? = null
|
||||
|
||||
fun build(): ExternalKotlinTargetDescriptorImpl<T> = ExternalKotlinTargetDescriptorImpl(
|
||||
targetName = targetName,
|
||||
platformType = platformType,
|
||||
decoratedExternalTargetFactory = decoratedExternalTargetFactory,
|
||||
configure = configure
|
||||
)
|
||||
}
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
private data class ExternalKotlinTargetDescriptorImpl<T : DecoratedExternalKotlinTarget>(
|
||||
override val targetName: String,
|
||||
override val platformType: KotlinPlatformType,
|
||||
override val decoratedExternalTargetFactory: DecoratedExternalTargetFactory<T>,
|
||||
override val configure: ((T) -> Unit)?
|
||||
) : ExternalKotlinTargetDescriptor<T>
|
||||
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
|
||||
import org.jetbrains.kotlin.gradle.plugin.Kotlin2JvmSourceSetProcessor
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationInfo
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationAssociator
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationFriendPathsResolver
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationAssociator
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationSourceSetsContainer
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory.KotlinCompilationTaskNamesContainerFactory
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.decoratedInstance
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.external.ExternalKotlinCompilation.Delegate
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
||||
import org.jetbrains.kotlin.gradle.tasks.configuration.KotlinCompileConfig
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
fun <T : ExternalKotlinCompilation> DecoratedExternalKotlinTarget.createCompilation(
|
||||
descriptor: ExternalKotlinCompilationDescriptor<T>
|
||||
): T {
|
||||
val compilationImplFactory = KotlinCompilationImplFactory(
|
||||
compilerOptionsFactory = when (platformType) {
|
||||
KotlinPlatformType.common -> KotlinMultiplatformCommonCompilerOptionsFactory
|
||||
KotlinPlatformType.jvm -> KotlinJvmCompilerOptionsFactory
|
||||
KotlinPlatformType.androidJvm -> KotlinJvmCompilerOptionsFactory
|
||||
KotlinPlatformType.js -> KotlinJsCompilerOptionsFactory
|
||||
KotlinPlatformType.native -> KotlinNativeCompilerOptionsFactory
|
||||
KotlinPlatformType.wasm -> KotlinMultiplatformCommonCompilerOptionsFactory
|
||||
},
|
||||
compilationSourceSetsContainerFactory = { _, _ -> KotlinCompilationSourceSetsContainer(descriptor.defaultSourceSet) },
|
||||
compilationTaskNamesContainerFactory = KotlinCompilationTaskNamesContainerFactory { target, compilationName ->
|
||||
val default = DefaultKotlinCompilationTaskNamesContainerFactory.create(target, compilationName)
|
||||
default.copy(
|
||||
compileTaskName = descriptor.compileTaskName ?: default.compileTaskName,
|
||||
compileAllTaskName = descriptor.compileAllTaskName ?: default.compileAllTaskName
|
||||
)
|
||||
},
|
||||
compilationAssociator = descriptor.compilationAssociator?.let { declaredAssociator ->
|
||||
@Suppress("unchecked_cast")
|
||||
KotlinCompilationAssociator { _, first, second ->
|
||||
declaredAssociator.associate(first.decoratedInstance as T, second.decoratedInstance as ExternalKotlinCompilation)
|
||||
}
|
||||
} ?: DefaultKotlinCompilationAssociator,
|
||||
compilationFriendPathsResolver = DefaultKotlinCompilationFriendPathsResolver(
|
||||
DefaultKotlinCompilationFriendPathsResolver.FriendArtifactResolver.composite(
|
||||
DefaultKotlinCompilationFriendPathsResolver.DefaultFriendArtifactResolver,
|
||||
descriptor.friendArtifactResolver?.let { declaredResolver ->
|
||||
DefaultKotlinCompilationFriendPathsResolver.FriendArtifactResolver { compilation ->
|
||||
@Suppress("unchecked_cast")
|
||||
declaredResolver.resolveFriendPaths(compilation as T)
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
val compilationImpl = compilationImplFactory.create(this, descriptor.compilationName)
|
||||
val decoratedCompilation = descriptor.decoratedKotlinCompilationFactory.create(Delegate(compilationImpl))
|
||||
descriptor.configure?.invoke(decoratedCompilation)
|
||||
this.delegate.compilations.add(decoratedCompilation)
|
||||
|
||||
|
||||
val tasksProvider = KotlinTasksProvider()
|
||||
val compilationInfo = KotlinCompilationInfo(decoratedCompilation)
|
||||
|
||||
val config = KotlinCompileConfig(compilationInfo)
|
||||
config.configureTask { task ->
|
||||
task.useModuleDetection.value(true).disallowChanges()
|
||||
task.destinationDirectory.set(project.layout.buildDirectory.dir("tmp/kotlin-classes/debug"))
|
||||
}
|
||||
|
||||
Kotlin2JvmSourceSetProcessor(tasksProvider, compilationInfo).run()
|
||||
project.logger.quiet("Registered: ${compilationInfo.compileKotlinTaskName}")
|
||||
|
||||
return decoratedCompilation
|
||||
}
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
fun <T : ExternalKotlinCompilation> DecoratedExternalKotlinTarget.createCompilation(
|
||||
descriptor: ExternalKotlinCompilationDescriptorBuilder<T>.() -> Unit
|
||||
): T {
|
||||
return createCompilation(ExternalKotlinCompilationDescriptor(descriptor))
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExternalKotlinTargetApi::class)
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin.mpp.external
|
||||
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.jetbrains.kotlin.gradle.ExternalKotlinTargetApi
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.tasks.locateOrRegisterTask
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
fun <T : DecoratedExternalKotlinTarget> KotlinMultiplatformExtension.createExternalKotlinTarget(
|
||||
descriptor: ExternalKotlinTargetDescriptor<T>
|
||||
): T {
|
||||
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 = ExternalKotlinTarget.ArtifactsTaskLocator { target ->
|
||||
target.project.locateOrRegisterTask<Jar>(lowerCamelCaseName(descriptor.targetName, "jar"))
|
||||
}
|
||||
|
||||
val target = ExternalKotlinTarget(
|
||||
project = project,
|
||||
targetName = descriptor.targetName,
|
||||
platformType = descriptor.platformType,
|
||||
defaultConfiguration = defaultConfiguration,
|
||||
apiElementsConfiguration = apiElementsConfiguration,
|
||||
runtimeElementsConfiguration = runtimeElementsConfiguration,
|
||||
publishable = true,
|
||||
kotlinComponents = emptySet(),
|
||||
artifactsTaskLocator = artifactsTaskLocator
|
||||
)
|
||||
|
||||
val decorated = descriptor.decoratedExternalTargetFactory.create(target)
|
||||
target.onCreated()
|
||||
descriptor.configure?.invoke(decorated)
|
||||
targets.add(decorated)
|
||||
return decorated
|
||||
}
|
||||
|
||||
@ExternalKotlinTargetApi
|
||||
fun <T : DecoratedExternalKotlinTarget> KotlinMultiplatformExtension.createExternalKotlinTarget(
|
||||
descriptor: ExternalKotlinTargetDescriptorBuilder<T>.() -> Unit
|
||||
): T {
|
||||
return createExternalKotlinTarget(ExternalKotlinTargetDescriptor(descriptor))
|
||||
}
|
||||
+8
-3
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import com.android.build.api.dsl.ApplicationExtension
|
||||
import com.android.build.gradle.LibraryExtension
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.internal.project.ProjectInternal
|
||||
@@ -13,7 +14,6 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.kpm.applyKpmPlugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformJvmPlugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.extraProperties
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension
|
||||
|
||||
fun buildProject(
|
||||
@@ -51,8 +51,13 @@ fun Project.kotlin(code: KotlinMultiplatformExtension.() -> Unit) {
|
||||
|
||||
fun Project.androidLibrary(code: LibraryExtension.() -> Unit) {
|
||||
plugins.findPlugin("com.android.library") ?: plugins.apply("com.android.library")
|
||||
val androidExtension = project.extensions.findByName("android") as? LibraryExtension
|
||||
?: throw IllegalStateException("Android library extension is missing in project")
|
||||
val androidExtension = project.extensions.getByName("android") as LibraryExtension
|
||||
androidExtension.code()
|
||||
}
|
||||
|
||||
fun Project.androidApplication(code: ApplicationExtension.() -> Unit) {
|
||||
plugins.findPlugin("com.android.application") ?: plugins.apply("com.android.application")
|
||||
val androidExtension = project.extensions.getByName("android") as ApplicationExtension
|
||||
androidExtension.code()
|
||||
}
|
||||
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("FunctionName")
|
||||
|
||||
package org.jetbrains.kotlin.gradle.externalTargetApi
|
||||
|
||||
import org.jetbrains.kotlin.gradle.android.androidTargetPrototype
|
||||
import org.jetbrains.kotlin.gradle.androidApplication
|
||||
import org.jetbrains.kotlin.gradle.buildProjectWithMPP
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.kpm.idea.mavenCentralCacheRedirector
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ExternalAndroidTargetPrototypeSmokeTest {
|
||||
|
||||
@Test
|
||||
fun `apply prototype - evaluate - compilations exist`() {
|
||||
val project = buildProjectWithMPP()
|
||||
project.androidApplication { compileSdk = 31 }
|
||||
val androidTargetPrototype = project.multiplatformExtension.androidTargetPrototype()
|
||||
project.evaluate()
|
||||
|
||||
assertEquals(
|
||||
setOf("main", "unitTest", "instrumentedTest"),
|
||||
androidTargetPrototype.compilations.map { it.name }.toSet()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `apply prototype - evaluate - configurations can be resolved`() {
|
||||
val project = buildProjectWithMPP()
|
||||
project.androidApplication { compileSdk = 31 }
|
||||
|
||||
val androidTargetPrototype = project.multiplatformExtension.androidTargetPrototype()
|
||||
project.repositories.mavenLocal()
|
||||
project.repositories.mavenCentralCacheRedirector()
|
||||
project.evaluate()
|
||||
|
||||
androidTargetPrototype.compilations.all { compilation ->
|
||||
compilation.compileDependencyFiles.files
|
||||
compilation.runtimeDependencyFiles?.files
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user