Moved the common klib writer from Kotlin/Native to util-klib

This commit is contained in:
Alexander Gorshenev
2019-05-31 18:11:58 +03:00
committed by alexander-gorshenev
parent 7ddbd8ca80
commit 10a54c2581
6 changed files with 214 additions and 9 deletions
@@ -45,7 +45,4 @@ val BaseKotlinLibrary.unresolvedDependencies: List<UnresolvedLibrary>
UnresolvedLibrary(it, manifestProperties.getProperty("dependency_version_$it"))
}
interface BackendLibrary : BaseKotlinLibrary, MetadataLibrary, IrLibrary
// typealias JsLibrary = BackendLibrary?
interface KotlinLibrary : BaseKotlinLibrary, MetadataLibrary, IrLibrary
@@ -0,0 +1,39 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
package org.jetbrains.kotlin.library
import org.jetbrains.kotlin.library.*
import org.jetbrains.kotlin.konan.properties.Properties
interface BaseWriter {
val versions: KonanLibraryVersioning
fun addLinkDependencies(libraries: List<KotlinLibrary>)
fun addManifestAddend(properties: Properties)
fun commit()
}
interface MetadataWriter {
fun addMetadata(metadata: SerializedMetadata)
}
interface IrWriter {
fun addIr(ir: SerializedIr)
fun addDataFlowGraph(dataFlowGraph: ByteArray)
}
interface KotlinLibraryWriter : MetadataWriter, BaseWriter, IrWriter
// TODO: Move SerializedIr here too to eliminate dependency on backend.common.serialization
class SerializedMetadata(
val module: ByteArray,
val fragments: List<List<ByteArray>>,
val fragmentNames: List<String>
)
class SerializedIr (
val module: ByteArray,
val combinedDeclarationFilePath: String
)
@@ -0,0 +1,25 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
package org.jetbrains.kotlin.library.impl
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.library.*
class IrWriterImpl(val irLayout: IrKotlinLibraryLayout) : IrWriter {
init {
irLayout.irDir.mkdirs()
}
override fun addIr(ir: SerializedIr) {
irLayout.irHeader.writeBytes(ir.module)
// TODO: use Files.move.
File(ir.combinedDeclarationFilePath).copyTo(irLayout.irFile)
}
override fun addDataFlowGraph(dataFlowGraph: ByteArray) {
irLayout.dataFlowGraphFile.writeBytes(dataFlowGraph)
}
}
@@ -108,19 +108,19 @@ open class IrLibraryImpl(
}
}
open class BackendLibraryImpl(
open class KotlinLibraryImpl(
base: BaseKotlinLibraryImpl,
metadata: MetadataLibraryImpl,
ir: IrLibraryImpl
) : BackendLibrary,
) : KotlinLibrary,
BaseKotlinLibrary by base,
MetadataLibrary by metadata,
IrLibrary by ir
fun createBackendLibrary(
fun createKotlinLibrary(
libraryFile: File,
isDefault: Boolean = false
): BackendLibrary {
): KotlinLibrary {
val baseAccess = BaseLibraryAccess<KotlinLibraryLayout>(libraryFile)
val metadataAccess = MetadataLibraryAccess<MetadataKotlinLibraryLayout>(libraryFile)
val irAccess = IrLibraryAccess<IrKotlinLibraryLayout>(libraryFile)
@@ -129,5 +129,5 @@ fun createBackendLibrary(
val metadata = MetadataLibraryImpl(metadataAccess)
val ir = IrLibraryImpl(irAccess)
return BackendLibraryImpl(base, metadata, ir)
return KotlinLibraryImpl(base, metadata, ir)
}
@@ -0,0 +1,111 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
package org.jetbrains.kotlin.library.impl
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.file.zipDirAs
import org.jetbrains.kotlin.konan.properties.Properties
import org.jetbrains.kotlin.konan.properties.saveToFile
import org.jetbrains.kotlin.library.*
open class KotlinLibraryLayoutForWriter(
override val libDir: File
) : KotlinLibraryLayout, MetadataKotlinLibraryLayout, IrKotlinLibraryLayout
open class BaseWriterImpl(
val libraryLayout: KotlinLibraryLayoutForWriter,
moduleName: String,
override val versions: KonanLibraryVersioning,
val nopack: Boolean = false
) : BaseWriter {
val klibFile = File("${libraryLayout.libDir.path}.$KLIB_FILE_EXTENSION")
val manifestProperties = Properties()
init {
// TODO: figure out the proper policy here.
libraryLayout.libDir.deleteRecursively()
klibFile.delete()
libraryLayout.libDir.mkdirs()
libraryLayout.resourcesDir.mkdirs()
// TODO: <name>:<hash> will go somewhere around here.
manifestProperties.setProperty(KLIB_PROPERTY_UNIQUE_NAME, moduleName)
manifestProperties.writeKonanLibraryVersioning(versions)
}
override fun addLinkDependencies(libraries: List<KotlinLibrary>) {
if (libraries.isEmpty()) {
manifestProperties.remove(KLIB_PROPERTY_DEPENDS)
// make sure there are no leftovers from the .def file.
return
} else {
val newValue = libraries.joinToString(" ") { it.uniqueName }
manifestProperties.setProperty(KLIB_PROPERTY_DEPENDS, newValue)
libraries.forEach { it ->
if (it.versions.libraryVersion != null) {
manifestProperties.setProperty(
"${KLIB_PROPERTY_DEPENDENCY_VERSION}_${it.uniqueName}",
it.versions.libraryVersion
)
}
}
}
}
override fun addManifestAddend(properties: Properties) {
manifestProperties.putAll(properties)
}
override fun commit() {
manifestProperties.saveToFile(libraryLayout.manifestFile)
if (!nopack) {
libraryLayout.libDir.zipDirAs(klibFile)
libraryLayout.libDir.deleteRecursively()
}
}
}
/**
* Requires non-null [target].
*/
class KoltinLibraryWriterImpl(
libDir: File,
moduleName: String,
versions: KonanLibraryVersioning,
nopack: Boolean = false,
val layout: KotlinLibraryLayoutForWriter = KotlinLibraryLayoutForWriter(libDir),
base: BaseWriter = BaseWriterImpl(layout, moduleName, versions, nopack),
metadata: MetadataWriter = MetadataWriterImpl(layout),
ir: IrWriter = IrWriterImpl(layout)
) : BaseWriter by base, MetadataWriter by metadata, IrWriter by ir, KotlinLibraryWriter
internal fun buildKoltinLibrary(
linkDependencies: List<KotlinLibrary>,
metadata: SerializedMetadata,
ir: SerializedIr,
versions: KonanLibraryVersioning,
output: String,
moduleName: String,
nopack: Boolean,
manifestProperties: Properties?,
dataFlowGraph: ByteArray?
): KotlinLibraryLayout {
val library = KoltinLibraryWriterImpl(File(output), moduleName, versions, nopack)
library.addMetadata(metadata)
library.addIr(ir)
manifestProperties?.let { library.addManifestAddend(it) }
library.addLinkDependencies(linkDependencies)
dataFlowGraph?.let { library.addDataFlowGraph(it) }
library.commit()
return library.layout
}
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
package org.jetbrains.kotlin.library.impl
import org.jetbrains.kotlin.library.MetadataKotlinLibraryLayout
import org.jetbrains.kotlin.library.MetadataWriter
import org.jetbrains.kotlin.library.SerializedMetadata
class MetadataWriterImpl(val metadataLayout: MetadataKotlinLibraryLayout) : MetadataWriter {
init {
metadataLayout.metadataDir.mkdirs()
}
override fun addMetadata(metadata: SerializedMetadata) {
metadataLayout.moduleHeaderFile.writeBytes(metadata.module)
metadata.fragments.forEachIndexed { index, it ->
val packageFqName = metadata.fragmentNames[index]
val shortName = packageFqName.substringAfterLast(".")
val dir = metadataLayout.packageFragmentsDir(packageFqName)
dir.deleteRecursively()
dir.mkdirs()
val numCount = it.size.toString().length
fun withLeadingZeros(i: Int) = String.format("%0${numCount}d", i)
for ((i, fragment) in it.withIndex()) {
metadataLayout.packageFragmentFile(packageFqName, "${withLeadingZeros(i)}_$shortName")
.writeBytes(fragment)
}
}
}
}