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, moduleName: String,
override val versions: KotlinLibraryVersioning, override val versions: KotlinLibraryVersioning,
builtInsPlatform: BuiltInsPlatform, builtInsPlatform: BuiltInsPlatform,
nativeTargets: List<String> = emptyList(),
val nopack: Boolean = false, val nopack: Boolean = false,
val shortName: String? = null val shortName: String? = null
) : BaseWriter { ) : BaseWriter {
@@ -39,11 +40,14 @@ open class BaseWriterImpl(
// TODO: <name>:<hash> will go somewhere around here. // TODO: <name>:<hash> will go somewhere around here.
manifestProperties.setProperty(KLIB_PROPERTY_UNIQUE_NAME, moduleName) manifestProperties.setProperty(KLIB_PROPERTY_UNIQUE_NAME, moduleName)
manifestProperties.writeKonanLibraryVersioning(versions) manifestProperties.writeKonanLibraryVersioning(versions)
if (builtInsPlatform != BuiltInsPlatform.COMMON)
if (builtInsPlatform != BuiltInsPlatform.COMMON) {
manifestProperties.setProperty(KLIB_PROPERTY_BUILTINS_PLATFORM, builtInsPlatform.name) manifestProperties.setProperty(KLIB_PROPERTY_BUILTINS_PLATFORM, builtInsPlatform.name)
shortName?.let { if (builtInsPlatform == BuiltInsPlatform.NATIVE)
manifestProperties.setProperty(KLIB_PROPERTY_SHORT_NAME, it) manifestProperties.setProperty(KLIB_PROPERTY_NATIVE_TARGETS, nativeTargets.joinToString(" "))
} }
shortName?.let { manifestProperties.setProperty(KLIB_PROPERTY_SHORT_NAME, it) }
} }
override fun addLinkDependencies(libraries: List<KotlinLibrary>) { override fun addLinkDependencies(libraries: List<KotlinLibrary>) {
@@ -86,12 +90,13 @@ class KoltinLibraryWriterImpl(
moduleName: String, moduleName: String,
versions: KotlinLibraryVersioning, versions: KotlinLibraryVersioning,
builtInsPlatform: BuiltInsPlatform, builtInsPlatform: BuiltInsPlatform,
nativeTargets: List<String>,
nopack: Boolean = false, nopack: Boolean = false,
shortName: String? = null, shortName: String? = null,
val layout: KotlinLibraryLayoutForWriter = KotlinLibraryLayoutForWriter(libDir), 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), metadata: MetadataWriter = MetadataWriterImpl(layout),
ir: IrWriter = IrMonoliticWriterImpl(layout) ir: IrWriter = IrMonoliticWriterImpl(layout)
// ir: IrWriter = IrPerFileWriterImpl(layout) // ir: IrWriter = IrPerFileWriterImpl(layout)
@@ -108,10 +113,11 @@ fun buildKoltinLibrary(
nopack: Boolean, nopack: Boolean,
manifestProperties: Properties?, manifestProperties: Properties?,
dataFlowGraph: ByteArray?, dataFlowGraph: ByteArray?,
builtInsPlatform: BuiltInsPlatform builtInsPlatform: BuiltInsPlatform,
nativeTargets: List<String> = emptyList()
): KotlinLibraryLayout { ): KotlinLibraryLayout {
val library = KoltinLibraryWriterImpl(File(output), moduleName, versions, builtInsPlatform, nopack) val library = KoltinLibraryWriterImpl(File(output), moduleName, versions, builtInsPlatform, nativeTargets, nopack)
library.addMetadata(metadata) library.addMetadata(metadata)
@@ -169,6 +169,8 @@ class NativeDistributionCommonizer(
} }
} }
val commonManifestProvider = CommonNativeManifestDataProvider(originalLibrariesByTargets.values)
val serializer = KlibMetadataMonolithicSerializer( val serializer = KlibMetadataMonolithicSerializer(
languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT, languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
metadataVersion = KlibMetadataVersion.INSTANCE, metadataVersion = KlibMetadataVersion.INSTANCE,
@@ -177,16 +179,16 @@ class NativeDistributionCommonizer(
fun serializeTarget(target: Target) { fun serializeTarget(target: Target) {
val libsDestination: File val libsDestination: File
val originalLibraries: NativeDistributionLibraries val manifestProvider: NativeManifestDataProvider
when (target) { when (target) {
is InputTarget -> { is InputTarget -> {
libsDestination = destination.resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR).resolve(target.konanTarget!!.name) libsDestination = destination.resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR).resolve(target.konanTarget!!.name)
originalLibraries = originalLibrariesByTargets.getValue(target) manifestProvider = originalLibrariesByTargets.getValue(target)
} }
is OutputTarget -> { is OutputTarget -> {
libsDestination = destination.resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR) 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 metadata = serializer.serializeModule(newModule)
val plainName = libraryName.asString().removePrefix("<").removeSuffix(">") val plainName = libraryName.asString().removePrefix("<").removeSuffix(">")
val manifestData = originalLibraries.index.getValue(plainName).manifestData val manifestData = manifestProvider.getManifest(plainName)
val libraryDestination = libsDestination.resolve(plainName) val libraryDestination = libsDestination.resolve(plainName)
writeLibrary(metadata, manifestData, libraryDestination) writeLibrary(metadata, manifestData, libraryDestination)
@@ -218,10 +220,11 @@ class NativeDistributionCommonizer(
destination: File destination: File
) { ) {
val library = KoltinLibraryWriterImpl( val library = KoltinLibraryWriterImpl(
KFile(destination.path), libDir = KFile(destination.path),
manifestData.uniqueName, moduleName = manifestData.uniqueName,
manifestData.versions, versions = manifestData.versions,
BuiltInsPlatform.NATIVE, builtInsPlatform = BuiltInsPlatform.NATIVE,
nativeTargets = emptyList(), // will be overwritten with NativeSensitiveManifestData.applyTo() below
nopack = true, nopack = true,
shortName = manifestData.shortName shortName = manifestData.shortName
) )
@@ -7,20 +7,63 @@ package org.jetbrains.kotlin.descriptors.commonizer.konan
import org.jetbrains.kotlin.library.KotlinLibrary 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( internal class NativeDistributionLibrary(
val library: KotlinLibrary val library: KotlinLibrary
) { ) {
val manifestData = NativeSensitiveManifestData.readFrom(library) val manifestData = NativeSensitiveManifestData.readFrom(library)
} }
/**
* A collection of Kotlin/Native libraries for a certain Native target + stdlib from the distribution.
*/
internal class NativeDistributionLibraries( internal class NativeDistributionLibraries(
val stdlib: NativeDistributionLibrary, val stdlib: NativeDistributionLibrary,
val platformLibs: List<NativeDistributionLibrary> val platformLibs: List<NativeDistributionLibrary>
) { ) : NativeManifestDataProvider {
constructor(stdlib: KotlinLibrary, platformLibs: List<KotlinLibrary>) : this( constructor(stdlib: KotlinLibrary, platformLibs: List<KotlinLibrary>) : this(
NativeDistributionLibrary(stdlib), NativeDistributionLibrary(stdlib),
platformLibs.map(::NativeDistributionLibrary) 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) -> platformModulesMap.forEach { (name, module) ->
val dependencies = libraries.index val dependencies = libraries.getManifest(name)
.getValue(name)
.manifestData
.dependencies .dependencies
.map { if (it == KONAN_STDLIB_NAME) stdlib else platformModulesMap.getValue(it) } .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.*
import org.jetbrains.kotlin.library.impl.BaseWriterImpl 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( internal data class NativeSensitiveManifestData(
val uniqueName: String, val uniqueName: String,
val versions: KotlinLibraryVersioning, val versions: KotlinLibraryVersioning,
@@ -16,6 +20,7 @@ internal data class NativeSensitiveManifestData(
val isInterop: Boolean, val isInterop: Boolean,
val packageFqName: String?, val packageFqName: String?,
val exportForwardDeclarations: List<String>, val exportForwardDeclarations: List<String>,
val nativeTargets: Collection<String>,
val shortName: String? val shortName: String?
) { ) {
fun applyTo(library: BaseWriterImpl) { fun applyTo(library: BaseWriterImpl) {
@@ -33,11 +38,36 @@ internal data class NativeSensitiveManifestData(
addOptionalProperty(KLIB_PROPERTY_INTEROP, isInterop) { "true" } addOptionalProperty(KLIB_PROPERTY_INTEROP, isInterop) { "true" }
addOptionalProperty(KLIB_PROPERTY_PACKAGE, packageFqName != null) { packageFqName!! } addOptionalProperty(KLIB_PROPERTY_PACKAGE, packageFqName != null) { packageFqName!! }
addOptionalProperty(KLIB_PROPERTY_EXPORT_FORWARD_DECLARATIONS, exportForwardDeclarations.isNotEmpty()) { 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!! } 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 { companion object {
fun readFrom(library: KotlinLibrary) = NativeSensitiveManifestData( fun readFrom(library: KotlinLibrary) = NativeSensitiveManifestData(
uniqueName = library.uniqueName, uniqueName = library.uniqueName,
@@ -46,6 +76,7 @@ internal data class NativeSensitiveManifestData(
isInterop = library.isInterop, isInterop = library.isInterop,
packageFqName = library.packageFqName, packageFqName = library.packageFqName,
exportForwardDeclarations = library.exportForwardDeclarations, exportForwardDeclarations = library.exportForwardDeclarations,
nativeTargets = library.nativeTargets,
shortName = library.shortName shortName = library.shortName
) )
} }