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.Named
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
||||||
|
|
||||||
interface CInteropSettings : Named {
|
interface CInteropSettings : Named {
|
||||||
|
|
||||||
@@ -22,7 +23,7 @@ interface CInteropSettings : Named {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Provide an interface for native compilations.
|
// TODO: Provide an interface for native compilations.
|
||||||
val compilation: KotlinCompilation<KotlinCommonOptions>
|
val compilation: KotlinCompilationData<out KotlinCommonOptions>
|
||||||
|
|
||||||
val dependencyConfigurationName: String
|
val dependencyConfigurationName: String
|
||||||
var dependencyFiles: FileCollection
|
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.model.builder.KotlinModelBuilder
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinCompilationData
|
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.scripting.internal.ScriptingGradleSubplugin
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode
|
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsBinaryMode
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.ir.*
|
import org.jetbrains.kotlin.gradle.targets.js.ir.*
|
||||||
@@ -281,7 +281,7 @@ internal class Kotlin2JsSourceSetProcessor(
|
|||||||
kotlinOptions.freeCompilerArgs.contains(PRODUCE_ZIPPED_KLIB)
|
kotlinOptions.freeCompilerArgs.contains(PRODUCE_ZIPPED_KLIB)
|
||||||
) {
|
) {
|
||||||
// Configure FQ module name to avoid cyclic dependencies in klib manifests (see KT-36721).
|
// 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
|
project.name
|
||||||
} else {
|
} else {
|
||||||
"${project.name}_${kotlinCompilation.compilationPurpose}"
|
"${project.name}_${kotlinCompilation.compilationPurpose}"
|
||||||
@@ -366,7 +366,7 @@ internal class KotlinCommonSourceSetProcessor(
|
|||||||
override fun doTargetSpecificProcessing() {
|
override fun doTargetSpecificProcessing() {
|
||||||
project.tasks.named(kotlinCompilation.compileAllTaskName).dependsOn(kotlinTask)
|
project.tasks.named(kotlinCompilation.compileAllTaskName).dependsOn(kotlinTask)
|
||||||
// can be missing (e.g. in case of tests)
|
// 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)
|
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)
|
val compileClasspath = getCompileDependenciesConfigurationForVariant(project, requestingVariant)
|
||||||
|
|
||||||
// TODO optimize O(n) search, store the mapping
|
val dependencyModuleId = dependencyModule.moduleIdentifier
|
||||||
val component = compileClasspath.incoming.resolutionResult.allComponents.find { it.id.matchesModule(dependencyModule) }
|
|
||||||
?: return VariantResolution.NotRequested(requestingVariant, dependencyModule)
|
|
||||||
|
|
||||||
val dependencyModuleId = ModuleIds.fromComponent(project, component)
|
|
||||||
// FIXME check composite builds, it's likely that resolvedVariantProvider fails on them?
|
// FIXME check composite builds, it's likely that resolvedVariantProvider fails on them?
|
||||||
val resolvedGradleVariantName = resolvedVariantProvider.getResolvedVariantName(dependencyModuleId, compileClasspath)
|
val resolvedGradleVariantName = resolvedVariantProvider.getResolvedVariantName(dependencyModuleId, compileClasspath)
|
||||||
val kotlinVariantName = when (dependencyModule) {
|
val kotlinVariantName = when (dependencyModule) {
|
||||||
@@ -323,7 +319,7 @@ class GradleModuleVariantResolver(val project: Project) : ModuleVariantResolver
|
|||||||
project.configurations.getByName(compilation.compileDependencyConfigurationName)
|
project.configurations.getByName(compilation.compileDependencyConfigurationName)
|
||||||
}
|
}
|
||||||
is KotlinPm20ProjectExtension -> {
|
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")
|
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)
|
GlobalProjectStructureMetadataStorage.getProjectStructureMetadata(project, id.build.name, id.projectPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
private open class JarArtifactMppDependencyMetadataExtractor(
|
internal open class JarArtifactMppDependencyMetadataExtractor(
|
||||||
project: Project,
|
project: Project,
|
||||||
dependency: ResolvedComponentResult,
|
dependency: ResolvedComponentResult,
|
||||||
val primaryArtifact: File
|
val primaryArtifact: File
|
||||||
@@ -602,7 +602,7 @@ private fun mppDependencyMetadataExtractor(
|
|||||||
return when {
|
return when {
|
||||||
moduleId is ProjectComponentIdentifier -> when {
|
moduleId is ProjectComponentIdentifier -> when {
|
||||||
moduleId.build.isCurrentBuild ->
|
moduleId.build.isCurrentBuild ->
|
||||||
ProjectMppDependencyMetadataExtractor(project, actualComponent, project.project(moduleId.projectPath))
|
ProjectMppDependencyMetadataExtractor(project, actualComponent, moduleIdentifier, project.project(moduleId.projectPath))
|
||||||
metadataArtifact != null ->
|
metadataArtifact != null ->
|
||||||
IncludedBuildMetadataExtractor(project, actualComponent, metadataArtifact)
|
IncludedBuildMetadataExtractor(project, actualComponent, metadataArtifact)
|
||||||
else -> null
|
else -> null
|
||||||
|
|||||||
+4
-9
@@ -10,18 +10,16 @@ import com.google.gson.JsonObject
|
|||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
||||||
import com.google.gson.stream.JsonWriter
|
import com.google.gson.stream.JsonWriter
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.provider.Provider
|
|
||||||
import org.gradle.api.tasks.Input
|
import org.gradle.api.tasks.Input
|
||||||
import org.gradle.api.tasks.Internal
|
import org.gradle.api.tasks.Internal
|
||||||
import org.gradle.api.tasks.Nested
|
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.multiplatformExtensionOrNull
|
||||||
import org.jetbrains.kotlin.gradle.dsl.topLevelExtension
|
|
||||||
import org.jetbrains.kotlin.gradle.dsl.topLevelExtensionOrNull
|
import org.jetbrains.kotlin.gradle.dsl.topLevelExtensionOrNull
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.KotlinGradleModule
|
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.KotlinPm20ProjectExtension
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.refinesClosure
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.refinesClosure
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.KotlinDependencyScope
|
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.plugin.sources.sourceSetDependencyConfigurationByScope
|
||||||
import org.jetbrains.kotlin.gradle.targets.metadata.dependsOnClosureWithInterCompilationDependencies
|
import org.jetbrains.kotlin.gradle.targets.metadata.dependsOnClosureWithInterCompilationDependencies
|
||||||
import org.jetbrains.kotlin.gradle.targets.metadata.getPublishedPlatformCompilations
|
import org.jetbrains.kotlin.gradle.targets.metadata.getPublishedPlatformCompilations
|
||||||
@@ -133,10 +131,7 @@ data class KotlinProjectStructureMetadata(
|
|||||||
|
|
||||||
internal fun buildKotlinProjectStructureMetadata(project: Project): KotlinProjectStructureMetadata? {
|
internal fun buildKotlinProjectStructureMetadata(project: Project): KotlinProjectStructureMetadata? {
|
||||||
val topLevelExtensionOrNull = project.topLevelExtensionOrNull
|
val topLevelExtensionOrNull = project.topLevelExtensionOrNull
|
||||||
if (topLevelExtensionOrNull is KotlinPm20ProjectExtension) {
|
require(topLevelExtensionOrNull is KotlinMultiplatformExtension) { "this function only works with the stable plugin" }
|
||||||
// FIXME: get module by ID, don't just take the main module
|
|
||||||
return buildProjectStructureMetadata(topLevelExtensionOrNull.main)
|
|
||||||
}
|
|
||||||
|
|
||||||
val sourceSetsWithMetadataCompilations =
|
val sourceSetsWithMetadataCompilations =
|
||||||
project.multiplatformExtensionOrNull?.targets?.getByName(KotlinMultiplatformPlugin.METADATA_TARGET_NAME)?.compilations?.associate {
|
project.multiplatformExtensionOrNull?.targets?.getByName(KotlinMultiplatformPlugin.METADATA_TARGET_NAME)?.compilations?.associate {
|
||||||
@@ -195,7 +190,7 @@ internal fun buildProjectStructureMetadata(module: KotlinGradleModule): KotlinPr
|
|||||||
val kotlinFragmentsPerKotlinVariant =
|
val kotlinFragmentsPerKotlinVariant =
|
||||||
module.variants.associate { variant -> variant.name to variant.refinesClosure.map { it.name }.toSet() }
|
module.variants.associate { variant -> variant.name to variant.refinesClosure.map { it.name }.toSet() }
|
||||||
val fragmentRefinesRelation =
|
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 native implementation-as-api-dependencies
|
||||||
// FIXME: support dependencies on auxiliary modules
|
// FIXME: support dependencies on auxiliary modules
|
||||||
@@ -211,7 +206,7 @@ internal fun buildProjectStructureMetadata(module: KotlinGradleModule): KotlinPr
|
|||||||
fragmentRefinesRelation,
|
fragmentRefinesRelation,
|
||||||
module.fragments.associate { it.name to SourceSetMetadataLayout.KLIB },
|
module.fragments.associate { it.name to SourceSetMetadataLayout.KLIB },
|
||||||
fragmentDependencies,
|
fragmentDependencies,
|
||||||
emptySet(),
|
getHostSpecificFragments(module).mapTo(mutableSetOf()) { it.name },
|
||||||
isPublishedAsRoot = true
|
isPublishedAsRoot = true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -288,7 +288,7 @@ abstract class AbstractKotlinCompilation<T : KotlinCommonOptions>(
|
|||||||
override val project: Project
|
override val project: Project
|
||||||
get() = target.project
|
get() = target.project
|
||||||
|
|
||||||
override val owner: Any?
|
override val owner: KotlinTarget
|
||||||
get() = target
|
get() = target
|
||||||
|
|
||||||
override val compilationClassifier: String?
|
override val compilationClassifier: String?
|
||||||
|
|||||||
+35
-9
@@ -39,15 +39,18 @@ class GradleKotlinDependencyGraphResolver(
|
|||||||
configurationToResolveMetadataDependencies(project, requestingModule)
|
configurationToResolveMetadataDependencies(project, requestingModule)
|
||||||
|
|
||||||
override fun resolveDependencyGraph(requestingModule: KotlinModule): DependencyGraphResolution {
|
override fun resolveDependencyGraph(requestingModule: KotlinModule): DependencyGraphResolution {
|
||||||
if (!requestingModule.representsProject(project))
|
if (requestingModule !is KotlinGradleModule)
|
||||||
return DependencyGraphResolution.Unknown(requestingModule)
|
return DependencyGraphResolution.Unknown(requestingModule)
|
||||||
|
return resolveAsGraph(requestingModule)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolveAsGraph(requestingModule: KotlinGradleModule): GradleDependencyGraph {
|
||||||
val excludeLegacyMetadataModulesFromResult = mutableSetOf<ResolvedComponentResult>()
|
val excludeLegacyMetadataModulesFromResult = mutableSetOf<ResolvedComponentResult>()
|
||||||
|
|
||||||
val nodeByModuleId = mutableMapOf<KotlinModuleIdentifier, DependencyGraphNode>()
|
val nodeByModuleId = mutableMapOf<KotlinModuleIdentifier, GradleDependencyGraphNode>()
|
||||||
|
|
||||||
fun nodeFromComponent(component: ResolvedComponentResult, isRoot: Boolean /*refactor*/): DependencyGraphNode {
|
fun nodeFromComponent(component: ResolvedComponentResult, isRoot: Boolean /*refactor me*/): GradleDependencyGraphNode {
|
||||||
val id = component.toModuleIdentifier()
|
val id = component.toSingleModuleIdentifier()
|
||||||
return nodeByModuleId.getOrPut(id) {
|
return nodeByModuleId.getOrPut(id) {
|
||||||
val module = if (isRoot)
|
val module = if (isRoot)
|
||||||
requestingModule
|
requestingModule
|
||||||
@@ -55,14 +58,20 @@ class GradleKotlinDependencyGraphResolver(
|
|||||||
.takeIf { component !in excludeLegacyMetadataModulesFromResult }
|
.takeIf { component !in excludeLegacyMetadataModulesFromResult }
|
||||||
?: buildSyntheticModule(component, component.variants.singleOrNull()?.displayName ?: "default")
|
?: buildSyntheticModule(component, component.variants.singleOrNull()?.displayName ?: "default")
|
||||||
|
|
||||||
val componentContainingTransitiveDependencies =
|
val metadataSourceComponent =
|
||||||
(module as? ExternalImportedKotlinModule)
|
(module as? ExternalImportedKotlinModule)
|
||||||
?.takeIf { it.hasLegacyMetadataModule }
|
?.takeIf { it.hasLegacyMetadataModule }
|
||||||
?.let { (component.dependencies.singleOrNull() as? ResolvedDependencyResult)?.selected }
|
?.let { (component.dependencies.singleOrNull() as? ResolvedDependencyResult)?.selected }
|
||||||
?: component
|
?: component
|
||||||
|
|
||||||
val resolvedComponentDependencies = componentContainingTransitiveDependencies.dependencies
|
val dependenciesRequestedByModule =
|
||||||
|
module.fragments.flatMap { fragment -> fragment.declaredModuleDependencies.map { it.moduleIdentifier } }.toSet()
|
||||||
|
|
||||||
|
val resolvedComponentDependencies = metadataSourceComponent.dependencies
|
||||||
.filterIsInstance<ResolvedDependencyResult>()
|
.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 } }
|
.flatMap { dependency -> dependency.requested.toModuleIdentifiers().map { id -> id to dependency.selected } }
|
||||||
.toMap()
|
.toMap()
|
||||||
|
|
||||||
@@ -72,13 +81,30 @@ class GradleKotlinDependencyGraphResolver(
|
|||||||
deps.mapNotNull { resolvedComponentDependencies[it.moduleIdentifier] }.map { nodeFromComponent(it, isRoot = false) }
|
deps.mapNotNull { resolvedComponentDependencies[it.moduleIdentifier] }.map { nodeFromComponent(it, isRoot = false) }
|
||||||
}
|
}
|
||||||
|
|
||||||
DependencyGraphNode(module, nodeDependenciesMap)
|
GradleDependencyGraphNode(
|
||||||
|
module,
|
||||||
|
component,
|
||||||
|
metadataSourceComponent,
|
||||||
|
nodeDependenciesMap
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return DependencyGraphResolution.DependencyGraph(
|
return GradleDependencyGraph(
|
||||||
requestingModule,
|
requestingModule,
|
||||||
nodeFromComponent(configurationToResolve(requestingModule).incoming.resolutionResult.root, isRoot = true)
|
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(
|
internal class ExternalImportedKotlinModule(
|
||||||
private val moduleData: BasicKotlinModule,
|
private val moduleData: BasicKotlinModule,
|
||||||
val projectStructureMetadata: KotlinProjectStructureMetadata
|
val projectStructureMetadata: KotlinProjectStructureMetadata,
|
||||||
|
val hostSpecificFragments: Set<KotlinModuleFragment>
|
||||||
) : KotlinModule by moduleData {
|
) : KotlinModule by moduleData {
|
||||||
val hasLegacyMetadataModule = !projectStructureMetadata.isPublishedAsRoot
|
val hasLegacyMetadataModule = !projectStructureMetadata.isPublishedAsRoot
|
||||||
|
|
||||||
|
|||||||
+47
-21
@@ -51,14 +51,12 @@ internal class FragmentGranularMetadataResolver(
|
|||||||
if (dependencyGraph is DependencyGraphResolution.Unknown)
|
if (dependencyGraph is DependencyGraphResolution.Unknown)
|
||||||
error("unexpected failure in dependency graph resolution for $requestingFragment in $project")
|
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 fragmentsToInclude = requestingFragment.refinesClosure
|
||||||
val requestedDependencies = dependencyGraph.root.dependenciesByFragment.filterKeys { it in fragmentsToInclude }.values.flatten()
|
val requestedDependencies = dependencyGraph.root.dependenciesByFragment.filterKeys { it in fragmentsToInclude }.values.flatten()
|
||||||
|
|
||||||
val visited = mutableSetOf<DependencyGraphNode>()
|
val visited = mutableSetOf<GradleDependencyGraphNode>()
|
||||||
val fragmentResolutionQueue = ArrayDeque<DependencyGraphNode>().apply {
|
val fragmentResolutionQueue = ArrayDeque<GradleDependencyGraphNode>(requestedDependencies)
|
||||||
addAll(requestedDependencies)
|
|
||||||
}
|
|
||||||
|
|
||||||
val results = mutableSetOf<MetadataDependencyResolution>()
|
val results = mutableSetOf<MetadataDependencyResolution>()
|
||||||
|
|
||||||
@@ -69,18 +67,15 @@ internal class FragmentGranularMetadataResolver(
|
|||||||
val dependencyModule = dependencyNode.module
|
val dependencyModule = dependencyNode.module
|
||||||
|
|
||||||
val fragmentVisibility = fragmentResolver.getChosenFragments(requestingFragment, dependencyModule)
|
val fragmentVisibility = fragmentResolver.getChosenFragments(requestingFragment, dependencyModule)
|
||||||
val visibleFragments = (fragmentVisibility as? FragmentResolution.ChosenFragments)?.visibleFragments?.toList().orEmpty()
|
val chosenFragments = fragmentVisibility as? FragmentResolution.ChosenFragments
|
||||||
val variantResolutions =
|
val visibleFragments = chosenFragments?.visibleFragments?.toList().orEmpty()
|
||||||
(fragmentVisibility as? FragmentResolution.ChosenFragments)?.variantResolutions?.associateBy { it.requestingVariant }
|
|
||||||
|
|
||||||
val visibleTransitiveDependencies =
|
val visibleTransitiveDependencies =
|
||||||
dependencyNode.dependenciesByFragment.filterKeys { it in visibleFragments }.values.flattenTo(mutableSetOf())
|
dependencyNode.dependenciesByFragment.filterKeys { it in visibleFragments }.values.flattenTo(mutableSetOf())
|
||||||
|
|
||||||
//FIXME host-specific fragments
|
|
||||||
|
|
||||||
fragmentResolutionQueue.addAll(visibleTransitiveDependencies.filter { it !in visited })
|
fragmentResolutionQueue.addAll(visibleTransitiveDependencies.filter { it !in visited })
|
||||||
|
|
||||||
val resolvedComponentResult = resolvedComponentsByModuleId.getValue(dependencyModule.moduleIdentifier)
|
val resolvedComponentResult = dependencyNode.selectedComponent
|
||||||
val isResolvedAsProject = resolvedComponentResult.toProjectOrNull(project)
|
val isResolvedAsProject = resolvedComponentResult.toProjectOrNull(project)
|
||||||
val result = when (dependencyModule) {
|
val result = when (dependencyModule) {
|
||||||
is ExternalSyntheticKotlinModule -> {
|
is ExternalSyntheticKotlinModule -> {
|
||||||
@@ -90,14 +85,7 @@ internal class FragmentGranularMetadataResolver(
|
|||||||
val projectStructureMetadata = (dependencyModule as? ExternalImportedKotlinModule)?.projectStructureMetadata
|
val projectStructureMetadata = (dependencyModule as? ExternalImportedKotlinModule)?.projectStructureMetadata
|
||||||
?: checkNotNull(getProjectStructureMetadata(project, resolvedComponentResult, configurationToResolve))
|
?: checkNotNull(getProjectStructureMetadata(project, resolvedComponentResult, configurationToResolve))
|
||||||
|
|
||||||
// FIXME host-specific metadata!!!
|
val metadataSourceComponent = dependencyNode.run { metadataSourceComponent ?: selectedComponent }
|
||||||
|
|
||||||
val metadataSourceComponent = when {
|
|
||||||
dependencyModule is ExternalImportedKotlinModule && dependencyModule.hasLegacyMetadataModule ->
|
|
||||||
resolvedComponentResult.dependencies.filterIsInstance<ResolvedDependencyResult>().singleOrNull()?.selected
|
|
||||||
?: resolvedComponentResult
|
|
||||||
else -> resolvedComponentResult
|
|
||||||
}
|
|
||||||
|
|
||||||
val parentResolutionsForDependency =
|
val parentResolutionsForDependency =
|
||||||
parentResultsByModuleIdentifier[metadataSourceComponent.toSingleModuleIdentifier()].orEmpty()
|
parentResultsByModuleIdentifier[metadataSourceComponent.toSingleModuleIdentifier()].orEmpty()
|
||||||
@@ -106,6 +94,15 @@ internal class FragmentGranularMetadataResolver(
|
|||||||
.flatMapTo(mutableSetOf()) { it.allVisibleSourceSetNames }
|
.flatMapTo(mutableSetOf()) { it.allVisibleSourceSetNames }
|
||||||
val visibleFragmentNames = visibleFragments.map { it.fragmentName }.toSet()
|
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(
|
ChooseVisibleSourceSetsImpl(
|
||||||
metadataSourceComponent,
|
metadataSourceComponent,
|
||||||
isResolvedAsProject,
|
isResolvedAsProject,
|
||||||
@@ -113,14 +110,14 @@ internal class FragmentGranularMetadataResolver(
|
|||||||
visibleFragmentNames,
|
visibleFragmentNames,
|
||||||
visibleFragmentNames.minus(fragmentsVisibleByParents),
|
visibleFragmentNames.minus(fragmentsVisibleByParents),
|
||||||
visibleTransitiveDependencies.map { resolvedDependenciesByModuleId.getValue(it.module.moduleIdentifier) }.toSet(),
|
visibleTransitiveDependencies.map { resolvedDependenciesByModuleId.getValue(it.module.moduleIdentifier) }.toSet(),
|
||||||
checkNotNull(getMetadataExtractor(project, resolvedComponentResult, configurationToResolve, true))
|
checkNotNull(metadataExtractor)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
results.add(result)
|
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 }
|
val resultSourceComponents = results.mapTo(mutableSetOf()) { it.dependency }
|
||||||
resolvedComponentsByModuleId.values.minus(resultSourceComponents).forEach {
|
resolvedComponentsByModuleId.values.minus(resultSourceComponents).forEach {
|
||||||
results.add(MetadataDependencyResolution.ExcludeAsUnrequested(it, it.toProjectOrNull(project)))
|
results.add(MetadataDependencyResolution.ExcludeAsUnrequested(it, it.toProjectOrNull(project)))
|
||||||
@@ -128,4 +125,33 @@ internal class FragmentGranularMetadataResolver(
|
|||||||
|
|
||||||
return results
|
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.gradle.utils.checkGradleCompatibility
|
||||||
import org.jetbrains.kotlin.project.model.KotlinModuleIdentifier
|
import org.jetbrains.kotlin.project.model.KotlinModuleIdentifier
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
abstract class KotlinPm20GradlePlugin @Inject constructor(
|
abstract class KotlinPm20GradlePlugin @Inject constructor(
|
||||||
@Inject private val softwareComponentFactory: SoftwareComponentFactory
|
@Inject private val softwareComponentFactory: SoftwareComponentFactory
|
||||||
@@ -35,11 +36,28 @@ abstract class KotlinPm20GradlePlugin @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun registerDefaultVariantFactories(project: Project) {
|
private fun registerDefaultVariantFactories(project: Project) {
|
||||||
project.pm20Extension.modules.configureEach {
|
project.pm20Extension.modules.configureEach { module ->
|
||||||
it.fragments.registerFactory(
|
module.fragments.registerFactory(
|
||||||
KotlinJvmVariant::class.java,
|
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
|
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.gradle.api.plugins.BasePluginConvention
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
|
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
|
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl
|
||||||
import org.jetbrains.kotlin.gradle.dsl.pm20Extension
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
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.filterModuleName
|
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) :
|
open class KotlinJvmVariant(containingModule: KotlinGradleModule, fragmentName: String) :
|
||||||
KotlinGradlePublishedVariantWithRuntime(containingModule, fragmentName) {
|
KotlinGradlePublishedVariantWithRuntime(containingModule, fragmentName) {
|
||||||
@@ -29,48 +21,6 @@ open class KotlinJvmVariant(containingModule: KotlinGradleModule, fragmentName:
|
|||||||
class KotlinJvmVariantCompilationData(val variant: KotlinJvmVariant) : KotlinVariantCompilationDataInternal<KotlinJvmOptions> {
|
class KotlinJvmVariantCompilationData(val variant: KotlinJvmVariant) : KotlinVariantCompilationDataInternal<KotlinJvmOptions> {
|
||||||
override val owner: KotlinJvmVariant get() = variant
|
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
|
// TODO pull out to the variant
|
||||||
override val kotlinOptions: KotlinJvmOptions
|
override val kotlinOptions: KotlinJvmOptions
|
||||||
get() = KotlinJvmOptionsImpl()
|
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.library.KLIB_FILE_EXTENSION
|
||||||
import org.jetbrains.kotlin.project.model.refinesClosure
|
import org.jetbrains.kotlin.project.model.refinesClosure
|
||||||
import org.jetbrains.kotlin.project.model.utils.variantsContainingFragment
|
import org.jetbrains.kotlin.project.model.utils.variantsContainingFragment
|
||||||
|
import java.util.concurrent.Callable
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
open class KotlinNativeVariantFactory<T : KotlinNativeVariantInternal>(
|
open class KotlinNativeVariantFactory<T : KotlinNativeVariantInternal>(
|
||||||
|
|||||||
+7
-6
@@ -27,12 +27,13 @@ abstract class AbstractKotlinGradleVariantFactory<T : KotlinGradleVariant>(
|
|||||||
module: KotlinGradleModule
|
module: KotlinGradleModule
|
||||||
) : AbstractKotlinGradleFragmentFactory<T>(module) {
|
) : AbstractKotlinGradleFragmentFactory<T>(module) {
|
||||||
|
|
||||||
override fun create(name: String): T = super.create(name).also { fragment ->
|
override fun create(name: String): T =
|
||||||
createSourcesArchiveTask(fragment)
|
super.create(name).also { fragment ->
|
||||||
configureKotlinCompilation(fragment)
|
createSourcesArchiveTask(fragment)
|
||||||
createElementsConfigurations(fragment)
|
createElementsConfigurations(fragment)
|
||||||
// TODO configure resources processing
|
configureKotlinCompilation(fragment)
|
||||||
}
|
// TODO configure resources processing
|
||||||
|
}
|
||||||
|
|
||||||
protected open fun setPlatformAttributesInConfiguration(fragment: T, configuration: Configuration) {
|
protected open fun setPlatformAttributesInConfiguration(fragment: T, configuration: Configuration) {
|
||||||
configuration.attributes.attribute(KotlinPlatformType.attribute, fragment.platformType)
|
configuration.attributes.attribute(KotlinPlatformType.attribute, fragment.platformType)
|
||||||
|
|||||||
+3
@@ -57,6 +57,9 @@ abstract class KotlinGradleVariantInternal(
|
|||||||
override fun toString(): String = "variant $fragmentName in $containingModule"
|
override fun toString(): String = "variant $fragmentName in $containingModule"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val KotlinGradleVariant.compileDependencyConfiguration: Configuration
|
||||||
|
get() = containingModule.project.configurations.getByName(compileDependencyConfigurationName)
|
||||||
|
|
||||||
class DefaultSingleMavenPublicationHolder(
|
class DefaultSingleMavenPublicationHolder(
|
||||||
private var module: KotlinGradleModule,
|
private var module: KotlinGradleModule,
|
||||||
override val defaultPublishedModuleSuffix: String?
|
override val defaultPublishedModuleSuffix: String?
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ abstract class AbstractKotlinGradleFragmentFactory<T : KotlinGradleFragment>(
|
|||||||
with(project.configurations) {
|
with(project.configurations) {
|
||||||
fragment.relatedConfigurationNames.forEach { configurationName ->
|
fragment.relatedConfigurationNames.forEach { configurationName ->
|
||||||
maybeCreate(configurationName).apply {
|
maybeCreate(configurationName).apply {
|
||||||
// FIXME add metadata configurations?
|
// FIXME add metadata configurations or API for IDE import?
|
||||||
if (!configurationName.endsWith(METADATA_CONFIGURATION_NAME_SUFFIX)) {
|
if (!configurationName.endsWith(METADATA_CONFIGURATION_NAME_SUFFIX)) {
|
||||||
isCanBeResolved = false
|
isCanBeResolved = false
|
||||||
}
|
}
|
||||||
|
|||||||
+68
-28
@@ -10,7 +10,6 @@ import org.gradle.api.Project
|
|||||||
import org.gradle.api.attributes.Usage
|
import org.gradle.api.attributes.Usage
|
||||||
import org.gradle.api.tasks.TaskProvider
|
import org.gradle.api.tasks.TaskProvider
|
||||||
import org.gradle.jvm.tasks.Jar
|
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.dsl.pm20Extension
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCommonSourceSetProcessor
|
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.tasks.withType
|
||||||
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
|
import org.jetbrains.kotlin.gradle.utils.addExtendsFromRelation
|
||||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
|
import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION
|
||||||
import org.jetbrains.kotlin.project.model.KotlinModuleFragment
|
import org.jetbrains.kotlin.project.model.KotlinModuleFragment
|
||||||
import java.util.concurrent.Callable
|
import java.util.concurrent.Callable
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ private fun generateAndExportProjectStructureMetadata(
|
|||||||
module: KotlinGradleModule
|
module: KotlinGradleModule
|
||||||
) {
|
) {
|
||||||
val project = module.project
|
val project = module.project
|
||||||
val projectStructureMetadata = project.createGenerateProjectStructureMetadataTask(module.moduleClassifier)
|
val projectStructureMetadata = project.createGenerateProjectStructureMetadataTask(module)
|
||||||
project.tasks.withType<Jar>().named(metadataJarName(module)).configure { jar ->
|
project.tasks.withType<Jar>().named(metadataJarName(module)).configure { jar ->
|
||||||
jar.from(projectStructureMetadata.map { it.resultFile }) { spec ->
|
jar.from(projectStructureMetadata.map { it.resultFile }) { spec ->
|
||||||
spec.into("META-INF")
|
spec.into("META-INF")
|
||||||
@@ -74,7 +74,7 @@ private fun generateAndExportProjectStructureMetadata(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
GlobalProjectStructureMetadataStorage.registerProjectStructureMetadata(project) {
|
GlobalProjectStructureMetadataStorage.registerProjectStructureMetadata(project) {
|
||||||
checkNotNull(buildKotlinProjectStructureMetadata(project))
|
buildProjectStructureMetadata(module)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +108,13 @@ private fun configureMetadataCompilationsAndCreateRegistry(
|
|||||||
}
|
}
|
||||||
val compileAllTask = project.registerTask<DefaultTask>(lowerCamelCaseName(module.moduleClassifier, "metadataClasses"))
|
val compileAllTask = project.registerTask<DefaultTask>(lowerCamelCaseName(module.moduleClassifier, "metadataClasses"))
|
||||||
module.fragments.all { fragment ->
|
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) =
|
internal fun metadataJarName(module: KotlinGradleModule) =
|
||||||
lowerCamelCaseName(module.moduleClassifier, "metadataJar")
|
lowerCamelCaseName(module.moduleClassifier, "metadataJar")
|
||||||
|
|
||||||
private fun createMetadataCompilation(
|
private fun createCommonMetadataCompilation(
|
||||||
fragment: KotlinGradleFragment,
|
fragment: KotlinGradleFragment,
|
||||||
compileAllTask: TaskProvider<DefaultTask>,
|
compileAllTask: TaskProvider<DefaultTask>,
|
||||||
metadataCompilationRegistry: MetadataCompilationRegistry
|
metadataCompilationRegistry: MetadataCompilationRegistry
|
||||||
): KotlinCompilationData<out KotlinMultiplatformCommonOptions> {
|
) {
|
||||||
val module = fragment.containingModule
|
val module = fragment.containingModule
|
||||||
val project = module.project
|
val project = module.project
|
||||||
|
|
||||||
val metadataCompilationData =
|
val metadataCompilationData =
|
||||||
KotlinFragmentMetadataCompilationData(
|
KotlinCommonFragmentMetadataCompilationDataImpl(
|
||||||
project,
|
project,
|
||||||
fragment,
|
fragment,
|
||||||
module,
|
module,
|
||||||
compileAllTask,
|
compileAllTask,
|
||||||
metadataCompilationRegistry,
|
metadataCompilationRegistry,
|
||||||
lazy {
|
lazy { resolvedMetadataProviders(fragment) }
|
||||||
fragment.refinesClosure.map {
|
|
||||||
FragmentResolvedMetadataProvider(
|
|
||||||
project.tasks.withType<TransformKotlinGranularMetadataForFragment>()
|
|
||||||
.named(transformFragmentMetadataTaskName(it))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
metadataCompilationRegistry.register(fragment, metadataCompilationData)
|
|
||||||
|
|
||||||
addSourcesToKotlinCompileTask(
|
|
||||||
project,
|
|
||||||
metadataCompilationData.compileKotlinTaskName,
|
|
||||||
/*FIXME*/ emptyList(),
|
|
||||||
{ fragment.kotlinSourceRoots },
|
|
||||||
lazyOf(true)
|
|
||||||
)
|
|
||||||
|
|
||||||
KotlinCommonSourceSetProcessor(
|
KotlinCommonSourceSetProcessor(
|
||||||
metadataCompilationData,
|
metadataCompilationData,
|
||||||
KotlinTasksProvider(),
|
KotlinTasksProvider(),
|
||||||
project.getKotlinPluginVersion() ?: "undefined"
|
project.getKotlinPluginVersion() ?: "undefined"
|
||||||
).run()
|
).run()
|
||||||
|
addSourcesToMetadataCompileTask(metadataCompilationData)
|
||||||
return 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(
|
private fun createExtractMetadataTask(
|
||||||
project: Project,
|
project: Project,
|
||||||
fragment: KotlinGradleFragment,
|
fragment: KotlinGradleFragment,
|
||||||
@@ -206,7 +246,7 @@ private fun createExtractMetadataTask(
|
|||||||
|
|
||||||
// FIXME: use this function once more than one platform is supported
|
// FIXME: use this function once more than one platform is supported
|
||||||
private fun disableMetadataCompilationIfNotYetSupported(
|
private fun disableMetadataCompilationIfNotYetSupported(
|
||||||
metadataCompilationData: KotlinFragmentMetadataCompilationData
|
metadataCompilationData: AbstractKotlinFragmentMetadataCompilationData<*>
|
||||||
) {
|
) {
|
||||||
val fragment = metadataCompilationData.fragment
|
val fragment = metadataCompilationData.fragment
|
||||||
val platforms = fragment.containingModule.variantsContainingFragment(fragment).map { it.platformType }.toSet()
|
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.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.CompilationSourceSetUtil.compilationsBySourceSets
|
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.mpp.pm20.KotlinPm20ProjectExtension
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.*
|
import org.jetbrains.kotlin.gradle.plugin.sources.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
import org.jetbrains.kotlin.gradle.plugin.statistics.KotlinBuildStatsService
|
||||||
@@ -119,20 +121,6 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) :
|
|||||||
else -> error("unsupported compilation type ${compilation::class.qualifiedName}")
|
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> {
|
override fun createArchiveTasks(target: KotlinMetadataTarget): TaskProvider<out Zip> {
|
||||||
if (!target.project.isKotlinGranularMetadataEnabled)
|
if (!target.project.isKotlinGranularMetadataEnabled)
|
||||||
return super.createArchiveTasks(target)
|
return super.createArchiveTasks(target)
|
||||||
@@ -486,8 +474,28 @@ class KotlinMetadataTargetConfigurator(kotlinPluginVersion: String) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Project.createGenerateProjectStructureMetadataTask(moduleClassifier: String? = null): TaskProvider<GenerateProjectStructureMetadata> =
|
internal class NativeSharedCompilationProcessor(
|
||||||
project.registerTask(lowerCamelCaseName("generate", moduleClassifier, "ProjectStructureMetadata")) { task ->
|
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)) }
|
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.gradle.util.ConfigureUtil
|
||||||
import org.jetbrains.kotlin.gradle.plugin.CInteropSettings
|
import org.jetbrains.kotlin.gradle.plugin.CInteropSettings
|
||||||
import org.jetbrains.kotlin.gradle.plugin.CInteropSettings.IncludeDirectories
|
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.targets.native.internal.CInteropIdentifier
|
||||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -23,7 +27,7 @@ import javax.inject.Inject
|
|||||||
open class DefaultCInteropSettings @Inject constructor(
|
open class DefaultCInteropSettings @Inject constructor(
|
||||||
private val project: Project,
|
private val project: Project,
|
||||||
private val name: String,
|
private val name: String,
|
||||||
override val compilation: KotlinNativeCompilation
|
override val compilation: KotlinNativeCompilationData<*>
|
||||||
) : CInteropSettings {
|
) : CInteropSettings {
|
||||||
|
|
||||||
inner class DefaultIncludeDirectories : CInteropSettings.IncludeDirectories {
|
inner class DefaultIncludeDirectories : CInteropSettings.IncludeDirectories {
|
||||||
@@ -46,8 +50,8 @@ open class DefaultCInteropSettings @Inject constructor(
|
|||||||
internal val identifier: CInteropIdentifier
|
internal val identifier: CInteropIdentifier
|
||||||
get() = CInteropIdentifier(CInteropIdentifier.Scope.create(compilation), name)
|
get() = CInteropIdentifier(CInteropIdentifier.Scope.create(compilation), name)
|
||||||
|
|
||||||
val target: KotlinNativeTarget
|
val target: KotlinNativeTarget?
|
||||||
get() = compilation.target
|
get() = (compilation as? KotlinNativeCompilation?)?.target
|
||||||
|
|
||||||
override val dependencyConfigurationName: String
|
override val dependencyConfigurationName: String
|
||||||
get() = compilation.disambiguateName("${name.capitalize()}CInterop")
|
get() = compilation.disambiguateName("${name.capitalize()}CInterop")
|
||||||
@@ -59,7 +63,7 @@ open class DefaultCInteropSettings @Inject constructor(
|
|||||||
"cinterop",
|
"cinterop",
|
||||||
compilation.compilationPurpose.takeIf { it != "main" }.orEmpty(),
|
compilation.compilationPurpose.takeIf { it != "main" }.orEmpty(),
|
||||||
name,
|
name,
|
||||||
target.disambiguationClassifier
|
target?.disambiguationClassifier ?: compilation.compilationClassifier
|
||||||
)
|
)
|
||||||
|
|
||||||
val defFileProperty: Property<File> = project.objects.property(File::class.java)
|
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() } })
|
_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 groovy.lang.Closure
|
||||||
import org.gradle.api.Action
|
import org.gradle.api.Action
|
||||||
import org.gradle.api.NamedDomainObjectContainer
|
import org.gradle.api.NamedDomainObjectContainer
|
||||||
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
import org.gradle.api.tasks.TaskProvider
|
import org.gradle.api.tasks.TaskProvider
|
||||||
import org.gradle.util.ConfigureUtil
|
import org.gradle.util.ConfigureUtil
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
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.getVisibleSourceSetsFromAssociateCompilations
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||||
import org.jetbrains.kotlin.gradle.targets.metadata.getMetadataCompilationForSourceSet
|
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.tasks.KotlinNativeCompile
|
||||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
|
import java.io.File
|
||||||
import java.util.concurrent.Callable
|
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(
|
abstract class AbstractKotlinNativeCompilation(
|
||||||
target: KotlinTarget,
|
target: KotlinTarget,
|
||||||
val konanTarget: KonanTarget,
|
override val konanTarget: KonanTarget,
|
||||||
compilationName: String
|
compilationName: String
|
||||||
) : AbstractKotlinCompilation<KotlinCommonOptions>(target, compilationName) {
|
) : AbstractKotlinCompilation<KotlinCommonOptions>(target, compilationName), KotlinNativeCompilationData<KotlinCommonOptions> {
|
||||||
|
|
||||||
override val kotlinOptions: KotlinCommonOptions = NativeCompileOptions { defaultSourceSet.languageSettings }
|
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
|
override val compileKotlinTask: KotlinNativeCompile
|
||||||
get() = super.compileKotlinTask as KotlinNativeCompile
|
get() = super.compileKotlinTask as KotlinNativeCompile
|
||||||
|
|
||||||
@@ -59,14 +68,25 @@ abstract class AbstractKotlinNativeCompilation(
|
|||||||
override val compileKotlinTaskProvider: TaskProvider<out KotlinNativeCompile>
|
override val compileKotlinTaskProvider: TaskProvider<out KotlinNativeCompile>
|
||||||
get() = super.compileKotlinTaskProvider as TaskProvider<out KotlinNativeCompile>
|
get() = super.compileKotlinTaskProvider as TaskProvider<out KotlinNativeCompile>
|
||||||
|
|
||||||
override fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Lazy<Boolean>) =
|
override fun addSourcesToCompileTask(sourceSet: KotlinSourceSet, addAsCommonSources: Lazy<Boolean>) {
|
||||||
compileKotlinTaskProvider.configure { task ->
|
addSourcesToKotlinNativeCompileTask(project, compileKotlinTaskName, { sourceSet.kotlin }, addAsCommonSources)
|
||||||
task.source(sourceSet.kotlin)
|
}
|
||||||
task.commonSources.from(target.project.files(Callable { if (addAsCommonSources.value) sourceSet.kotlin else emptyList<Any>() }))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Endorsed library controller.
|
// 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(
|
class KotlinNativeCompilation(
|
||||||
@@ -117,6 +137,7 @@ class KotlinNativeCompilation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
class KotlinSharedNativeCompilation(override val target: KotlinMetadataTarget, val konanTargets: List<KonanTarget>, name: String) :
|
class KotlinSharedNativeCompilation(override val target: KotlinMetadataTarget, val konanTargets: List<KonanTarget>, name: String) :
|
||||||
|
KotlinNativeFragmentMetadataCompilationData,
|
||||||
AbstractKotlinNativeCompilation(
|
AbstractKotlinNativeCompilation(
|
||||||
target,
|
target,
|
||||||
// TODO: this will end up as '-target' argument passed to K2Native, which is wrong.
|
// 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 })
|
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.Project
|
||||||
import org.gradle.api.artifacts.Dependency
|
import org.gradle.api.artifacts.Dependency
|
||||||
import org.gradle.api.attributes.Attribute
|
import org.gradle.api.attributes.Attribute
|
||||||
import org.gradle.api.attributes.Usage
|
|
||||||
import org.gradle.jvm.tasks.Jar
|
import org.gradle.jvm.tasks.Jar
|
||||||
import org.gradle.util.WrapUtil
|
import org.gradle.util.WrapUtil
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer
|
import org.jetbrains.kotlin.gradle.dsl.KotlinNativeBinaryContainer
|
||||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
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.*
|
||||||
|
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.*
|
||||||
import org.jetbrains.kotlin.gradle.targets.metadata.filesWithUnpackedArchives
|
import org.jetbrains.kotlin.gradle.targets.metadata.filesWithUnpackedArchives
|
||||||
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
|
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
|
||||||
@@ -136,26 +137,49 @@ open class KotlinNativeTarget @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun getHostSpecificSourceSets(project: Project): List<KotlinSourceSet> {
|
private val hostManager by lazy { HostManager() }
|
||||||
val compilationsBySourceSet = CompilationSourceSetUtil.compilationsBySourceSets(project)
|
|
||||||
|
|
||||||
val enabledByHost = HostManager().enabledByHost
|
private fun isHostSpecificKonanTargetsSet(konanTargets: Iterable<KonanTarget>): Boolean {
|
||||||
|
val enabledByHost = hostManager.enabledByHost
|
||||||
val allHosts = enabledByHost.keys
|
val allHosts = enabledByHost.keys
|
||||||
|
|
||||||
fun canBeBuiltOnHosts(konanTarget: KonanTarget) = enabledByHost.filterValues { konanTarget in it }.keys
|
fun canBeBuiltOnHosts(konanTarget: KonanTarget) = enabledByHost.filterValues { konanTarget in it }.keys
|
||||||
|
return konanTargets.flatMapTo(mutableSetOf(), ::canBeBuiltOnHosts) != allHosts
|
||||||
|
}
|
||||||
|
|
||||||
return project.kotlinExtension.sourceSets.filter { sourceSet ->
|
private fun <T> getHostSpecificElements(
|
||||||
if (sourceSet !in compilationsBySourceSet) return@filter false
|
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,
|
internal fun getHostSpecificFragments(
|
||||||
// we can't analyze the source set, so the source set's metadata can't be published from that host, and therefore
|
module: KotlinGradleModule
|
||||||
// we consider it platform-specific and publish as a part of the Native targets where the source set takes part,
|
): Set<KotlinGradleFragment> = getHostSpecificElements<KotlinGradleFragment>(
|
||||||
// not the common metadata artifact;
|
module.fragments,
|
||||||
val platformCompilations = compilationsBySourceSet.getValue(sourceSet).filter { it !is KotlinMetadataCompilation }
|
isNativeShared = { it.isNativeShared() },
|
||||||
val nativeCompilations = platformCompilations.filterIsInstance<KotlinNativeCompilation>()
|
getKonanTargets = {
|
||||||
val nativeEnabledOn = nativeCompilations.flatMapTo(mutableSetOf()) { compilation -> canBeBuiltOnHosts(compilation.konanTarget) }
|
val nativeVariants = module.variantsContainingFragment(it).filterIsInstance<KotlinNativeVariantInternal>()
|
||||||
platformCompilations == nativeCompilations && allHosts != nativeEnabledOn
|
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>(
|
abstract class KotlinNativeTargetWithTests<T : KotlinNativeBinaryTestRun>(
|
||||||
|
|||||||
+47
-35
@@ -7,6 +7,7 @@
|
|||||||
package org.jetbrains.kotlin.gradle.plugin
|
package org.jetbrains.kotlin.gradle.plugin
|
||||||
|
|
||||||
import org.gradle.api.DefaultTask
|
import org.gradle.api.DefaultTask
|
||||||
|
import org.gradle.api.NamedDomainObjectCollection
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.Task
|
import org.gradle.api.Task
|
||||||
import org.gradle.api.artifacts.Configuration
|
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.PropertiesProvider.Companion.KOTLIN_NATIVE_IGNORE_INCORRECT_DEPENDENCIES
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.registerAssembleAppleFrameworkTask
|
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.metadata.isKotlinGranularMetadataEnabled
|
||||||
import org.jetbrains.kotlin.gradle.targets.native.*
|
import org.jetbrains.kotlin.gradle.targets.native.*
|
||||||
import org.jetbrains.kotlin.gradle.targets.native.internal.commonizeCInteropTask
|
import org.jetbrains.kotlin.gradle.targets.native.internal.commonizeCInteropTask
|
||||||
@@ -51,10 +53,10 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
|
|||||||
createTestCompilation = true
|
createTestCompilation = true
|
||||||
) {
|
) {
|
||||||
private fun Project.klibOutputDirectory(
|
private fun Project.klibOutputDirectory(
|
||||||
compilation: AbstractKotlinNativeCompilation
|
compilation: KotlinCompilationData<*>
|
||||||
): File {
|
): File {
|
||||||
val targetSubDirectory = compilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty()
|
val targetSubDirectory = compilation.compilationClassifier?.let { "$it/" }.orEmpty()
|
||||||
return buildDir.resolve("classes/kotlin/$targetSubDirectory${compilation.name}")
|
return buildDir.resolve("classes/kotlin/$targetSubDirectory${compilation.compilationPurpose}")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addCompilerPlugins(compilation: AbstractKotlinNativeCompilation) {
|
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(
|
private fun Project.createKlibArtifact(
|
||||||
compilation: KotlinNativeCompilation,
|
compilation: KotlinNativeCompilationData<*>,
|
||||||
artifactFile: Provider<File>,
|
artifactFile: Provider<File>,
|
||||||
classifier: String?,
|
classifier: String?,
|
||||||
producingTask: TaskProvider<*>,
|
producingTask: TaskProvider<*>,
|
||||||
@@ -85,14 +103,14 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val apiElements = configurations.getByName(compilation.target.apiElementsConfigurationName)
|
val apiElements = configurations.getByName(compilation.apiElementsConfigurationName)
|
||||||
|
|
||||||
val realProducingTask: TaskProvider<*>
|
val realProducingTask: TaskProvider<*>
|
||||||
// TODO: Someone remove this HACK PLEASE!
|
// TODO: Someone remove this HACK PLEASE!
|
||||||
val realArtifactFile = if (copy) {
|
val realArtifactFile = if (copy) {
|
||||||
realProducingTask = project.registerTask<Copy>("copy${producingTask.name.capitalize()}") {
|
realProducingTask = project.registerTask<Copy>("copy${producingTask.name.capitalize()}") {
|
||||||
val targetSubDirectory = compilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty()
|
val targetSubDirectory = compilation.compilationClassifier?.let { "$it/" }.orEmpty()
|
||||||
it.destinationDir = project.buildDir.resolve("libs/$targetSubDirectory${compilation.name}")
|
it.destinationDir = project.buildDir.resolve("libs/$targetSubDirectory${compilation.compilationPurpose}")
|
||||||
it.from(artifactFile)
|
it.from(artifactFile)
|
||||||
it.dependsOn(producingTask)
|
it.dependsOn(producingTask)
|
||||||
}
|
}
|
||||||
@@ -104,7 +122,7 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
|
|||||||
|
|
||||||
with(apiElements) {
|
with(apiElements) {
|
||||||
val klibArtifact = project.artifacts.add(apiElements.name, realArtifactFile) { artifact ->
|
val klibArtifact = project.artifacts.add(apiElements.name, realArtifactFile) { artifact ->
|
||||||
artifact.name = compilation.name
|
artifact.name = compilation.compilationPurpose
|
||||||
artifact.extension = "klib"
|
artifact.extension = "klib"
|
||||||
artifact.type = "klib"
|
artifact.type = "klib"
|
||||||
artifact.classifier = classifier
|
artifact.classifier = classifier
|
||||||
@@ -115,18 +133,6 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
|
|||||||
attributes.attribute(ArtifactAttributes.ARTIFACT_FORMAT, NativeArtifactFormat.KLIB)
|
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.
|
// region Task creation.
|
||||||
private fun Project.createLinkTask(binary: NativeBinary) {
|
private fun Project.createLinkTask(binary: NativeBinary) {
|
||||||
val result = registerTask<KotlinNativeLink>(
|
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>(
|
val compileTaskProvider = registerTask<KotlinNativeCompile>(
|
||||||
compilation.compileKotlinTaskName, listOf(compilation)
|
compilation.compileKotlinTaskName, listOf(compilation)
|
||||||
) {
|
) {
|
||||||
it.group = BasePlugin.BUILD_GROUP
|
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}'."
|
"compilation for target '${compilation.platformType.name}'."
|
||||||
it.enabled = compilation.konanTarget.enabledOnCurrentHost
|
it.enabled = compilation.konanTarget.enabledOnCurrentHost
|
||||||
|
|
||||||
@@ -275,33 +281,39 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
|
|||||||
project.files(compileTaskProvider.map { it.outputFile })
|
project.files(compileTaskProvider.map { it.outputFile })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
project.tasks.getByName(compilation.compileAllTaskName).dependsOn(compileTaskProvider)
|
project.tasks.getByName(compilation.compileAllTaskName).dependsOn(compileTaskProvider)
|
||||||
|
|
||||||
if (compilation.isMain()) {
|
if (compilation.isMainCompilationData()) {
|
||||||
compilation as? KotlinNativeCompilation ?: error("Main shared-Native compilation is not yet supported!")
|
if (compilation is KotlinNativeCompilation) {
|
||||||
|
project.tasks.getByName(compilation.target.artifactsTaskName).apply {
|
||||||
project.tasks.getByName(compilation.target.artifactsTaskName).apply {
|
dependsOn(compileTaskProvider)
|
||||||
dependsOn(compileTaskProvider)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project.tasks.getByName(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).apply {
|
project.tasks.getByName(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).apply {
|
||||||
dependsOn(compileTaskProvider)
|
dependsOn(compileTaskProvider)
|
||||||
}
|
}
|
||||||
createRegularKlibArtifact(compilation, compileTaskProvider)
|
createRegularKlibArtifact(compilation, compileTaskProvider)
|
||||||
}
|
}
|
||||||
addCompilerPlugins(compilation)
|
if (compilation is AbstractKotlinNativeCompilation) {
|
||||||
|
// FIXME: support compiler plugins for PM20
|
||||||
|
addCompilerPlugins(compilation)
|
||||||
|
}
|
||||||
|
|
||||||
return compileTaskProvider
|
return compileTaskProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Project.createCInteropTasks(compilation: KotlinNativeCompilation) {
|
// FIXME support creating interop tasks for PM20
|
||||||
compilation.cinterops.all { interop ->
|
private fun Project.createCInteropTasks(
|
||||||
|
compilation: KotlinNativeCompilation,
|
||||||
|
cinterops: NamedDomainObjectCollection<DefaultCInteropSettings>
|
||||||
|
) {
|
||||||
|
cinterops.all { interop ->
|
||||||
val interopTask = registerTask<CInteropProcess>(interop.interopProcessingTaskName, listOf(interop)) {
|
val interopTask = registerTask<CInteropProcess>(interop.interopProcessingTaskName, listOf(interop)) {
|
||||||
it.destinationDir = provider { klibOutputDirectory(compilation).resolve("cinterop") }
|
it.destinationDir = provider { klibOutputDirectory(compilation).resolve("cinterop") }
|
||||||
it.group = INTEROP_GROUP
|
it.group = INTEROP_GROUP
|
||||||
it.description = "Generates Kotlin/Native interop library '${interop.name}' " +
|
it.description = "Generates Kotlin/Native interop library '${interop.name}' " +
|
||||||
"for compilation '${compilation.name}'" +
|
"for compilation '${compilation.compilationPurpose}'" +
|
||||||
"of target '${it.konanTarget.name}'."
|
"of target '${it.konanTarget.name}'."
|
||||||
it.enabled = compilation.konanTarget.enabledOnCurrentHost
|
it.enabled = compilation.konanTarget.enabledOnCurrentHost
|
||||||
}
|
}
|
||||||
@@ -377,7 +389,7 @@ open class KotlinNativeTargetConfigurator<T : KotlinNativeTarget>(
|
|||||||
|
|
||||||
protected fun configureCInterops(target: KotlinNativeTarget): Unit = with(target.project) {
|
protected fun configureCInterops(target: KotlinNativeTarget): Unit = with(target.project) {
|
||||||
target.compilations.all { compilation ->
|
target.compilations.all { compilation ->
|
||||||
createCInteropTasks(compilation)
|
createCInteropTasks(compilation, compilation.cinterops)
|
||||||
compilation.cinterops.all {
|
compilation.cinterops.all {
|
||||||
defineConfigurationsForCInterop(compilation, it, target, configurations)
|
defineConfigurationsForCInterop(compilation, it, target, configurations)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -172,7 +172,8 @@ private fun CInteropProcess.toGist(): CInteropGist {
|
|||||||
return CInteropGist(
|
return CInteropGist(
|
||||||
identifier = settings.identifier,
|
identifier = settings.identifier,
|
||||||
konanTarget = konanTarget,
|
konanTarget = konanTarget,
|
||||||
sourceSets = project.provider { settings.compilation.kotlinSourceSetsIncludingDefault },
|
// FIXME support cinterop with PM20
|
||||||
|
sourceSets = project.provider { (settings.compilation as? KotlinCompilation<*>)?.kotlinSourceSetsIncludingDefault },
|
||||||
libraryFile = outputFileProvider,
|
libraryFile = outputFileProvider,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+2
-2
@@ -6,7 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.gradle.targets.native.internal
|
package org.jetbrains.kotlin.gradle.targets.native.internal
|
||||||
|
|
||||||
import org.gradle.api.tasks.Input
|
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 org.jetbrains.kotlin.gradle.utils.UnsafeApi
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ internal data class CInteropIdentifier internal constructor(
|
|||||||
class Scope @UnsafeApi internal constructor(val name: String) : Serializable {
|
class Scope @UnsafeApi internal constructor(val name: String) : Serializable {
|
||||||
companion object {
|
companion object {
|
||||||
@OptIn(UnsafeApi::class)
|
@OptIn(UnsafeApi::class)
|
||||||
fun create(compilation: KotlinCompilation<*>): Scope {
|
fun create(compilation: KotlinCompilationData<*>): Scope {
|
||||||
return Scope("compilation/${compilation.compileKotlinTaskName}")
|
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.LanguageSettingsBuilder
|
||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.asValidFrameworkName
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.asValidFrameworkName
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
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.plugin.sources.DefaultLanguageSettingsBuilder
|
||||||
import org.jetbrains.kotlin.gradle.targets.native.internal.isAllowCommonizer
|
import org.jetbrains.kotlin.gradle.targets.native.internal.isAllowCommonizer
|
||||||
import org.jetbrains.kotlin.gradle.utils.getValue
|
import org.jetbrains.kotlin.gradle.utils.getValue
|
||||||
@@ -113,7 +116,7 @@ private fun Collection<File>.filterKlibsPassedToCompiler(project: Project) = fil
|
|||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
abstract class AbstractKotlinNativeCompile<T : KotlinCommonToolOptions, K : AbstractKotlinNativeCompilation> : AbstractCompile() {
|
abstract class AbstractKotlinNativeCompile<T : KotlinCommonToolOptions, K : KotlinNativeCompilationData<*>> : AbstractCompile() {
|
||||||
@get:Internal
|
@get:Internal
|
||||||
abstract val compilation: K
|
abstract val compilation: K
|
||||||
|
|
||||||
@@ -139,7 +142,7 @@ abstract class AbstractKotlinNativeCompile<T : KotlinCommonToolOptions, K : Abst
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val isSharedCompilation by project.provider {
|
private val isSharedCompilation by project.provider {
|
||||||
compilation is KotlinSharedNativeCompilation
|
compilation is KotlinNativeFragmentMetadataCompilationData
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inputs and outputs
|
// Inputs and outputs
|
||||||
@@ -178,7 +181,7 @@ abstract class AbstractKotlinNativeCompile<T : KotlinCommonToolOptions, K : Abst
|
|||||||
|
|
||||||
@get:Internal
|
@get:Internal
|
||||||
val languageSettings: LanguageSettingsBuilder by project.provider {
|
val languageSettings: LanguageSettingsBuilder by project.provider {
|
||||||
compilation.defaultSourceSet.languageSettings
|
compilation.languageSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
@get:Input
|
@get:Input
|
||||||
@@ -233,7 +236,7 @@ abstract class AbstractKotlinNativeCompile<T : KotlinCommonToolOptions, K : Abst
|
|||||||
get() = buildCommonArgs(true)
|
get() = buildCommonArgs(true)
|
||||||
|
|
||||||
private val languageSettingsBuilder by project.provider {
|
private val languageSettingsBuilder by project.provider {
|
||||||
compilation.defaultSourceSet.languageSettings
|
compilation.languageSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
// Args used by both the compiler and IDEA.
|
// Args used by both the compiler and IDEA.
|
||||||
@@ -343,8 +346,8 @@ open class KotlinNativeCompile
|
|||||||
constructor(
|
constructor(
|
||||||
@Internal
|
@Internal
|
||||||
@Transient // can't be serialized for Gradle configuration cache
|
@Transient // can't be serialized for Gradle configuration cache
|
||||||
final override val compilation: AbstractKotlinNativeCompilation
|
final override val compilation: KotlinNativeCompilationData<*>
|
||||||
) : AbstractKotlinNativeCompile<KotlinCommonOptions, AbstractKotlinNativeCompilation>(),
|
) : AbstractKotlinNativeCompile<KotlinCommonOptions, KotlinNativeCompilationData<*>>(),
|
||||||
KotlinCompile<KotlinCommonOptions> {
|
KotlinCompile<KotlinCommonOptions> {
|
||||||
|
|
||||||
@get:Input
|
@get:Input
|
||||||
@@ -357,7 +360,11 @@ constructor(
|
|||||||
override val debuggable = true
|
override val debuggable = true
|
||||||
|
|
||||||
@get:Internal
|
@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
|
// 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 }
|
// private val allSourceProvider = compilation.map { project.files(it.allSources).asFileTree }
|
||||||
@@ -390,10 +397,7 @@ constructor(
|
|||||||
|
|
||||||
|
|
||||||
private val friendModule: FileCollection by project.provider {
|
private val friendModule: FileCollection by project.provider {
|
||||||
project.files(
|
project.files(compilation.friendPaths)
|
||||||
compilation.associateWithTransitiveClosure.map { it.output.allOutputs },
|
|
||||||
compilation.friendArtifacts
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
// endregion.
|
// endregion.
|
||||||
|
|
||||||
@@ -934,7 +938,7 @@ open class CInteropProcess @Inject constructor(@get:Internal val settings: Defau
|
|||||||
val baseKlibName: String
|
val baseKlibName: String
|
||||||
@Input get() {
|
@Input get() {
|
||||||
val compilationPrefix = settings.compilation.let {
|
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"
|
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.cli.common.arguments.K2MetadataCompilerArguments
|
||||||
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
|
import org.jetbrains.kotlin.compilerRunner.GradleCompilerEnvironment
|
||||||
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
|
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompile
|
import org.jetbrains.kotlin.gradle.dsl.*
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptions
|
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptionsImpl
|
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformCommonOptionsImpl
|
||||||
import org.jetbrains.kotlin.gradle.dsl.fillDefaultValues
|
import org.jetbrains.kotlin.gradle.dsl.fillDefaultValues
|
||||||
import org.jetbrains.kotlin.gradle.internal.tasks.allOutputFiles
|
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.KotlinSourceSet
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinCommonCompilation
|
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.plugin.mpp.pm20.refinesClosure
|
||||||
import org.jetbrains.kotlin.gradle.utils.getValue
|
import org.jetbrains.kotlin.gradle.utils.getValue
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
import org.jetbrains.kotlin.gradle.plugin.sources.resolveAllDependsOnSourceSets
|
||||||
@@ -63,7 +63,7 @@ open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompilerArgumen
|
|||||||
args.moduleName = this@KotlinCompileCommon.moduleName
|
args.moduleName = this@KotlinCompileCommon.moduleName
|
||||||
|
|
||||||
if ((taskData.compilation as? KotlinCommonCompilation)?.isKlibCompilation == true ||
|
if ((taskData.compilation as? KotlinCommonCompilation)?.isKlibCompilation == true ||
|
||||||
taskData.compilation is KotlinFragmentMetadataCompilationData
|
taskData.compilation is KotlinMetadataCompilationData
|
||||||
) {
|
) {
|
||||||
args.expectActualLinker = true
|
args.expectActualLinker = true
|
||||||
}
|
}
|
||||||
@@ -84,13 +84,10 @@ open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompilerArgumen
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun outputPathsFromMetadataCompilationsOf(sourceSets: Iterable<KotlinSourceSet>): List<File> {
|
private fun outputPathsFromMetadataCompilationsOf(sourceSets: Iterable<KotlinSourceSet>): List<File> {
|
||||||
val target = taskData.compilation.owner
|
val metadataTarget = taskData.compilation.owner as KotlinTarget
|
||||||
return when (target) {
|
return sourceSets
|
||||||
is KotlinTarget -> sourceSets
|
.mapNotNull { sourceSet -> metadataTarget.compilations.findByName(sourceSet.name)?.output?.classesDirs }
|
||||||
.mapNotNull { sourceSet -> target.compilations.findByName(sourceSet.name)?.output?.classesDirs }
|
.flatten()
|
||||||
.flatten()
|
|
||||||
else -> error("unexpected compilation owner") // FIXME support PM20 variant
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||||
@@ -101,7 +98,7 @@ open class KotlinCompileCommon : AbstractKotlinCompile<K2MetadataCompilerArgumen
|
|||||||
val defaultKotlinSourceSet: KotlinSourceSet = compilation.defaultSourceSet
|
val defaultKotlinSourceSet: KotlinSourceSet = compilation.defaultSourceSet
|
||||||
outputPathsFromMetadataCompilationsOf(defaultKotlinSourceSet.resolveAllDependsOnSourceSets())
|
outputPathsFromMetadataCompilationsOf(defaultKotlinSourceSet.resolveAllDependsOnSourceSets())
|
||||||
}
|
}
|
||||||
is KotlinFragmentMetadataCompilationData -> {
|
is AbstractKotlinFragmentMetadataCompilationData -> {
|
||||||
val fragment = compilation.fragment
|
val fragment = compilation.fragment
|
||||||
project.files(
|
project.files(
|
||||||
fragment.refinesClosure.minus(fragment).map {
|
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
|
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 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?
|
// TODO: should this be a single graph for all dependency scopes as well, not just for all fragments?
|
||||||
class DependencyGraphNode(
|
open class DependencyGraphNode(
|
||||||
val module: KotlinModule,
|
open val module: KotlinModule,
|
||||||
val dependenciesByFragment: Map<KotlinModuleFragment, Iterable<DependencyGraphNode>>
|
open val dependenciesByFragment: Map<KotlinModuleFragment, Iterable<DependencyGraphNode>>
|
||||||
) {
|
) {
|
||||||
override fun toString(): String = "node ${module}"
|
override fun toString(): String = "node ${module}"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user