KLIB: Store native targets in manifest

This commit is contained in:
Dmitriy Dolovov
2020-04-03 16:03:57 +07:00
parent 1b06256650
commit 101442ad14
5 changed files with 101 additions and 20 deletions
@@ -23,6 +23,7 @@ open class BaseWriterImpl(
moduleName: String,
override val versions: KotlinLibraryVersioning,
builtInsPlatform: BuiltInsPlatform,
nativeTargets: List<String> = emptyList(),
val nopack: Boolean = false,
val shortName: String? = null
) : BaseWriter {
@@ -39,11 +40,14 @@ open class BaseWriterImpl(
// TODO: <name>:<hash> will go somewhere around here.
manifestProperties.setProperty(KLIB_PROPERTY_UNIQUE_NAME, moduleName)
manifestProperties.writeKonanLibraryVersioning(versions)
if (builtInsPlatform != BuiltInsPlatform.COMMON)
if (builtInsPlatform != BuiltInsPlatform.COMMON) {
manifestProperties.setProperty(KLIB_PROPERTY_BUILTINS_PLATFORM, builtInsPlatform.name)
shortName?.let {
manifestProperties.setProperty(KLIB_PROPERTY_SHORT_NAME, it)
if (builtInsPlatform == BuiltInsPlatform.NATIVE)
manifestProperties.setProperty(KLIB_PROPERTY_NATIVE_TARGETS, nativeTargets.joinToString(" "))
}
shortName?.let { manifestProperties.setProperty(KLIB_PROPERTY_SHORT_NAME, it) }
}
override fun addLinkDependencies(libraries: List<KotlinLibrary>) {
@@ -86,12 +90,13 @@ class KoltinLibraryWriterImpl(
moduleName: String,
versions: KotlinLibraryVersioning,
builtInsPlatform: BuiltInsPlatform,
nativeTargets: List<String>,
nopack: Boolean = false,
shortName: String? = null,
val layout: KotlinLibraryLayoutForWriter = KotlinLibraryLayoutForWriter(libDir),
val base: BaseWriter = BaseWriterImpl(layout, moduleName, versions, builtInsPlatform, nopack, shortName),
val base: BaseWriter = BaseWriterImpl(layout, moduleName, versions, builtInsPlatform, nativeTargets, nopack, shortName),
metadata: MetadataWriter = MetadataWriterImpl(layout),
ir: IrWriter = IrMonoliticWriterImpl(layout)
// ir: IrWriter = IrPerFileWriterImpl(layout)
@@ -108,10 +113,11 @@ fun buildKoltinLibrary(
nopack: Boolean,
manifestProperties: Properties?,
dataFlowGraph: ByteArray?,
builtInsPlatform: BuiltInsPlatform
builtInsPlatform: BuiltInsPlatform,
nativeTargets: List<String> = emptyList()
): KotlinLibraryLayout {
val library = KoltinLibraryWriterImpl(File(output), moduleName, versions, builtInsPlatform, nopack)
val library = KoltinLibraryWriterImpl(File(output), moduleName, versions, builtInsPlatform, nativeTargets, nopack)
library.addMetadata(metadata)
@@ -169,6 +169,8 @@ class NativeDistributionCommonizer(
}
}
val commonManifestProvider = CommonNativeManifestDataProvider(originalLibrariesByTargets.values)
val serializer = KlibMetadataMonolithicSerializer(
languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
metadataVersion = KlibMetadataVersion.INSTANCE,
@@ -177,16 +179,16 @@ class NativeDistributionCommonizer(
fun serializeTarget(target: Target) {
val libsDestination: File
val originalLibraries: NativeDistributionLibraries
val manifestProvider: NativeManifestDataProvider
when (target) {
is InputTarget -> {
libsDestination = destination.resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR).resolve(target.konanTarget!!.name)
originalLibraries = originalLibrariesByTargets.getValue(target)
manifestProvider = originalLibrariesByTargets.getValue(target)
}
is OutputTarget -> {
libsDestination = destination.resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR)
originalLibraries = originalLibrariesByTargets.values.first() // just take the first one
manifestProvider = commonManifestProvider
}
}
@@ -201,7 +203,7 @@ class NativeDistributionCommonizer(
val metadata = serializer.serializeModule(newModule)
val plainName = libraryName.asString().removePrefix("<").removeSuffix(">")
val manifestData = originalLibraries.index.getValue(plainName).manifestData
val manifestData = manifestProvider.getManifest(plainName)
val libraryDestination = libsDestination.resolve(plainName)
writeLibrary(metadata, manifestData, libraryDestination)
@@ -218,10 +220,11 @@ class NativeDistributionCommonizer(
destination: File
) {
val library = KoltinLibraryWriterImpl(
KFile(destination.path),
manifestData.uniqueName,
manifestData.versions,
BuiltInsPlatform.NATIVE,
libDir = KFile(destination.path),
moduleName = manifestData.uniqueName,
versions = manifestData.versions,
builtInsPlatform = BuiltInsPlatform.NATIVE,
nativeTargets = emptyList(), // will be overwritten with NativeSensitiveManifestData.applyTo() below
nopack = true,
shortName = manifestData.shortName
)
@@ -7,20 +7,63 @@ package org.jetbrains.kotlin.descriptors.commonizer.konan
import org.jetbrains.kotlin.library.KotlinLibrary
internal interface NativeManifestDataProvider {
fun getManifest(libraryName: String): NativeSensitiveManifestData
}
/**
* A separate Kotlin/Native library from the distribution.
*/
internal class NativeDistributionLibrary(
val library: KotlinLibrary
) {
val manifestData = NativeSensitiveManifestData.readFrom(library)
}
/**
* A collection of Kotlin/Native libraries for a certain Native target + stdlib from the distribution.
*/
internal class NativeDistributionLibraries(
val stdlib: NativeDistributionLibrary,
val platformLibs: List<NativeDistributionLibrary>
) {
) : NativeManifestDataProvider {
constructor(stdlib: KotlinLibrary, platformLibs: List<KotlinLibrary>) : this(
NativeDistributionLibrary(stdlib),
platformLibs.map(::NativeDistributionLibrary)
)
val index: Map<String, NativeDistributionLibrary> = (platformLibs + stdlib).associateBy { it.manifestData.uniqueName }
private val manifestIndex: Map<String, NativeSensitiveManifestData> = buildManifestIndex()
override fun getManifest(libraryName: String) = manifestIndex.getValue(libraryName)
}
internal class CommonNativeManifestDataProvider(
libraryGroups: Collection<NativeDistributionLibraries>
) : NativeManifestDataProvider {
private val manifestIndex: Map<String, NativeSensitiveManifestData>
init {
val iterator = libraryGroups.iterator()
val index = iterator.next().buildManifestIndex()
while (iterator.hasNext()) {
val otherIndex = iterator.next().buildManifestIndex()
otherIndex.forEach { (libraryName, otherManifestData) ->
val manifestData = index[libraryName]
if (manifestData != null) {
// merge manifests
index[libraryName] = manifestData.mergeWith(otherManifestData)
} else {
index[libraryName] = otherManifestData
}
}
}
manifestIndex = index
}
override fun getManifest(libraryName: String) = manifestIndex.getValue(libraryName)
}
private fun NativeDistributionLibraries.buildManifestIndex(): MutableMap<String, NativeSensitiveManifestData> =
(platformLibs + stdlib).map { it.manifestData }.associateByTo(HashMap()) { it.uniqueName }
@@ -56,9 +56,7 @@ internal class NativeDistributionModulesProvider(
)
platformModulesMap.forEach { (name, module) ->
val dependencies = libraries.index
.getValue(name)
.manifestData
val dependencies = libraries.getManifest(name)
.dependencies
.map { if (it == KONAN_STDLIB_NAME) stdlib else platformModulesMap.getValue(it) }
@@ -9,6 +9,10 @@ import org.jetbrains.kotlin.konan.properties.propertyList
import org.jetbrains.kotlin.library.*
import org.jetbrains.kotlin.library.impl.BaseWriterImpl
/**
* The set of properties in manifest of Kotlin/Native library that should be
* preserved in commonized libraries (both for "common" and platform-specific library parts).
*/
internal data class NativeSensitiveManifestData(
val uniqueName: String,
val versions: KotlinLibraryVersioning,
@@ -16,6 +20,7 @@ internal data class NativeSensitiveManifestData(
val isInterop: Boolean,
val packageFqName: String?,
val exportForwardDeclarations: List<String>,
val nativeTargets: Collection<String>,
val shortName: String?
) {
fun applyTo(library: BaseWriterImpl) {
@@ -33,11 +38,36 @@ internal data class NativeSensitiveManifestData(
addOptionalProperty(KLIB_PROPERTY_INTEROP, isInterop) { "true" }
addOptionalProperty(KLIB_PROPERTY_PACKAGE, packageFqName != null) { packageFqName!! }
addOptionalProperty(KLIB_PROPERTY_EXPORT_FORWARD_DECLARATIONS, exportForwardDeclarations.isNotEmpty()) {
exportForwardDeclarations.joinToString(separator = " ")
exportForwardDeclarations.joinToString(" ")
}
addOptionalProperty(KLIB_PROPERTY_NATIVE_TARGETS, nativeTargets.isNotEmpty()) {
nativeTargets.joinToString(" ")
}
addOptionalProperty(KLIB_PROPERTY_SHORT_NAME, shortName != null) { shortName!! }
}
fun mergeWith(other: NativeSensitiveManifestData): NativeSensitiveManifestData {
if (this === other) return this
check(uniqueName == other.uniqueName)
// Assumption: It's enough to merge native targets list, other properties can be taken from 'this' manifest.
return NativeSensitiveManifestData(
uniqueName = uniqueName,
versions = versions,
dependencies = dependencies,
isInterop = isInterop,
packageFqName = packageFqName,
exportForwardDeclarations = exportForwardDeclarations,
nativeTargets = HashSet<String>().apply {
addAll(nativeTargets)
addAll(other.nativeTargets)
},
shortName = shortName
)
}
companion object {
fun readFrom(library: KotlinLibrary) = NativeSensitiveManifestData(
uniqueName = library.uniqueName,
@@ -46,6 +76,7 @@ internal data class NativeSensitiveManifestData(
isInterop = library.isInterop,
packageFqName = library.packageFqName,
exportForwardDeclarations = library.exportForwardDeclarations,
nativeTargets = library.nativeTargets,
shortName = library.shortName
)
}