[Gradle] Implement Kotlin*NativeCompilations with underlying KotlinCompilationImpl

KT-54312
This commit is contained in:
Sebastian Sellmair
2022-09-30 00:07:08 +02:00
committed by Space Team
parent a67b2a8be5
commit 4cbd715b17
53 changed files with 1046 additions and 608 deletions
@@ -10,8 +10,6 @@ package org.jetbrains.kotlin.gradle.plugin
import org.gradle.api.Action
import org.gradle.api.Named
import org.gradle.api.file.FileCollection
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptionsDeprecated
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
interface CInteropSettings : Named {
@@ -23,9 +21,6 @@ interface CInteropSettings : Named {
fun headerFilterOnly(includeDirs: Collection<Any>)
}
// TODO: Provide an interface for native compilations.
val compilation: KotlinCompilationData<out KotlinCommonOptionsDeprecated>
val dependencyConfigurationName: String
var dependencyFiles: FileCollection
@@ -136,6 +136,7 @@ interface KotlinCompilationToRunnableFiles<T : KotlinCommonOptionsDeprecated> :
val <T : KotlinCommonOptionsDeprecated> KotlinCompilation<T>.runtimeDependencyConfigurationName: String?
get() = (this as? KotlinCompilationToRunnableFiles<T>)?.runtimeDependencyConfigurationName
@Deprecated("Scheduled for removal with Kotlin 1.9")
interface KotlinCompilationWithResources<T : KotlinCommonOptionsDeprecated> : KotlinCompilation<T> {
val processResourcesTaskName: String
}
@@ -1769,7 +1769,7 @@ class NewMultiplatformIT : BaseGradleIT() {
"Hello.internalFun\$new_mpp_associate_compilations",
"HelloTest.internalTestFun\$new_mpp_associate_compilations"
)
assertFileExists("build/classes/kotlin/jvm/integrationTest/META-INF/new-mpp-associate-compilations_integrationTest.kotlin_module")
assertFileExists("build/classes/kotlin/jvm/integrationTest/META-INF/new-mpp-associate-compilations.kotlin_module")
// JS:
assertFileExists(
@@ -2007,7 +2007,7 @@ class NewMultiplatformIT : BaseGradleIT() {
@Test
fun testResolveMetadataCompileClasspathKt50925() {
Project("lib", directoryPrefix = "kt-50925-resolve-metadata-compile-classpath").apply {
Project("lib", directoryPrefix = "kt-50925-resolve-metadata-compile-classpath").apply {
setupWorkingDir()
gradleBuildScript().modify(::transformBuildScriptWithPluginsDsl)
@@ -59,11 +59,11 @@ abstract class KotlinMultiplatformExtension(project: Project) :
val testableTargets: NamedDomainObjectCollection<KotlinTargetWithTests<*, *>>
get() = targets.withType(KotlinTargetWithTests::class.java)
fun metadata(configure: KotlinOnlyTarget<AbstractKotlinCompilation<*>>.() -> Unit = { }): KotlinOnlyTarget<AbstractKotlinCompilation<*>> =
fun metadata(configure: KotlinOnlyTarget<KotlinMetadataCompilation<*>>.() -> Unit = { }): KotlinOnlyTarget<KotlinMetadataCompilation<*>> =
@Suppress("UNCHECKED_CAST")
(targets.getByName(KotlinMultiplatformPlugin.METADATA_TARGET_NAME) as KotlinOnlyTarget<AbstractKotlinCompilation<*>>).also(configure)
(targets.getByName(KotlinMultiplatformPlugin.METADATA_TARGET_NAME) as KotlinOnlyTarget<KotlinMetadataCompilation<*>>).also(configure)
fun metadata(configure: Action<KotlinOnlyTarget<AbstractKotlinCompilation<*>>>) = metadata { configure.execute(this) }
fun metadata(configure: Action<KotlinOnlyTarget<KotlinMetadataCompilation<*>>>) = metadata { configure.execute(this) }
fun <T : KotlinTarget> targetFromPreset(
preset: KotlinTargetPreset<T>,
@@ -113,8 +113,10 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
defineConfigurationsForCompilation(compilation)
if (compilation is KotlinCompilationWithResources) {
configureResourceProcessing(compilation, project.files(Callable { compilation.allKotlinSourceSets.map { it.resources } }))
compilation.internal.processResourcesTaskName?.let { processResourcesTaskName ->
configureResourceProcessing(
compilation, processResourcesTaskName, project.files(Callable { compilation.allKotlinSourceSets.map { it.resources } })
)
}
createLifecycleTask(compilation)
@@ -122,13 +124,14 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
}
protected fun configureResourceProcessing(
compilation: KotlinCompilationWithResources<*>,
compilation: KotlinCompilation<*>,
processResourcesTaskName: String,
resourceSet: FileCollection
) {
val project = compilation.target.project
val resourcesDestinationDir = project.file(compilation.output.resourcesDir)
val resourcesTask = project.locateOrRegisterTask<ProcessResources>(compilation.processResourcesTaskName) { resourcesTask ->
val resourcesTask = project.locateOrRegisterTask<ProcessResources>(processResourcesTaskName) { resourcesTask ->
resourcesTask.description = "Processes $resourceSet."
resourcesTask.from(resourceSet)
resourcesTask.into(resourcesDestinationDir)
@@ -19,6 +19,8 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
import org.jetbrains.kotlin.gradle.tasks.locateTask
import org.jetbrains.kotlin.gradle.utils.ObservableSet
import org.jetbrains.kotlin.project.model.LanguageSettings
import org.jetbrains.kotlin.tooling.core.MutableExtras
import org.jetbrains.kotlin.tooling.core.mutableExtrasOf
import java.util.*
abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
@@ -62,6 +64,8 @@ abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
override val target: KotlinTarget get() = compilationDetails.target
override val extras: MutableExtras = mutableExtrasOf()
final override val compileDependencyConfigurationName: String
get() = compilationDetails.compileDependencyFilesHolder.dependencyConfigurationName
@@ -13,8 +13,11 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationM
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule.Type.Auxiliary
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule.Type.Main
import org.jetbrains.kotlin.gradle.utils.ObservableSet
import org.jetbrains.kotlin.tooling.core.MutableExtras
internal interface InternalKotlinCompilation<out T : KotlinCommonOptions> : KotlinCompilation<T> {
val extras: MutableExtras
override val kotlinSourceSets: ObservableSet<KotlinSourceSet>
override val allKotlinSourceSets: ObservableSet<KotlinSourceSet>
val friendPaths: Iterable<FileCollection>
@@ -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.
*/
package org.jetbrains.kotlin.gradle.plugin.mpp
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationDetailsImpl.MetadataCompilationDetails
class KotlinCommonCompilationFactory(
override val target: KotlinOnlyTarget<*>
) : KotlinCompilationFactory<KotlinCommonCompilation> {
override val itemClass: Class<KotlinCommonCompilation>
get() = KotlinCommonCompilation::class.java
override fun create(name: String): KotlinCommonCompilation = target.project.objects.newInstance(
KotlinCommonCompilation::class.java, MetadataCompilationDetails(target, name, getOrCreateDefaultSourceSet(name))
)
}
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationDetailsImpl.MetadataCompilationDetails
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
interface KotlinCompilationFactory<T : KotlinCompilation<*>> : NamedDomainObjectFactory<T> {
@@ -35,14 +34,3 @@ interface KotlinCompilationFactory<T : KotlinCompilation<*>> : NamedDomainObject
internal fun KotlinCompilationFactory<*>.getOrCreateDefaultSourceSet(compilationName: String): KotlinSourceSet {
return project.kotlinExtension.sourceSets.maybeCreate(defaultSourceSetName(compilationName))
}
class KotlinCommonCompilationFactory(
override val target: KotlinOnlyTarget<*>
) : KotlinCompilationFactory<KotlinCommonCompilation> {
override val itemClass: Class<KotlinCommonCompilation>
get() = KotlinCommonCompilation::class.java
override fun create(name: String): KotlinCommonCompilation = target.project.objects.newInstance(
KotlinCommonCompilation::class.java, MetadataCompilationDetails(target, name, getOrCreateDefaultSourceSet(name))
)
}
@@ -6,14 +6,16 @@
package org.jetbrains.kotlin.gradle.plugin.mpp
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent
import org.jetbrains.kotlin.gradle.targets.metadata.KotlinMetadataTargetConfigurator
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
import javax.inject.Inject
abstract class KotlinMetadataTarget @Inject constructor(
project: Project
) : KotlinOnlyTarget<AbstractKotlinCompilation<*>>(project, KotlinPlatformType.common) {
) : KotlinOnlyTarget</* TODO SEB AbstractKotlinCompilation<*> */ KotlinCompilation<*>>(project, KotlinPlatformType.common) {
override val artifactsTaskName: String
// The IDE import looks at this task name to determine the artifact and register the path to the artifact;
@@ -7,9 +7,11 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl
import org.gradle.api.Project
import org.gradle.api.artifacts.Dependency
import org.gradle.api.tasks.SourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.InternalKotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
import org.jetbrains.kotlin.gradle.plugin.mpp.isTest
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
import org.jetbrains.kotlin.gradle.utils.filesProvider
internal fun interface KotlinCompilationAssociator {
@@ -70,7 +72,7 @@ internal object DefaultKotlinCompilationAssociator : KotlinCompilationAssociator
}
}
internal object KotlinNativeCompilationAssociator : KotlinCompilationAssociator {
internal object NativeKotlinCompilationAssociator : KotlinCompilationAssociator {
override fun associate(target: KotlinTarget, first: InternalKotlinCompilation<*>, second: InternalKotlinCompilation<*>) {
target.project.kotlinCompilationModuleManager.unionModules(first.compilationModule, second.compilationModule)
@@ -83,12 +85,14 @@ internal object KotlinNativeCompilationAssociator : KotlinCompilationAssociator
}
}
internal object KotlinJvmWithJavaCompilationAssociator : KotlinCompilationAssociator {
internal object JvmKotlinCompilationAssociator : KotlinCompilationAssociator {
override fun associate(target: KotlinTarget, first: InternalKotlinCompilation<*>, second: InternalKotlinCompilation<*>) {
target.project.kotlinCompilationModuleManager.unionModules(first.compilationModule, second.compilationModule)
if (first.compilationName != SourceSet.TEST_SOURCE_SET_NAME || second.compilationName != SourceSet.MAIN_SOURCE_SET_NAME) {
DefaultKotlinCompilationAssociator.associate(target, first, second)
} // otherwise, do nothing: the Java Gradle plugin adds these dependencies for us, we don't need to add them to the classpath
/* Main to Test association handled already by java plugin */
if (target is KotlinJvmTarget && target.withJavaEnabled && first.isMain() && second.isTest()) {
return
} else DefaultKotlinCompilationAssociator.associate(target, first, second)
}
}
@@ -8,9 +8,12 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.jetbrains.kotlin.gradle.plugin.HasKotlinDependencies
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
import org.gradle.api.attributes.Category
import org.gradle.api.attributes.Usage
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinDependencyHandler
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.gradle.utils.*
internal interface KotlinCompilationDependencyConfigurationsContainer {
val apiConfiguration: Configuration
@@ -11,31 +11,82 @@ import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.jetbrains.kotlin.gradle.plugin.mpp.InternalKotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.associateWithClosure
import org.jetbrains.kotlin.gradle.plugin.mpp.isMain
import org.jetbrains.kotlin.gradle.plugin.sources.getVisibleSourceSetsFromAssociateCompilations
import org.jetbrains.kotlin.gradle.plugin.sources.internal
import org.jetbrains.kotlin.gradle.targets.metadata.getMetadataCompilationForSourceSet
import org.jetbrains.kotlin.gradle.utils.filesProvider
internal interface KotlinCompilationFriendPathsResolver {
fun resolveFriendPaths(compilation: InternalKotlinCompilation<*>): Iterable<FileCollection>
}
internal object DefaultKotlinCompilationFriendPathsResolver : KotlinCompilationFriendPathsResolver {
internal class DefaultKotlinCompilationFriendPathsResolver(
private val friendArtifactResolver: FriendArtifactResolver = DefaultFriendArtifactResolver
) : KotlinCompilationFriendPathsResolver {
override fun resolveFriendPaths(compilation: InternalKotlinCompilation<*>): Iterable<FileCollection> {
return mutableListOf<FileCollection>().also { allCollections ->
compilation.associateWithClosure.forEach { allCollections.add(it.output.classesDirs) }
allCollections.add(resolveFriendArtifacts(compilation))
return mutableListOf<FileCollection>().apply {
compilation.associateWithClosure.forEach { add(it.output.classesDirs) }
add(friendArtifactResolver.resolveFriendArtifacts(compilation))
}
}
private fun resolveFriendArtifacts(compilation: InternalKotlinCompilation<*>): FileCollection {
return with(compilation.project) {
val friendArtifactsTaskProvider = resolveFriendArtifactsTask(compilation) ?: return files()
filesProvider { friendArtifactsTaskProvider.flatMap { it.archiveFile } }
/* Resolution of friend artifacts */
interface FriendArtifactResolver {
fun resolveFriendArtifacts(compilation: InternalKotlinCompilation<*>): FileCollection
companion object {
fun composite(vararg resolvers: FriendArtifactResolver?): FriendArtifactResolver {
return CompositeFriendArtifactResolver(listOfNotNull(*resolvers))
}
}
}
private fun resolveFriendArtifactsTask(compilation: InternalKotlinCompilation<*>): TaskProvider<AbstractArchiveTask>? {
if (compilation.associateWithClosure.none { it.isMain() }) return null
val archiveTasks = compilation.project.tasks.withType(AbstractArchiveTask::class.java)
if (compilation.target.artifactsTaskName !in archiveTasks.names) return null
return archiveTasks.named(compilation.target.artifactsTaskName)
class CompositeFriendArtifactResolver(
private val resolvers: List<FriendArtifactResolver>
) : FriendArtifactResolver {
override fun resolveFriendArtifacts(compilation: InternalKotlinCompilation<*>): FileCollection {
return compilation.project.files(resolvers.map { resolver -> resolver.resolveFriendArtifacts(compilation) })
}
}
object DefaultFriendArtifactResolver : FriendArtifactResolver {
override fun resolveFriendArtifacts(compilation: InternalKotlinCompilation<*>): FileCollection {
return with(compilation.project) {
val friendArtifactsTaskProvider = resolveFriendArtifactsTask(compilation) ?: return files()
filesProvider { friendArtifactsTaskProvider.flatMap { it.archiveFile } }
}
}
private fun resolveFriendArtifactsTask(compilation: InternalKotlinCompilation<*>): TaskProvider<AbstractArchiveTask>? {
if (compilation.associateWithClosure.none { it.isMain() }) return null
val archiveTasks = compilation.project.tasks.withType(AbstractArchiveTask::class.java)
if (compilation.target.artifactsTaskName !in archiveTasks.names) return null
return archiveTasks.named(compilation.target.artifactsTaskName)
}
}
object AdditionalMetadataFriendArtifactResolver : FriendArtifactResolver {
override fun resolveFriendArtifacts(compilation: InternalKotlinCompilation<*>): FileCollection {
val friendSourceSets = getVisibleSourceSetsFromAssociateCompilations(compilation.defaultSourceSet)
return compilation.project.files(
friendSourceSets.mapNotNull { compilation.target.compilations.findByName(it.name)?.output?.classesDirs }
)
}
}
object AdditionalSharedNativeMetadataFriendArtifactResolver : FriendArtifactResolver {
override fun resolveFriendArtifacts(compilation: InternalKotlinCompilation<*>): FileCollection {
// TODO: implement proper dependsOn/refines compiler args for Kotlin/Native and pass the dependsOn klibs separately;
// But for now, those dependencies don't have any special semantics, so passing all them as friends works, too
val friendSourceSets = getVisibleSourceSetsFromAssociateCompilations(compilation.defaultSourceSet) +
compilation.defaultSourceSet.internal.dependsOnClosure
return compilation.project.files(
friendSourceSets.mapNotNull { compilation.project.getMetadataCompilationForSourceSet(it)?.output?.classesDirs }
)
}
}
}
@@ -21,6 +21,8 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.internal
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
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
@@ -35,7 +37,7 @@ internal class KotlinCompilationImpl @Inject constructor(
val compilationModule: KotlinCompilationModuleManager.CompilationModule,
val sourceSets: KotlinCompilationSourceSetsContainer,
val dependencyConfigurations: KotlinCompilationDependencyConfigurationsContainer,
val compilationTaskNames: KotlinCompilationTaskNameContainer,
val compilationTaskNames: KotlinCompilationTaskNamesContainer,
val processResourcesTaskName: String?,
val output: KotlinCompilationOutput,
val compilerOptions: HasCompilerOptions<*>,
@@ -55,6 +57,8 @@ internal class KotlinCompilationImpl @Inject constructor(
override val target: KotlinTarget
get() = params.target
override val extras: MutableExtras = mutableExtrasOf()
val sourceSets get() = params.sourceSets
val dependencyConfigurations: KotlinCompilationDependencyConfigurationsContainer
@@ -15,16 +15,17 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.addSourcesToKotlinCompileTask
import org.jetbrains.kotlin.gradle.plugin.mpp.addSourcesToKotlinNativeCompileTask
import org.jetbrains.kotlin.gradle.plugin.sources.defaultSourceSetLanguageSettingsChecker
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
import org.jetbrains.kotlin.tooling.core.extrasKeyOf
import org.jetbrains.kotlin.tooling.core.getOrPut
internal interface KotlinCompilationSourceSetInclusion {
fun include(compilation: InternalKotlinCompilation<*>, sourceSet: KotlinSourceSet)
}
internal class DefaultKotlinCompilationSourceSetInclusion(
private val addSourcesToCompileTask: AddSourcesToCompileTask
private val addSourcesToCompileTask: AddSourcesToCompileTask = AddSourcesToCompileTask.Default
) : KotlinCompilationSourceSetInclusion {
interface AddSourcesToCompileTask {
fun addSources(compilation: KotlinCompilation<*>, sourceSet: KotlinSourceSet, addAsCommonSources: Lazy<Boolean>)
@@ -51,10 +52,9 @@ internal class DefaultKotlinCompilationSourceSetInclusion(
}
}
private val processedSourceSets = hashSetOf<KotlinSourceSet>()
override fun include(compilation: InternalKotlinCompilation<*>, sourceSet: KotlinSourceSet) {
if (!processedSourceSets.add(sourceSet)) return
/* Check if the source set was already included */
if (!compilation.includedSourceSets.add(sourceSet)) return
addSourcesToCompileTask.addSources(
compilation, sourceSet,
@@ -97,4 +97,17 @@ internal class DefaultKotlinCompilationSourceSetInclusion(
defaultSourceSetLanguageSettingsChecker.runAllChecks(compilation.defaultSourceSet, sourceSet)
}
}
private companion object {
/**
* Key used to store already processed source sets on the compilation instance itself
* to avoid re-processing of unnecessary source sets!
*/
private val includedSourceSetsKey = extrasKeyOf<MutableSet<KotlinSourceSet>>(
DefaultKotlinCompilationSourceSetInclusion::class.java.name
)
val InternalKotlinCompilation<*>.includedSourceSets: MutableSet<KotlinSourceSet>
get() = extras.getOrPut(includedSourceSetsKey, { hashSetOf() })
}
}
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl
data class KotlinCompilationTaskNameContainer(
internal data class KotlinCompilationTaskNamesContainer(
val compileTaskName: String,
val compileAllTaskName: String
)
@@ -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.plugin.mpp.compilationImpl.factory
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager
import org.jetbrains.kotlin.gradle.plugin.mpp.filterModuleName
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.archivesName
internal object DefaultCompilationModuleFactory : KotlinCompilationImplFactory.CompilationModuleFactory {
override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationModuleManager.CompilationModule =
KotlinCompilationModuleManager.CompilationModule(
compilationName = compilationName,
ownModuleName = target.project.provider {
val baseName = target.project.archivesName.orNull
?: target.project.name
val suffix = if (compilationName == KotlinCompilation.MAIN_COMPILATION_NAME) "" else "_$compilationName"
filterModuleName("$baseName$suffix")
},
type = if (compilationName == KotlinCompilation.MAIN_COMPILATION_NAME) KotlinCompilationModuleManager.CompilationModule.Type.Main
else KotlinCompilationModuleManager.CompilationModule.Type.Auxiliary
)
}
@@ -0,0 +1,130 @@
/*
* 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.compilationImpl.factory
import org.gradle.api.attributes.Category
import org.gradle.api.attributes.Usage
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationDependencyConfigurationsContainer
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationDependencyConfigurationsContainer
import org.jetbrains.kotlin.gradle.utils.*
internal sealed class DefaultKotlinCompilationDependencyConfigurationsFactory :
KotlinCompilationImplFactory.KotlinCompilationDependencyConfigurationsFactory {
object WithRuntime : DefaultKotlinCompilationDependencyConfigurationsFactory() {
override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationDependencyConfigurationsContainer {
return KotlinCompilationDependencyConfigurationsContainer(target, compilationName, withRuntime = true)
}
}
object WithoutRuntime : DefaultKotlinCompilationDependencyConfigurationsFactory() {
override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationDependencyConfigurationsContainer {
return KotlinCompilationDependencyConfigurationsContainer(target, compilationName, withRuntime = false)
}
}
}
internal object NativeKotlinCompilationDependencyConfigurationsFactory :
KotlinCompilationImplFactory.KotlinCompilationDependencyConfigurationsFactory {
override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationDependencyConfigurationsContainer {
return KotlinCompilationDependencyConfigurationsContainer(
target, compilationName, withRuntime = false, compileClasspathConfigurationSuffix = "compileKlibraries"
)
}
}
private fun KotlinCompilationDependencyConfigurationsContainer(
target: KotlinTarget, compilationName: String, withRuntime: Boolean,
compileClasspathConfigurationSuffix: String = "compileClasspath",
runtimeClasspathConfigurationSuffix: String = "runtimeClasspath"
): KotlinCompilationDependencyConfigurationsContainer {
val compilation = "${target.disambiguationClassifier}/$compilationName"
val prefix = lowerCamelCaseName(
target.disambiguationClassifier,
compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
"compilation"
)
val apiConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, API)).apply {
isVisible = false
isCanBeConsumed = false
isCanBeResolved = false
description = "API dependencies for $compilation"
}
val implementationConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, IMPLEMENTATION)).apply {
extendsFrom(apiConfiguration)
isVisible = false
isCanBeConsumed = false
isCanBeResolved = false
description = "Implementation only dependencies for $compilation."
}
val compileOnlyConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, COMPILE_ONLY)).apply {
isCanBeConsumed = false
setupAsLocalTargetSpecificConfigurationIfSupported(target)
attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
isVisible = false
isCanBeResolved = false
description = "Compile only dependencies for $compilation."
}
val runtimeOnlyConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, RUNTIME_ONLY)).apply {
isVisible = false
isCanBeConsumed = false
isCanBeResolved = false
description = "Runtime only dependencies for $compilation."
}
val compileDependencyConfiguration = target.project.configurations.maybeCreate(
lowerCamelCaseName(
target.disambiguationClassifier,
compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
compileClasspathConfigurationSuffix
)
).apply {
extendsFrom(compileOnlyConfiguration, implementationConfiguration)
usesPlatformOf(target)
isVisible = false
isCanBeConsumed = false
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target))
if (target.platformType != KotlinPlatformType.androidJvm) {
attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
}
description = "Compile classpath for $compilation."
}
val runtimeDependencyConfiguration = if (withRuntime) target.project.configurations.maybeCreate(
lowerCamelCaseName(
target.disambiguationClassifier,
compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
runtimeClasspathConfigurationSuffix
)
).apply {
extendsFrom(runtimeOnlyConfiguration, implementationConfiguration)
usesPlatformOf(target)
isVisible = false
isCanBeConsumed = false
isCanBeResolved = true
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target))
if (target.platformType != KotlinPlatformType.androidJvm) {
attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
}
description = "Runtime classpath of $compilation."
} else null
return DefaultKotlinCompilationDependencyConfigurationsContainer(
apiConfiguration = apiConfiguration,
implementationConfiguration = implementationConfiguration,
compileOnlyConfiguration = compileOnlyConfiguration,
runtimeOnlyConfiguration = runtimeOnlyConfiguration,
compileDependencyConfiguration = compileDependencyConfiguration,
runtimeDependencyConfiguration = runtimeDependencyConfiguration
)
}
@@ -0,0 +1,17 @@
/*
* 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.compilationImpl.factory
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinCompilationOutput
import java.util.concurrent.Callable
internal object DefaultKotlinCompilationOutputFactory : KotlinCompilationImplFactory.KotlinCompilationOutputFactory {
override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationOutput = DefaultKotlinCompilationOutput(
target.project, Callable { target.project.buildDir.resolve("processedResources/${target.targetName}/$compilationName") }
)
}
@@ -0,0 +1,38 @@
/*
* 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.compilationImpl.factory
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationSourceSetsContainer
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
internal class DefaultKotlinCompilationSourceSetsContainerFactory(
private val defaultSourceSetNaming: DefaultSourceSetNaming = DefaultDefaultSourceSetNaming
) : KotlinCompilationImplFactory.KotlinCompilationSourceSetsContainerFactory {
fun interface DefaultSourceSetNaming {
fun defaultSourceSetName(target: KotlinTarget, compilationName: String): String
}
object DefaultDefaultSourceSetNaming : DefaultSourceSetNaming {
override fun defaultSourceSetName(target: KotlinTarget, compilationName: String): String = lowerCamelCaseName(
target.disambiguationClassifier.takeIf { target !is KotlinMetadataTarget },
if (compilationName == KotlinCompilation.MAIN_COMPILATION_NAME && target is KotlinMetadataTarget)
KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME
else compilationName
)
}
override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationSourceSetsContainer {
val defaultSourceSetName = defaultSourceSetNaming.defaultSourceSetName(target, compilationName)
val defaultSourceSet = target.project.kotlinExtension.sourceSets.maybeCreate(defaultSourceSetName)
return KotlinCompilationSourceSetsContainer(defaultSourceSet)
}
}
@@ -0,0 +1,21 @@
/*
* 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.compilationImpl.factory
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationTaskNamesContainer
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
internal object DefaultKotlinCompilationTaskNamesContainerFactory :
KotlinCompilationImplFactory.KotlinCompilationTaskNamesContainerFactory {
override fun create(target: KotlinTarget, compilationName: String) = KotlinCompilationTaskNamesContainer(
compileTaskName = lowerCamelCaseName(
"compile", compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, "Kotlin", target.targetName
),
compileAllTaskName = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "classes")
)
}
@@ -0,0 +1,18 @@
/*
* 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.compilationImpl.factory
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
internal object DefaultProcessResourcesTaskNameFactory : KotlinCompilationImplFactory.ProcessResourcesTaskNameFactory {
override fun create(target: KotlinTarget, compilationName: String): String = lowerCamelCaseName(
target.disambiguationClassifier,
compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
"processResources"
)
}
@@ -0,0 +1,23 @@
package org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory
import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptions
import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptionsDefault
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
internal object JvmCompilerOptionsFactory : KotlinCompilationImplFactory.CompilerOptionsFactory {
override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationImplFactory.CompilerOptionsFactory.Options {
val compilerOptions = object : HasCompilerOptions<CompilerJvmOptions> {
override val options: CompilerJvmOptions =
target.project.objects.newInstance(CompilerJvmOptionsDefault::class.java)
}
val kotlinOptions = object : KotlinJvmOptions {
override val options: CompilerJvmOptions
get() = compilerOptions.options
}
return KotlinCompilationImplFactory.CompilerOptionsFactory.Options(compilerOptions, kotlinOptions)
}
}
@@ -0,0 +1,94 @@
/*
* 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.compilationImpl.factory
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.*
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule
internal class KotlinCompilationImplFactory(
private val compilerOptionsFactory: CompilerOptionsFactory,
private val compilationModuleFactory: CompilationModuleFactory =
DefaultCompilationModuleFactory,
private val compilationSourceSetsContainerFactory: KotlinCompilationSourceSetsContainerFactory =
DefaultKotlinCompilationSourceSetsContainerFactory(),
private val compilationDependencyConfigurationsFactory: KotlinCompilationDependencyConfigurationsFactory =
DefaultKotlinCompilationDependencyConfigurationsFactory.WithRuntime,
private val compilationAssociator: KotlinCompilationAssociator =
DefaultKotlinCompilationAssociator,
private val compilationFriendPathsResolver: KotlinCompilationFriendPathsResolver =
DefaultKotlinCompilationFriendPathsResolver(),
private val compilationSourceSetInclusion: KotlinCompilationSourceSetInclusion =
DefaultKotlinCompilationSourceSetInclusion(),
private val compilationOutputFactory: KotlinCompilationOutputFactory =
DefaultKotlinCompilationOutputFactory,
private val compilationTaskNamesContainerFactory: KotlinCompilationTaskNamesContainerFactory =
DefaultKotlinCompilationTaskNamesContainerFactory,
private val processResourcesTaskNameFactory: ProcessResourcesTaskNameFactory =
DefaultProcessResourcesTaskNameFactory
) {
fun interface CompilationModuleFactory {
fun create(target: KotlinTarget, compilationName: String): CompilationModule
}
fun interface KotlinCompilationSourceSetsContainerFactory {
fun create(target: KotlinTarget, compilationName: String): KotlinCompilationSourceSetsContainer
}
fun interface KotlinCompilationTaskNamesContainerFactory {
fun create(target: KotlinTarget, compilationName: String): KotlinCompilationTaskNamesContainer
}
fun interface ProcessResourcesTaskNameFactory {
fun create(target: KotlinTarget, compilationName: String): String?
}
fun interface KotlinCompilationDependencyConfigurationsFactory {
fun create(target: KotlinTarget, compilationName: String): KotlinCompilationDependencyConfigurationsContainer
}
fun interface KotlinCompilationOutputFactory {
fun create(target: KotlinTarget, compilationName: String): KotlinCompilationOutput
}
fun interface CompilerOptionsFactory {
data class Options(val compilerOptions: HasCompilerOptions<*>, val kotlinOptions: KotlinCommonOptions)
fun create(target: KotlinTarget, compilationName: String): Options
}
fun create(target: KotlinTarget, compilationName: String): KotlinCompilationImpl {
val options = compilerOptionsFactory.create(target, compilationName)
return KotlinCompilationImpl(
KotlinCompilationImpl.Params(
target = target,
compilationModule = compilationModuleFactory.create(target, compilationName),
sourceSets = compilationSourceSetsContainerFactory.create(target, compilationName),
dependencyConfigurations = compilationDependencyConfigurationsFactory.create(target, compilationName),
compilationTaskNames = compilationTaskNamesContainerFactory.create(target, compilationName),
processResourcesTaskName = processResourcesTaskNameFactory.create(target, compilationName),
output = compilationOutputFactory.create(target, compilationName),
compilerOptions = options.compilerOptions,
kotlinOptions = options.kotlinOptions,
compilationAssociator = compilationAssociator,
compilationFriendPathsResolver = compilationFriendPathsResolver,
compilationSourceSetInclusion = compilationSourceSetInclusion
)
)
}
}
@@ -0,0 +1,23 @@
/*
* 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.compilationImpl.factory
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.targets.native.NativeCompilerOptions
internal object NativeCompilerOptionsFactory : KotlinCompilationImplFactory.CompilerOptionsFactory {
override fun create(target: KotlinTarget, compilationName: String): KotlinCompilationImplFactory.CompilerOptionsFactory.Options {
val compilerOptions = NativeCompilerOptions(target.project)
val kotlinOptions = object : KotlinCommonOptions {
override val options get() = compilerOptions.options
}
return KotlinCompilationImplFactory.CompilerOptionsFactory.Options(compilerOptions, kotlinOptions)
}
}
@@ -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.plugin.mpp.compilationImpl.factory
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
internal object NativeKotlinCompilationTaskNamesContainerFactory :
KotlinCompilationImplFactory.KotlinCompilationTaskNamesContainerFactory {
override fun create(target: KotlinTarget, compilationName: String) =
DefaultKotlinCompilationTaskNamesContainerFactory.create(target, compilationName)
.copy(compileAllTaskName = lowerCamelCaseName(target.disambiguationClassifier, compilationName, "klibrary"))
}
@@ -51,7 +51,9 @@ open class GradleKpmCompilationTaskConfigurator(
compilationData: KotlinNativeCompilationData<*>,
configure: KotlinNativeCompile.() -> Unit
): TaskProvider<KotlinNativeCompile> {
val compileTask = KotlinNativeTargetConfigurator.createKlibCompilationTask(compilationData)
val compileTask = KotlinNativeTargetConfigurator.createKlibCompilationTask(
KotlinCompilationProjection.KPM(compilationData), compilationData.konanTarget
)
val allSources = getSourcesForFragmentCompilation(fragment)
val commonSources = getCommonSourcesForFragmentCompilation(fragment)
@@ -66,9 +68,9 @@ open class GradleKpmCompilationTaskConfigurator(
}
fun createKotlinNativeCompilationTask(
variant: GradleKpmVariant,
variant: GradleKpmNativeVariantInternal,
compilationData: KotlinNativeCompilationData<*>
): TaskProvider<KotlinNativeCompile> = createKotlinNativeCompilationTask(variant, compilationData) {
kotlinPluginData = project.compilerPluginProviderForPlatformCompilation(variant, compilationData)
}
}
}
@@ -28,10 +28,7 @@ internal class GradleKpmNativeVariantCompilationData(
override val owner: GradleKpmNativeVariant
get() = variant
override val compilerOptions: HasCompilerOptions<KotlinCommonCompilerOptions> = NativeCompilerOptions(
project,
variant.languageSettings
)
override val compilerOptions: HasCompilerOptions<KotlinCommonCompilerOptions> = NativeCompilerOptions(project)
@Suppress("DEPRECATION")
@Deprecated("Replaced with compilerOptions.options", replaceWith = ReplaceWith("compilerOptions.options"))
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
import org.gradle.api.artifacts.Configuration
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultCInteropSettings
import org.jetbrains.kotlin.gradle.plugin.mpp.GradleKpmDefaultCInteropSettingsFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.publishedConfigurationName
import org.jetbrains.kotlin.konan.target.KonanTarget
@@ -35,8 +36,10 @@ abstract class GradleKpmNativeVariantInternal(
override val gradleVariantNames: Set<String>
get() = listOf(apiElementsConfiguration.name).flatMap { listOf(it, publishedConfigurationName(it)) }.toSet()
val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName ->
project.objects.newInstance(DefaultCInteropSettings::class.java, project, cinteropName, compilationData)
val cinterops by lazy {
project.container(
DefaultCInteropSettings::class.java, GradleKpmDefaultCInteropSettingsFactory(compilationData)
)
}
override val compilationData by lazy { GradleKpmNativeVariantCompilationData(this) }
@@ -177,10 +177,7 @@ internal open class KotlinNativeFragmentMetadataCompilationDataImpl(
override val isActive: Boolean
get() = fragment.isNativeShared() && fragment.containingVariants.count() > 1
override val compilerOptions: HasCompilerOptions<KotlinCommonCompilerOptions> = NativeCompilerOptions(
project,
languageSettings
)
override val compilerOptions: HasCompilerOptions<KotlinCommonCompilerOptions> = NativeCompilerOptions(project)
@Suppress("DEPRECATION")
@Deprecated("Replaced with compilerOptions.options", replaceWith = ReplaceWith("compilerOptions.options"))
@@ -79,7 +79,7 @@ internal class DefaultLanguageSettingsBuilder : LanguageSettingsBuilder {
val pluginOptionsTask = compilerPluginOptionsTask.value ?: return null
return when (pluginOptionsTask) {
is AbstractKotlinCompile<*> -> pluginOptionsTask.pluginOptions.toSingleCompilerPluginOptions()
is AbstractKotlinNativeCompile<*, *, *> -> pluginOptionsTask.compilerPluginOptions
is AbstractKotlinNativeCompile<*, *> -> pluginOptionsTask.compilerPluginOptions
else -> error("Unexpected task: $pluginOptionsTask")
}.arguments
}
@@ -89,7 +89,7 @@ internal class DefaultLanguageSettingsBuilder : LanguageSettingsBuilder {
val pluginClasspathTask = compilerPluginOptionsTask.value ?: return null
return when (pluginClasspathTask) {
is AbstractKotlinCompile<*> -> pluginClasspathTask.pluginClasspath
is AbstractKotlinNativeCompile<*, *, *> -> pluginClasspathTask.compilerPluginClasspath ?: pluginClasspathTask.project.files()
is AbstractKotlinNativeCompile<*, *> -> pluginClasspathTask.compilerPluginClasspath ?: pluginClasspathTask.project.files()
else -> error("Unexpected task: $pluginClasspathTask")
}
}
@@ -106,16 +106,16 @@ internal fun applyLanguageSettingsToCompilerOptions(
) = with(compilerOptions) {
languageVersion.convention(languageSettingsBuilder.languageVersion?.let { KotlinVersion.fromVersion(it) })
apiVersion.convention(languageSettingsBuilder.apiVersion?.let { KotlinVersion.fromVersion(it) })
val freeArgs = mutableListOf<String>().apply {
if (languageSettingsBuilder.progressiveMode) {
add("-progressive")
}
languageSettingsBuilder.enabledLanguageFeatures.forEach { featureName ->
add("-XXLanguage:+$featureName")
}
languageSettingsBuilder.optInAnnotationsInUse.forEach { annotationName ->
add("-opt-in=$annotationName")
}
@@ -65,7 +65,11 @@ open class KotlinJsTargetConfigurator :
compilation.source(compilation.defaultSourceSet)
configureResourceProcessing(compilation, project.files(Callable { compilation.allKotlinSourceSets.map { it.resources } }))
configureResourceProcessing(
compilation,
compilation.processResourcesTaskName,
project.files(Callable { compilation.allKotlinSourceSets.map { it.resources } })
)
createLifecycleTaskInternal(compilation)
}
@@ -70,56 +70,16 @@ open class KotlinJvmCompilation @Inject internal constructor(
get() = compilation.relatedConfigurationNames
}
private inline fun <reified T : KotlinCommonOptions> InternalKotlinCompilation<*>.castKotlinOptionsType(): InternalKotlinCompilation<T> {
//TODO SEB: Find a good spot for this function
internal inline fun <reified T : KotlinCommonOptions> InternalKotlinCompilation<*>.castKotlinOptionsType(): InternalKotlinCompilation<T> {
this.kotlinOptions as T
@Suppress("UNCHECKED_CAST")
return this as InternalKotlinCompilation<T>
}
private inline fun <reified T : CompilerCommonOptions> HasCompilerOptions<*>.castCompilerOptionsType(): HasCompilerOptions<T> {
//TODO SEB: Find home for function
internal inline fun <reified T : CompilerCommonOptions> HasCompilerOptions<*>.castCompilerOptionsType(): HasCompilerOptions<T> {
this.options as T
@Suppress("UNCHECKED_CAST")
return this as HasCompilerOptions<T>
}
abstract class oKotlinJvmCompilation @Inject constructor(
compilationDetails: CompilationDetailsWithRuntime<KotlinJvmOptions>,
) : AbstractKotlinCompilationToRunnableFiles<KotlinJvmOptions>(compilationDetails),
KotlinCompilationWithResources<KotlinJvmOptions> {
override val target: KotlinJvmTarget get() = compilationDetails.target as KotlinJvmTarget
@Suppress("UNCHECKED_CAST")
override val compilerOptions: HasCompilerOptions<CompilerJvmOptions>
get() = super.compilerOptions as HasCompilerOptions<CompilerJvmOptions>
override val processResourcesTaskName: String
get() = disambiguateName("processResources")
@Deprecated("Replaced with compileTaskProvider", replaceWith = ReplaceWith("compileTaskProvider"))
@Suppress("UNCHECKED_CAST", "DEPRECATION")
override val compileKotlinTaskProvider: TaskProvider<out org.jetbrains.kotlin.gradle.tasks.KotlinCompile>
get() = super.compileKotlinTaskProvider as TaskProvider<out org.jetbrains.kotlin.gradle.tasks.KotlinCompile>
@Suppress("DEPRECATION")
@Deprecated("Accessing task instance directly is deprecated", replaceWith = ReplaceWith("compileTaskProvider"))
override val compileKotlinTask: org.jetbrains.kotlin.gradle.tasks.KotlinCompile
get() = super.compileKotlinTask as org.jetbrains.kotlin.gradle.tasks.KotlinCompile
@Suppress("UNCHECKED_CAST")
override val compileTaskProvider: TaskProvider<out KotlinCompilationTask<CompilerJvmOptions>>
get() = super.compileTaskProvider as TaskProvider<KotlinCompilationTask<CompilerJvmOptions>>
val compileJavaTaskProvider: TaskProvider<out JavaCompile>?
get() = if (target.withJavaEnabled) {
val project = target.project
val javaSourceSets =
project.gradle.variantImplementationFactory<JavaSourceSetsAccessor.JavaSourceSetsAccessorVariantFactory>()
.getInstance(project)
.sourceSets
val javaSourceSet = javaSourceSets.getByName(compilationPurpose)
project.tasks.withType(JavaCompile::class.java).named(javaSourceSet.compileJavaTaskName)
} else null
}
@@ -6,172 +6,25 @@
@file:Suppress("PackageDirectoryMismatch") // Old package for compatibility
package org.jetbrains.kotlin.gradle.plugin.mpp
import org.gradle.api.attributes.Category
import org.gradle.api.attributes.Usage
import org.gradle.api.provider.Provider
import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptions
import org.jetbrains.kotlin.gradle.dsl.CompilerJvmOptionsDefault
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.*
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule.Type.Auxiliary
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationModuleManager.CompilationModule.Type.Main
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.archivesName
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.JvmCompilerOptionsFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
import org.jetbrains.kotlin.gradle.utils.*
import java.util.concurrent.Callable
open class KotlinJvmCompilationFactory(
override val target: KotlinJvmTarget
open class KotlinJvmCompilationFactory internal constructor(
override val target: KotlinJvmTarget,
private val compilationImplFactory: KotlinCompilationImplFactory =
KotlinCompilationImplFactory(
compilerOptionsFactory = JvmCompilerOptionsFactory,
compilationAssociator = JvmKotlinCompilationAssociator
),
) : KotlinCompilationFactory<KotlinJvmCompilation> {
override val itemClass: Class<KotlinJvmCompilation>
get() = KotlinJvmCompilation::class.java
override fun create(name: String): KotlinJvmCompilation {
val compilerOptions = createCompilerOptions()
val params = KotlinCompilationImpl.Params(
target = target,
compilationModule = KotlinCompilationModuleManager.CompilationModule(
compilationName = name,
ownModuleName = ownModuleName(target, name),
type = if (name == KotlinCompilation.MAIN_COMPILATION_NAME) Main else Auxiliary
),
sourceSets = KotlinCompilationSourceSetsContainer(getOrCreateDefaultSourceSet(name)),
dependencyConfigurations = createDependencyConfigurations(name),
compilationTaskNames = KotlinCompilationTaskNameContainer(
compileTaskName = lowerCamelCaseName(
"compile", name.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME }, "Kotlin", target.targetName
),
compileAllTaskName = lowerCamelCaseName(target.disambiguationClassifier, name, "classes")
),
processResourcesTaskName = lowerCamelCaseName(
target.disambiguationClassifier,
name.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
"processResources"
),
output = DefaultKotlinCompilationOutput(
project, Callable { target.project.buildDir.resolve("processedResources/${target.targetName}/$name") }
),
compilerOptions = compilerOptions,
kotlinOptions = compilerOptions.asKotlinJvmOptions(),
compilationAssociator = if (target.withJavaEnabled) KotlinJvmWithJavaCompilationAssociator else
DefaultKotlinCompilationAssociator,
compilationFriendPathsResolver = DefaultKotlinCompilationFriendPathsResolver,
compilationSourceSetInclusion = DefaultKotlinCompilationSourceSetInclusion(
DefaultKotlinCompilationSourceSetInclusion.AddSourcesToCompileTask.Default
)
)
return target.project.objects.newInstance(KotlinJvmCompilation::class.java, KotlinCompilationImpl(params))
}
private fun createDependencyConfigurations(
compilationName: String
): KotlinCompilationDependencyConfigurationsContainer {
val compilation = "${target.disambiguationClassifier}/$compilationName"
val prefix = lowerCamelCaseName(
target.disambiguationClassifier,
compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
"compilation"
)
val apiConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, API)).apply {
isVisible = false
isCanBeConsumed = false
isCanBeResolved = false
description = "API dependencies for $compilation"
}
val implementationConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, IMPLEMENTATION)).apply {
extendsFrom(apiConfiguration)
isVisible = false
isCanBeConsumed = false
isCanBeResolved = false
description = "Implementation only dependencies for $compilation."
}
val compileOnlyConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, COMPILE_ONLY)).apply {
isCanBeConsumed = false
setupAsLocalTargetSpecificConfigurationIfSupported(target)
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
isVisible = false
isCanBeResolved = false
description = "Compile only dependencies for $compilation."
}
val runtimeOnlyConfiguration = target.project.configurations.maybeCreate(lowerCamelCaseName(prefix, RUNTIME_ONLY)).apply {
isVisible = false
isCanBeConsumed = false
isCanBeResolved = false
description = "Runtime only dependencies for $compilation."
}
val compileDependencyConfiguration = target.project.configurations.maybeCreate(
lowerCamelCaseName(
target.disambiguationClassifier,
compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
"compileClasspath"
)
).apply {
extendsFrom(compileOnlyConfiguration, implementationConfiguration)
usesPlatformOf(target)
isVisible = false
isCanBeConsumed = false
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target))
if (target.platformType != KotlinPlatformType.androidJvm) {
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
}
description = "Compile classpath for $compilation."
}
val runtimeDependencyConfiguration = target.project.configurations.maybeCreate(
lowerCamelCaseName(
target.disambiguationClassifier,
compilationName.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
"runtimeClasspath"
)
).apply {
extendsFrom(runtimeOnlyConfiguration, implementationConfiguration)
usesPlatformOf(target)
isVisible = false
isCanBeConsumed = false
isCanBeResolved = true
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target))
if (target.platformType != KotlinPlatformType.androidJvm) {
attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.categoryByName(Category.LIBRARY))
}
description = "Runtime classpath of $compilation."
}
return DefaultKotlinCompilationDependencyConfigurationsContainer(
apiConfiguration = apiConfiguration,
implementationConfiguration = implementationConfiguration,
compileOnlyConfiguration = compileOnlyConfiguration,
runtimeOnlyConfiguration = runtimeOnlyConfiguration,
compileDependencyConfiguration = compileDependencyConfiguration,
runtimeDependencyConfiguration = runtimeDependencyConfiguration
)
}
private fun createCompilerOptions(): HasCompilerOptions<CompilerJvmOptions> {
return object : HasCompilerOptions<CompilerJvmOptions> {
override val options: CompilerJvmOptions =
target.project.objects.newInstance(CompilerJvmOptionsDefault::class.java)
}
}
private fun HasCompilerOptions<CompilerJvmOptions>.asKotlinJvmOptions(): KotlinJvmOptions {
return object : KotlinJvmOptions {
override val options: CompilerJvmOptions
get() = this@asKotlinJvmOptions.options
}
return target.project.objects.newInstance(KotlinJvmCompilation::class.java, compilationImplFactory.create(target, name))
}
}
private fun ownModuleName(target: KotlinTarget, compilationName: String): Provider<String> = target.project.provider {
val baseName = target.project.archivesName.orNull
?: target.project.name
val suffix = if (compilationName == KotlinCompilation.MAIN_COMPILATION_NAME) "" else "_$compilationName"
filterModuleName("$baseName$suffix")
}
@@ -20,7 +20,6 @@ import org.gradle.api.tasks.bundling.Zip
import org.jetbrains.kotlin.gradle.dsl.*
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationDetailsImpl.DefaultCompilationDetails
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
import org.jetbrains.kotlin.gradle.plugin.sources.*
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
@@ -54,7 +53,7 @@ internal val Project.isCompatibilityMetadataVariantEnabled: Boolean
get() = PropertiesProvider(this).enableCompatibilityMetadataVariant == true
class KotlinMetadataTargetConfigurator :
KotlinOnlyTargetConfigurator<AbstractKotlinCompilation<*>, KotlinMetadataTarget>(createTestCompilation = false) {
KotlinOnlyTargetConfigurator<KotlinCompilation<*>, KotlinMetadataTarget>(createTestCompilation = false) {
companion object {
internal const val ALL_METADATA_JAR_NAME = "allMetadataJar"
@@ -115,7 +114,7 @@ class KotlinMetadataTargetConfigurator :
super.setupCompilationDependencyFiles(compilation)
}
override fun buildCompilationProcessor(compilation: AbstractKotlinCompilation<*>): KotlinCompilationProcessor<*> = when (compilation) {
override fun buildCompilationProcessor(compilation: KotlinCompilation<*>): KotlinCompilationProcessor<*> = when (compilation) {
is KotlinCommonCompilation -> {
val tasksProvider = KotlinTasksProvider()
KotlinCommonSourceSetProcessor(KotlinCompilationProjection(compilation), tasksProvider)
@@ -181,7 +180,7 @@ class KotlinMetadataTargetConfigurator :
val publishedCommonSourceSets: Set<KotlinSourceSet> = getCommonSourceSetsForMetadataCompilation(project)
val hostSpecificSourceSets: Set<KotlinSourceSet> = getHostSpecificSourceSets(project).toSet()
val sourceSetsWithMetadataCompilations: Map<KotlinSourceSet, AbstractKotlinCompilation<*>> = publishedCommonSourceSets
val sourceSetsWithMetadataCompilations: Map<KotlinSourceSet, KotlinCompilation<*>> = publishedCommonSourceSets
.associateWith { sourceSet ->
createMetadataCompilation(target, sourceSet, allMetadataJar, sourceSet in hostSpecificSourceSets)
}
@@ -236,7 +235,7 @@ class KotlinMetadataTargetConfigurator :
}
private fun exportDependenciesForPublishing(
compilation: AbstractKotlinCompilation<*>
compilation: KotlinCompilation<*>
) {
val sourceSet = compilation.defaultSourceSet
val isSharedNativeCompilation = compilation is KotlinSharedNativeCompilation
@@ -290,7 +289,7 @@ class KotlinMetadataTargetConfigurator :
sourceSet: KotlinSourceSet,
allMetadataJar: TaskProvider<out Jar>,
isHostSpecific: Boolean
): AbstractKotlinCompilation<*> {
): KotlinCompilation<*> {
val project = target.project
val compilationName = sourceSet.name
@@ -300,10 +299,11 @@ class KotlinMetadataTargetConfigurator :
val isNativeSourceSet = isNativeSourceSet(sourceSet)
val compilationFactory: KotlinCompilationFactory<out AbstractKotlinCompilation<*>> = when {
val compilationFactory: KotlinCompilationFactory<out KotlinCompilation<*>> = when {
isNativeSourceSet -> KotlinSharedNativeCompilationFactory(
target,
platformCompilations.map { (it as AbstractKotlinNativeCompilation).konanTarget }
target = target,
konanTargets = platformCompilations.map { (it as AbstractKotlinNativeCompilation).konanTarget }.toSet(),
defaultSourceSet = sourceSet
)
else -> KotlinCommonCompilationFactory(target)
@@ -312,8 +312,6 @@ class KotlinMetadataTargetConfigurator :
return compilationFactory.create(compilationName).apply {
target.compilations.add(this@apply)
(compilationDetails as DefaultCompilationDetails<*, *>).addExactSourceSetEagerly(sourceSet)
configureMetadataDependenciesForCompilation(this@apply)
if (!isHostSpecific) {
@@ -334,7 +332,7 @@ class KotlinMetadataTargetConfigurator :
}
}
private fun configureMetadataDependenciesForCompilation(compilation: AbstractKotlinCompilation<*>) {
private fun configureMetadataDependenciesForCompilation(compilation: KotlinCompilation<*>) {
val project = compilation.target.project
val sourceSet = compilation.defaultSourceSet
@@ -342,7 +340,8 @@ class KotlinMetadataTargetConfigurator :
transformGranularMetadataTaskName(compilation.name),
listOf(sourceSet)
) {
it.description = "Generates serialized dependencies metadata for compilation '${compilation.name}' of target '${compilation.target.name}' (for tooling)"
it.description =
"Generates serialized dependencies metadata for compilation '${compilation.name}' of target '${compilation.target.name}' (for tooling)"
}
compilation.compileDependencyFiles += createMetadataDependencyTransformationClasspath(
@@ -436,7 +435,7 @@ class KotlinMetadataTargetConfigurator :
private fun createMetadataDependencyTransformationClasspath(
fromFiles: Configuration,
compilation: AbstractKotlinCompilation<*>
compilation: KotlinCompilation<*>
): FileCollection {
val project = compilation.target.project
@@ -486,11 +485,11 @@ class KotlinMetadataTargetConfigurator :
}
internal class NativeSharedCompilationProcessor(
private val kotlinCompilation: KotlinSharedNativeCompilation
) : KotlinCompilationProcessor<KotlinNativeCompile>(KotlinCompilationProjection(kotlinCompilation)) {
private val compilation: KotlinSharedNativeCompilation
) : KotlinCompilationProcessor<KotlinNativeCompile>(KotlinCompilationProjection(compilation)) {
override val kotlinTask: TaskProvider<out KotlinNativeCompile> =
KotlinNativeTargetConfigurator.createKlibCompilationTask(kotlinCompilation)
KotlinNativeTargetConfigurator.createKlibCompilationTask(compilationProjection, compilation.konanTarget)
override fun run() = Unit
}
@@ -633,6 +632,6 @@ internal fun Project.filesWithUnpackedArchives(from: FileCollection, extensions:
}
}).builtBy(from)
internal fun Project.getMetadataCompilationForSourceSet(sourceSet: KotlinSourceSet): AbstractKotlinCompilation<*>? {
internal fun Project.getMetadataCompilationForSourceSet(sourceSet: KotlinSourceSet): KotlinMetadataCompilation<*>? {
return multiplatformExtension.metadata().compilations.findByName(sourceSet.name)
}
@@ -14,17 +14,17 @@ import org.jetbrains.kotlin.gradle.targets.metadata.KotlinMetadataTargetConfigur
class KotlinMetadataTargetPreset(
project: Project
) : KotlinOnlyTargetPreset<KotlinMetadataTarget, AbstractKotlinCompilation<*>>(project) {
) : KotlinOnlyTargetPreset<KotlinMetadataTarget, KotlinCompilation<*>>(project) {
override fun getName(): String = PRESET_NAME
override fun createCompilationFactory(
forTarget: KotlinMetadataTarget
): KotlinCompilationFactory<AbstractKotlinCompilation<*>> =
object : KotlinCompilationFactory<AbstractKotlinCompilation<*>> {
): KotlinCompilationFactory<KotlinCompilation<*>> =
object : KotlinCompilationFactory<KotlinCompilation<*>> {
override val target: KotlinTarget = forTarget
override val itemClass: Class<AbstractKotlinCompilation<*>>
get() = AbstractKotlinCompilation::class.java
override val itemClass: Class<KotlinCompilation<*>>
get() = KotlinCompilation::class.java
override fun create(name: String): AbstractKotlinCompilation<*> = when (name) {
KotlinCompilation.MAIN_COMPILATION_NAME -> KotlinCommonCompilationFactory(forTarget).create(name)
@@ -7,6 +7,7 @@
package org.jetbrains.kotlin.gradle.plugin.mpp
import org.gradle.api.Action
import org.gradle.api.NamedDomainObjectFactory
import org.gradle.api.file.FileCollection
import org.gradle.api.file.ProjectLayout
import org.gradle.api.internal.file.FileOperations
@@ -17,26 +18,36 @@ import org.gradle.api.provider.ProviderFactory
import org.jetbrains.kotlin.gradle.plugin.CInteropSettings
import org.jetbrains.kotlin.gradle.plugin.CInteropSettings.IncludeDirectories
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeCompilationData
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmNativeVariantCompilationData
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.disambiguateName
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropIdentifier
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.gradle.utils.newInstance
import org.jetbrains.kotlin.gradle.utils.property
import java.io.File
import javax.inject.Inject
abstract class DefaultCInteropSettings @Inject constructor(
private val name: String,
@Transient
override val compilation: KotlinNativeCompilationData<*>,
private val providerFactory: ProviderFactory,
private val objectFactory: ObjectFactory,
private val projectLayout: ProjectLayout,
private val fileOperations: FileOperations,
) : CInteropSettings {
private fun files() = objectFactory.fileCollection()
private fun files(vararg paths: Any) = objectFactory.fileCollection().from(*paths)
abstract class DefaultCInteropSettings @Inject internal constructor(
private val params: Params
) : CInteropSettings {
internal data class Params(
val name: String,
val identifier: CInteropIdentifier,
val dependencyConfigurationName: String,
val interopProcessingTaskName: String,
val services: Services
) {
open class Services @Inject constructor(
val providerFactory: ProviderFactory,
val objectFactory: ObjectFactory,
val projectLayout: ProjectLayout,
val fileOperations: FileOperations,
)
}
private fun files() = params.services.objectFactory.fileCollection()
private fun files(vararg paths: Any) = params.services.objectFactory.fileCollection().from(*paths)
inner class DefaultIncludeDirectories : IncludeDirectories {
var allHeadersDirs: FileCollection = files()
@@ -53,29 +64,19 @@ abstract class DefaultCInteropSettings @Inject constructor(
}
}
override fun getName(): String = name
override fun getName(): String = params.name
internal val identifier: CInteropIdentifier
get() = CInteropIdentifier(CInteropIdentifier.Scope.create(compilation), name)
val target: KotlinNativeTarget?
get() = (compilation as? KotlinNativeCompilation?)?.target
internal val identifier = params.identifier
override val dependencyConfigurationName: String
get() = compilation.disambiguateName("${name.capitalize()}CInterop")
get() = params.dependencyConfigurationName
override var dependencyFiles: FileCollection = files()
val interopProcessingTaskName: String
get() = lowerCamelCaseName(
"cinterop",
compilation.compilationPurpose.takeIf { it != "main" }.orEmpty(),
name,
target?.disambiguationClassifier ?: compilation.compilationClassifier
)
val interopProcessingTaskName get() = params.interopProcessingTaskName
val defFileProperty: Property<File> = objectFactory.property<File>().value(
projectLayout.projectDirectory.file("src/nativeInterop/cinterop/$name.def").asFile
val defFileProperty: Property<File> = params.services.objectFactory.property<File>().value(
params.services.projectLayout.projectDirectory.file("src/nativeInterop/cinterop/$name.def").asFile
)
var defFile: File
@@ -90,18 +91,18 @@ abstract class DefaultCInteropSettings @Inject constructor(
_packageNameProp.set(value)
}
internal val _packageNameProp: Property<String> = objectFactory.property(String::class.java)
internal val _packageNameProp: Property<String> = params.services.objectFactory.property(String::class.java)
val compilerOpts = mutableListOf<String>()
val linkerOpts = mutableListOf<String>()
var extraOpts: List<String>
get() = _extraOptsProp.get()
set(value) {
_extraOptsProp = objectFactory.listProperty(String::class.java)
_extraOptsProp = params.services.objectFactory.listProperty(String::class.java)
extraOpts(value)
}
internal var _extraOptsProp: ListProperty<String> = objectFactory.listProperty(String::class.java)
internal var _extraOptsProp: ListProperty<String> = params.services.objectFactory.listProperty(String::class.java)
val includeDirs = DefaultIncludeDirectories()
var headers: FileCollection = files()
@@ -109,7 +110,7 @@ abstract class DefaultCInteropSettings @Inject constructor(
// DSL methods.
override fun defFile(file: Any) {
defFileProperty.set(fileOperations.file(file))
defFileProperty.set(params.services.fileOperations.file(file))
}
override fun packageName(value: String) {
@@ -138,16 +139,46 @@ abstract class DefaultCInteropSettings @Inject constructor(
override fun extraOpts(vararg values: Any) = extraOpts(values.toList())
override fun extraOpts(values: List<Any>) {
_extraOptsProp.addAll(providerFactory.provider { values.map { it.toString() } })
_extraOptsProp.addAll(params.services.providerFactory.provider { values.map { it.toString() } })
}
}
private fun KotlinNativeCompilationData<*>.disambiguateName(simpleName: String): String = when (this) {
is AbstractKotlinNativeCompilation -> (this as AbstractKotlinCompilation<*>).disambiguateName(simpleName)
is GradleKpmNativeVariantCompilationData -> owner.disambiguateName(simpleName)
else -> lowerCamelCaseName(
this.compilationClassifier,
this.compilationPurpose.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
simpleName
)
internal class DefaultCInteropSettingsFactory(private val compilation: KotlinCompilation<*>) :
NamedDomainObjectFactory<DefaultCInteropSettings> {
override fun create(name: String): DefaultCInteropSettings {
val params = DefaultCInteropSettings.Params(
name = name,
identifier = CInteropIdentifier(CInteropIdentifier.Scope.create(compilation), name),
dependencyConfigurationName = compilation.disambiguateName("${name.capitalize()}CInterop"),
interopProcessingTaskName = lowerCamelCaseName(
"cinterop",
compilation.name.takeIf { it != "main" }.orEmpty(),
name,
compilation.target.disambiguationClassifier
),
services = compilation.project.objects.newInstance()
)
return compilation.project.objects.newInstance(params)
}
}
internal class GradleKpmDefaultCInteropSettingsFactory(private val compilation: GradleKpmNativeVariantCompilationData) :
NamedDomainObjectFactory<DefaultCInteropSettings> {
override fun create(name: String): DefaultCInteropSettings {
val params = DefaultCInteropSettings.Params(
name = name,
identifier = CInteropIdentifier(CInteropIdentifier.Scope.create(compilation), name),
dependencyConfigurationName = compilation.owner.disambiguateName("${name.capitalize()}CInterop"),
interopProcessingTaskName = lowerCamelCaseName(
"cinterop",
compilation.compilationPurpose.takeIf { it != "main" }.orEmpty(),
name,
compilation.compilationClassifier
),
services = compilation.project.objects.newInstance()
)
return compilation.project.objects.newInstance(params)
}
}
@@ -11,11 +11,8 @@ import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project
import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationWithResources
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeCompilationData
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeFragmentMetadataCompilationData
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationImpl
import org.jetbrains.kotlin.gradle.targets.native.NativeCompilerOptions
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
@@ -24,39 +21,69 @@ import java.io.File
import java.util.concurrent.Callable
import javax.inject.Inject
abstract class AbstractKotlinNativeCompilation(
override val konanTarget: KonanTarget,
compilationDetails: CompilationDetails<KotlinCommonOptions>
) : AbstractKotlinCompilation<KotlinCommonOptions>(
compilationDetails
),
KotlinNativeCompilationData<KotlinCommonOptions> {
abstract class AbstractKotlinNativeCompilation internal constructor(
private val compilation: KotlinCompilationImpl,
val konanTarget: KonanTarget
) : InternalKotlinCompilation<KotlinCommonOptions> by compilation.castKotlinOptionsType() {
@Suppress("DEPRECATION")
@Deprecated("Accessing task instance directly is deprecated", replaceWith = ReplaceWith("compileTaskProvider"))
override val compileKotlinTask: KotlinNativeCompile
get() = super.compileKotlinTask as KotlinNativeCompile
get() = compilation.compileKotlinTask as KotlinNativeCompile
@Suppress("UNCHECKED_CAST", "DEPRECATION")
@Deprecated("Replaced with compileTaskProvider", replaceWith = ReplaceWith("compileTaskProvider"))
override val compileKotlinTaskProvider: TaskProvider<out KotlinNativeCompile>
get() = super.compileKotlinTaskProvider as TaskProvider<out KotlinNativeCompile>
get() = compilation.compileKotlinTaskProvider as TaskProvider<out KotlinNativeCompile>
@Suppress("UNCHECKED_CAST")
override val compileTaskProvider: TaskProvider<KotlinNativeCompile>
get() = super.compileTaskProvider as TaskProvider<KotlinNativeCompile>
get() = compilation.compileTaskProvider as TaskProvider<KotlinNativeCompile>
internal val useGenericPluginArtifact: Boolean
get() = project.nativeUseEmbeddableCompilerJar
// Endorsed library controller.
@Deprecated("Please declare explicit dependency on kotlinx-cli. This option is scheduled to be removed in 1.9.0")
override var enableEndorsedLibs: Boolean = false
var enableEndorsedLibs: Boolean = false
}
open class KotlinNativeCompilation @Inject internal constructor(
konanTarget: KonanTarget, private val compilation: KotlinCompilationImpl,
) : AbstractKotlinNativeCompilation(compilation, konanTarget) {
final override val target: KotlinNativeTarget
get() = compilation.target as KotlinNativeTarget
override val compilerOptions: NativeCompilerOptions
get() = super.compilerOptions as NativeCompilerOptions
// Interop DSL.
val cinterops = compilation.project.container(DefaultCInteropSettings::class.java, DefaultCInteropSettingsFactory(compilation))
fun cinterops(action: Action<NamedDomainObjectContainer<DefaultCInteropSettings>>) = action.execute(cinterops)
// Naming
final override val processResourcesTaskName: String
get() = disambiguateName("processResources")
val binariesTaskName: String
get() = lowerCamelCaseName(target.disambiguationClassifier, compilation.compilationName, "binaries")
}
open class KotlinSharedNativeCompilation @Inject internal constructor(
val konanTargets: List<KonanTarget>,
compilation: KotlinCompilationImpl
) : AbstractKotlinNativeCompilation(compilation, konanTargets.find { it.enabledOnCurrentHost } ?: konanTargets.first()),
KotlinMetadataCompilation<KotlinCommonOptions> {
override val target: KotlinMetadataTarget = compilation.target as KotlinMetadataTarget
}
// TODO SEB: Find home
internal val Project.nativeUseEmbeddableCompilerJar: Boolean
get() = PropertiesProvider(this).nativeUseEmbeddableCompilerJar
//TODO SEB: Find home for fuctnion
internal fun addSourcesToKotlinNativeCompileTask(
project: Project,
taskName: String,
@@ -68,50 +95,4 @@ internal fun addSourcesToKotlinNativeCompileTask(
task.commonSources.from(project.files(Callable { if (addAsCommonSources.value) sourceFiles() else emptyList() }))
}
}
abstract class KotlinNativeCompilation @Inject constructor(
konanTarget: KonanTarget,
details: CompilationDetails<KotlinCommonOptions>
) : AbstractKotlinNativeCompilation(konanTarget, details),
KotlinCompilationWithResources<KotlinCommonOptions> {
override val target: KotlinNativeTarget
get() = super.target as KotlinNativeTarget
override val compilerOptions: NativeCompilerOptions
get() = super.compilerOptions as NativeCompilerOptions
// Interop DSL.
val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName ->
project.objects.newInstance(DefaultCInteropSettings::class.java, cinteropName, this)
}
fun cinterops(action: Action<NamedDomainObjectContainer<DefaultCInteropSettings>>) = action.execute(cinterops)
// Naming
override val processResourcesTaskName: String
get() = disambiguateName("processResources")
val binariesTaskName: String
get() = lowerCamelCaseName(target.disambiguationClassifier, compilationPurpose, "binaries")
}
abstract class KotlinSharedNativeCompilation @Inject constructor(
val konanTargets: List<KonanTarget>,
compilationDetails: CompilationDetails<KotlinCommonOptions>
) : KotlinNativeFragmentMetadataCompilationData,
AbstractKotlinNativeCompilation(
// TODO: this will end up as '-target' argument passed to K2Native, which is wrong.
// Rewrite this when we'll compile native-shared source-sets against commonized platform libs
// We find any konan target that is enabled on the current host in order to pass the checks that avoid compiling the code otherwise.
konanTargets.find { it.enabledOnCurrentHost } ?: konanTargets.first(),
compilationDetails
),
KotlinMetadataCompilation<KotlinCommonOptions> {
override val target: KotlinMetadataTarget get() = super.target as KotlinMetadataTarget
override val isActive: Boolean
get() = true // old plugin only creates necessary compilations
}
}
@@ -6,81 +6,33 @@
@file:Suppress("PackageDirectoryMismatch") // Old package for compatibility
package org.jetbrains.kotlin.gradle.plugin.mpp
import org.jetbrains.kotlin.gradle.dsl.CompilerCommonOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationDetailsImpl.NativeCompilationDetails
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationDetailsImpl.SharedNativeCompilationDetails
import org.jetbrains.kotlin.gradle.targets.native.NativeCompilerOptions
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationSourceSetInclusion
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.NativeKotlinCompilationAssociator
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.NativeCompilerOptionsFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.NativeKotlinCompilationDependencyConfigurationsFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.NativeKotlinCompilationTaskNamesContainerFactory
open class KotlinNativeCompilationFactory(
override val target: KotlinNativeTarget
open class KotlinNativeCompilationFactory internal constructor(
override val target: KotlinNativeTarget,
private val compilationImplFactory: KotlinCompilationImplFactory =
KotlinCompilationImplFactory(
compilationTaskNamesContainerFactory = NativeKotlinCompilationTaskNamesContainerFactory,
compilationDependencyConfigurationsFactory = NativeKotlinCompilationDependencyConfigurationsFactory,
compilerOptionsFactory = NativeCompilerOptionsFactory,
compilationAssociator = NativeKotlinCompilationAssociator,
compilationSourceSetInclusion = DefaultKotlinCompilationSourceSetInclusion(
DefaultKotlinCompilationSourceSetInclusion.AddSourcesToCompileTask.Native
),
)
) : KotlinCompilationFactory<KotlinNativeCompilation> {
override val itemClass: Class<KotlinNativeCompilation>
get() = KotlinNativeCompilation::class.java
@Suppress("DEPRECATION")
override fun create(name: String): KotlinNativeCompilation {
// TODO: Validate compilation free args using the [CompilationFreeArgsValidator]
// when the compilation and the link args are separated (see KT-33717).
// Note: such validation should be done in the whenEvaluate block because
// a user can change args during project configuration.
val defaultSourceSet = getOrCreateDefaultSourceSet(name)
return target.project.objects.newInstance(
KotlinNativeCompilation::class.java,
target.konanTarget,
NativeCompilationDetails(
target,
name,
defaultSourceSet,
{
NativeCompilerOptions(
target.project,
defaultSourceSet.languageSettings
)
},
{
object : KotlinCommonOptions {
override val options: CompilerCommonOptions
get() = compilerOptions.options
}
}
)
KotlinNativeCompilation::class.java, target.konanTarget, compilationImplFactory.create(target, name)
)
}
}
class KotlinSharedNativeCompilationFactory(
override val target: KotlinMetadataTarget,
val konanTargets: List<KonanTarget>
) : KotlinCompilationFactory<KotlinSharedNativeCompilation> {
override val itemClass: Class<KotlinSharedNativeCompilation>
get() = KotlinSharedNativeCompilation::class.java
override fun create(name: String): KotlinSharedNativeCompilation {
val defaultSourceSet = getOrCreateDefaultSourceSet(name)
return target.project.objects.newInstance(
KotlinSharedNativeCompilation::class.java,
konanTargets,
SharedNativeCompilationDetails(
target,
name,
defaultSourceSet,
{
NativeCompilerOptions(
target.project,
defaultSourceSet.languageSettings
)
},
{
object : KotlinCommonOptions {
override val options: CompilerCommonOptions
get() = compilerOptions.options
}
}
)
)
}
}
@@ -26,6 +26,7 @@ import org.gradle.api.tasks.Exec
import org.gradle.api.tasks.TaskProvider
import org.gradle.language.base.plugins.LifecycleBasePlugin
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPILATION_NAME
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationProjection.KPM
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.KOTLIN_NATIVE_IGNORE_INCORRECT_DEPENDENCIES
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.registerEmbedAndSignAppleFrameworkTask
@@ -43,8 +44,6 @@ import org.jetbrains.kotlin.gradle.testing.internal.configureConventions
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
import org.jetbrains.kotlin.gradle.testing.testTaskName
import org.jetbrains.kotlin.gradle.utils.*
import org.jetbrains.kotlin.gradle.utils.Xcode
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget
import java.io.File
@@ -88,7 +87,7 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
private fun Project.syncLanguageSettingsToLinkTask(binary: NativeBinary) {
tasks.named(binary.linkTaskName, KotlinNativeLink::class.java).configure {
// We propagate compilation free args to the link task for now (see KT-33717).
val defaultLanguageSettings = binary.compilation.languageSettings as? DefaultLanguageSettingsBuilder
val defaultLanguageSettings = binary.compilation.defaultSourceSet.languageSettings as? DefaultLanguageSettingsBuilder
if (defaultLanguageSettings != null) {
it.toolOptions.freeCompilerArgs.addAll(
defaultLanguageSettings.freeCompilerArgs
@@ -210,12 +209,26 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
compilation: KotlinNativeCompilation,
cinterops: NamedDomainObjectCollection<DefaultCInteropSettings>
) {
val compilationProjection = KotlinCompilationProjection(compilation)
cinterops.all { interop ->
val interopTask = registerTask<CInteropProcess>(interop.interopProcessingTaskName, listOf(interop)) {
it.destinationDir = provider { klibOutputDirectory(compilation).resolve("cinterop") }
val params = CInteropProcess.Params(
settings = interop,
targetName = compilation.target.name,
compilationName = compilation.name,
konanTarget = compilation.konanTarget,
baseKlibName = run {
val compilationPrefix = if (compilation.isMain()) project.name else compilation.name
"$compilationPrefix-cinterop-${interop.name}"
},
services = objects.newInstance()
)
val interopTask = registerTask<CInteropProcess>(interop.interopProcessingTaskName, listOf(params)) {
it.destinationDir = provider { klibOutputDirectory(compilationProjection).resolve("cinterop") }
it.group = INTEROP_GROUP
it.description = "Generates Kotlin/Native interop library '${interop.name}' " +
"for compilation '${compilation.compilationPurpose}'" +
"for compilation '${compilation.compilationName}'" +
"of target '${it.konanTarget.name}'."
it.enabled = compilation.konanTarget.enabledOnCurrentHost
}
@@ -233,11 +246,12 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
project.dependencies.add(target.apiElementsConfigurationName, interopOutput)
// Add interop library to special CInteropApiElements configuration
createCInteropApiElementsKlibArtifact(interop, interopTask)
createCInteropApiElementsKlibArtifact(compilation.target, interop, interopTask)
// Add the interop library in publication.
createKlibArtifact(
compilation = interop.compilation,
compilationProjection = compilationProjection,
konanTarget = konanTarget,
artifactFile = interopTask.map { it.outputFile },
classifier = "cinterop-${interop.name}",
producingTask = interopTask,
@@ -280,7 +294,7 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
it.group = BasePlugin.BUILD_GROUP
it.description = "Assembles outputs for target '${target.name}'."
}
target.compilations.all { createKlibCompilationTask(it) }
target.compilations.all { createKlibCompilationTask(KotlinCompilationProjection(it), it.konanTarget) }
val apiElements = configurations.getByName(target.apiElementsConfigurationName)
@@ -325,7 +339,7 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
}
project.runOnceAfterEvaluated("Sync native compilation language settings to compiler options") {
target.compilations.all { compilation ->
compilation.compilerOptions.syncLanguageSettings()
compilation.compilerOptions.syncLanguageSettings(compilation.defaultSourceSet.languageSettings)
}
}
@@ -459,50 +473,55 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
const val RUN_GROUP = "run"
internal fun createKlibCompilationTask(
compilation: KotlinNativeCompilationData<*>
compilationProjection: KotlinCompilationProjection,
konanTarget: KonanTarget
): TaskProvider<KotlinNativeCompile> {
val project = compilation.project
val project = compilationProjection.project
val compileTaskProvider = project.registerTask<KotlinNativeCompile>(
compilation.compileKotlinTaskName,
listOf(compilation)
compilationProjection.compileKotlinTaskName,
listOf(compilationProjection)
) {
it.group = BasePlugin.BUILD_GROUP
it.description = "Compiles a klibrary from the '${compilation.compilationPurpose}' " +
"compilation for target '${compilation.platformType.name}'."
it.enabled = compilation.konanTarget.enabledOnCurrentHost
it.description = "Compiles a klibrary from the '${compilationProjection.compilationName}' " +
"compilation for target '${compilationProjection.platformType.name}'."
it.enabled = konanTarget.enabledOnCurrentHost
it.destinationDirectory.set(project.klibOutputDirectory(compilation).resolve("klib"))
it.destinationDirectory.set(project.klibOutputDirectory(compilationProjection).resolve("klib"))
}
compilation.output.classesDirs.from(compileTaskProvider.map { it.outputFile })
compilationProjection.classesDirs.from(compileTaskProvider.map { it.outputFile })
project.project.tasks.named(compilation.compileAllTaskName).dependsOn(compileTaskProvider)
project.project.tasks.named(compilationProjection.compileAllTaskName).dependsOn(compileTaskProvider)
if (compilation.isMainCompilationData()) {
if (compilation is KotlinNativeCompilation) {
project.project.tasks.named(compilation.target.artifactsTaskName).dependsOn(compileTaskProvider)
if (compilationProjection.isMain) {
if (compilationProjection is KotlinCompilationProjection.TCS && compilationProjection.compilation is KotlinNativeCompilation) {
project.project.tasks.named(compilationProjection.compilation.target.artifactsTaskName).dependsOn(compileTaskProvider)
}
project.project.tasks.named(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(compileTaskProvider)
}
val shouldAddCompileOutputsToElements = compilation.owner is GradleKpmVariant || compilation.isMainCompilationData()
val shouldAddCompileOutputsToElements =
(compilationProjection is KPM && compilationProjection.compilationData.owner is GradleKpmVariant) ||
compilationProjection.isMain
if (shouldAddCompileOutputsToElements) {
createRegularKlibArtifact(compilation, compileTaskProvider)
createRegularKlibArtifact(compilationProjection, konanTarget, compileTaskProvider)
}
if (compilation is AbstractKotlinNativeCompilation) {
if (compilationProjection is KotlinCompilationProjection.TCS && compilationProjection.compilation is AbstractKotlinNativeCompilation) {
// FIXME: support compiler plugins for PM20
addCompilerPlugins(compilation)
addCompilerPlugins(compilationProjection.compilation)
}
return compileTaskProvider
}
private fun Project.klibOutputDirectory(
compilation: KotlinCompilationData<*>
compilation: KotlinCompilationProjection
): File {
val targetSubDirectory = compilation.compilationClassifier?.let { "$it/" }.orEmpty()
return buildDir.resolve("classes/kotlin/$targetSubDirectory${compilation.compilationPurpose}")
val targetSubDirectory = compilation.targetDisambiguationClassifier?.let { "$it/" }.orEmpty()
return buildDir.resolve("classes/kotlin/$targetSubDirectory${compilation.compilationName}")
}
private fun addCompilerPlugins(compilation: AbstractKotlinNativeCompilation) {
@@ -522,30 +541,37 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
}
internal fun createRegularKlibArtifact(
compilation: KotlinNativeCompilationData<*>,
compilation: KotlinCompilationProjection,
konanTarget: KonanTarget,
compileTask: TaskProvider<out KotlinNativeCompile>
) = createKlibArtifact(compilation, compileTask.map { it.outputFile.get() }, null, compileTask)
) = createKlibArtifact(compilation, konanTarget, compileTask.map { it.outputFile.get() }, null, compileTask)
private fun createKlibArtifact(
compilation: KotlinNativeCompilationData<*>,
compilationProjection: KotlinCompilationProjection,
konanTarget: KonanTarget,
artifactFile: Provider<File>,
classifier: String?,
producingTask: TaskProvider<*>,
copy: Boolean = false
) {
val project = compilation.project
if (!compilation.konanTarget.enabledOnCurrentHost) {
val project = compilationProjection.project
if (!konanTarget.enabledOnCurrentHost) {
return
}
val apiElements = project.configurations.getByName(compilation.apiElementsConfigurationName)
val apiElementsName = when (compilationProjection) {
is KPM -> (compilationProjection.compilationData.owner as GradleKpmVariant).apiElementsConfiguration.name
is KotlinCompilationProjection.TCS -> compilationProjection.compilation.target.apiElementsConfigurationName
}
val apiElements = project.configurations.getByName(apiElementsName)
val realProducingTask: TaskProvider<*>
// TODO: Someone remove this HACK PLEASE!
val realArtifactFile = if (copy) {
realProducingTask = project.project.registerTask<Copy>("copy${producingTask.name.capitalize()}") {
val targetSubDirectory = compilation.compilationClassifier?.let { "$it/" }.orEmpty()
it.destinationDir = project.project.buildDir.resolve("libs/$targetSubDirectory${compilation.compilationPurpose}")
val targetSubDirectory = compilationProjection.targetDisambiguationClassifier?.let { "$it/" }.orEmpty()
it.destinationDir = project.project.buildDir.resolve("libs/$targetSubDirectory${compilationProjection.compilationName}")
it.from(artifactFile)
it.dependsOn(producingTask)
}
@@ -557,7 +583,7 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
with(apiElements) {
val klibArtifact = project.project.artifacts.add(apiElements.name, realArtifactFile) { artifact ->
artifact.name = compilation.compilationPurpose
artifact.name = compilationProjection.compilationName
artifact.extension = "klib"
artifact.type = "klib"
artifact.classifier = classifier
@@ -568,13 +594,6 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget> : AbstractKotl
attributes.attribute(ArtifactAttributes.ARTIFACT_FORMAT, NativeArtifactFormat.KLIB)
}
}
private val KotlinNativeCompilationData<*>.apiElementsConfigurationName: String
get() = when (val dataOwner = owner) {
is GradleKpmVariant -> dataOwner.apiElementsConfiguration.name
is KotlinTarget -> dataOwner.apiElementsConfigurationName
else -> error("unexpected owner of $this")
}
}
}
@@ -0,0 +1,59 @@
/*
* 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("PackageDirectoryMismatch") // Old package for compatibility
package org.jetbrains.kotlin.gradle.plugin.mpp
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationFriendPathsResolver
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.DefaultKotlinCompilationSourceSetInclusion
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationSourceSetsContainer
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.NativeKotlinCompilationAssociator
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.DefaultKotlinCompilationDependencyConfigurationsFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.KotlinCompilationImplFactory
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.factory.NativeCompilerOptionsFactory
import org.jetbrains.kotlin.konan.target.KonanTarget
open class KotlinSharedNativeCompilationFactory internal constructor(
override val target: KotlinMetadataTarget,
private val konanTargets: Set<KonanTarget>,
private val defaultSourceSet: KotlinSourceSet,
private val compilationImplFactory: KotlinCompilationImplFactory =
KotlinCompilationImplFactory(
compilationDependencyConfigurationsFactory = DefaultKotlinCompilationDependencyConfigurationsFactory.WithoutRuntime,
compilerOptionsFactory = NativeCompilerOptionsFactory,
compilationAssociator = NativeKotlinCompilationAssociator,
compilationSourceSetInclusion = DefaultKotlinCompilationSourceSetInclusion(
DefaultKotlinCompilationSourceSetInclusion.AddSourcesToCompileTask.Native
),
compilationFriendPathsResolver = DefaultKotlinCompilationFriendPathsResolver(
friendArtifactResolver = DefaultKotlinCompilationFriendPathsResolver.FriendArtifactResolver.composite(
DefaultKotlinCompilationFriendPathsResolver.DefaultFriendArtifactResolver,
DefaultKotlinCompilationFriendPathsResolver.AdditionalSharedNativeMetadataFriendArtifactResolver
)
),
/*
Metadata compilations are created *because* of a pre-existing SourceSet.
We therefore can create the container inline
*/
compilationSourceSetsContainerFactory = KotlinCompilationImplFactory.KotlinCompilationSourceSetsContainerFactory { _, _ ->
KotlinCompilationSourceSetsContainer(defaultSourceSet)
}
)
) : KotlinCompilationFactory<KotlinSharedNativeCompilation> {
override val itemClass: Class<KotlinSharedNativeCompilation>
get() = KotlinSharedNativeCompilation::class.java
@Suppress("DEPRECATION")
override fun create(name: String): KotlinSharedNativeCompilation {
return target.project.objects.newInstance(
itemClass, konanTargets.toList(), compilationImplFactory.create(target, name)
)
}
}
@@ -6,23 +6,22 @@
package org.jetbrains.kotlin.gradle.targets.native
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptionsDefault
import org.jetbrains.kotlin.gradle.dsl.CompilerCommonOptions
import org.jetbrains.kotlin.gradle.dsl.CompilerCommonOptionsDefault
import org.jetbrains.kotlin.gradle.plugin.HasCompilerOptions
import org.jetbrains.kotlin.gradle.plugin.sources.applyLanguageSettingsToCompilerOptions
import org.jetbrains.kotlin.project.model.LanguageSettings
class NativeCompilerOptions(
project: Project,
private val nativeLanguageSettings: LanguageSettings
) : HasCompilerOptions<KotlinCommonCompilerOptions> {
override val options: KotlinCommonCompilerOptions = project.objects
.newInstance(KotlinCommonCompilerOptionsDefault::class.java)
class NativeCompilerOptions(project: Project) : HasCompilerOptions<CompilerCommonOptions> {
override val options: CompilerCommonOptions = project.objects
.newInstance(CompilerCommonOptionsDefault::class.java)
.apply {
useK2.finalizeValue()
}
fun syncLanguageSettings() {
applyLanguageSettingsToCompilerOptions(nativeLanguageSettings, options)
internal fun syncLanguageSettings(languageSettings: LanguageSettings) {
applyLanguageSettingsToCompilerOptions(languageSettings, options)
}
}
@@ -19,6 +19,8 @@ import org.jetbrains.kotlin.compilerRunner.GradleCliCommonizer
import org.jetbrains.kotlin.compilerRunner.KotlinNativeCommonizerToolRunner
import org.jetbrains.kotlin.compilerRunner.KotlinToolRunner
import org.jetbrains.kotlin.compilerRunner.konanHome
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
@@ -283,7 +285,10 @@ private fun CInteropProcess.toGist(): CInteropGist {
identifier = settings.identifier,
konanTarget = konanTarget,
// FIXME support cinterop with PM20
sourceSets = project.provider { (settings.compilation as? KotlinCompilation<*>)?.kotlinSourceSets },
sourceSets = project.provider {
project.multiplatformExtension.targets.getByName(targetName)
.compilations.getByName(compilationName).kotlinSourceSets
},
libraryFile = outputFileProvider,
dependencies = libraries
)
@@ -10,20 +10,25 @@ import org.gradle.api.artifacts.Configuration
import org.gradle.api.attributes.*
import org.gradle.api.internal.artifacts.ArtifactAttributes
import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.CInteropSettings
import org.jetbrains.kotlin.gradle.plugin.KotlinNativeTargetConfigurator.NativeArtifactFormat
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.categoryByName
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultCInteropSettings
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
import org.jetbrains.kotlin.gradle.plugin.usesPlatformOf
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements.cinteropKlibLibraryElements
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
internal fun createCInteropApiElementsKlibArtifact(
target: KotlinNativeTarget,
settings: DefaultCInteropSettings,
interopTask: TaskProvider<out CInteropProcess>
) {
val project = settings.compilation.project
val configurationName = cInteropApiElementsConfigurationName(settings.target ?: return)
val project = target.project
val configurationName = cInteropApiElementsConfigurationName(target)
val configuration = project.configurations.getByName(configurationName)
project.artifacts.add(configuration.name, interopTask.map { it.outputFile }) { artifact ->
artifact.extension = "klib"
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.gradle.targets.native.internal
import org.gradle.api.tasks.Input
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
import org.jetbrains.kotlin.tooling.core.UnsafeApi
import java.io.Serializable
@@ -19,6 +20,11 @@ internal data class CInteropIdentifier internal constructor(
) : Serializable {
class Scope @UnsafeApi internal constructor(val name: String) : Serializable {
companion object {
@OptIn(UnsafeApi::class)
fun create(compilation: KotlinCompilation<*>): Scope {
return Scope("compilation/${compilation.compileKotlinTaskName}")
}
@OptIn(UnsafeApi::class)
fun create(compilation: KotlinCompilationData<*>): Scope {
return Scope("compilation/${compilation.compileKotlinTaskName}")
@@ -107,7 +107,7 @@ constructor(
@Suppress("DEPRECATION")
@Deprecated("Use toolOptions to configure the task")
@get:Internal
val languageSettings: LanguageSettings = compilation.languageSettings
val languageSettings: LanguageSettings = compilation.defaultSourceSet.languageSettings
@Suppress("unused")
@get:Input
@@ -14,11 +14,7 @@ import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.api.artifacts.component.ModuleComponentSelector
import org.gradle.api.artifacts.result.DependencyResult
import org.gradle.api.artifacts.result.ResolvedDependencyResult
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection
import org.gradle.api.file.FileTree
import org.gradle.api.file.ProjectLayout
import org.gradle.api.file.RegularFile
import org.gradle.api.file.*
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Provider
import org.gradle.api.provider.ProviderFactory
@@ -34,12 +30,13 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
import org.jetbrains.kotlin.gradle.internal.ensureParentDirsCreated
import org.jetbrains.kotlin.gradle.internal.isInIdeaSync
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationProjection
import org.jetbrains.kotlin.gradle.plugin.cocoapods.asValidFrameworkName
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinMetadataCompilationData
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeCompilationData
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeFragmentMetadataCompilationData
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.isMainCompilationData
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
import org.jetbrains.kotlin.gradle.plugin.tcsOrNull
import org.jetbrains.kotlin.gradle.targets.native.KonanPropertiesBuildService
import org.jetbrains.kotlin.gradle.targets.native.internal.isAllowCommonizer
import org.jetbrains.kotlin.gradle.targets.native.tasks.*
@@ -58,6 +55,42 @@ import java.io.File
import java.nio.file.Files
import java.nio.file.Path
import javax.inject.Inject
import kotlin.collections.Collection
import kotlin.collections.Iterable
import kotlin.collections.List
import kotlin.collections.Map
import kotlin.collections.MutableList
import kotlin.collections.MutableMap
import kotlin.collections.MutableSet
import kotlin.collections.Set
import kotlin.collections.any
import kotlin.collections.asSequence
import kotlin.collections.associateBy
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.emptyList
import kotlin.collections.filter
import kotlin.collections.filterIsInstance
import kotlin.collections.flatMap
import kotlin.collections.forEach
import kotlin.collections.getOrPut
import kotlin.collections.getValue
import kotlin.collections.isNotEmpty
import kotlin.collections.joinToString
import kotlin.collections.listOf
import kotlin.collections.listOfNotNull
import kotlin.collections.map
import kotlin.collections.mapNotNull
import kotlin.collections.minus
import kotlin.collections.mutableListOf
import kotlin.collections.mutableMapOf
import kotlin.collections.mutableSetOf
import kotlin.collections.orEmpty
import kotlin.collections.plus
import kotlin.collections.plusAssign
import kotlin.collections.set
import kotlin.collections.sortedBy
import kotlin.collections.toMutableSet
import org.jetbrains.kotlin.konan.file.File as KFile
import org.jetbrains.kotlin.utils.ResolvedDependencies as KResolvedDependencies
import org.jetbrains.kotlin.utils.ResolvedDependenciesSupport as KResolvedDependenciesSupport
@@ -127,7 +160,6 @@ internal fun FileCollection.filterKlibsPassedToCompiler(): FileCollection = filt
// endregion
abstract class AbstractKotlinNativeCompile<
T : KotlinCommonToolOptions,
K : KotlinNativeCompilationData<*>,
M : CommonToolArguments
>
@Inject constructor(
@@ -138,7 +170,7 @@ abstract class AbstractKotlinNativeCompile<
protected abstract val projectLayout: ProjectLayout
@get:Internal
abstract val compilation: K
internal abstract val compilation: KotlinCompilationProjection
// region inputs/outputs
@get:Input
@@ -155,24 +187,30 @@ abstract class AbstractKotlinNativeCompile<
@get:Internal
protected val konanTarget by project.provider {
compilation.konanTarget
when (val compilation = compilation) {
is KotlinCompilationProjection.KPM -> (compilation.compilationData as KotlinNativeCompilationData<*>).konanTarget
is KotlinCompilationProjection.TCS -> (compilation.compilation as AbstractKotlinNativeCompilation).konanTarget
}
}
@get:Classpath
override val libraries: ConfigurableFileCollection = objectFactory.fileCollection().from({
// Avoid resolving these dependencies during task graph construction when we can't build the target:
if (konanTarget.enabledOnCurrentHost)
objectFactory.fileCollection().from(
compilation.compileDependencyFiles.filterOutPublishableInteropLibs(project)
)
else objectFactory.fileCollection()
})
override val libraries: ConfigurableFileCollection = objectFactory.fileCollection().from(
{
// Avoid resolving these dependencies during task graph construction when we can't build the target:
if (konanTarget.enabledOnCurrentHost)
objectFactory.fileCollection().from(
compilation.compileDependencyFiles.filterOutPublishableInteropLibs(project)
)
else objectFactory.fileCollection()
}
)
@get:Classpath
protected val friendModule: FileCollection = project.files({ compilation.friendPaths })
@get:Input
val target: String by project.provider { compilation.konanTarget.name }
val target: String by project.provider { konanTarget.name }
// region Compiler options.
@Deprecated(
@@ -210,7 +248,9 @@ abstract class AbstractKotlinNativeCompile<
@Deprecated("Please declare explicit dependency on kotlinx-cli. This option is scheduled to be removed in 1.9.0")
@get:Input
val enableEndorsedLibs: Boolean by project.provider { compilation.enableEndorsedLibs }
val enableEndorsedLibs: Boolean by project.provider {
compilation.tcsOrNull?.compilation?.run { this as? KotlinNativeCompilation }?.enableEndorsedLibs ?: false
}
@get:Input
val kotlinNativeVersion: String
@@ -229,8 +269,10 @@ abstract class AbstractKotlinNativeCompile<
when {
outputKind == FRAMEWORK ->
it.asValidFrameworkName()
outputKind in listOf(STATIC, DYNAMIC) || outputKind == PROGRAM && konanTarget == KonanTarget.WASM32 ->
it.replace('-', '_')
else -> it
}
}
@@ -286,6 +328,7 @@ abstract class AbstractKotlinNativeCompile<
@get:Internal
internal val manifestFile: Provider<RegularFile> get() = projectLayout.buildDirectory.file("tmp/$name/inputManifest")
}
// Remove it once actual K2NativeCompilerArguments will be available without 'kotlin.native.enabled = true' flag
@@ -297,14 +340,14 @@ class StubK2NativeCompilerArguments : CommonCompilerArguments()
@CacheableTask
abstract class KotlinNativeCompile
@Inject
constructor(
@Internal
internal constructor(
@get:Internal
@Transient // can't be serialized for Gradle configuration cache
final override val compilation: KotlinNativeCompilationData<*>,
final override val compilation: KotlinCompilationProjection,
private val objectFactory: ObjectFactory,
private val providerFactory: ProviderFactory,
private val execOperations: ExecOperations
) : AbstractKotlinNativeCompile<KotlinCommonOptions, KotlinNativeCompilationData<*>, StubK2NativeCompilerArguments>(objectFactory),
) : AbstractKotlinNativeCompile<KotlinCommonOptions, StubK2NativeCompilerArguments>(objectFactory),
KotlinCompile<KotlinCommonOptions>,
KotlinCompilationTask<KotlinCommonCompilerOptions> {
@@ -319,9 +362,8 @@ constructor(
@get:Internal
override val baseName: String by lazy {
if (compilation.isMainCompilationData())
project.name
else "${project.name}_${compilation.compilationPurpose}"
if (compilation.isMain) project.name
else "${project.name}_${compilation.compilationName}"
}
// Store as an explicit provider in order to allow Gradle Instant Execution to capture the state
@@ -373,7 +415,7 @@ constructor(
// endregion.
// region Kotlin options.
override val compilerOptions: KotlinCommonCompilerOptions = compilation.compilerOptions.options
override val compilerOptions: CompilerCommonOptions = compilation.compilerOptions.options
@Deprecated(
message = "Replaced with compilerOptions",
@@ -409,11 +451,10 @@ constructor(
replaceWith = ReplaceWith("compilerOptions.freeCompilerArgs")
)
@get:Input
override val additionalCompilerOptions: Provider<Collection<String>> get() = compilerOptions
.freeCompilerArgs
.map {
it + (languageSettings as DefaultLanguageSettingsBuilder).freeCompilerArgs
}
override val additionalCompilerOptions: Provider<Collection<String>>
get() = compilerOptions
.freeCompilerArgs
.map { it + (languageSettings as DefaultLanguageSettingsBuilder).freeCompilerArgs }
private val runnerSettings = KotlinNativeCompilerRunner.Settings.fromProject(project)
private val isAllowCommonizer: Boolean by lazy { project.isAllowCommonizer() }
@@ -441,24 +482,26 @@ constructor(
)
}
private fun createSharedCompilationDataOrNull(): SharedCompilationData? {
when (compilation) {
is KotlinCompilationProjection.KPM -> if (compilation.compilationData !is KotlinMetadataCompilationData<*>) return null
is KotlinCompilationProjection.TCS -> if (compilation.compilation !is KotlinMetadataCompilation<*>) return null
}
val manifestFile: File = manifestFile.get().asFile
manifestFile.ensureParentDirsCreated()
val properties = java.util.Properties()
properties[KLIB_PROPERTY_NATIVE_TARGETS] = konanTargetsForManifest
properties.saveToFile(org.jetbrains.kotlin.konan.file.File(manifestFile.toPath()))
return SharedCompilationData(manifestFile, isAllowCommonizer)
}
@TaskAction
fun compile() {
val output = outputFile.get()
output.parentFile.mkdirs()
var sharedCompilationData: SharedCompilationData? = null
if (compilation is KotlinNativeFragmentMetadataCompilationData) {
val manifestFile: File = manifestFile.get().asFile
manifestFile.ensureParentDirsCreated()
val properties = java.util.Properties()
properties[KLIB_PROPERTY_NATIVE_TARGETS] = konanTargetsForManifest
properties.saveToFile(org.jetbrains.kotlin.konan.file.File(manifestFile.toPath()))
sharedCompilationData = SharedCompilationData(
manifestFile,
isAllowCommonizer
)
}
val plugins = listOfNotNull(
compilerPluginClasspath?.let { CompilerPluginData(it, compilerPluginOptions) },
@@ -478,7 +521,7 @@ constructor(
moduleName,
shortModuleName,
friendModule,
sharedCompilationData,
createSharedCompilationDataOrNull(),
sources.asFileTree,
commonSourcesTree
)
@@ -681,12 +724,13 @@ internal class CacheBuilder(
val toolOptions: KotlinCommonCompilerToolOptions,
val externalDependenciesArgs: List<String>
) {
val rootCacheDirectory get() = getRootCacheDirectory(
File(runnerSettings.parent.konanHome),
konanTarget,
binary.debuggable,
konanCacheKind
)
val rootCacheDirectory
get() = getRootCacheDirectory(
File(runnerSettings.parent.konanHome),
konanTarget,
binary.debuggable,
konanCacheKind
)
companion object {
fun createWithProject(
@@ -939,36 +983,54 @@ internal class CacheBuilder(
}
@CacheableTask
open class CInteropProcess
@Inject constructor(
open class CInteropProcess @Inject internal constructor(params: Params) : DefaultTask() {
internal class Params(
val settings: DefaultCInteropSettings,
val targetName: String,
val compilationName: String,
val konanTarget: KonanTarget,
val baseKlibName: String,
val services: Services
) {
internal open class Services @Inject constructor(
val objectFactory: ObjectFactory,
val execOperations: ExecOperations
)
}
private val objectFactory: ObjectFactory = params.services.objectFactory
private val execOperations: ExecOperations = params.services.execOperations
@get:Internal
internal val targetName: String = params.targetName
@get:Internal
internal val compilationName: String = params.compilationName
@Internal
val settings: DefaultCInteropSettings,
private val objectFactory: ObjectFactory,
private val execOperations: ExecOperations
) : DefaultTask() {
val settings: DefaultCInteropSettings = params.settings
@Internal // Taken into account in the outputFileProvider property
lateinit var destinationDir: Provider<File>
@get:Input
val konanTarget: KonanTarget = settings.compilation.konanTarget
val konanTarget: KonanTarget = params.konanTarget
@get:Input
val konanVersion: CompilerVersion = project.konanVersion
@Suppress("unused")
@get:Input
val interopName: String = settings.name
val interopName: String = params.settings.name
@get:Input
val baseKlibName: String = run {
val compilationPrefix = settings.compilation.let {
if (it.isMainCompilationData()) project.name else it.compilationPurpose
}
"$compilationPrefix-cinterop-$interopName"
}
val baseKlibName: String = params.baseKlibName
@get:Internal
val outputFileName: String = with(CompilerOutputKind.LIBRARY) {
val outputFileName: String = with(LIBRARY) {
"$baseKlibName${suffix(konanTarget)}"
}
@@ -533,7 +533,7 @@ internal inline val <reified T : Task> T.thisTaskProvider: TaskProvider<out T>
@CacheableTask
abstract class KotlinCompile @Inject constructor(
override val compilerOptions: KotlinJvmCompilerOptions,
final override val compilerOptions: CompilerJvmOptions,
workerExecutor: WorkerExecutor,
objectFactory: ObjectFactory
) : AbstractKotlinCompile<K2JVMCompilerArguments>(objectFactory, workerExecutor),
@@ -76,9 +76,8 @@ internal open class BaseKotlinCompileConfig<TASK : KotlinCompile> : AbstractKotl
task.associatedJavaCompileTaskSources.from(javaTaskProvider.map { it.source })
task.associatedJavaCompileTaskName.value(javaTaskProvider.name)
}
task.ownModuleName.value(
(compilationProjection.compilerOptions.options as CompilerJvmOptions).moduleName.convention(compilationProjection.ownModuleName)
)
task.ownModuleName.value(compilationProjection.ownModuleName)
}
}
}
@@ -13,6 +13,7 @@ import org.gradle.api.internal.project.ProjectInternal
import org.gradle.api.plugins.ExtraPropertiesExtension
import org.gradle.testfixtures.ProjectBuilder
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ANDROID_SOURCE_SET_LAYOUT_VERSION
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_CINTEROP_COMMONIZATION
@@ -20,7 +21,6 @@ import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLI
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_STDLIB_DEFAULT_DEPENDENCY
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinSharedNativeCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropCommonizerDependent
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropIdentifier
import org.jetbrains.kotlin.gradle.targets.native.internal.from
@@ -78,7 +78,7 @@ abstract class MultiplatformExtensionTest {
return compilations.getByName("test").cinteropIdentifier(name)
}
internal fun KotlinCompilationData<*>.cinteropIdentifier(name: String): CInteropIdentifier {
internal fun KotlinCompilation<*>.cinteropIdentifier(name: String): CInteropIdentifier {
return CInteropIdentifier(CInteropIdentifier.Scope.create(this), name)
}
}
@@ -14,7 +14,9 @@ import org.jetbrains.kotlin.gradle.buildProject
import org.jetbrains.kotlin.gradle.buildProjectWithMPP
import org.jetbrains.kotlin.gradle.kotlin
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.tasks.*
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinNativeCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import kotlin.test.*
internal class CompilationSpecificPluginPath {
@@ -292,7 +294,7 @@ internal class CompilationSpecificPluginPath {
.getByName(taskName)
.let {
when (it) {
is AbstractKotlinNativeCompile<*, *, *> -> it.compilerPluginClasspath
is AbstractKotlinNativeCompile<*, *> -> it.compilerPluginClasspath
is AbstractKotlinCompile<*> -> it.pluginClasspath.from.single()
else -> error("Unexpected task type with name $taskName. Is it kotlin compile task?")
}
@@ -17,7 +17,10 @@ import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinNativeCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilerPluginData
import org.jetbrains.kotlin.project.model.*
import kotlin.test.*
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue
class KpmCompilerPluginTest {
@Test
@@ -146,7 +149,7 @@ class KpmCompilerPluginTest {
.let {
when (it) {
is AbstractKotlinCompile<*> -> it.kotlinPluginData
is AbstractKotlinNativeCompile<*, *, *> -> it.kotlinPluginData
is AbstractKotlinNativeCompile<*, *> -> it.kotlinPluginData
else -> error("Unknown task type: $it")
}
}
@@ -54,3 +54,6 @@ operator fun Extras.plus(entry: Extras.Entry<*>): Extras = ImmutableExtrasImpl(t
operator fun Extras.plus(entries: Iterable<Extras.Entry<*>>): Extras = ImmutableExtrasImpl(this.entries + entries)
inline fun <T : Any> MutableExtras.getOrPut(key: Extras.Key<T>, defaultValue: () -> T): T {
return this[key] ?: defaultValue().also { this[key] = it }
}