[Commonizer] NativeKlibCommonize: Only load dependencies from native distribution

This commit is contained in:
sebastian.sellmair
2021-03-11 12:00:45 +01:00
committed by Space
parent 97a57a7d93
commit b777c89bc8
6 changed files with 60 additions and 45 deletions
@@ -11,20 +11,14 @@ import org.jetbrains.kotlin.descriptors.commonizer.stats.StatsCollector
class CommonizerParameters(
val resultsConsumer: ResultsConsumer,
val manifestDataProvider: TargetedNativeManifestDataProvider,
// common module dependencies (ex: Kotlin stdlib)
val dependencyModulesProvider: ModulesProvider? = null,
val statsCollector: StatsCollector? = null,
val progressLogger: ((String) -> Unit)? = null
) {
// use linked hash map to preserve order
private val _targetProviders = LinkedHashMap<LeafCommonizerTarget, TargetProvider>()
val targetProviders: List<TargetProvider> get() = _targetProviders.values.toList()
val sharedTarget: SharedCommonizerTarget get() = SharedCommonizerTarget(_targetProviders.keys)
// common module dependencies (ex: Kotlin stdlib)
var dependencyModulesProvider: ModulesProvider? = null
set(value) {
check(field == null)
field = value
}
fun addTarget(targetProvider: TargetProvider): CommonizerParameters {
require(targetProvider.target !in _targetProviders) { "Target ${targetProvider.target} is already added" }
@@ -7,15 +7,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.cli
import org.jetbrains.kotlin.descriptors.commonizer.*
import org.jetbrains.kotlin.descriptors.commonizer.konan.*
import org.jetbrains.kotlin.descriptors.commonizer.konan.CopyUnconsumedModulesAsIsConsumer
import org.jetbrains.kotlin.descriptors.commonizer.konan.CopyStdlibResultsConsumer
import org.jetbrains.kotlin.descriptors.commonizer.konan.LibraryCommonizer
import org.jetbrains.kotlin.descriptors.commonizer.konan.ModuleSerializer
import org.jetbrains.kotlin.descriptors.commonizer.repository.*
import org.jetbrains.kotlin.descriptors.commonizer.repository.EmptyRepository
import org.jetbrains.kotlin.descriptors.commonizer.repository.FilesRepository
import org.jetbrains.kotlin.descriptors.commonizer.repository.KonanDistributionRepository
import org.jetbrains.kotlin.descriptors.commonizer.repository.Repository
import org.jetbrains.kotlin.descriptors.commonizer.stats.FileStatsOutput
import org.jetbrains.kotlin.descriptors.commonizer.stats.StatsCollector
import org.jetbrains.kotlin.descriptors.commonizer.stats.StatsType
@@ -78,8 +70,11 @@ internal class NativeKlibCommonize(options: Collection<Option<*>>) : Task(option
LibraryCommonizer(
konanDistribution = distribution,
repository = repository,
dependencies = KonanDistributionRepository(distribution, commonizerTargets.toSet(), libraryLoader) +
FilesRepository(dependencyLibraries.toSet(), libraryLoader),
dependencies =
KonanDistributionRepository(
distribution, commonizerTargets.toSet(), libraryLoader,
filter = KonanDistributionRepository.Filter.onlyDependenciesOf(repository)
) + FilesRepository(dependencyLibraries.toSet(), libraryLoader),
libraryLoader = libraryLoader,
targets = commonizerTargets,
resultsConsumer = resultsConsumer,
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.library.SerializedMetadata
import org.jetbrains.kotlin.library.metadata.parseModuleHeader
import java.io.File
internal class NativeDistributionModulesProvider(libraries: Collection<NativeLibrary>) : ModulesProvider {
internal class DefaultModulesProvider(libraries: Collection<NativeLibrary>) : ModulesProvider {
internal class NativeModuleInfo(
name: String,
originalLocation: File,
@@ -69,10 +69,13 @@ internal class NativeDistributionModulesProvider(libraries: Collection<NativeLib
companion object {
fun forStandardLibrary(stdlib: NativeLibrary): ModulesProvider {
check(stdlib.manifestData.uniqueName == KONAN_STDLIB_NAME)
return NativeDistributionModulesProvider(listOf(stdlib))
return DefaultModulesProvider(listOf(stdlib))
}
fun platformLibraries(librariesToCommonize: NativeLibrariesToCommonize): ModulesProvider =
NativeDistributionModulesProvider(librariesToCommonize.libraries)
DefaultModulesProvider(librariesToCommonize.libraries)
fun platformLibraries(libraries: Iterable<NativeLibrary>): ModulesProvider =
DefaultModulesProvider(libraries.toList())
}
}
@@ -6,11 +6,9 @@
package org.jetbrains.kotlin.descriptors.commonizer.konan
import org.jetbrains.kotlin.descriptors.commonizer.*
import org.jetbrains.kotlin.descriptors.commonizer.konan.LibraryCommonizer.*
import org.jetbrains.kotlin.descriptors.commonizer.repository.Repository
import org.jetbrains.kotlin.descriptors.commonizer.stats.StatsCollector
import org.jetbrains.kotlin.descriptors.commonizer.utils.ProgressLogger
import org.jetbrains.kotlin.konan.library.*
internal class LibraryCommonizer internal constructor(
private val konanDistribution: KonanDistribution,
@@ -47,32 +45,36 @@ internal class LibraryCommonizer internal constructor(
}
private fun commonizeAndSaveResults(allLibraries: AllNativeLibraries) {
val manifestProvider = TargetedNativeManifestDataProvider(allLibraries)
val parameters = CommonizerParameters(
resultsConsumer = resultsConsumer,
manifestDataProvider = TargetedNativeManifestDataProvider(allLibraries),
dependencyModulesProvider = DefaultModulesProvider.forStandardLibrary(allLibraries.stdlib),
statsCollector = statsCollector,
progressLogger = progressLogger::log
)
val parameters = CommonizerParameters(resultsConsumer, manifestProvider, statsCollector, progressLogger::log).apply {
dependencyModulesProvider = NativeDistributionModulesProvider.forStandardLibrary(allLibraries.stdlib)
allLibraries.librariesByTargets.forEach { (target, librariesToCommonize) ->
if (librariesToCommonize.libraries.isEmpty()) return@forEach
val modulesProvider = NativeDistributionModulesProvider.platformLibraries(librariesToCommonize)
val dependencyModuleProvider = NativeDistributionModulesProvider.platformLibraries(
NativeLibrariesToCommonize(dependencies.getLibraries(target).toList()),
)
addTarget(
TargetProvider(
target = target,
modulesProvider = modulesProvider,
dependencyModulesProvider = dependencyModuleProvider
)
)
}
allLibraries.librariesByTargets.forEach { (target, librariesToCommonize) ->
parameters.addTarget(target, librariesToCommonize)
}
runCommonization(parameters)
}
private fun CommonizerParameters.addTarget(target: LeafCommonizerTarget, libraries: NativeLibrariesToCommonize) {
if (libraries.libraries.isEmpty()) return
val modulesProvider = DefaultModulesProvider.platformLibraries(libraries)
val dependencyModuleProvider = DefaultModulesProvider.platformLibraries(dependencies.getLibraries(target))
addTarget(
TargetProvider(
target = target,
modulesProvider = modulesProvider,
dependencyModulesProvider = dependencyModuleProvider
)
)
}
private fun checkPreconditions() {
when (targets.size) {
0 -> progressLogger.fatal("No targets specified")
@@ -10,12 +10,19 @@ import org.jetbrains.kotlin.descriptors.commonizer.LeafCommonizerTarget
import org.jetbrains.kotlin.descriptors.commonizer.NativeLibraryLoader
import org.jetbrains.kotlin.descriptors.commonizer.konan.NativeLibrary
import org.jetbrains.kotlin.descriptors.commonizer.platformLibsDir
import org.jetbrains.kotlin.descriptors.commonizer.repository.KonanDistributionRepository.Filter
internal class KonanDistributionRepository(
konanDistribution: KonanDistribution,
targets: Set<LeafCommonizerTarget>,
libraryLoader: NativeLibraryLoader,
filter: Filter = Filter.none()
) : Repository {
fun interface Filter {
operator fun invoke(target: LeafCommonizerTarget, library: NativeLibrary): Boolean
companion object Factory
}
private val librariesByTarget: Map<LeafCommonizerTarget, Lazy<Set<NativeLibrary>>> =
targets.associateWith { target ->
@@ -26,6 +33,7 @@ internal class KonanDistributionRepository(
?.listFiles()
.orEmpty().toList()
.map { libraryLoader(it) }
.filter { filter(target, it) }
.toSet()
}
}
@@ -34,3 +42,15 @@ internal class KonanDistributionRepository(
return librariesByTarget[target]?.value ?: error("Missing target $target")
}
}
internal fun Filter.Factory.onlyDependenciesOf(libraries: Repository): Filter {
val requestedDependencies = mutableMapOf<LeafCommonizerTarget, Set<String>>()
return Filter { target, dependency ->
val requestedDependenciesForTarget = requestedDependencies.getOrPut(target) {
libraries.getLibraries(target).flatMap { library -> library.manifestData.dependencies }.toSet()
}
dependency.manifestData.uniqueName in requestedDependenciesForTarget
}
}
internal fun Filter.Factory.none() = Filter { _, _ -> true }
@@ -207,8 +207,9 @@ private class AnalyzedModules(
fun toCommonizerParameters(
resultsConsumer: ResultsConsumer, manifestDataProvider: TargetedNativeManifestDataProvider = MockNativeManifestDataProvider()
) = CommonizerParameters(resultsConsumer, manifestDataProvider).also { parameters ->
parameters.dependencyModulesProvider = dependencyModules[sharedTarget]?.let(MockModulesProvider::create)
) = CommonizerParameters(
resultsConsumer, manifestDataProvider, dependencyModulesProvider = dependencyModules[sharedTarget]?.let(MockModulesProvider::create)
).also { parameters ->
leafTargets.forEach { leafTarget ->
val originalModule = originalModules.getValue(leafTarget)