[Gradle] Implement 'findMetadataCompilation' in safe way
(replacing old getMetadataCompilationsForSourceSet) ^KT-34662 Verification Pending
This commit is contained in:
committed by
Space Team
parent
4c653a4297
commit
b6a215d681
+5
-3
@@ -315,6 +315,8 @@ internal interface KotlinPluginLifecycle {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val values = values().toList()
|
val values = values().toList()
|
||||||
|
val first = values.first()
|
||||||
|
val last = values.last()
|
||||||
fun upTo(stage: Stage): Set<Stage> = values.first()..stage
|
fun upTo(stage: Stage): Set<Stage> = values.first()..stage
|
||||||
fun until(stage: Stage): Set<Stage> {
|
fun until(stage: Stage): Set<Stage> {
|
||||||
return upTo(stage.previousOrNull ?: return emptySet())
|
return upTo(stage.previousOrNull ?: return emptySet())
|
||||||
@@ -368,9 +370,9 @@ private class KotlinPluginLifecycleImpl(override val project: Project) : KotlinP
|
|||||||
private val enqueuedActions: Map<Stage, ArrayDeque<KotlinPluginLifecycle.() -> Unit>> =
|
private val enqueuedActions: Map<Stage, ArrayDeque<KotlinPluginLifecycle.() -> Unit>> =
|
||||||
Stage.values().associateWith { ArrayDeque() }
|
Stage.values().associateWith { ArrayDeque() }
|
||||||
|
|
||||||
private var loopRunning = AtomicBoolean(false)
|
private val loopRunning = AtomicBoolean(false)
|
||||||
private var isStarted = AtomicBoolean(false)
|
private val isStarted = AtomicBoolean(false)
|
||||||
private var isFinished = AtomicBoolean(false)
|
private val isFinished = AtomicBoolean(false)
|
||||||
|
|
||||||
private val properties = WeakHashMap<Property<*>, WeakReference<LifecycleAwareProperty<*>>>()
|
private val properties = WeakHashMap<Property<*>, WeakReference<LifecycleAwareProperty<*>>>()
|
||||||
|
|
||||||
|
|||||||
+29
-8
@@ -17,19 +17,28 @@ import org.gradle.api.tasks.TaskProvider
|
|||||||
import org.gradle.api.tasks.bundling.Jar
|
import org.gradle.api.tasks.bundling.Jar
|
||||||
import org.gradle.api.tasks.bundling.Zip
|
import org.gradle.api.tasks.bundling.Zip
|
||||||
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
|
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
|
||||||
import org.jetbrains.kotlin.gradle.dsl.*
|
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.pm20ExtensionOrNull
|
||||||
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.pm20.*
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmModule
|
||||||
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
|
||||||
import org.jetbrains.kotlin.gradle.targets.native.internal.*
|
import org.jetbrains.kotlin.gradle.targets.native.internal.createCInteropMetadataDependencyClasspath
|
||||||
import org.jetbrains.kotlin.gradle.tasks.*
|
import org.jetbrains.kotlin.gradle.targets.native.internal.includeCommonizedCInteropMetadata
|
||||||
|
import org.jetbrains.kotlin.gradle.targets.native.internal.sharedCommonizerTarget
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
||||||
import org.jetbrains.kotlin.gradle.utils.*
|
import org.jetbrains.kotlin.gradle.utils.*
|
||||||
import org.jetbrains.kotlin.gradle.utils.filesProvider
|
import org.jetbrains.kotlin.gradle.utils.filesProvider
|
||||||
import org.jetbrains.kotlin.gradle.utils.getResolvedArtifactsCompat
|
import org.jetbrains.kotlin.gradle.utils.getResolvedArtifactsCompat
|
||||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
|
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
|
||||||
|
import org.jetbrains.kotlin.tooling.core.UnsafeApi
|
||||||
|
import org.jetbrains.kotlin.tooling.core.extrasLazyProperty
|
||||||
|
|
||||||
internal const val COMMON_MAIN_ELEMENTS_CONFIGURATION_NAME = "commonMainMetadataElements"
|
internal const val COMMON_MAIN_ELEMENTS_CONFIGURATION_NAME = "commonMainMetadataElements"
|
||||||
|
|
||||||
@@ -175,7 +184,7 @@ class KotlinMetadataTargetConfigurator :
|
|||||||
private fun createMetadataCompilationsForCommonSourceSets(
|
private fun createMetadataCompilationsForCommonSourceSets(
|
||||||
target: KotlinMetadataTarget,
|
target: KotlinMetadataTarget,
|
||||||
allMetadataJar: TaskProvider<out Jar>
|
allMetadataJar: TaskProvider<out Jar>
|
||||||
) = target.project.launchInStage(KotlinPluginLifecycle.Stage.FinaliseCompilations) {
|
) = target.project.launchInRequiredStage(KotlinPluginLifecycle.Stage.FinaliseCompilations) {
|
||||||
// Do this after all targets are configured by the user build script
|
// Do this after all targets are configured by the user build script
|
||||||
|
|
||||||
val publishedCommonSourceSets: Set<KotlinSourceSet> = getCommonSourceSetsForMetadataCompilation(project)
|
val publishedCommonSourceSets: Set<KotlinSourceSet> = getCommonSourceSetsForMetadataCompilation(project)
|
||||||
@@ -199,6 +208,8 @@ class KotlinMetadataTargetConfigurator :
|
|||||||
sourceSetsWithMetadataCompilations.values.forEach { compilation ->
|
sourceSetsWithMetadataCompilations.values.forEach { compilation ->
|
||||||
exportDependenciesForPublishing(compilation)
|
exportDependenciesForPublishing(compilation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target.metadataCompilationsCreated.complete()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isMetadataCompilationSupported(sourceSet: KotlinSourceSet): Boolean {
|
private fun isMetadataCompilationSupported(sourceSet: KotlinSourceSet): Boolean {
|
||||||
@@ -358,7 +369,7 @@ class KotlinMetadataTargetConfigurator :
|
|||||||
private val KotlinSourceSet.dependsOnClassesDirs: FileCollection
|
private val KotlinSourceSet.dependsOnClassesDirs: FileCollection
|
||||||
get() = project.filesProvider {
|
get() = project.filesProvider {
|
||||||
internal.dependsOnClosure.mapNotNull { hierarchySourceSet ->
|
internal.dependsOnClosure.mapNotNull { hierarchySourceSet ->
|
||||||
val compilation = project.getMetadataCompilationForSourceSet(hierarchySourceSet) ?: return@mapNotNull null
|
val compilation = project.future { findMetadataCompilation(hierarchySourceSet) }.getOrThrow() ?: return@mapNotNull null
|
||||||
compilation.output.classesDirs
|
compilation.output.classesDirs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -491,6 +502,16 @@ internal fun Project.filesWithUnpackedArchives(from: FileCollection, extensions:
|
|||||||
}
|
}
|
||||||
}).builtBy(from)
|
}).builtBy(from)
|
||||||
|
|
||||||
internal fun Project.getMetadataCompilationForSourceSet(sourceSet: KotlinSourceSet): KotlinMetadataCompilation<*>? {
|
private val KotlinMetadataTarget.metadataCompilationsCreated: CompletableFuture<Unit> by extrasLazyProperty("metadataCompilationsCreated") {
|
||||||
return multiplatformExtension.metadata().compilations.findByName(sourceSet.name)
|
CompletableFuture()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal suspend fun KotlinMetadataTarget.awaitMetadataCompilationsCreated() {
|
||||||
|
metadataCompilationsCreated.await()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal suspend fun Project.findMetadataCompilation(sourceSet: KotlinSourceSet): KotlinMetadataCompilation<*>? {
|
||||||
|
val metadataTarget = multiplatformExtension.metadata() as KotlinMetadataTarget
|
||||||
|
metadataTarget.awaitMetadataCompilationsCreated()
|
||||||
|
return metadataTarget.compilations.findByName(sourceSet.name) as KotlinMetadataCompilation<*>?
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-11
@@ -56,7 +56,7 @@ abstract class KotlinNativeTarget @Inject constructor(
|
|||||||
// NB: another usage context for the host-specific metadata may be added to this set below
|
// NB: another usage context for the host-specific metadata may be added to this set below
|
||||||
val mutableUsageContexts = createUsageContexts(mainCompilation).toMutableSet()
|
val mutableUsageContexts = createUsageContexts(mainCompilation).toMutableSet()
|
||||||
|
|
||||||
project.whenEvaluated {
|
project.launchInStage(KotlinPluginLifecycle.Stage.AfterFinaliseDsl) {
|
||||||
val hostSpecificSourceSets = getHostSpecificSourceSets(project)
|
val hostSpecificSourceSets = getHostSpecificSourceSets(project)
|
||||||
.intersect(mainCompilation.allKotlinSourceSets)
|
.intersect(mainCompilation.allKotlinSourceSets)
|
||||||
|
|
||||||
@@ -70,18 +70,20 @@ abstract class KotlinNativeTarget @Inject constructor(
|
|||||||
val publishable = this@KotlinNativeTarget.publishable
|
val publishable = this@KotlinNativeTarget.publishable
|
||||||
metadataJar.onlyIf { publishable }
|
metadataJar.onlyIf { publishable }
|
||||||
|
|
||||||
val metadataCompilations = hostSpecificSourceSets.mapNotNull {
|
launch {
|
||||||
project.getMetadataCompilationForSourceSet(it)
|
val metadataCompilations = hostSpecificSourceSets.mapNotNull {
|
||||||
}
|
project.findMetadataCompilation(it)
|
||||||
|
|
||||||
metadataCompilations.forEach { compilation ->
|
|
||||||
metadataJar.from(project.filesWithUnpackedArchives(compilation.output.allOutputs, setOf("klib"))) { spec ->
|
|
||||||
spec.into(compilation.name)
|
|
||||||
}
|
}
|
||||||
metadataJar.dependsOn(compilation.output.classesDirs)
|
|
||||||
|
|
||||||
if (compilation is KotlinSharedNativeCompilation) {
|
metadataCompilations.forEach { compilation ->
|
||||||
project.includeCommonizedCInteropMetadata(metadataJar, compilation)
|
metadataJar.from(project.filesWithUnpackedArchives(compilation.output.allOutputs, setOf("klib"))) { spec ->
|
||||||
|
spec.into(compilation.name)
|
||||||
|
}
|
||||||
|
metadataJar.dependsOn(compilation.output.classesDirs)
|
||||||
|
|
||||||
|
if (compilation is KotlinSharedNativeCompilation) {
|
||||||
|
project.includeCommonizedCInteropMetadata(metadataJar, compilation)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.gradle.plugin.ide.ideaImportDependsOn
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.getVisibleSourceSetsFromAssociateCompilations
|
import org.jetbrains.kotlin.gradle.plugin.sources.getVisibleSourceSetsFromAssociateCompilations
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.internal
|
import org.jetbrains.kotlin.gradle.plugin.sources.internal
|
||||||
import org.jetbrains.kotlin.gradle.targets.metadata.getMetadataCompilationForSourceSet
|
import org.jetbrains.kotlin.gradle.targets.metadata.findMetadataCompilation
|
||||||
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
|
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
|
||||||
import org.jetbrains.kotlin.gradle.targets.native.internal.MissingNativeStdlibWarning.showMissingNativeStdlibWarning
|
import org.jetbrains.kotlin.gradle.targets.native.internal.MissingNativeStdlibWarning.showMissingNativeStdlibWarning
|
||||||
import org.jetbrains.kotlin.gradle.utils.filesProvider
|
import org.jetbrains.kotlin.gradle.utils.filesProvider
|
||||||
@@ -89,11 +89,11 @@ private fun NativeDistributionCommonizerTask.getCommonizedPlatformLibrariesFor(t
|
|||||||
return project.filesProvider { targetOutputDirectory.listLibraryFiles() }.builtBy(this)
|
return project.filesProvider { targetOutputDirectory.listLibraryFiles() }.builtBy(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Project.addDependencies(
|
private suspend fun Project.addDependencies(
|
||||||
sourceSet: KotlinSourceSet, libraries: FileCollection, isCompilationDependency: Boolean = true, isIdeDependency: Boolean = true
|
sourceSet: KotlinSourceSet, libraries: FileCollection, isCompilationDependency: Boolean = true, isIdeDependency: Boolean = true
|
||||||
) {
|
) {
|
||||||
if (isCompilationDependency) {
|
if (isCompilationDependency) {
|
||||||
getMetadataCompilationForSourceSet(sourceSet)?.let { compilation ->
|
findMetadataCompilation(sourceSet)?.let { compilation ->
|
||||||
compilation.compileDependencyFiles += libraries
|
compilation.compileDependencyFiles += libraries
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-3
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.gradle.plugin.HasProject
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.IllegalLifecycleException
|
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginLifecycle.IllegalLifecycleException
|
||||||
import org.jetbrains.kotlin.gradle.plugin.kotlinPluginLifecycle
|
import org.jetbrains.kotlin.gradle.plugin.kotlinPluginLifecycle
|
||||||
import org.jetbrains.kotlin.gradle.plugin.launch
|
|
||||||
import org.jetbrains.kotlin.tooling.core.ExtrasLazyProperty
|
import org.jetbrains.kotlin.tooling.core.ExtrasLazyProperty
|
||||||
import org.jetbrains.kotlin.tooling.core.HasMutableExtras
|
import org.jetbrains.kotlin.tooling.core.HasMutableExtras
|
||||||
import org.jetbrains.kotlin.tooling.core.extrasLazyProperty
|
import org.jetbrains.kotlin.tooling.core.extrasLazyProperty
|
||||||
@@ -47,6 +46,12 @@ internal interface Future<T> {
|
|||||||
fun getOrThrow(): T
|
fun getOrThrow(): T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal interface CompletableFuture<T> : Future<T> {
|
||||||
|
fun complete(value: T)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun CompletableFuture<Unit>.complete() = complete(Unit)
|
||||||
|
|
||||||
internal inline fun <Receiver, reified T> lazyFuture(
|
internal inline fun <Receiver, reified T> lazyFuture(
|
||||||
name: String? = null, noinline block: suspend Receiver.() -> T
|
name: String? = null, noinline block: suspend Receiver.() -> T
|
||||||
): ExtrasLazyProperty<Receiver, Future<T>> where Receiver : HasMutableExtras, Receiver : HasProject {
|
): ExtrasLazyProperty<Receiver, Future<T>> where Receiver : HasMutableExtras, Receiver : HasProject {
|
||||||
@@ -55,8 +60,10 @@ internal inline fun <Receiver, reified T> lazyFuture(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun <T> Project.future(block: suspend Project.() -> T): Future<T> = kotlinPluginLifecycle.future { block() }
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
internal fun <T> Project.future(block: suspend Project.() -> T): Future<T> {
|
internal fun <T> KotlinPluginLifecycle.future(block: suspend () -> T): Future<T> {
|
||||||
val deferred = CompletableDeferred<T>()
|
val deferred = CompletableDeferred<T>()
|
||||||
|
|
||||||
launch {
|
launch {
|
||||||
@@ -70,8 +77,30 @@ internal fun <T> Project.future(block: suspend Project.() -> T): Future<T> {
|
|||||||
|
|
||||||
override fun getOrThrow(): T {
|
override fun getOrThrow(): T {
|
||||||
return if (deferred.isCompleted) deferred.getCompleted() else throw IllegalLifecycleException(
|
return if (deferred.isCompleted) deferred.getCompleted() else throw IllegalLifecycleException(
|
||||||
"Future was not completed yet. Stage: '${kotlinPluginLifecycle.stage}'"
|
"Future was not completed yet. Stage: '${stage}'"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
internal fun <T> CompletableFuture(): CompletableFuture<T> {
|
||||||
|
val deferred = CompletableDeferred<T>()
|
||||||
|
|
||||||
|
|
||||||
|
return object : CompletableFuture<T> {
|
||||||
|
override fun complete(value: T) {
|
||||||
|
deferred.complete(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun await(): T {
|
||||||
|
return deferred.await()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getOrThrow(): T {
|
||||||
|
return if (deferred.isCompleted) deferred.getCompleted() else throw IllegalLifecycleException(
|
||||||
|
"Future was not completed yet"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user