Add basic support for Kotlin/Native variants to the PM20 Gradle plugin
This commit is contained in:
+2
-1
@@ -10,6 +10,7 @@ import org.gradle.api.Action
|
||||
import org.gradle.api.Named
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||
|
||||
interface CInteropSettings : Named {
|
||||
|
||||
@@ -22,7 +23,7 @@ interface CInteropSettings : Named {
|
||||
}
|
||||
|
||||
// TODO: Provide an interface for native compilations.
|
||||
val compilation: KotlinCompilation<KotlinCommonOptions>
|
||||
val compilation: KotlinCompilationData<out KotlinCommonOptions>
|
||||
|
||||
val dependencyConfigurationName: String
|
||||
var dependencyFiles: FileCollection
|
||||
|
||||
+3
-3
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.gradle.logging.kotlinDebug
|
||||
import org.jetbrains.kotlin.gradle.model.builder.KotlinModelBuilder
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.isMain
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.isMainCompilationData
|
||||
import org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubplugin
|
||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode
|
||||
import org.jetbrains.kotlin.gradle.targets.js.ir.*
|
||||
@@ -281,7 +281,7 @@ internal class Kotlin2JsSourceSetProcessor(
|
||||
kotlinOptions.freeCompilerArgs.contains(PRODUCE_ZIPPED_KLIB)
|
||||
) {
|
||||
// Configure FQ module name to avoid cyclic dependencies in klib manifests (see KT-36721).
|
||||
val baseName = if (kotlinCompilation.isMain()) {
|
||||
val baseName = if (kotlinCompilation.isMainCompilationData()) {
|
||||
project.name
|
||||
} else {
|
||||
"${project.name}_${kotlinCompilation.compilationPurpose}"
|
||||
@@ -366,7 +366,7 @@ internal class KotlinCommonSourceSetProcessor(
|
||||
override fun doTargetSpecificProcessing() {
|
||||
project.tasks.named(kotlinCompilation.compileAllTaskName).dependsOn(kotlinTask)
|
||||
// can be missing (e.g. in case of tests)
|
||||
if ((kotlinCompilation as? AbstractKotlinCompilation<*>)?.isMain() == true) {
|
||||
if ((kotlinCompilation as? AbstractKotlinCompilation<*>)?.isMainCompilationData() == true) {
|
||||
project.locateTask<Task>(kotlinCompilation.target.artifactsTaskName)?.dependsOn(kotlinTask)
|
||||
}
|
||||
|
||||
|
||||
+2
-6
@@ -281,11 +281,7 @@ class GradleModuleVariantResolver(val project: Project) : ModuleVariantResolver
|
||||
|
||||
val compileClasspath = getCompileDependenciesConfigurationForVariant(project, requestingVariant)
|
||||
|
||||
// TODO optimize O(n) search, store the mapping
|
||||
val component = compileClasspath.incoming.resolutionResult.allComponents.find { it.id.matchesModule(dependencyModule) }
|
||||
?: return VariantResolution.NotRequested(requestingVariant, dependencyModule)
|
||||
|
||||
val dependencyModuleId = ModuleIds.fromComponent(project, component)
|
||||
val dependencyModuleId = dependencyModule.moduleIdentifier
|
||||
// FIXME check composite builds, it's likely that resolvedVariantProvider fails on them?
|
||||
val resolvedGradleVariantName = resolvedVariantProvider.getResolvedVariantName(dependencyModuleId, compileClasspath)
|
||||
val kotlinVariantName = when (dependencyModule) {
|
||||
@@ -323,7 +319,7 @@ class GradleModuleVariantResolver(val project: Project) : ModuleVariantResolver
|
||||
project.configurations.getByName(compilation.compileDependencyConfigurationName)
|
||||
}
|
||||
is KotlinPm20ProjectExtension -> {
|
||||
project.configurations.getByName((requestingVariant as KotlinGradleVariant).compileDependencyConfigurationName)
|
||||
(requestingVariant as KotlinGradleVariant).compileDependencyConfiguration
|
||||
}
|
||||
else -> error("could not find the compile dependencies configuration for variant $requestingVariant")
|
||||
}
|
||||
|
||||
+2
-2
@@ -427,7 +427,7 @@ private class IncludedBuildMetadataExtractor(
|
||||
GlobalProjectStructureMetadataStorage.getProjectStructureMetadata(project, id.build.name, id.projectPath)
|
||||
}
|
||||
|
||||
private open class JarArtifactMppDependencyMetadataExtractor(
|
||||
internal open class JarArtifactMppDependencyMetadataExtractor(
|
||||
project: Project,
|
||||
dependency: ResolvedComponentResult,
|
||||
val primaryArtifact: File
|
||||
@@ -602,7 +602,7 @@ private fun mppDependencyMetadataExtractor(
|
||||
return when {
|
||||
moduleId is ProjectComponentIdentifier -> when {
|
||||
moduleId.build.isCurrentBuild ->
|
||||
ProjectMppDependencyMetadataExtractor(project, actualComponent, project.project(moduleId.projectPath))
|
||||
ProjectMppDependencyMetadataExtractor(project, actualComponent, moduleIdentifier, project.project(moduleId.projectPath))
|
||||
metadataArtifact != null ->
|
||||
IncludedBuildMetadataExtractor(project, actualComponent, metadataArtifact)
|
||||
else -> null
|
||||
|
||||
+4
-9
@@ -10,18 +10,16 @@ import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
import com.google.gson.stream.JsonWriter
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.gradle.api.tasks.Nested
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||
import org.jetbrains.kotlin.gradle.dsl.topLevelExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.topLevelExtensionOrNull
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.refinesClosure
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.withAllDependsOnSourceSets
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.sourceSetDependencyConfigurationByScope
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.dependsOnClosureWithInterCompilationDependencies
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.getPublishedPlatformCompilations
|
||||
@@ -133,10 +131,7 @@ data class KotlinProjectStructureMetadata(
|
||||
|
||||
internal fun buildKotlinProjectStructureMetadata(project: Project): KotlinProjectStructureMetadata? {
|
||||
val topLevelExtensionOrNull = project.topLevelExtensionOrNull
|
||||
if (topLevelExtensionOrNull is KotlinPm20ProjectExtension) {
|
||||
// FIXME: get module by ID, don't just take the main module
|
||||
return buildProjectStructureMetadata(topLevelExtensionOrNull.main)
|
||||
}
|
||||
require(topLevelExtensionOrNull is KotlinMultiplatformExtension) { "this function only works with the stable plugin" }
|
||||
|
||||
val sourceSetsWithMetadataCompilations =
|
||||
project.multiplatformExtensionOrNull?.targets?.getByName(KotlinMultiplatformPlugin.METADATA_TARGET_NAME)?.compilations?.associate {
|
||||
@@ -195,7 +190,7 @@ internal fun buildProjectStructureMetadata(module: KotlinGradleModule): KotlinPr
|
||||
val kotlinFragmentsPerKotlinVariant =
|
||||
module.variants.associate { variant -> variant.name to variant.refinesClosure.map { it.name }.toSet() }
|
||||
val fragmentRefinesRelation =
|
||||
module.fragments.associate { it.name to it.directRefinesDependencies.map { it.name }.toSet() }
|
||||
module.fragments.associate { it.name to it.directRefinesDependencies.map { it.fragmentName }.toSet() }
|
||||
|
||||
// FIXME: support native implementation-as-api-dependencies
|
||||
// FIXME: support dependencies on auxiliary modules
|
||||
@@ -211,7 +206,7 @@ internal fun buildProjectStructureMetadata(module: KotlinGradleModule): KotlinPr
|
||||
fragmentRefinesRelation,
|
||||
module.fragments.associate { it.name to SourceSetMetadataLayout.KLIB },
|
||||
fragmentDependencies,
|
||||
emptySet(),
|
||||
getHostSpecificFragments(module).mapTo(mutableSetOf()) { it.name },
|
||||
isPublishedAsRoot = true
|
||||
)
|
||||
}
|
||||
|
||||
+1
-1
@@ -288,7 +288,7 @@ abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
|
||||
override val project: Project
|
||||
get() = target.project
|
||||
|
||||
override val owner: Any?
|
||||
override val owner: KotlinTarget
|
||||
get() = target
|
||||
|
||||
override val compilationClassifier: String?
|
||||
|
||||
+35
-9
@@ -39,15 +39,18 @@ class GradleKotlinDependencyGraphResolver(
|
||||
configurationToResolveMetadataDependencies(project, requestingModule)
|
||||
|
||||
override fun resolveDependencyGraph(requestingModule: KotlinModule): DependencyGraphResolution {
|
||||
if (!requestingModule.representsProject(project))
|
||||
if (requestingModule !is KotlinGradleModule)
|
||||
return DependencyGraphResolution.Unknown(requestingModule)
|
||||
return resolveAsGraph(requestingModule)
|
||||
}
|
||||
|
||||
private fun resolveAsGraph(requestingModule: KotlinGradleModule): GradleDependencyGraph {
|
||||
val excludeLegacyMetadataModulesFromResult = mutableSetOf<ResolvedComponentResult>()
|
||||
|
||||
val nodeByModuleId = mutableMapOf<KotlinModuleIdentifier, DependencyGraphNode>()
|
||||
val nodeByModuleId = mutableMapOf<KotlinModuleIdentifier, GradleDependencyGraphNode>()
|
||||
|
||||
fun nodeFromComponent(component: ResolvedComponentResult, isRoot: Boolean /*refactor*/): DependencyGraphNode {
|
||||
val id = component.toModuleIdentifier()
|
||||
fun nodeFromComponent(component: ResolvedComponentResult, isRoot: Boolean /*refactor me*/): GradleDependencyGraphNode {
|
||||
val id = component.toSingleModuleIdentifier()
|
||||
return nodeByModuleId.getOrPut(id) {
|
||||
val module = if (isRoot)
|
||||
requestingModule
|
||||
@@ -55,14 +58,20 @@ class GradleKotlinDependencyGraphResolver(
|
||||
.takeIf { component !in excludeLegacyMetadataModulesFromResult }
|
||||
?: buildSyntheticModule(component, component.variants.singleOrNull()?.displayName ?: "default")
|
||||
|
||||
val componentContainingTransitiveDependencies =
|
||||
val metadataSourceComponent =
|
||||
(module as? ExternalImportedKotlinModule)
|
||||
?.takeIf { it.hasLegacyMetadataModule }
|
||||
?.let { (component.dependencies.singleOrNull() as? ResolvedDependencyResult)?.selected }
|
||||
?: component
|
||||
|
||||
val resolvedComponentDependencies = componentContainingTransitiveDependencies.dependencies
|
||||
val dependenciesRequestedByModule =
|
||||
module.fragments.flatMap { fragment -> fragment.declaredModuleDependencies.map { it.moduleIdentifier } }.toSet()
|
||||
|
||||
val resolvedComponentDependencies = metadataSourceComponent.dependencies
|
||||
.filterIsInstance<ResolvedDependencyResult>()
|
||||
// This filter statement is used to only visit the dependencies of the variant(s) of the requested Kotlin module and not
|
||||
// other variants. This prevents infinite recursion when visiting multiple Kotlin modules within one Gradle components
|
||||
.filter { dependency -> dependency.requested.toModuleIdentifiers().any { it in dependenciesRequestedByModule } }
|
||||
.flatMap { dependency -> dependency.requested.toModuleIdentifiers().map { id -> id to dependency.selected } }
|
||||
.toMap()
|
||||
|
||||
@@ -72,13 +81,30 @@ class GradleKotlinDependencyGraphResolver(
|
||||
deps.mapNotNull { resolvedComponentDependencies[it.moduleIdentifier] }.map { nodeFromComponent(it, isRoot = false) }
|
||||
}
|
||||
|
||||
DependencyGraphNode(module, nodeDependenciesMap)
|
||||
GradleDependencyGraphNode(
|
||||
module,
|
||||
component,
|
||||
metadataSourceComponent,
|
||||
nodeDependenciesMap
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return DependencyGraphResolution.DependencyGraph(
|
||||
return GradleDependencyGraph(
|
||||
requestingModule,
|
||||
nodeFromComponent(configurationToResolve(requestingModule).incoming.resolutionResult.root, isRoot = true)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GradleDependencyGraphNode(
|
||||
override val module: KotlinModule,
|
||||
val selectedComponent: ResolvedComponentResult,
|
||||
val metadataSourceComponent: ResolvedComponentResult?,
|
||||
override val dependenciesByFragment: Map<KotlinModuleFragment, Iterable<GradleDependencyGraphNode>>
|
||||
) : DependencyGraphNode(module, dependenciesByFragment)
|
||||
|
||||
class GradleDependencyGraph(
|
||||
override val requestingModule: KotlinGradleModule,
|
||||
override val root: GradleDependencyGraphNode
|
||||
) : DependencyGraphResolution.DependencyGraph(requestingModule, root)
|
||||
|
||||
+2
-1
@@ -163,7 +163,8 @@ internal class ExternalSyntheticKotlinModule(private val moduleData: BasicKotlin
|
||||
|
||||
internal class ExternalImportedKotlinModule(
|
||||
private val moduleData: BasicKotlinModule,
|
||||
val projectStructureMetadata: KotlinProjectStructureMetadata
|
||||
val projectStructureMetadata: KotlinProjectStructureMetadata,
|
||||
val hostSpecificFragments: Set<KotlinModuleFragment>
|
||||
) : KotlinModule by moduleData {
|
||||
val hasLegacyMetadataModule = !projectStructureMetadata.isPublishedAsRoot
|
||||
|
||||
|
||||
+47
-21
@@ -51,14 +51,12 @@ internal class FragmentGranularMetadataResolver(
|
||||
if (dependencyGraph is DependencyGraphResolution.Unknown)
|
||||
error("unexpected failure in dependency graph resolution for $requestingFragment in $project")
|
||||
|
||||
dependencyGraph as DependencyGraphResolution.DependencyGraph
|
||||
dependencyGraph as GradleDependencyGraph // refactor the type hierarchy to avoid this downcast? FIXME?
|
||||
val fragmentsToInclude = requestingFragment.refinesClosure
|
||||
val requestedDependencies = dependencyGraph.root.dependenciesByFragment.filterKeys { it in fragmentsToInclude }.values.flatten()
|
||||
|
||||
val visited = mutableSetOf<DependencyGraphNode>()
|
||||
val fragmentResolutionQueue = ArrayDeque<DependencyGraphNode>().apply {
|
||||
addAll(requestedDependencies)
|
||||
}
|
||||
val visited = mutableSetOf<GradleDependencyGraphNode>()
|
||||
val fragmentResolutionQueue = ArrayDeque<GradleDependencyGraphNode>(requestedDependencies)
|
||||
|
||||
val results = mutableSetOf<MetadataDependencyResolution>()
|
||||
|
||||
@@ -69,18 +67,15 @@ internal class FragmentGranularMetadataResolver(
|
||||
val dependencyModule = dependencyNode.module
|
||||
|
||||
val fragmentVisibility = fragmentResolver.getChosenFragments(requestingFragment, dependencyModule)
|
||||
val visibleFragments = (fragmentVisibility as? FragmentResolution.ChosenFragments)?.visibleFragments?.toList().orEmpty()
|
||||
val variantResolutions =
|
||||
(fragmentVisibility as? FragmentResolution.ChosenFragments)?.variantResolutions?.associateBy { it.requestingVariant }
|
||||
val chosenFragments = fragmentVisibility as? FragmentResolution.ChosenFragments
|
||||
val visibleFragments = chosenFragments?.visibleFragments?.toList().orEmpty()
|
||||
|
||||
val visibleTransitiveDependencies =
|
||||
dependencyNode.dependenciesByFragment.filterKeys { it in visibleFragments }.values.flattenTo(mutableSetOf())
|
||||
|
||||
//FIXME host-specific fragments
|
||||
|
||||
fragmentResolutionQueue.addAll(visibleTransitiveDependencies.filter { it !in visited })
|
||||
|
||||
val resolvedComponentResult = resolvedComponentsByModuleId.getValue(dependencyModule.moduleIdentifier)
|
||||
val resolvedComponentResult = dependencyNode.selectedComponent
|
||||
val isResolvedAsProject = resolvedComponentResult.toProjectOrNull(project)
|
||||
val result = when (dependencyModule) {
|
||||
is ExternalSyntheticKotlinModule -> {
|
||||
@@ -90,14 +85,7 @@ internal class FragmentGranularMetadataResolver(
|
||||
val projectStructureMetadata = (dependencyModule as? ExternalImportedKotlinModule)?.projectStructureMetadata
|
||||
?: checkNotNull(getProjectStructureMetadata(project, resolvedComponentResult, configurationToResolve))
|
||||
|
||||
// FIXME host-specific metadata!!!
|
||||
|
||||
val metadataSourceComponent = when {
|
||||
dependencyModule is ExternalImportedKotlinModule && dependencyModule.hasLegacyMetadataModule ->
|
||||
resolvedComponentResult.dependencies.filterIsInstance<ResolvedDependencyResult>().singleOrNull()?.selected
|
||||
?: resolvedComponentResult
|
||||
else -> resolvedComponentResult
|
||||
}
|
||||
val metadataSourceComponent = dependencyNode.run { metadataSourceComponent ?: selectedComponent }
|
||||
|
||||
val parentResolutionsForDependency =
|
||||
parentResultsByModuleIdentifier[metadataSourceComponent.toSingleModuleIdentifier()].orEmpty()
|
||||
@@ -106,6 +94,15 @@ internal class FragmentGranularMetadataResolver(
|
||||
.flatMapTo(mutableSetOf()) { it.allVisibleSourceSetNames }
|
||||
val visibleFragmentNames = visibleFragments.map { it.fragmentName }.toSet()
|
||||
|
||||
val metadataExtractor = getMetadataExtractor(project, resolvedComponentResult, configurationToResolve, true)
|
||||
|
||||
if (dependencyModule is ExternalImportedKotlinModule &&
|
||||
metadataExtractor is JarArtifactMppDependencyMetadataExtractor &&
|
||||
chosenFragments != null
|
||||
) {
|
||||
resolveHostSpecificMetadataArtifacts(dependencyModule, chosenFragments, metadataExtractor)
|
||||
}
|
||||
|
||||
ChooseVisibleSourceSetsImpl(
|
||||
metadataSourceComponent,
|
||||
isResolvedAsProject,
|
||||
@@ -113,14 +110,14 @@ internal class FragmentGranularMetadataResolver(
|
||||
visibleFragmentNames,
|
||||
visibleFragmentNames.minus(fragmentsVisibleByParents),
|
||||
visibleTransitiveDependencies.map { resolvedDependenciesByModuleId.getValue(it.module.moduleIdentifier) }.toSet(),
|
||||
checkNotNull(getMetadataExtractor(project, resolvedComponentResult, configurationToResolve, true))
|
||||
checkNotNull(metadataExtractor)
|
||||
)
|
||||
}
|
||||
}
|
||||
results.add(result)
|
||||
fragmentResolutionQueue.addAll(visibleTransitiveDependencies.filterNot(visited::contains))
|
||||
}
|
||||
|
||||
// FIXME this code is based on whole components; use module IDs with classifiers instead
|
||||
val resultSourceComponents = results.mapTo(mutableSetOf()) { it.dependency }
|
||||
resolvedComponentsByModuleId.values.minus(resultSourceComponents).forEach {
|
||||
results.add(MetadataDependencyResolution.ExcludeAsUnrequested(it, it.toProjectOrNull(project)))
|
||||
@@ -128,4 +125,33 @@ internal class FragmentGranularMetadataResolver(
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
private fun resolveHostSpecificMetadataArtifacts(
|
||||
dependencyModule: ExternalImportedKotlinModule,
|
||||
chosenFragments: FragmentResolution.ChosenFragments,
|
||||
metadataExtractor: JarArtifactMppDependencyMetadataExtractor
|
||||
) {
|
||||
val visibleFragments = chosenFragments.visibleFragments
|
||||
val variantResolutions = chosenFragments.variantResolutions
|
||||
val hostSpecificFragments = dependencyModule.hostSpecificFragments
|
||||
val hostSpecificFragmentToArtifact = visibleFragments.intersect(hostSpecificFragments).mapNotNull { hostSpecificFragment ->
|
||||
val relevantResolution = variantResolutions
|
||||
.filterIsInstance<VariantResolution.VariantMatch>()
|
||||
// find some of our variants that resolved a dependency's variant containing the fragment
|
||||
.find { hostSpecificFragment in it.chosenVariant.refinesClosure }
|
||||
// resolve the dependencies of that variant getting the host-specific metadata artifact
|
||||
relevantResolution?.let { resolution ->
|
||||
val variantResolvingPlatformArtifact =
|
||||
(resolution.requestingVariant as KotlinGradleVariant).compileDependencyConfiguration
|
||||
val configuration = variantResolvingPlatformArtifact
|
||||
val hostSpecificArtifact = ResolvedMppVariantsProvider.get(project)
|
||||
.getHostSpecificMetadataArtifactByRootModule(
|
||||
dependencyModule.moduleIdentifier,
|
||||
configuration
|
||||
)
|
||||
hostSpecificArtifact?.let { hostSpecificFragment.fragmentName to it }
|
||||
}
|
||||
}
|
||||
metadataExtractor.metadataArtifactBySourceSet.putAll(hostSpecificFragmentToArtifact)
|
||||
}
|
||||
}
|
||||
+21
-3
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.gradle.internal.customizeKotlinDependencies
|
||||
import org.jetbrains.kotlin.gradle.utils.checkGradleCompatibility
|
||||
import org.jetbrains.kotlin.project.model.KotlinModuleIdentifier
|
||||
import javax.inject.Inject
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
abstract class KotlinPm20GradlePlugin @Inject constructor(
|
||||
@Inject private val softwareComponentFactory: SoftwareComponentFactory
|
||||
@@ -35,11 +36,28 @@ abstract class KotlinPm20GradlePlugin @Inject constructor(
|
||||
}
|
||||
|
||||
private fun registerDefaultVariantFactories(project: Project) {
|
||||
project.pm20Extension.modules.configureEach {
|
||||
it.fragments.registerFactory(
|
||||
project.pm20Extension.modules.configureEach { module ->
|
||||
module.fragments.registerFactory(
|
||||
KotlinJvmVariant::class.java,
|
||||
KotlinJvmVariantFactory(it)
|
||||
KotlinJvmVariantFactory(module)
|
||||
)
|
||||
|
||||
fun <T: KotlinNativeVariantInternal> registerNativeVariantFactory(variantClass: KClass<T>) {
|
||||
module.fragments.registerFactory(
|
||||
variantClass.java,
|
||||
KotlinNativeVariantFactory(module, variantClass)
|
||||
)
|
||||
}
|
||||
listOf(
|
||||
// FIXME codegen, add missing native targets
|
||||
KotlinLinuxX64Variant::class,
|
||||
KotlinMacosX64Variant::class,
|
||||
KotlinMacosArm64Variant::class,
|
||||
KotlinIosX64Variant::class,
|
||||
KotlinIosArm64Variant::class
|
||||
).forEach { variantClass ->
|
||||
registerNativeVariantFactory(variantClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-115
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.pm20
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.file.SourceDirectorySet
|
||||
import org.gradle.api.plugins.BasePluginConvention
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptionsImpl
|
||||
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinCompilationOutput
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.filterModuleName
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.ResolvedMetadataFilesProvider
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.createTransformedMetadataClasspath
|
||||
import org.jetbrains.kotlin.gradle.utils.getValue
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
|
||||
internal class KotlinFragmentMetadataCompilationData(
|
||||
override val project: Project,
|
||||
val fragment: KotlinGradleFragment,
|
||||
private val module: KotlinGradleModule,
|
||||
private val compileAllTask: TaskProvider<DefaultTask>,
|
||||
val metadataCompilationRegistry: MetadataCompilationRegistry,
|
||||
private val resolvedMetadataFiles: Lazy<Iterable<ResolvedMetadataFilesProvider>>
|
||||
) : KotlinCompilationData<KotlinMultiplatformCommonOptions> {
|
||||
|
||||
override val owner
|
||||
get() = project.pm20Extension
|
||||
|
||||
override val compilationPurpose: String
|
||||
get() = fragment.fragmentName
|
||||
|
||||
override val compilationClassifier: String
|
||||
get() = lowerCamelCaseName(module.name, "metadata")
|
||||
|
||||
override val kotlinSourceDirectoriesByFragmentName: Map<String, SourceDirectorySet>
|
||||
get() = mapOf(fragment.fragmentName to fragment.kotlinSourceRoots)
|
||||
|
||||
override val compileKotlinTaskName: String
|
||||
get() = lowerCamelCaseName("compile", fragment.disambiguateName(""), "KotlinMetadata")
|
||||
|
||||
override val compileAllTaskName: String
|
||||
get() = compileAllTask.name
|
||||
|
||||
override val compileDependencyFiles: FileCollection by project.provider {
|
||||
createTransformedMetadataClasspath(
|
||||
project,
|
||||
resolvableMetadataConfiguration(fragment.containingModule),
|
||||
lazy { fragment.refinesClosure.minus(fragment).map { metadataCompilationRegistry.byFragment(it).output.classesDirs } },
|
||||
resolvedMetadataFiles
|
||||
)
|
||||
}
|
||||
|
||||
override val output: KotlinCompilationOutput = DefaultKotlinCompilationOutput(
|
||||
project,
|
||||
project.provider { project.buildDir.resolve("processedResources/${fragment.disambiguateName("metadata")}") }
|
||||
)
|
||||
|
||||
override val languageSettings: LanguageSettingsBuilder = DefaultLanguageSettingsBuilder() // FIXME apply settings
|
||||
|
||||
override val platformType: KotlinPlatformType
|
||||
get() = KotlinPlatformType.common
|
||||
|
||||
override val moduleName: String
|
||||
get() { // FIXME deduplicate with ownModuleName
|
||||
val baseName = project.convention.findPlugin(BasePluginConvention::class.java)?.archivesBaseName
|
||||
?: project.name
|
||||
val suffix = if (module.moduleClassifier == null) "" else "_${module.moduleClassifier}"
|
||||
return filterModuleName("$baseName$suffix")
|
||||
}
|
||||
|
||||
override val ownModuleName: String
|
||||
get() = moduleName
|
||||
|
||||
override val kotlinOptions: KotlinMultiplatformCommonOptions = // FIXME expose for configuration
|
||||
KotlinMultiplatformCommonOptionsImpl()
|
||||
|
||||
override val friendPaths: Iterable<FileCollection>
|
||||
get() = metadataCompilationRegistry.run {
|
||||
fragment.refinesClosure.minus(fragment)
|
||||
.map {
|
||||
metadataCompilationRegistry.byFragment(it).output.classesDirs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class MetadataCompilationRegistry {
|
||||
private val compilationDataPerFragment = mutableMapOf<KotlinGradleFragment, KotlinFragmentMetadataCompilationData>()
|
||||
|
||||
fun register(fragment: KotlinGradleFragment, compilationData: KotlinFragmentMetadataCompilationData) {
|
||||
compilationDataPerFragment[fragment]?.let { error("compilation data for fragment $fragment already registered") }
|
||||
compilationDataPerFragment[fragment] = compilationData
|
||||
withAllCallbacks.forEach { it.invoke(compilationData) }
|
||||
}
|
||||
|
||||
fun byFragment(fragment: KotlinGradleFragment): KotlinFragmentMetadataCompilationData =
|
||||
compilationDataPerFragment.getValue(fragment)
|
||||
|
||||
private val withAllCallbacks = mutableListOf<(KotlinFragmentMetadataCompilationData) -> Unit>()
|
||||
|
||||
fun withAll(action: (KotlinFragmentMetadataCompilationData) -> Unit) {
|
||||
compilationDataPerFragment.forEach { action(it.value) }
|
||||
withAllCallbacks += action
|
||||
}
|
||||
}
|
||||
+1
-51
@@ -5,19 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin.mpp.pm20
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.file.SourceDirectorySet
|
||||
import org.gradle.api.plugins.BasePluginConvention
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
|
||||
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
|
||||
import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.filterModuleName
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import org.jetbrains.kotlin.project.model.refinesClosure
|
||||
|
||||
open class KotlinJvmVariant(containingModule: KotlinGradleModule, fragmentName: String) :
|
||||
KotlinGradlePublishedVariantWithRuntime(containingModule, fragmentName) {
|
||||
@@ -29,48 +21,6 @@ open class KotlinJvmVariant(containingModule: KotlinGradleModule, fragmentName:
|
||||
class KotlinJvmVariantCompilationData(val variant: KotlinJvmVariant) : KotlinVariantCompilationDataInternal<KotlinJvmOptions> {
|
||||
override val owner: KotlinJvmVariant get() = variant
|
||||
|
||||
override val compilationPurpose: String
|
||||
get() = variant.containingModule.name
|
||||
|
||||
override val compilationClassifier: String
|
||||
get() = variant.name
|
||||
|
||||
override val kotlinSourceDirectoriesByFragmentName: Map<String, SourceDirectorySet>
|
||||
get() = variant.refinesClosure.filterIsInstance<KotlinGradleVariant>().associate { it.disambiguateName("") to it.kotlinSourceRoots }
|
||||
|
||||
override val output: KotlinCompilationOutput
|
||||
get() = variant.compilationOutputs
|
||||
|
||||
override val compileKotlinTaskName: String
|
||||
get() = lowerCamelCaseName("compile", compilationPurpose.takeIf { it != "main" }, "Kotlin", compilationClassifier)
|
||||
|
||||
override val compileAllTaskName: String
|
||||
get() = variant.disambiguateName("classes")
|
||||
|
||||
override val compileDependencyFiles: FileCollection
|
||||
get() = variant.compileDependencyFiles
|
||||
|
||||
override val languageSettings: LanguageSettingsBuilder
|
||||
get() = variant.languageSettings
|
||||
|
||||
override val platformType: KotlinPlatformType
|
||||
get() = variant.platformType
|
||||
|
||||
override val friendPaths: Iterable<FileCollection>
|
||||
// TODO for now, all output classes of the module are considered friends, even those not on the classpath
|
||||
get() {
|
||||
// FIXME support compiling against the JARs
|
||||
return variant.containingModule.project.pm20Extension.modules.flatMap { it.variants.map { it.compilationOutputs.classesDirs } }
|
||||
}
|
||||
|
||||
override val moduleName: String
|
||||
get() = // TODO accurate module names that don't rely on all variants having a main counterpart
|
||||
variant.containingModule.project.pm20Extension.modules
|
||||
.getByName(KotlinGradleModule.MAIN_MODULE_NAME).variants.findByName(variant.name)?.ownModuleName() ?: ownModuleName
|
||||
|
||||
override val ownModuleName: String
|
||||
get() = variant.ownModuleName()
|
||||
|
||||
// TODO pull out to the variant
|
||||
override val kotlinOptions: KotlinJvmOptions
|
||||
get() = KotlinJvmOptionsImpl()
|
||||
|
||||
+206
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.pm20
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.file.SourceDirectorySet
|
||||
import org.gradle.api.plugins.BasePluginConvention
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptionsImpl
|
||||
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.ResolvedMetadataFilesProvider
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.createTransformedMetadataClasspath
|
||||
import org.jetbrains.kotlin.gradle.utils.getValue
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
|
||||
interface KotlinMetadataCompilationData<T : KotlinCommonOptions> : KotlinCompilationData<T> {
|
||||
val isActive: Boolean
|
||||
}
|
||||
|
||||
interface KotlinCommonFragmentMetadataCompilationData : KotlinMetadataCompilationData<KotlinMultiplatformCommonOptions>
|
||||
|
||||
internal abstract class AbstractKotlinFragmentMetadataCompilationData<T : KotlinCommonOptions>(
|
||||
final override val project: Project,
|
||||
val fragment: KotlinGradleFragment,
|
||||
private val module: KotlinGradleModule,
|
||||
private val compileAllTask: TaskProvider<DefaultTask>,
|
||||
val metadataCompilationRegistry: MetadataCompilationRegistry,
|
||||
private val resolvedMetadataFiles: Lazy<Iterable<ResolvedMetadataFilesProvider>>
|
||||
) : KotlinMetadataCompilationData<T> {
|
||||
|
||||
override val owner
|
||||
get() = project.pm20Extension
|
||||
|
||||
override val compilationPurpose: String
|
||||
get() = fragment.fragmentName
|
||||
|
||||
override val compilationClassifier: String
|
||||
get() = lowerCamelCaseName(module.name, "metadata")
|
||||
|
||||
override val kotlinSourceDirectoriesByFragmentName: Map<String, SourceDirectorySet>
|
||||
get() = mapOf(fragment.fragmentName to fragment.kotlinSourceRoots)
|
||||
|
||||
override val compileKotlinTaskName: String
|
||||
get() = lowerCamelCaseName("compile", fragment.disambiguateName(""), "KotlinMetadata")
|
||||
|
||||
override val compileAllTaskName: String
|
||||
get() = compileAllTask.name
|
||||
|
||||
override val compileDependencyFiles: FileCollection by project.provider {
|
||||
createTransformedMetadataClasspath(
|
||||
project,
|
||||
resolvableMetadataConfiguration(fragment.containingModule),
|
||||
lazy { fragment.refinesClosure.minus(fragment).map { metadataCompilationRegistry.byFragment(it).output.classesDirs } },
|
||||
resolvedMetadataFiles
|
||||
)
|
||||
}
|
||||
|
||||
override val output: KotlinCompilationOutput = DefaultKotlinCompilationOutput(
|
||||
project,
|
||||
project.provider { project.buildDir.resolve("processedResources/${fragment.disambiguateName("metadata")}") }
|
||||
)
|
||||
|
||||
override val languageSettings: LanguageSettingsBuilder = DefaultLanguageSettingsBuilder() // FIXME apply settings
|
||||
|
||||
override val platformType: KotlinPlatformType
|
||||
get() = KotlinPlatformType.common
|
||||
|
||||
override val moduleName: String
|
||||
get() { // FIXME deduplicate with ownModuleName
|
||||
val baseName = project.convention.findPlugin(BasePluginConvention::class.java)?.archivesBaseName
|
||||
?: project.name
|
||||
val suffix = if (module.moduleClassifier == null) "" else "_${module.moduleClassifier}"
|
||||
return filterModuleName("$baseName$suffix")
|
||||
}
|
||||
|
||||
override val ownModuleName: String
|
||||
get() = moduleName
|
||||
|
||||
override val friendPaths: Iterable<FileCollection>
|
||||
get() = metadataCompilationRegistry.run {
|
||||
fragment.refinesClosure.minus(fragment)
|
||||
.map {
|
||||
metadataCompilationRegistry.byFragment(it).output.classesDirs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal open class KotlinCommonFragmentMetadataCompilationDataImpl(
|
||||
project: Project,
|
||||
fragment: KotlinGradleFragment,
|
||||
module: KotlinGradleModule,
|
||||
compileAllTask: TaskProvider<DefaultTask>,
|
||||
metadataCompilationRegistry: MetadataCompilationRegistry,
|
||||
resolvedMetadataFiles: Lazy<Iterable<ResolvedMetadataFilesProvider>>
|
||||
) : AbstractKotlinFragmentMetadataCompilationData<KotlinMultiplatformCommonOptions>(
|
||||
project,
|
||||
fragment,
|
||||
module,
|
||||
compileAllTask,
|
||||
metadataCompilationRegistry,
|
||||
resolvedMetadataFiles), KotlinCommonFragmentMetadataCompilationData {
|
||||
|
||||
override val isActive: Boolean
|
||||
get() = !fragment.isNativeShared()
|
||||
|
||||
override val kotlinOptions: KotlinMultiplatformCommonOptions = KotlinMultiplatformCommonOptionsImpl()
|
||||
}
|
||||
|
||||
interface KotlinNativeFragmentMetadataCompilationData :
|
||||
KotlinMetadataCompilationData<KotlinCommonOptions>,
|
||||
KotlinNativeCompilationData<KotlinCommonOptions>
|
||||
|
||||
internal fun KotlinGradleFragment.isNativeShared(): Boolean =
|
||||
containingModule.variantsContainingFragment(this).all { it.platformType == KotlinPlatformType.native }
|
||||
|
||||
internal fun KotlinGradleFragment.isNativeHostSpecific(): Boolean =
|
||||
this in getHostSpecificFragments(containingModule)
|
||||
|
||||
internal open class KotlinNativeFragmentMetadataCompilationDataImpl(
|
||||
project: Project,
|
||||
fragment: KotlinGradleFragment,
|
||||
module: KotlinGradleModule,
|
||||
compileAllTask: TaskProvider<DefaultTask>,
|
||||
metadataCompilationRegistry: MetadataCompilationRegistry,
|
||||
resolvedMetadataFiles: Lazy<Iterable<ResolvedMetadataFilesProvider>>
|
||||
) : AbstractKotlinFragmentMetadataCompilationData<KotlinCommonOptions>(
|
||||
project,
|
||||
fragment,
|
||||
module,
|
||||
compileAllTask,
|
||||
metadataCompilationRegistry,
|
||||
resolvedMetadataFiles
|
||||
), KotlinNativeFragmentMetadataCompilationData {
|
||||
|
||||
override val compileKotlinTaskName: String
|
||||
get() = lowerCamelCaseName("compile", fragment.disambiguateName(""), "KotlinNativeMetadata")
|
||||
|
||||
override val isActive: Boolean
|
||||
get() = fragment.isNativeShared()
|
||||
|
||||
override val kotlinOptions: NativeCompileOptions
|
||||
get() = NativeCompileOptions { languageSettings }
|
||||
|
||||
override val konanTarget: KonanTarget
|
||||
get() {
|
||||
val nativeVariants =
|
||||
fragment.containingModule.variantsContainingFragment(fragment).filterIsInstance<KotlinNativeVariantInternal>()
|
||||
return nativeVariants.firstOrNull { it.konanTarget.enabledOnCurrentHost }?.konanTarget
|
||||
?: nativeVariants.firstOrNull()?.konanTarget
|
||||
?: HostManager.host
|
||||
}
|
||||
|
||||
// FIXME endorsed libs?
|
||||
override val enableEndorsedLibs: Boolean
|
||||
get() = false
|
||||
}
|
||||
|
||||
// TODO think about more generic case: a fragment that can be compiled by an arbitrary compiler
|
||||
// what tasks should we create? should there be a generic task for that?
|
||||
internal class MetadataCompilationRegistry {
|
||||
private val commonCompilationDataPerFragment = mutableMapOf<KotlinGradleFragment, KotlinCommonFragmentMetadataCompilationDataImpl>()
|
||||
private val nativeCompilationDataPerFragment = mutableMapOf<KotlinGradleFragment, KotlinNativeFragmentMetadataCompilationDataImpl>()
|
||||
|
||||
fun registerCommon(fragment: KotlinGradleFragment, compilationData: KotlinCommonFragmentMetadataCompilationDataImpl) {
|
||||
commonCompilationDataPerFragment.compute(fragment) { _, existing ->
|
||||
existing?.let { error("common compilation data for fragment $fragment already registered") }
|
||||
compilationData
|
||||
}
|
||||
withAllCommonCallbacks.forEach { it.invoke(compilationData) }
|
||||
}
|
||||
|
||||
fun registerNative(fragment: KotlinGradleFragment, compilationData: KotlinNativeFragmentMetadataCompilationDataImpl) {
|
||||
nativeCompilationDataPerFragment.compute(fragment) { _, existing ->
|
||||
existing?.let { error("native compilation data for fragment $fragment already registered") }
|
||||
compilationData
|
||||
}
|
||||
withAllNativeCallbacks.forEach { it.invoke(compilationData) }
|
||||
}
|
||||
|
||||
fun byFragment(fragment: KotlinGradleFragment): KotlinMetadataCompilationData<*> =
|
||||
listOf(commonCompilationDataPerFragment.getValue(fragment), nativeCompilationDataPerFragment.getValue(fragment)).single {
|
||||
it.isActive
|
||||
}
|
||||
|
||||
private val withAllCommonCallbacks = mutableListOf<(AbstractKotlinFragmentMetadataCompilationData<*>) -> Unit>()
|
||||
private val withAllNativeCallbacks = mutableListOf<(AbstractKotlinFragmentMetadataCompilationData<*>) -> Unit>()
|
||||
|
||||
fun withAll(action: (AbstractKotlinFragmentMetadataCompilationData<*>) -> Unit) {
|
||||
commonCompilationDataPerFragment.forEach { action(it.value) }
|
||||
nativeCompilationDataPerFragment.forEach { action(it.value) }
|
||||
withAllCommonCallbacks += action
|
||||
withAllNativeCallbacks += action
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.pm20
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultCInteropSettings
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeCompileOptions
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.publishedConfigurationName
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import javax.inject.Inject
|
||||
|
||||
open class KotlinNativeVariantInternal(
|
||||
containingModule: KotlinGradleModule,
|
||||
fragmentName: String,
|
||||
val konanTarget: KonanTarget
|
||||
) : KotlinNativeVariant,
|
||||
KotlinGradleVariantInternal(containingModule, fragmentName),
|
||||
SingleMavenPublicationHolder by DefaultSingleMavenPublicationHolder(containingModule, fragmentName) {
|
||||
|
||||
override var enableEndorsedLibraries: Boolean = false
|
||||
|
||||
override val gradleVariantNames: Set<String>
|
||||
get() = listOf(apiElementsConfigurationName).flatMap { listOf(it, publishedConfigurationName(it)) }.toSet()
|
||||
|
||||
val cinterops = project.container(DefaultCInteropSettings::class.java) { cinteropName ->
|
||||
DefaultCInteropSettings(project, cinteropName, compilationData)
|
||||
}
|
||||
|
||||
internal val compilationData by lazy { KotlinNativeVariantCompilationData(this) }
|
||||
}
|
||||
|
||||
// FIXME codegen
|
||||
open class KotlinLinuxX64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) :
|
||||
KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.LINUX_X64)
|
||||
|
||||
open class KotlinMacosX64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) :
|
||||
KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.MACOS_X64)
|
||||
|
||||
open class KotlinMacosArm64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) :
|
||||
KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.MACOS_ARM64)
|
||||
|
||||
open class KotlinIosX64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) :
|
||||
KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.IOS_X64)
|
||||
|
||||
open class KotlinIosArm64Variant @Inject constructor(containingModule: KotlinGradleModule, fragmentName: String) :
|
||||
KotlinNativeVariantInternal(containingModule, fragmentName, KonanTarget.IOS_ARM64)
|
||||
|
||||
|
||||
internal val KotlinNativeVariant.hostSpecificMetadataConfigurationName
|
||||
get() = disambiguateName("MetadataElements")
|
||||
|
||||
interface KotlinNativeCompilationData<T : KotlinCommonOptions> : KotlinCompilationData<T> {
|
||||
val konanTarget: KonanTarget
|
||||
val enableEndorsedLibs: Boolean
|
||||
}
|
||||
|
||||
internal class KotlinNativeVariantCompilationData(
|
||||
val variant: KotlinNativeVariantInternal
|
||||
) : KotlinVariantCompilationDataInternal<KotlinCommonOptions>, KotlinNativeCompilationData<KotlinCommonOptions> {
|
||||
override val konanTarget: KonanTarget
|
||||
get() = variant.konanTarget
|
||||
|
||||
override val enableEndorsedLibs: Boolean
|
||||
get() = variant.enableEndorsedLibraries
|
||||
|
||||
override val project: Project
|
||||
get() = variant.containingModule.project
|
||||
|
||||
override val owner: KotlinNativeVariant
|
||||
get() = variant
|
||||
|
||||
override val kotlinOptions: KotlinCommonOptions = NativeCompileOptions { languageSettings }
|
||||
}
|
||||
+1
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.gradle.utils.dashSeparatedName
|
||||
import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION
|
||||
import org.jetbrains.kotlin.project.model.refinesClosure
|
||||
import org.jetbrains.kotlin.project.model.utils.variantsContainingFragment
|
||||
import java.util.concurrent.Callable
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
open class KotlinNativeVariantFactory<T : KotlinNativeVariantInternal>(
|
||||
|
||||
+7
-6
@@ -27,12 +27,13 @@ abstract class AbstractKotlinGradleVariantFactory<T : KotlinGradleVariant>(
|
||||
module: KotlinGradleModule
|
||||
) : AbstractKotlinGradleFragmentFactory<T>(module) {
|
||||
|
||||
override fun create(name: String): T = super.create(name).also { fragment ->
|
||||
createSourcesArchiveTask(fragment)
|
||||
configureKotlinCompilation(fragment)
|
||||
createElementsConfigurations(fragment)
|
||||
// TODO configure resources processing
|
||||
}
|
||||
override fun create(name: String): T =
|
||||
super.create(name).also { fragment ->
|
||||
createSourcesArchiveTask(fragment)
|
||||
createElementsConfigurations(fragment)
|
||||
configureKotlinCompilation(fragment)
|
||||
// TODO configure resources processing
|
||||
}
|
||||
|
||||
protected open fun setPlatformAttributesInConfiguration(fragment: T, configuration: Configuration) {
|
||||
configuration.attributes.attribute(KotlinPlatformType.attribute, fragment.platformType)
|
||||
|
||||
+3
@@ -57,6 +57,9 @@ abstract class KotlinGradleVariantInternal(
|
||||
override fun toString(): String = "variant $fragmentName in $containingModule"
|
||||
}
|
||||
|
||||
internal val KotlinGradleVariant.compileDependencyConfiguration: Configuration
|
||||
get() = containingModule.project.configurations.getByName(compileDependencyConfigurationName)
|
||||
|
||||
class DefaultSingleMavenPublicationHolder(
|
||||
private var module: KotlinGradleModule,
|
||||
override val defaultPublishedModuleSuffix: String?
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ abstract class AbstractKotlinGradleFragmentFactory<T : KotlinGradleFragment>(
|
||||
with(project.configurations) {
|
||||
fragment.relatedConfigurationNames.forEach { configurationName ->
|
||||
maybeCreate(configurationName).apply {
|
||||
// FIXME add metadata configurations?
|
||||
// FIXME add metadata configurations or API for IDE import?
|
||||
if (!configurationName.endsWith(METADATA_CONFIGURATION_NAME_SUFFIX)) {
|
||||
isCanBeResolved = false
|
||||
}
|
||||
|
||||
+68
-28
@@ -10,7 +10,6 @@ import org.gradle.api.Project
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCommonSourceSetProcessor
|
||||
@@ -23,6 +22,7 @@ import org.jetbrains.kotlin.gradle.tasks.registerTask
|
||||
import org.jetbrains.kotlin.gradle.tasks.withType
|
||||
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION
|
||||
import org.jetbrains.kotlin.project.model.KotlinModuleFragment
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
@@ -66,7 +66,7 @@ private fun generateAndExportProjectStructureMetadata(
|
||||
module: KotlinGradleModule
|
||||
) {
|
||||
val project = module.project
|
||||
val projectStructureMetadata = project.createGenerateProjectStructureMetadataTask(module.moduleClassifier)
|
||||
val projectStructureMetadata = project.createGenerateProjectStructureMetadataTask(module)
|
||||
project.tasks.withType<Jar>().named(metadataJarName(module)).configure { jar ->
|
||||
jar.from(projectStructureMetadata.map { it.resultFile }) { spec ->
|
||||
spec.into("META-INF")
|
||||
@@ -74,7 +74,7 @@ private fun generateAndExportProjectStructureMetadata(
|
||||
}
|
||||
}
|
||||
GlobalProjectStructureMetadataStorage.registerProjectStructureMetadata(project) {
|
||||
checkNotNull(buildKotlinProjectStructureMetadata(project))
|
||||
buildProjectStructureMetadata(module)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,13 @@ private fun configureMetadataCompilationsAndCreateRegistry(
|
||||
}
|
||||
val compileAllTask = project.registerTask<DefaultTask>(lowerCamelCaseName(module.moduleClassifier, "metadataClasses"))
|
||||
module.fragments.all { fragment ->
|
||||
createMetadataCompilation(fragment, compileAllTask, metadataCompilationRegistry)
|
||||
createCommonMetadataCompilation(fragment, compileAllTask, metadataCompilationRegistry)
|
||||
createNativeMetadataCompilation(fragment, compileAllTask, metadataCompilationRegistry)
|
||||
}
|
||||
metadataCompilationRegistry.withAll { compilation ->
|
||||
project.tasks.matching { it.name == compilation.compileKotlinTaskName }.configureEach { task ->
|
||||
task.onlyIf { compilation.isActive }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,49 +146,83 @@ private fun configureMetadataJarTask(
|
||||
internal fun metadataJarName(module: KotlinGradleModule) =
|
||||
lowerCamelCaseName(module.moduleClassifier, "metadataJar")
|
||||
|
||||
private fun createMetadataCompilation(
|
||||
private fun createCommonMetadataCompilation(
|
||||
fragment: KotlinGradleFragment,
|
||||
compileAllTask: TaskProvider<DefaultTask>,
|
||||
metadataCompilationRegistry: MetadataCompilationRegistry
|
||||
): KotlinCompilationData<out KotlinMultiplatformCommonOptions> {
|
||||
) {
|
||||
val module = fragment.containingModule
|
||||
val project = module.project
|
||||
|
||||
val metadataCompilationData =
|
||||
KotlinFragmentMetadataCompilationData(
|
||||
KotlinCommonFragmentMetadataCompilationDataImpl(
|
||||
project,
|
||||
fragment,
|
||||
module,
|
||||
compileAllTask,
|
||||
metadataCompilationRegistry,
|
||||
lazy {
|
||||
fragment.refinesClosure.map {
|
||||
FragmentResolvedMetadataProvider(
|
||||
project.tasks.withType<TransformKotlinGranularMetadataForFragment>()
|
||||
.named(transformFragmentMetadataTaskName(it))
|
||||
)
|
||||
}
|
||||
}
|
||||
lazy { resolvedMetadataProviders(fragment) }
|
||||
)
|
||||
metadataCompilationRegistry.register(fragment, metadataCompilationData)
|
||||
|
||||
addSourcesToKotlinCompileTask(
|
||||
project,
|
||||
metadataCompilationData.compileKotlinTaskName,
|
||||
/*FIXME*/ emptyList(),
|
||||
{ fragment.kotlinSourceRoots },
|
||||
lazyOf(true)
|
||||
)
|
||||
|
||||
KotlinCommonSourceSetProcessor(
|
||||
metadataCompilationData,
|
||||
KotlinTasksProvider(),
|
||||
project.getKotlinPluginVersion() ?: "undefined"
|
||||
).run()
|
||||
|
||||
return metadataCompilationData
|
||||
addSourcesToMetadataCompileTask(metadataCompilationData)
|
||||
metadataCompilationRegistry.registerCommon(fragment, metadataCompilationData)
|
||||
}
|
||||
|
||||
private fun createNativeMetadataCompilation(
|
||||
fragment: KotlinGradleFragment,
|
||||
compileAllTask: TaskProvider<DefaultTask>,
|
||||
metadataCompilationRegistry: MetadataCompilationRegistry
|
||||
) {
|
||||
val module = fragment.containingModule
|
||||
val project = module.project
|
||||
|
||||
val metadataCompilationData =
|
||||
KotlinNativeFragmentMetadataCompilationDataImpl(
|
||||
project,
|
||||
fragment,
|
||||
module,
|
||||
compileAllTask,
|
||||
metadataCompilationRegistry,
|
||||
lazy { resolvedMetadataProviders(fragment) }
|
||||
)
|
||||
NativeSharedCompilationProcessor(metadataCompilationData).run()
|
||||
addSourcesToMetadataCompileTask(metadataCompilationData)
|
||||
metadataCompilationRegistry.registerNative(fragment, metadataCompilationData)
|
||||
}
|
||||
|
||||
private fun addSourcesToMetadataCompileTask(compilationData: AbstractKotlinFragmentMetadataCompilationData<*>) {
|
||||
val sources = { compilationData.fragment.kotlinSourceRoots }
|
||||
when (compilationData) {
|
||||
// Note: this call is invalid for compilations that use Kotlin/Native compile tasks!
|
||||
is KotlinCommonFragmentMetadataCompilationData -> addSourcesToKotlinCompileTask(
|
||||
compilationData.project,
|
||||
compilationData.compileKotlinTaskName,
|
||||
/*FIXME*/ emptyList(),
|
||||
sources,
|
||||
lazyOf(true)
|
||||
)
|
||||
is KotlinNativeFragmentMetadataCompilationData -> addSourcesToKotlinNativeCompileTask(
|
||||
compilationData.project,
|
||||
compilationData.compileKotlinTaskName,
|
||||
sources,
|
||||
lazyOf(true)
|
||||
)
|
||||
else -> error("unexpected compilation data $compilationData")
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolvedMetadataProviders(fragment: KotlinGradleFragment) =
|
||||
fragment.refinesClosure.map {
|
||||
FragmentResolvedMetadataProvider(
|
||||
fragment.project.tasks.withType<TransformKotlinGranularMetadataForFragment>()
|
||||
.named(transformFragmentMetadataTaskName(it))
|
||||
)
|
||||
}
|
||||
|
||||
private fun createExtractMetadataTask(
|
||||
project: Project,
|
||||
fragment: KotlinGradleFragment,
|
||||
@@ -206,7 +246,7 @@ private fun createExtractMetadataTask(
|
||||
|
||||
// FIXME: use this function once more than one platform is supported
|
||||
private fun disableMetadataCompilationIfNotYetSupported(
|
||||
metadataCompilationData: KotlinFragmentMetadataCompilationData
|
||||
metadataCompilationData: AbstractKotlinFragmentMetadataCompilationData<*>
|
||||
) {
|
||||
val fragment = metadataCompilationData.fragment
|
||||
val platforms = fragment.containingModule.variantsContainingFragment(fragment).map { it.platformType }.toSet()
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.pm20
|
||||
|
||||
fun <T> publishVariantWithSinglePublication(
|
||||
variant: T
|
||||
) where T : SingleMavenPublicationHolder, T : KotlinGradleVariant {
|
||||
|
||||
}
|
||||
+24
-16
@@ -21,6 +21,8 @@ import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.CompilationSourceSetUtil.compilationsBySourceSets
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeFragmentMetadataCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinPm20ProjectExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
||||
@@ -119,20 +121,6 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) :
|
||||
else -> error("unsupported compilation type ${compilation::class.qualifiedName}")
|
||||
}
|
||||
|
||||
private inner class NativeSharedCompilationProcessor(
|
||||
override val kotlinCompilation: KotlinSharedNativeCompilation
|
||||
) : KotlinCompilationProcessor<KotlinNativeCompile>(kotlinCompilation) {
|
||||
|
||||
private val nativeTargetConfigurator = KotlinNativeTargetConfigurator<KotlinNativeTarget>(kotlinPluginVersion)
|
||||
|
||||
override val kotlinTask: TaskProvider<out KotlinNativeCompile> =
|
||||
with(nativeTargetConfigurator) {
|
||||
project.createKlibCompilationTask(kotlinCompilation)
|
||||
}
|
||||
|
||||
override fun run() = Unit
|
||||
}
|
||||
|
||||
override fun createArchiveTasks(target: KotlinMetadataTarget): TaskProvider<out Zip> {
|
||||
if (!target.project.isKotlinGranularMetadataEnabled)
|
||||
return super.createArchiveTasks(target)
|
||||
@@ -486,8 +474,28 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) :
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Project.createGenerateProjectStructureMetadataTask(moduleClassifier: String? = null): TaskProvider<GenerateProjectStructureMetadata> =
|
||||
project.registerTask(lowerCamelCaseName("generate", moduleClassifier, "ProjectStructureMetadata")) { task ->
|
||||
internal class NativeSharedCompilationProcessor(
|
||||
override val kotlinCompilation: KotlinNativeFragmentMetadataCompilationData
|
||||
) : KotlinCompilationProcessor<KotlinNativeCompile>(kotlinCompilation) {
|
||||
|
||||
private val nativeTargetConfigurator =
|
||||
KotlinNativeTargetConfigurator<KotlinNativeTarget>(kotlinCompilation.project.getKotlinPluginVersion() ?: "" /*FIXME*/)
|
||||
|
||||
override val kotlinTask: TaskProvider<out KotlinNativeCompile> =
|
||||
with(nativeTargetConfigurator) {
|
||||
project.createKlibCompilationTask(kotlinCompilation)
|
||||
}
|
||||
|
||||
override fun run() = Unit
|
||||
}
|
||||
|
||||
internal fun Project.createGenerateProjectStructureMetadataTask(module: KotlinGradleModule): TaskProvider<GenerateProjectStructureMetadata> =
|
||||
project.registerTask(lowerCamelCaseName("generate", module.moduleClassifier, "ProjectStructureMetadata")) { task ->
|
||||
task.lazyKotlinProjectStructureMetadata = lazy { buildProjectStructureMetadata(module) }
|
||||
}
|
||||
|
||||
internal fun Project.createGenerateProjectStructureMetadataTask(): TaskProvider<GenerateProjectStructureMetadata> =
|
||||
project.registerTask(lowerCamelCaseName("generateProjectStructureMetadata")) { task ->
|
||||
task.lazyKotlinProjectStructureMetadata = lazy { checkNotNull(buildKotlinProjectStructureMetadata(project)) }
|
||||
}
|
||||
|
||||
|
||||
+18
-4
@@ -15,6 +15,10 @@ import org.gradle.api.provider.Property
|
||||
import org.gradle.util.ConfigureUtil
|
||||
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.KotlinNativeVariantCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.disambiguateName
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropIdentifier
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import java.io.File
|
||||
@@ -23,7 +27,7 @@ import javax.inject.Inject
|
||||
open class DefaultCInteropSettings @Inject constructor(
|
||||
private val project: Project,
|
||||
private val name: String,
|
||||
override val compilation: KotlinNativeCompilation
|
||||
override val compilation: KotlinNativeCompilationData<*>
|
||||
) : CInteropSettings {
|
||||
|
||||
inner class DefaultIncludeDirectories : CInteropSettings.IncludeDirectories {
|
||||
@@ -46,8 +50,8 @@ open class DefaultCInteropSettings @Inject constructor(
|
||||
internal val identifier: CInteropIdentifier
|
||||
get() = CInteropIdentifier(CInteropIdentifier.Scope.create(compilation), name)
|
||||
|
||||
val target: KotlinNativeTarget
|
||||
get() = compilation.target
|
||||
val target: KotlinNativeTarget?
|
||||
get() = (compilation as? KotlinNativeCompilation?)?.target
|
||||
|
||||
override val dependencyConfigurationName: String
|
||||
get() = compilation.disambiguateName("${name.capitalize()}CInterop")
|
||||
@@ -59,7 +63,7 @@ open class DefaultCInteropSettings @Inject constructor(
|
||||
"cinterop",
|
||||
compilation.compilationPurpose.takeIf { it != "main" }.orEmpty(),
|
||||
name,
|
||||
target.disambiguationClassifier
|
||||
target?.disambiguationClassifier ?: compilation.compilationClassifier
|
||||
)
|
||||
|
||||
val defFileProperty: Property<File> = project.objects.property(File::class.java)
|
||||
@@ -129,3 +133,13 @@ open class DefaultCInteropSettings @Inject constructor(
|
||||
_extraOptsProp.addAll(project.provider { values.map { it.toString() } })
|
||||
}
|
||||
}
|
||||
|
||||
private fun KotlinNativeCompilationData<*>.disambiguateName(simpleName: String): String = when (this) {
|
||||
is AbstractKotlinNativeCompilation -> (this as AbstractKotlinCompilation<*>).disambiguateName(simpleName)
|
||||
is KotlinNativeVariantCompilationData -> owner.disambiguateName(simpleName)
|
||||
else -> lowerCamelCaseName(
|
||||
this.compilationClassifier,
|
||||
this.compilationPurpose.takeIf { it != KotlinCompilation.MAIN_COMPILATION_NAME },
|
||||
simpleName
|
||||
)
|
||||
}
|
||||
+54
-30
@@ -9,49 +9,58 @@ package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||
import groovy.lang.Closure
|
||||
import org.gradle.api.Action
|
||||
import org.gradle.api.NamedDomainObjectContainer
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.util.ConfigureUtil
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinNativeFragmentMetadataCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.getVisibleSourceSetsFromAssociateCompilations
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.getMetadataCompilationForSourceSet
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinNativeCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import java.io.File
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
internal class NativeCompileOptions(languageSettingsProvider: () -> LanguageSettingsBuilder) : KotlinCommonOptions {
|
||||
private val languageSettings: LanguageSettingsBuilder by lazy(languageSettingsProvider)
|
||||
|
||||
override var apiVersion: String?
|
||||
get() = languageSettings.apiVersion
|
||||
set(value) {
|
||||
languageSettings.apiVersion = value
|
||||
}
|
||||
|
||||
override var languageVersion: String?
|
||||
get() = languageSettings.languageVersion
|
||||
set(value) {
|
||||
languageSettings.languageVersion = value
|
||||
}
|
||||
|
||||
override var useFir: Boolean
|
||||
get() = false
|
||||
set(@Suppress("UNUSED_PARAMETER") value) {}
|
||||
|
||||
override var allWarningsAsErrors: Boolean = false
|
||||
override var suppressWarnings: Boolean = false
|
||||
override var verbose: Boolean = false
|
||||
|
||||
override var freeCompilerArgs: List<String> = listOf()
|
||||
}
|
||||
|
||||
abstract class AbstractKotlinNativeCompilation(
|
||||
target: KotlinTarget,
|
||||
val konanTarget: KonanTarget,
|
||||
override val konanTarget: KonanTarget,
|
||||
compilationName: String
|
||||
) : AbstractKotlinCompilation<KotlinCommonOptions>(target, compilationName) {
|
||||
) : AbstractKotlinCompilation<KotlinCommonOptions>(target, compilationName), KotlinNativeCompilationData<KotlinCommonOptions> {
|
||||
|
||||
override val kotlinOptions: KotlinCommonOptions = NativeCompileOptions { defaultSourceSet.languageSettings }
|
||||
|
||||
private class NativeCompileOptions(languageSettingsProvider: () -> LanguageSettingsBuilder) : KotlinCommonOptions {
|
||||
private val languageSettings: LanguageSettingsBuilder by lazy(languageSettingsProvider)
|
||||
|
||||
override var apiVersion: String?
|
||||
get() = languageSettings.apiVersion
|
||||
set(value) { languageSettings.apiVersion = value }
|
||||
|
||||
override var languageVersion: String?
|
||||
get() = languageSettings.languageVersion
|
||||
set(value) { languageSettings.languageVersion = value }
|
||||
|
||||
override var useFir: Boolean
|
||||
get() = false
|
||||
set(@Suppress("UNUSED_PARAMETER") value) {}
|
||||
|
||||
override var allWarningsAsErrors: Boolean = false
|
||||
override var suppressWarnings: Boolean = false
|
||||
override var verbose: Boolean = false
|
||||
|
||||
override var freeCompilerArgs: List<String> = listOf()
|
||||
}
|
||||
|
||||
override val compileKotlinTask: KotlinNativeCompile
|
||||
get() = super.compileKotlinTask as KotlinNativeCompile
|
||||
|
||||
@@ -59,14 +68,25 @@ abstract class AbstractKotlinNativeCompilation(
|
||||
override val compileKotlinTaskProvider: TaskProvider<out KotlinNativeCompile>
|
||||
get() = super.compileKotlinTaskProvider as TaskProvider<out KotlinNativeCompile>
|
||||
|
||||
override fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Lazy<Boolean>) =
|
||||
compileKotlinTaskProvider.configure { task ->
|
||||
task.source(sourceSet.kotlin)
|
||||
task.commonSources.from(target.project.files(Callable { if (addAsCommonSources.value) sourceSet.kotlin else emptyList<Any>() }))
|
||||
}
|
||||
override fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Lazy<Boolean>) {
|
||||
addSourcesToKotlinNativeCompileTask(project, compileKotlinTaskName, { sourceSet.kotlin }, addAsCommonSources)
|
||||
}
|
||||
|
||||
// Endorsed library controller.
|
||||
var enableEndorsedLibs: Boolean = false
|
||||
override var enableEndorsedLibs: Boolean = false
|
||||
}
|
||||
|
||||
internal fun addSourcesToKotlinNativeCompileTask(
|
||||
project: Project,
|
||||
taskName: String,
|
||||
sourceFiles: () -> Iterable<File>,
|
||||
addAsCommonSources: Lazy<Boolean>
|
||||
) {
|
||||
project.tasks.withType(KotlinNativeCompile::class.java).matching { it.name == taskName }.configureEach { task ->
|
||||
task.source(sourceFiles)
|
||||
task.commonSources.from(project.files(Callable { if (addAsCommonSources.value) sourceFiles() else emptyList() }))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class KotlinNativeCompilation(
|
||||
@@ -117,6 +137,7 @@ class KotlinNativeCompilation(
|
||||
}
|
||||
|
||||
class KotlinSharedNativeCompilation(override val target: KotlinMetadataTarget, val konanTargets: List<KonanTarget>, name: String) :
|
||||
KotlinNativeFragmentMetadataCompilationData,
|
||||
AbstractKotlinNativeCompilation(
|
||||
target,
|
||||
// TODO: this will end up as '-target' argument passed to K2Native, which is wrong.
|
||||
@@ -137,4 +158,7 @@ class KotlinSharedNativeCompilation(override val target: KotlinMetadataTarget, v
|
||||
}
|
||||
project.files(friendSourceSets.mapNotNull { project.getMetadataCompilationForSourceSet(it)?.output?.classesDirs })
|
||||
})
|
||||
|
||||
override val isActive: Boolean
|
||||
get() = true // old plugin only creates necessary compilations
|
||||
}
|
||||
|
||||
+40
-16
@@ -10,13 +10,14 @@ import org.gradle.api.NamedDomainObjectContainer
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Dependency
|
||||
import org.gradle.api.attributes.Attribute
|
||||
import org.gradle.api.attributes.Usage
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.gradle.util.WrapUtil
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.isNativeShared
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.variantsContainingFragment
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.*
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.filesWithUnpackedArchives
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
|
||||
@@ -136,26 +137,49 @@ open class KotlinNativeTarget @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun getHostSpecificSourceSets(project: Project): List<KotlinSourceSet> {
|
||||
val compilationsBySourceSet = CompilationSourceSetUtil.compilationsBySourceSets(project)
|
||||
private val hostManager by lazy { HostManager() }
|
||||
|
||||
val enabledByHost = HostManager().enabledByHost
|
||||
private fun isHostSpecificKonanTargetsSet(konanTargets: Iterable<KonanTarget>): Boolean {
|
||||
val enabledByHost = hostManager.enabledByHost
|
||||
val allHosts = enabledByHost.keys
|
||||
|
||||
fun canBeBuiltOnHosts(konanTarget: KonanTarget) = enabledByHost.filterValues { konanTarget in it }.keys
|
||||
return konanTargets.flatMapTo(mutableSetOf(), ::canBeBuiltOnHosts) != allHosts
|
||||
}
|
||||
|
||||
return project.kotlinExtension.sourceSets.filter { sourceSet ->
|
||||
if (sourceSet !in compilationsBySourceSet) return@filter false
|
||||
private fun <T> getHostSpecificElements(
|
||||
fragments: Iterable<T>,
|
||||
isNativeShared: (T) -> Boolean,
|
||||
getKonanTargets: (T) -> Set<KonanTarget>
|
||||
): Set<T> = fragments.filterTo(mutableSetOf()) { isNativeShared(it) && isHostSpecificKonanTargetsSet(getKonanTargets(it)) }
|
||||
|
||||
// If the source set participates in compilations such that some host can't run either of them, then on that host,
|
||||
// we can't analyze the source set, so the source set's metadata can't be published from that host, and therefore
|
||||
// we consider it platform-specific and publish as a part of the Native targets where the source set takes part,
|
||||
// not the common metadata artifact;
|
||||
val platformCompilations = compilationsBySourceSet.getValue(sourceSet).filter { it !is KotlinMetadataCompilation }
|
||||
val nativeCompilations = platformCompilations.filterIsInstance<KotlinNativeCompilation>()
|
||||
val nativeEnabledOn = nativeCompilations.flatMapTo(mutableSetOf()) { compilation -> canBeBuiltOnHosts(compilation.konanTarget) }
|
||||
platformCompilations == nativeCompilations && allHosts != nativeEnabledOn
|
||||
internal fun getHostSpecificFragments(
|
||||
module: KotlinGradleModule
|
||||
): Set<KotlinGradleFragment> = getHostSpecificElements<KotlinGradleFragment>(
|
||||
module.fragments,
|
||||
isNativeShared = { it.isNativeShared() },
|
||||
getKonanTargets = {
|
||||
val nativeVariants = module.variantsContainingFragment(it).filterIsInstance<KotlinNativeVariantInternal>()
|
||||
nativeVariants.mapTo(mutableSetOf()) { it.konanTarget }
|
||||
}
|
||||
)
|
||||
|
||||
internal fun getHostSpecificSourceSets(project: Project): Set<KotlinSourceSet> {
|
||||
val compilationsBySourceSet = CompilationSourceSetUtil.compilationsBySourceSets(project).mapValues { (_, compilations) ->
|
||||
compilations.filter { it !is KotlinMetadataCompilation<*> }
|
||||
}
|
||||
|
||||
return getHostSpecificElements(
|
||||
project.kotlinExtension.sourceSets,
|
||||
isNativeShared = { sourceSet ->
|
||||
val compilations = compilationsBySourceSet[sourceSet].orEmpty()
|
||||
compilations.isNotEmpty() && compilations.all { it.platformType == KotlinPlatformType.native }
|
||||
},
|
||||
getKonanTargets = { sourceSet ->
|
||||
compilationsBySourceSet[sourceSet].orEmpty()
|
||||
.filterIsInstance<KotlinNativeCompilation>()
|
||||
.mapTo(mutableSetOf()) { it.konanTarget }
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
abstract class KotlinNativeTargetWithTests<T : KotlinNativeBinaryTestRun>(
|
||||
|
||||
+47
-35
@@ -7,6 +7,7 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.NamedDomainObjectCollection
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
@@ -29,6 +30,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.TEST_COMPI
|
||||
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.registerAssembleAppleFrameworkTask
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.*
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
|
||||
import org.jetbrains.kotlin.gradle.targets.native.*
|
||||
import org.jetbrains.kotlin.gradle.targets.native.internal.commonizeCInteropTask
|
||||
@@ -51,10 +53,10 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
|
||||
createTestCompilation = true
|
||||
) {
|
||||
private fun Project.klibOutputDirectory(
|
||||
compilation: AbstractKotlinNativeCompilation
|
||||
compilation: KotlinCompilationData<*>
|
||||
): File {
|
||||
val targetSubDirectory = compilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty()
|
||||
return buildDir.resolve("classes/kotlin/$targetSubDirectory${compilation.name}")
|
||||
val targetSubDirectory = compilation.compilationClassifier?.let { "$it/" }.orEmpty()
|
||||
return buildDir.resolve("classes/kotlin/$targetSubDirectory${compilation.compilationPurpose}")
|
||||
}
|
||||
|
||||
private fun addCompilerPlugins(compilation: AbstractKotlinNativeCompilation) {
|
||||
@@ -73,9 +75,25 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
|
||||
}
|
||||
}
|
||||
|
||||
// region Artifact creation.
|
||||
private val KotlinNativeCompilationData<*>.apiElementsConfigurationName: String
|
||||
get() = when (val dataOwner = owner) {
|
||||
is KotlinGradleVariant -> dataOwner.apiElementsConfigurationName
|
||||
is KotlinTarget -> dataOwner.apiElementsConfigurationName
|
||||
else -> error("unexpected owner of $this")
|
||||
}
|
||||
|
||||
internal fun Project.createRegularKlibArtifact(
|
||||
compilation: KotlinNativeCompilationData<*>,
|
||||
compileTask: TaskProvider<out KotlinNativeCompile>
|
||||
) = createKlibArtifact(compilation, compileTask.map { it.outputFile.get() }, null, compileTask)
|
||||
|
||||
internal fun Project.createCInteropKlibArtifact(
|
||||
interop: DefaultCInteropSettings,
|
||||
interopTask: TaskProvider<out CInteropProcess>
|
||||
) = createKlibArtifact(interop.compilation, interopTask.map { it.outputFile }, "cinterop-${interop.name}", interopTask, copy = true)
|
||||
|
||||
private fun Project.createKlibArtifact(
|
||||
compilation: KotlinNativeCompilation,
|
||||
compilation: KotlinNativeCompilationData<*>,
|
||||
artifactFile: Provider<File>,
|
||||
classifier: String?,
|
||||
producingTask: TaskProvider<*>,
|
||||
@@ -85,14 +103,14 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
|
||||
return
|
||||
}
|
||||
|
||||
val apiElements = configurations.getByName(compilation.target.apiElementsConfigurationName)
|
||||
val apiElements = configurations.getByName(compilation.apiElementsConfigurationName)
|
||||
|
||||
val realProducingTask: TaskProvider<*>
|
||||
// TODO: Someone remove this HACK PLEASE!
|
||||
val realArtifactFile = if (copy) {
|
||||
realProducingTask = project.registerTask<Copy>("copy${producingTask.name.capitalize()}") {
|
||||
val targetSubDirectory = compilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty()
|
||||
it.destinationDir = project.buildDir.resolve("libs/$targetSubDirectory${compilation.name}")
|
||||
val targetSubDirectory = compilation.compilationClassifier?.let { "$it/" }.orEmpty()
|
||||
it.destinationDir = project.buildDir.resolve("libs/$targetSubDirectory${compilation.compilationPurpose}")
|
||||
it.from(artifactFile)
|
||||
it.dependsOn(producingTask)
|
||||
}
|
||||
@@ -104,7 +122,7 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
|
||||
|
||||
with(apiElements) {
|
||||
val klibArtifact = project.artifacts.add(apiElements.name, realArtifactFile) { artifact ->
|
||||
artifact.name = compilation.name
|
||||
artifact.name = compilation.compilationPurpose
|
||||
artifact.extension = "klib"
|
||||
artifact.type = "klib"
|
||||
artifact.classifier = classifier
|
||||
@@ -115,18 +133,6 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
|
||||
attributes.attribute(ArtifactAttributes.ARTIFACT_FORMAT, NativeArtifactFormat.KLIB)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.createRegularKlibArtifact(
|
||||
compilation: KotlinNativeCompilation,
|
||||
compileTask: TaskProvider<out KotlinNativeCompile>
|
||||
) = createKlibArtifact(compilation, compileTask.map { it.outputFile.get() }, null, compileTask)
|
||||
|
||||
private fun Project.createCInteropKlibArtifact(
|
||||
interop: DefaultCInteropSettings,
|
||||
interopTask: TaskProvider<out CInteropProcess>
|
||||
) = createKlibArtifact(interop.compilation, interopTask.map { it.outputFile }, "cinterop-${interop.name}", interopTask, copy = true)
|
||||
// endregion.
|
||||
|
||||
// region Task creation.
|
||||
private fun Project.createLinkTask(binary: NativeBinary) {
|
||||
val result = registerTask<KotlinNativeLink>(
|
||||
@@ -258,12 +264,12 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Project.createKlibCompilationTask(compilation: AbstractKotlinNativeCompilation): TaskProvider<KotlinNativeCompile> {
|
||||
internal fun Project.createKlibCompilationTask(compilation: KotlinNativeCompilationData<*>): TaskProvider<KotlinNativeCompile> {
|
||||
val compileTaskProvider = registerTask<KotlinNativeCompile>(
|
||||
compilation.compileKotlinTaskName, listOf(compilation)
|
||||
) {
|
||||
it.group = BasePlugin.BUILD_GROUP
|
||||
it.description = "Compiles a klibrary from the '${compilation.name}' " +
|
||||
it.description = "Compiles a klibrary from the '${compilation.compilationPurpose}' " +
|
||||
"compilation for target '${compilation.platformType.name}'."
|
||||
it.enabled = compilation.konanTarget.enabledOnCurrentHost
|
||||
|
||||
@@ -275,33 +281,39 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
|
||||
project.files(compileTaskProvider.map { it.outputFile })
|
||||
}
|
||||
|
||||
|
||||
project.tasks.getByName(compilation.compileAllTaskName).dependsOn(compileTaskProvider)
|
||||
|
||||
if (compilation.isMain()) {
|
||||
compilation as? KotlinNativeCompilation ?: error("Main shared-Native compilation is not yet supported!")
|
||||
|
||||
project.tasks.getByName(compilation.target.artifactsTaskName).apply {
|
||||
dependsOn(compileTaskProvider)
|
||||
if (compilation.isMainCompilationData()) {
|
||||
if (compilation is KotlinNativeCompilation) {
|
||||
project.tasks.getByName(compilation.target.artifactsTaskName).apply {
|
||||
dependsOn(compileTaskProvider)
|
||||
}
|
||||
}
|
||||
|
||||
project.tasks.getByName(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).apply {
|
||||
dependsOn(compileTaskProvider)
|
||||
}
|
||||
createRegularKlibArtifact(compilation, compileTaskProvider)
|
||||
}
|
||||
addCompilerPlugins(compilation)
|
||||
|
||||
if (compilation is AbstractKotlinNativeCompilation) {
|
||||
// FIXME: support compiler plugins for PM20
|
||||
addCompilerPlugins(compilation)
|
||||
}
|
||||
|
||||
return compileTaskProvider
|
||||
}
|
||||
|
||||
private fun Project.createCInteropTasks(compilation: KotlinNativeCompilation) {
|
||||
compilation.cinterops.all { interop ->
|
||||
// FIXME support creating interop tasks for PM20
|
||||
private fun Project.createCInteropTasks(
|
||||
compilation: KotlinNativeCompilation,
|
||||
cinterops: NamedDomainObjectCollection<DefaultCInteropSettings>
|
||||
) {
|
||||
cinterops.all { interop ->
|
||||
val interopTask = registerTask<CInteropProcess>(interop.interopProcessingTaskName, listOf(interop)) {
|
||||
it.destinationDir = provider { klibOutputDirectory(compilation).resolve("cinterop") }
|
||||
it.group = INTEROP_GROUP
|
||||
it.description = "Generates Kotlin/Native interop library '${interop.name}' " +
|
||||
"for compilation '${compilation.name}'" +
|
||||
"for compilation '${compilation.compilationPurpose}'" +
|
||||
"of target '${it.konanTarget.name}'."
|
||||
it.enabled = compilation.konanTarget.enabledOnCurrentHost
|
||||
}
|
||||
@@ -377,7 +389,7 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
|
||||
|
||||
protected fun configureCInterops(target: KotlinNativeTarget): Unit = with(target.project) {
|
||||
target.compilations.all { compilation ->
|
||||
createCInteropTasks(compilation)
|
||||
createCInteropTasks(compilation, compilation.cinterops)
|
||||
compilation.cinterops.all {
|
||||
defineConfigurationsForCInterop(compilation, it, target, configurations)
|
||||
}
|
||||
|
||||
+2
-1
@@ -172,7 +172,8 @@ private fun CInteropProcess.toGist(): CInteropGist {
|
||||
return CInteropGist(
|
||||
identifier = settings.identifier,
|
||||
konanTarget = konanTarget,
|
||||
sourceSets = project.provider { settings.compilation.kotlinSourceSetsIncludingDefault },
|
||||
// FIXME support cinterop with PM20
|
||||
sourceSets = project.provider { (settings.compilation as? KotlinCompilation<*>)?.kotlinSourceSetsIncludingDefault },
|
||||
libraryFile = outputFileProvider,
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -6,7 +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.gradle.utils.UnsafeApi
|
||||
import java.io.Serializable
|
||||
|
||||
@@ -20,7 +20,7 @@ internal data class CInteropIdentifier internal constructor(
|
||||
class Scope @UnsafeApi internal constructor(val name: String) : Serializable {
|
||||
companion object {
|
||||
@OptIn(UnsafeApi::class)
|
||||
fun create(compilation: KotlinCompilation<*>): Scope {
|
||||
fun create(compilation: KotlinCompilationData<*>): Scope {
|
||||
return Scope("compilation/${compilation.compileKotlinTaskName}")
|
||||
}
|
||||
}
|
||||
|
||||
+16
-12
@@ -26,6 +26,9 @@ import org.jetbrains.kotlin.gradle.internal.ensureParentDirsCreated
|
||||
import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
|
||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.asValidFrameworkName
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||
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.targets.native.internal.isAllowCommonizer
|
||||
import org.jetbrains.kotlin.gradle.utils.getValue
|
||||
@@ -113,7 +116,7 @@ private fun Collection<File>.filterKlibsPassedToCompiler(project: Project) = fil
|
||||
}
|
||||
|
||||
// endregion
|
||||
abstract class AbstractKotlinNativeCompile<T : KotlinCommonToolOptions, K : AbstractKotlinNativeCompilation> : AbstractCompile() {
|
||||
abstract class AbstractKotlinNativeCompile<T : KotlinCommonToolOptions, K : KotlinNativeCompilationData<*>> : AbstractCompile() {
|
||||
@get:Internal
|
||||
abstract val compilation: K
|
||||
|
||||
@@ -139,7 +142,7 @@ abstract class AbstractKotlinNativeCompile<T : KotlinCommonToolOptions, K : Abst
|
||||
}
|
||||
|
||||
private val isSharedCompilation by project.provider {
|
||||
compilation is KotlinSharedNativeCompilation
|
||||
compilation is KotlinNativeFragmentMetadataCompilationData
|
||||
}
|
||||
|
||||
// Inputs and outputs
|
||||
@@ -178,7 +181,7 @@ abstract class AbstractKotlinNativeCompile<T : KotlinCommonToolOptions, K : Abst
|
||||
|
||||
@get:Internal
|
||||
val languageSettings: LanguageSettingsBuilder by project.provider {
|
||||
compilation.defaultSourceSet.languageSettings
|
||||
compilation.languageSettings
|
||||
}
|
||||
|
||||
@get:Input
|
||||
@@ -233,7 +236,7 @@ abstract class AbstractKotlinNativeCompile<T : KotlinCommonToolOptions, K : Abst
|
||||
get() = buildCommonArgs(true)
|
||||
|
||||
private val languageSettingsBuilder by project.provider {
|
||||
compilation.defaultSourceSet.languageSettings
|
||||
compilation.languageSettings
|
||||
}
|
||||
|
||||
// Args used by both the compiler and IDEA.
|
||||
@@ -343,8 +346,8 @@ open class KotlinNativeCompile
|
||||
constructor(
|
||||
@Internal
|
||||
@Transient // can't be serialized for Gradle configuration cache
|
||||
final override val compilation: AbstractKotlinNativeCompilation
|
||||
) : AbstractKotlinNativeCompile<KotlinCommonOptions, AbstractKotlinNativeCompilation>(),
|
||||
final override val compilation: KotlinNativeCompilationData<*>
|
||||
) : AbstractKotlinNativeCompile<KotlinCommonOptions, KotlinNativeCompilationData<*>>(),
|
||||
KotlinCompile<KotlinCommonOptions> {
|
||||
|
||||
@get:Input
|
||||
@@ -357,7 +360,11 @@ constructor(
|
||||
override val debuggable = true
|
||||
|
||||
@get:Internal
|
||||
override val baseName: String by project.provider { if (compilation.isMain()) project.name else "${project.name}_${compilation.name}" }
|
||||
override val baseName: String by project.provider {
|
||||
if (compilation.isMainCompilationData())
|
||||
project.name
|
||||
else "${project.name}_${compilation.compilationPurpose}"
|
||||
}
|
||||
|
||||
// Store as an explicit provider in order to allow Gradle Instant Execution to capture the state
|
||||
// private val allSourceProvider = compilation.map { project.files(it.allSources).asFileTree }
|
||||
@@ -390,10 +397,7 @@ constructor(
|
||||
|
||||
|
||||
private val friendModule: FileCollection by project.provider {
|
||||
project.files(
|
||||
compilation.associateWithTransitiveClosure.map { it.output.allOutputs },
|
||||
compilation.friendArtifacts
|
||||
)
|
||||
project.files(compilation.friendPaths)
|
||||
}
|
||||
// endregion.
|
||||
|
||||
@@ -934,7 +938,7 @@ open class CInteropProcess @Inject constructor(@get:Internal val settings: Defau
|
||||
val baseKlibName: String
|
||||
@Input get() {
|
||||
val compilationPrefix = settings.compilation.let {
|
||||
if (it.isMain()) project.name else it.name
|
||||
if (it.isMainCompilationData()) project.name else it.compilationPurpose
|
||||
}
|
||||
return "$compilationPrefix-cinterop-$interopName"
|
||||
}
|
||||
|
||||
+10
-13
@@ -24,8 +24,7 @@ import org.gradle.api.tasks.PathSensitivity
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
|
||||
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
|
||||
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompile
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.*
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptionsImpl
|
||||
import org.jetbrains.kotlin.gradle.dsl.fillDefaultValues
|
||||
import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles
|
||||
@@ -34,7 +33,8 @@ 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.KotlinCommonCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinFragmentMetadataCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.AbstractKotlinFragmentMetadataCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinMetadataCompilationData
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.refinesClosure
|
||||
import org.jetbrains.kotlin.gradle.utils.getValue
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||
@@ -63,7 +63,7 @@ open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompilerArgumen
|
||||
args.moduleName = this@KotlinCompileCommon.moduleName
|
||||
|
||||
if ((taskData.compilation as? KotlinCommonCompilation)?.isKlibCompilation == true ||
|
||||
taskData.compilation is KotlinFragmentMetadataCompilationData
|
||||
taskData.compilation is KotlinMetadataCompilationData
|
||||
) {
|
||||
args.expectActualLinker = true
|
||||
}
|
||||
@@ -84,13 +84,10 @@ open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompilerArgumen
|
||||
}
|
||||
|
||||
private fun outputPathsFromMetadataCompilationsOf(sourceSets: Iterable<KotlinSourceSet>): List<File> {
|
||||
val target = taskData.compilation.owner
|
||||
return when (target) {
|
||||
is KotlinTarget -> sourceSets
|
||||
.mapNotNull { sourceSet -> target.compilations.findByName(sourceSet.name)?.output?.classesDirs }
|
||||
.flatten()
|
||||
else -> error("unexpected compilation owner") // FIXME support PM20 variant
|
||||
}
|
||||
val metadataTarget = taskData.compilation.owner as KotlinTarget
|
||||
return sourceSets
|
||||
.mapNotNull { sourceSet -> metadataTarget.compilations.findByName(sourceSet.name)?.output?.classesDirs }
|
||||
.flatten()
|
||||
}
|
||||
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
@@ -101,7 +98,7 @@ open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompilerArgumen
|
||||
val defaultKotlinSourceSet: KotlinSourceSet = compilation.defaultSourceSet
|
||||
outputPathsFromMetadataCompilationsOf(defaultKotlinSourceSet.resolveAllDependsOnSourceSets())
|
||||
}
|
||||
is KotlinFragmentMetadataCompilationData -> {
|
||||
is AbstractKotlinFragmentMetadataCompilationData -> {
|
||||
val fragment = compilation.fragment
|
||||
project.files(
|
||||
fragment.refinesClosure.minus(fragment).map {
|
||||
@@ -109,7 +106,7 @@ open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompilerArgumen
|
||||
}
|
||||
)
|
||||
}
|
||||
else -> error("unexpected compilation type") // FIXME support PM20 variant
|
||||
else -> error("unexpected compilation type")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,15 +25,15 @@ interface KotlinDependencyGraphResolver {
|
||||
fun resolveDependencyGraph(requestingModule: KotlinModule): DependencyGraphResolution
|
||||
}
|
||||
|
||||
sealed class DependencyGraphResolution(val requestingModule: KotlinModule) {
|
||||
sealed class DependencyGraphResolution(open val requestingModule: KotlinModule) {
|
||||
class Unknown(requestingModule: KotlinModule) : DependencyGraphResolution(requestingModule)
|
||||
class DependencyGraph(requestingModule: KotlinModule, val root: DependencyGraphNode): DependencyGraphResolution(requestingModule)
|
||||
open class DependencyGraph(requestingModule: KotlinModule, open val root: DependencyGraphNode): DependencyGraphResolution(requestingModule)
|
||||
}
|
||||
|
||||
// TODO: should this be a single graph for all dependency scopes as well, not just for all fragments?
|
||||
class DependencyGraphNode(
|
||||
val module: KotlinModule,
|
||||
val dependenciesByFragment: Map<KotlinModuleFragment, Iterable<DependencyGraphNode>>
|
||||
open class DependencyGraphNode(
|
||||
open val module: KotlinModule,
|
||||
open val dependenciesByFragment: Map<KotlinModuleFragment, Iterable<DependencyGraphNode>>
|
||||
) {
|
||||
override fun toString(): String = "node ${module}"
|
||||
}
|
||||
Reference in New Issue
Block a user