From 10a54c25816031c7e0ea6502e1dd402ebd6ee876 Mon Sep 17 00:00:00 2001 From: Alexander Gorshenev Date: Fri, 31 May 2019 18:11:58 +0300 Subject: [PATCH] Moved the common klib writer from Kotlin/Native to util-klib --- .../jetbrains/kotlin/library/KotlinLibrary.kt | 5 +- .../kotlin/library/KotlinLibraryWriter.kt | 39 ++++++ .../kotlin/library/impl/IrWriterImpl.kt | 25 ++++ .../kotlin/library/impl/KotlinLibraryImpl.kt | 10 +- .../library/impl/KotlinLibraryWriterImpl.kt | 111 ++++++++++++++++++ .../kotlin/library/impl/MetadataWriterImpl.kt | 33 ++++++ 6 files changed, 214 insertions(+), 9 deletions(-) create mode 100644 compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibraryWriter.kt create mode 100644 compiler/util-klib/src/org/jetbrains/kotlin/library/impl/IrWriterImpl.kt create mode 100644 compiler/util-klib/src/org/jetbrains/kotlin/library/impl/KotlinLibraryWriterImpl.kt create mode 100644 compiler/util-klib/src/org/jetbrains/kotlin/library/impl/MetadataWriterImpl.kt diff --git a/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibrary.kt b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibrary.kt index 6d151f0ed45..d9067cebc1b 100644 --- a/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibrary.kt +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibrary.kt @@ -45,7 +45,4 @@ val BaseKotlinLibrary.unresolvedDependencies: List UnresolvedLibrary(it, manifestProperties.getProperty("dependency_version_$it")) } -interface BackendLibrary : BaseKotlinLibrary, MetadataLibrary, IrLibrary - - -// typealias JsLibrary = BackendLibrary? +interface KotlinLibrary : BaseKotlinLibrary, MetadataLibrary, IrLibrary diff --git a/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibraryWriter.kt b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibraryWriter.kt new file mode 100644 index 00000000000..7c340c5b2b1 --- /dev/null +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibraryWriter.kt @@ -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) + 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>, + val fragmentNames: List +) + +class SerializedIr ( + val module: ByteArray, + val combinedDeclarationFilePath: String +) \ No newline at end of file diff --git a/compiler/util-klib/src/org/jetbrains/kotlin/library/impl/IrWriterImpl.kt b/compiler/util-klib/src/org/jetbrains/kotlin/library/impl/IrWriterImpl.kt new file mode 100644 index 00000000000..123628c0704 --- /dev/null +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/impl/IrWriterImpl.kt @@ -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) + } +} diff --git a/compiler/util-klib/src/org/jetbrains/kotlin/library/impl/KotlinLibraryImpl.kt b/compiler/util-klib/src/org/jetbrains/kotlin/library/impl/KotlinLibraryImpl.kt index abd0df77e41..50a8ad49497 100644 --- a/compiler/util-klib/src/org/jetbrains/kotlin/library/impl/KotlinLibraryImpl.kt +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/impl/KotlinLibraryImpl.kt @@ -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(libraryFile) val metadataAccess = MetadataLibraryAccess(libraryFile) val irAccess = IrLibraryAccess(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) } \ No newline at end of file diff --git a/compiler/util-klib/src/org/jetbrains/kotlin/library/impl/KotlinLibraryWriterImpl.kt b/compiler/util-klib/src/org/jetbrains/kotlin/library/impl/KotlinLibraryWriterImpl.kt new file mode 100644 index 00000000000..88c6f505f01 --- /dev/null +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/impl/KotlinLibraryWriterImpl.kt @@ -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: : will go somewhere around here. + manifestProperties.setProperty(KLIB_PROPERTY_UNIQUE_NAME, moduleName) + manifestProperties.writeKonanLibraryVersioning(versions) + } + + override fun addLinkDependencies(libraries: List) { + 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, + 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 +} \ No newline at end of file diff --git a/compiler/util-klib/src/org/jetbrains/kotlin/library/impl/MetadataWriterImpl.kt b/compiler/util-klib/src/org/jetbrains/kotlin/library/impl/MetadataWriterImpl.kt new file mode 100644 index 00000000000..731b6c01593 --- /dev/null +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/impl/MetadataWriterImpl.kt @@ -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) + } + } + } +}