[Commonizer] LibraryCommonizer: Allow passing dependencies for a shared target

This commit is contained in:
sebastian.sellmair
2021-03-22 15:32:05 +01:00
committed by Space
parent 096e715652
commit e44877f562
15 changed files with 78 additions and 61 deletions
@@ -0,0 +1,9 @@
/*
* 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.commonizer
public typealias TargetDependent<T> = Map<CommonizerTarget, T>
@@ -12,12 +12,12 @@ class CommonizerParameters(
val resultsConsumer: ResultsConsumer,
val manifestDataProvider: TargetedNativeManifestDataProvider,
// common module dependencies (ex: Kotlin stdlib)
val dependencyModulesProvider: ModulesProvider? = null,
val commonDependencyModulesProvider: ModulesProvider? = null,
val statsCollector: StatsCollector? = null,
val progressLogger: ((String) -> Unit)? = null
) {
// use linked hash map to preserve order
private val _targetProviders = LinkedHashMap<LeafCommonizerTarget, TargetProvider>()
private val _targetProviders = LinkedHashMap<CommonizerTarget, TargetProvider>()
val targetProviders: List<TargetProvider> get() = _targetProviders.values.toList()
fun addTarget(targetProvider: TargetProvider): CommonizerParameters {
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.library.SerializedMetadata
import java.io.File
class TargetProvider(
val target: LeafCommonizerTarget,
val target: CommonizerTarget,
val modulesProvider: ModulesProvider,
val dependencyModulesProvider: ModulesProvider?
)
@@ -68,12 +68,11 @@ internal class NativeKlibCommonize(options: Collection<Option<*>>) : Task(option
}
LibraryCommonizer(
konanDistribution = distribution,
commonTarget = outputCommonizerTarget,
repository = repository,
dependencies = KonanDistributionRepository(distribution, commonizerTargets.toSet(), libraryLoader) +
dependencies = StdlibRepository(distribution, libraryLoader) +
KonanDistributionRepository(distribution, commonizerTargets.toSet(), libraryLoader) +
FilesRepository(dependencyLibraries.toSet(), libraryLoader),
libraryLoader = libraryLoader,
targets = commonizerTargets,
resultsConsumer = resultsConsumer,
statsCollector = statsCollector,
progressLogger = progressLogger
@@ -121,11 +120,9 @@ internal class NativeDistributionCommonize(options: Collection<Option<*>>) : Tas
println(description)
LibraryCommonizer(
commonTarget = SharedCommonizerTarget(commonizerTargets.toSet()),
repository = repository,
konanDistribution = distribution,
dependencies = EmptyRepository,
libraryLoader = libraryLoader,
targets = commonizerTargets,
dependencies = StdlibRepository(distribution, libraryLoader),
resultsConsumer = resultsConsumer,
statsCollector = statsCollector,
progressLogger = progressLogger
@@ -41,7 +41,7 @@ private fun mergeAndCommonize(storageManager: StorageManager, parameters: Common
commonizedNodes = CirCommonizedClassifierNodes.default(),
commonDependencies = CirProvidedClassifiers.of(
CirFictitiousFunctionClassifiers,
CirProvidedClassifiers.by(parameters.dependencyModulesProvider)
CirProvidedClassifiers.by(parameters.commonDependencyModulesProvider)
)
)
val mergeResult = mergeCirTree(storageManager, classifiers, parameters)
@@ -67,15 +67,10 @@ internal class DefaultModulesProvider(libraries: Collection<NativeLibrary>) : Mo
}
companion object {
fun forStandardLibrary(stdlib: NativeLibrary): ModulesProvider {
check(stdlib.manifestData.uniqueName == KONAN_STDLIB_NAME)
return DefaultModulesProvider(listOf(stdlib))
}
fun platformLibraries(librariesToCommonize: NativeLibrariesToCommonize): ModulesProvider =
fun create(librariesToCommonize: NativeLibrariesToCommonize): ModulesProvider =
DefaultModulesProvider(librariesToCommonize.libraries)
fun platformLibraries(libraries: Iterable<NativeLibrary>): ModulesProvider =
fun create(libraries: Iterable<NativeLibrary>): ModulesProvider =
DefaultModulesProvider(libraries.toList())
}
}
@@ -11,11 +11,9 @@ import org.jetbrains.kotlin.commonizer.stats.StatsCollector
import org.jetbrains.kotlin.commonizer.utils.ProgressLogger
internal class LibraryCommonizer internal constructor(
private val konanDistribution: KonanDistribution,
private val repository: Repository,
private val dependencies: Repository,
private val libraryLoader: NativeLibraryLoader,
private val targets: List<LeafCommonizerTarget>,
private val commonTarget: SharedCommonizerTarget,
private val resultsConsumer: ResultsConsumer,
private val statsCollector: StatsCollector?,
private val progressLogger: ProgressLogger
@@ -28,10 +26,8 @@ internal class LibraryCommonizer internal constructor(
progressLogger.logTotal()
}
private fun loadLibraries(): AllNativeLibraries {
val stdlib = libraryLoader(konanDistribution.stdlib)
val librariesByTargets = targets.associateWith { target ->
private fun loadLibraries(): TargetDependent<NativeLibrariesToCommonize> {
val librariesByTargets = commonTarget.targets.associateWith { target ->
NativeLibrariesToCommonize(repository.getLibraries(target).toList())
}
@@ -41,30 +37,30 @@ internal class LibraryCommonizer internal constructor(
}
}
progressLogger.log("Resolved libraries to be commonized")
return AllNativeLibraries(stdlib, librariesByTargets)
return librariesByTargets
}
private fun commonizeAndSaveResults(allLibraries: AllNativeLibraries) {
private fun commonizeAndSaveResults(allLibraries: TargetDependent<NativeLibrariesToCommonize>) {
val parameters = CommonizerParameters(
resultsConsumer = resultsConsumer,
manifestDataProvider = TargetedNativeManifestDataProvider(allLibraries),
dependencyModulesProvider = DefaultModulesProvider.forStandardLibrary(allLibraries.stdlib),
commonDependencyModulesProvider = DefaultModulesProvider.create(dependencies.getLibraries(commonTarget)),
statsCollector = statsCollector,
progressLogger = progressLogger::log
)
allLibraries.librariesByTargets.forEach { (target, librariesToCommonize) ->
allLibraries.forEach { (target, librariesToCommonize) ->
parameters.addTarget(target, librariesToCommonize)
}
runCommonization(parameters)
}
private fun CommonizerParameters.addTarget(target: LeafCommonizerTarget, libraries: NativeLibrariesToCommonize) {
private fun CommonizerParameters.addTarget(target: CommonizerTarget, libraries: NativeLibrariesToCommonize) {
if (libraries.libraries.isEmpty()) return
val modulesProvider = DefaultModulesProvider.platformLibraries(libraries)
val dependencyModuleProvider = DefaultModulesProvider.platformLibraries(dependencies.getLibraries(target))
val modulesProvider = DefaultModulesProvider.create(libraries)
val dependencyModuleProvider = DefaultModulesProvider.create(dependencies.getLibraries(target))
addTarget(
TargetProvider(
@@ -76,9 +72,9 @@ internal class LibraryCommonizer internal constructor(
}
private fun checkPreconditions() {
when (targets.size) {
when (commonTarget.targets.size) {
0 -> progressLogger.fatal("No targets specified")
1 -> progressLogger.fatal("Too few targets specified: $targets")
1 -> progressLogger.fatal("Too few targets specified: $commonTarget")
}
}
}
@@ -10,6 +10,7 @@ import gnu.trove.THashMap
import org.jetbrains.kotlin.commonizer.CommonizerTarget
import org.jetbrains.kotlin.commonizer.LeafCommonizerTarget
import org.jetbrains.kotlin.commonizer.SharedCommonizerTarget
import org.jetbrains.kotlin.commonizer.TargetDependent
import org.jetbrains.kotlin.library.KotlinLibrary
fun interface TargetedNativeManifestDataProvider {
@@ -20,11 +21,13 @@ internal interface NativeManifestDataProvider {
fun getManifest(libraryName: String): NativeSensitiveManifestData
}
internal fun TargetedNativeManifestDataProvider(libraries: AllNativeLibraries): TargetedNativeManifestDataProvider {
internal fun TargetedNativeManifestDataProvider(
libraries: TargetDependent<NativeLibrariesToCommonize>
): TargetedNativeManifestDataProvider {
val cachedManifestProviders: Map<CommonizerTarget, NativeManifestDataProvider> = FactoryMap.create { target ->
when (target) {
is LeafCommonizerTarget -> libraries.librariesByTargets.getValue(target)
is SharedCommonizerTarget -> CommonNativeManifestDataProvider(libraries.librariesByTargets.values)
is LeafCommonizerTarget -> libraries.getValue(target)
is SharedCommonizerTarget -> CommonNativeManifestDataProvider(libraries.values)
}
}
return TargetedNativeManifestDataProvider { target, libraryName ->
@@ -54,11 +57,6 @@ internal class NativeLibrariesToCommonize(val libraries: List<NativeLibrary>) :
}
}
internal class AllNativeLibraries(
val stdlib: NativeLibrary,
val librariesByTargets: Map<LeafCommonizerTarget, NativeLibrariesToCommonize>
)
internal class CommonNativeManifestDataProvider(
libraryGroups: Collection<NativeLibrariesToCommonize>
) : NativeManifestDataProvider {
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.commonizer.mergedtree
import kotlinx.metadata.KmTypeParameter
import org.jetbrains.kotlin.commonizer.CommonizerParameters
import org.jetbrains.kotlin.commonizer.CommonizerTarget
import org.jetbrains.kotlin.commonizer.LeafCommonizerTarget
import org.jetbrains.kotlin.commonizer.ModulesProvider.ModuleInfo
import org.jetbrains.kotlin.commonizer.mergedtree.mergers.*
@@ -46,7 +47,7 @@ import org.jetbrains.kotlin.storage.StorageManager
class CirTreeMergeResult(
val root: CirRootNode,
val missingModuleInfos: Map<LeafCommonizerTarget, Collection<ModuleInfo>>
val missingModuleInfos: Map<CommonizerTarget, Collection<ModuleInfo>>
)
internal class CirTargetMergingContext(
@@ -5,13 +5,10 @@
package org.jetbrains.kotlin.commonizer.mergedtree.mergers
import org.jetbrains.kotlin.commonizer.CommonizerParameters
import org.jetbrains.kotlin.commonizer.LeafCommonizerTarget
import org.jetbrains.kotlin.commonizer.ModulesProvider
import org.jetbrains.kotlin.commonizer.*
import org.jetbrains.kotlin.commonizer.mergedtree.*
import org.jetbrains.kotlin.commonizer.mergedtree.buildRootNode
import org.jetbrains.kotlin.commonizer.metadata.CirTypeResolver
import org.jetbrains.kotlin.commonizer.prettyName
import org.jetbrains.kotlin.storage.StorageManager
internal class RootMerger(
@@ -25,7 +22,7 @@ internal class RootMerger(
val rootNode: CirRootNode = buildRootNode(storageManager, parameters.targetProviders.size)
val commonModuleNames = parameters.getCommonModuleNames()
val missingModuleInfosByTargets = mutableMapOf<LeafCommonizerTarget, Collection<ModulesProvider.ModuleInfo>>()
val missingModuleInfosByTargets = mutableMapOf<CommonizerTarget, Collection<ModulesProvider.ModuleInfo>>()
parameters.targetProviders.forEachIndexed { targetIndex, targetProvider ->
val allModuleInfos = targetProvider.modulesProvider.loadModuleInfos()
@@ -24,7 +24,7 @@ internal class FilesRepository(
.mapValues { (_, list) -> list.toSet() }
}
override fun getLibraries(target: LeafCommonizerTarget): Set<NativeLibrary> {
override fun getLibraries(target: CommonizerTarget): Set<NativeLibrary> {
return librariesByTarget[target].orEmpty()
}
}
@@ -5,11 +5,8 @@
package org.jetbrains.kotlin.commonizer.repository
import org.jetbrains.kotlin.commonizer.KonanDistribution
import org.jetbrains.kotlin.commonizer.LeafCommonizerTarget
import org.jetbrains.kotlin.commonizer.NativeLibraryLoader
import org.jetbrains.kotlin.commonizer.*
import org.jetbrains.kotlin.commonizer.konan.NativeLibrary
import org.jetbrains.kotlin.commonizer.platformLibsDir
internal class KonanDistributionRepository(
konanDistribution: KonanDistribution,
@@ -29,7 +26,10 @@ internal class KonanDistributionRepository(
}
}
override fun getLibraries(target: LeafCommonizerTarget): Set<NativeLibrary> {
return librariesByTarget[target]?.value ?: error("Missing target $target")
override fun getLibraries(target: CommonizerTarget): Set<NativeLibrary> {
return when (target) {
is LeafCommonizerTarget -> librariesByTarget[target]?.value ?: error("Missing target libraries for: $target")
is SharedCommonizerTarget -> emptySet()
}
}
}
@@ -5,11 +5,12 @@
package org.jetbrains.kotlin.commonizer.repository
import org.jetbrains.kotlin.commonizer.CommonizerTarget
import org.jetbrains.kotlin.commonizer.LeafCommonizerTarget
import org.jetbrains.kotlin.commonizer.konan.NativeLibrary
internal interface Repository {
fun getLibraries(target: LeafCommonizerTarget): Set<NativeLibrary>
fun getLibraries(target: CommonizerTarget): Set<NativeLibrary>
}
internal operator fun Repository.plus(other: Repository): Repository {
@@ -20,13 +21,13 @@ internal operator fun Repository.plus(other: Repository): Repository {
}
private class CompositeRepository(val repositories: Iterable<Repository>) : Repository {
override fun getLibraries(target: LeafCommonizerTarget): Set<NativeLibrary> {
override fun getLibraries(target: CommonizerTarget): Set<NativeLibrary> {
return repositories.map { it.getLibraries(target) }.flatten().toSet()
}
}
internal object EmptyRepository : Repository {
override fun getLibraries(target: LeafCommonizerTarget): Set<NativeLibrary> {
override fun getLibraries(target: CommonizerTarget): Set<NativeLibrary> {
return emptySet()
}
}
@@ -0,0 +1,24 @@
/*
* 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.commonizer.repository
import org.jetbrains.kotlin.commonizer.*
import org.jetbrains.kotlin.commonizer.konan.NativeLibrary
internal class StdlibRepository(
private val konanDistribution: KonanDistribution,
private val libraryLoader: NativeLibraryLoader,
) : Repository {
private val stdlib by lazy {
libraryLoader(konanDistribution.stdlib)
}
override fun getLibraries(target: CommonizerTarget): Set<NativeLibrary> {
return if (target is SharedCommonizerTarget) setOf(stdlib)
else emptySet()
}
}
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.commonizer.ResultsConsumer.ModuleResult
import org.jetbrains.kotlin.commonizer.ResultsConsumer.Status
import org.jetbrains.kotlin.commonizer.SourceModuleRoot.Companion.SHARED_TARGET_NAME
import org.jetbrains.kotlin.commonizer.cir.CirPackageName
import org.jetbrains.kotlin.commonizer.konan.TargetedNativeManifestDataProvider
import org.jetbrains.kotlin.commonizer.utils.*
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies
@@ -208,7 +207,7 @@ private class AnalyzedModules(
fun toCommonizerParameters(
resultsConsumer: ResultsConsumer, manifestDataProvider: TargetedNativeManifestDataProvider = MockNativeManifestDataProvider()
) = CommonizerParameters(
resultsConsumer, manifestDataProvider, dependencyModulesProvider = dependencyModules[sharedTarget]?.let(MockModulesProvider::create)
resultsConsumer, manifestDataProvider, commonDependencyModulesProvider = dependencyModules[sharedTarget]?.let(MockModulesProvider::create)
).also { parameters ->
leafTargets.forEach { leafTarget ->