From 42cbf8428b760d98f11c3f2f732176573429c4c7 Mon Sep 17 00:00:00 2001 From: Alexander Gorshenev Date: Tue, 26 Sep 2017 17:08:36 +0300 Subject: [PATCH] Collect dependent libraries in the manifest. Link dependencies recursively. --- backend.native/build.gradle | 4 +- .../org/jetbrains/kotlin/cli/bc/K2Native.kt | 2 +- .../cli/bc/K2NativeCompilerArguments.kt | 3 + .../kotlin/backend/konan/CompilerOutput.kt | 87 +++++++++++++++++++ .../kotlin/backend/konan/KonanConfig.kt | 34 ++++++-- .../backend/konan/KonanConfigurationKeys.kt | 2 + .../kotlin/backend/konan/KonanDriver.kt | 1 - .../kotlin/backend/konan/LinkStage.kt | 6 +- .../konan/library/KonanLibraryReader.kt | 2 + .../konan/library/KonanLibraryWriter.kt | 1 + .../library/impl/KonanLibraryReaderImpl.kt | 6 ++ .../library/impl/KonanLibraryWriterImpl.kt | 21 +++-- .../kotlin/backend/konan/llvm/IrToBitcode.kt | 56 ------------ 13 files changed, 148 insertions(+), 77 deletions(-) create mode 100644 backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt diff --git a/backend.native/build.gradle b/backend.native/build.gradle index 25e04f1ae45..bb754bc48ac 100644 --- a/backend.native/build.gradle +++ b/backend.native/build.gradle @@ -162,7 +162,7 @@ targetList.each { target -> "-Djava.library.path=${project.buildDir}/nativelibs", "-Dfile.encoding=UTF-8"] - def defaultArgs = ['-nopack', '-nostdlib','-ea' ] + def defaultArgs = ['-nopack', '-nostdlib', '-nodefaultlibs', '-ea' ] if (target != "wasm32") defaultArgs += '-g' def konanArgs = [*defaultArgs, '-target', target, @@ -176,7 +176,7 @@ targetList.each { target -> jvmArgs = konanJvmArgs args = [*konanArgs, '-output', project(':runtime').file("build/${target}Stdlib"), - '-produce', 'library', + '-produce', 'library', '-module_name', 'stdlib', project(':Interop:Runtime').file('src/main/kotlin'), project(':Interop:Runtime').file('src/native/kotlin'), project(':runtime').file('src/main/kotlin')] diff --git a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt index 7f2e94ba94c..c48b3bfa8d9 100644 --- a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt +++ b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt @@ -86,7 +86,7 @@ class K2Native : CLICompiler() { arguments.libraries.toNonNullList()) put(LINKER_ARGS, arguments.linkerArguments.toNonNullList()) - + arguments.moduleName ?. let{ put(MODULE_NAME, it) } arguments.target ?.let{ put(TARGET, it) } put(INCLUDED_BINARY_FILES, diff --git a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt index 5e64dfead59..58d9513c9af 100644 --- a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt +++ b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt @@ -45,6 +45,9 @@ class K2NativeCompilerArguments : CommonCompilerArguments() { @Argument(value = "-manifest", valueDescription = "", description = "Provide a maniferst addend file") var manifestFile: String? = null + @Argument(value = "-module_name", valueDescription = "", description = "Spicify a name for the compilation module") + var moduleName: String? = null + @Argument(value = "-nativelibrary", shortName = "-nl", valueDescription = "", description = "Include the native bitcode library") var nativeLibraries: Array? = null diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt new file mode 100644 index 00000000000..ef307fd51f3 --- /dev/null +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt @@ -0,0 +1,87 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.kotlin.backend.konan + +import llvm.LLVMLinkModules2 +import llvm.LLVMWriteBitcodeToFile +import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader +import org.jetbrains.kotlin.backend.konan.library.impl.buildLibrary +import org.jetbrains.kotlin.backend.konan.llvm.parseBitcodeFile +import org.jetbrains.kotlin.konan.target.CompilerOutputKind + +internal fun produceOutput(context: Context) { + + val llvmModule = context.llvmModule!! + val config = context.config.configuration + + when (config.get(KonanConfigKeys.PRODUCE)) { + CompilerOutputKind.PROGRAM -> { + val program = context.config.outputName + val output = "$program.kt.bc" + context.bitcodeFileName = output + + PhaseManager(context).phase(KonanPhase.BITCODE_LINKER) { + for (library in context.config.nativeLibraries) { + val libraryModule = parseBitcodeFile(library) + val failed = LLVMLinkModules2(llvmModule, libraryModule) + if (failed != 0) { + throw Error("failed to link $library") // TODO: retrieve error message from LLVM. + } + } + } + + LLVMWriteBitcodeToFile(llvmModule, output) + } + CompilerOutputKind.LIBRARY -> { + val output = context.config.outputName + val libraryName = context.config.moduleId + val neededLibraries + = context.config.immediateLibraries.purgeUnneeded() + val abiVersion = context.config.currentAbiVersion + val target = context.config.targetManager.target + val nopack = config.getBoolean(KonanConfigKeys.NOPACK) + val manifest = config.get(KonanConfigKeys.MANIFEST_FILE) + + val library = buildLibrary( + context.config.nativeLibraries, + context.config.includeBinaries, + neededLibraries, + context.serializedLinkData!!, + abiVersion, + target, + output, + libraryName, + llvmModule, + nopack, + manifest, + context.moduleEscapeAnalysisResult.build().toByteArray()) + + context.library = library + context.bitcodeFileName = library.mainBitcodeFileName + } + CompilerOutputKind.BITCODE -> { + val output = context.config.outputFile + context.bitcodeFileName = output + LLVMWriteBitcodeToFile(llvmModule, output) + } + } +} + +internal fun List.purgeUnneeded(): List { + return this.map { + if (!it.isNeededForLink && it.isDefaultLink) null else it + }.filterNotNull() +} diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt index 2864a66245a..17df9ef25af 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt @@ -71,15 +71,15 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration val outputFile = outputName.suffixIfNot(produce.suffix(targetManager.target)) val moduleId: String - // This is a decision we could change - get() = outputName + get() = configuration.get(KonanConfigKeys.MODULE_NAME) ?: File(outputName).name private val libraryNames: List get() = configuration.getList(KonanConfigKeys.LIBRARY_FILES) private val repositories = configuration.getList(KonanConfigKeys.REPOSITORIES) private val resolver = KonanLibrarySearchPathResolver(repositories, distribution.klib, distribution.localKonanDir) - val libraries: List by lazy { + + val immediateLibraries: List by lazy { val target = targetManager.target val defaultLibraries = resolver.defaultLinks( @@ -91,10 +91,25 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration .map { resolver.resolve(it) } .map{ LibraryReaderImpl(it, currentAbiVersion, target) } - val resolvedLibraries = defaultLibraries + userProvidedLibraries - checkLibraryDuplicates(resolvedLibraries.map{it.libraryFile}) + var resolvedLibraries = defaultLibraries + userProvidedLibraries + warnOnLibraryDuplicates(resolvedLibraries.map{ it.libraryFile }) + resolvedLibraries.distinctBy { it.libraryFile.absolutePath } + } - resolvedLibraries + val libraries: List by lazy { + val result = mutableListOf() + result.addAll(immediateLibraries) + do { + val dependencies = result + .map { it.dependencies } .flatten() + .map { resolver.resolve(it) } + .map { LibraryReaderImpl(it, currentAbiVersion, targetManager.target) } + + val newDependencies = dependencies.deleteMatching(result, { it.libraryFile.absolutePath }) + result.addAll(newDependencies) + } while (newDependencies.size > 0) + + result } private val loadedDescriptors = loadLibMetadata() @@ -144,7 +159,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration loadedDescriptors } - private fun checkLibraryDuplicates(resolvedLibraries: List) { + private fun warnOnLibraryDuplicates(resolvedLibraries: List) { val duplicates = resolvedLibraries.groupBy { it.absolutePath } .values.filter { it.size > 1 } duplicates.forEach { configuration.report(STRONG_WARNING, "library included more than once: ${it.first().absolutePath}") @@ -152,5 +167,10 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration } } +private fun List.deleteMatching(other: List, transform: (T) -> K): List { + val transformed = other.map { transform(it) } + return this.filterNot { transformed.contains( transform(it) ) } +} + fun CompilerConfiguration.report(priority: CompilerMessageSeverity, message: String) = this.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(priority, message) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt index 14ef94f9664..61fa7a0f9ad 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt @@ -55,6 +55,8 @@ class KonanConfigKeys { = CompilerConfigurationKey.create("generate metadata") val MODULE_KIND: CompilerConfigurationKey = CompilerConfigurationKey.create("module kind") + val MODULE_NAME: CompilerConfigurationKey + = CompilerConfigurationKey.create("module name") val NATIVE_LIBRARY_FILES: CompilerConfigurationKey> = CompilerConfigurationKey.create("native library file paths") val NODEFAULTLIBS: CompilerConfigurationKey diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanDriver.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanDriver.kt index e4549fdf325..63ac69e9671 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanDriver.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanDriver.kt @@ -22,7 +22,6 @@ import org.jetbrains.kotlin.backend.konan.ir.DeserializerDriver import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.backend.konan.ir.ModuleIndex import org.jetbrains.kotlin.backend.konan.llvm.emitLLVM -import org.jetbrains.kotlin.backend.konan.llvm.produceOutput import org.jetbrains.kotlin.backend.konan.serialization.KonanSerializationUtil import org.jetbrains.kotlin.backend.konan.serialization.markBackingFields import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt index a84f2f7e037..cb59f0400e5 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt @@ -235,11 +235,7 @@ internal class LinkStage(val context: Context) { private val debug = config.get(KonanConfigKeys.DEBUG) ?: false private val nomain = config.get(KonanConfigKeys.NOMAIN) ?: false private val emitted = context.bitcodeFileName - private val libraries = context.config.libraries - .map { - if (!it.isNeededForLink && it.isDefaultLink) null else it - }.filterNotNull() - + private val libraries = context.config.libraries.purgeUnneeded() private fun MutableList.addNonEmpty(elements: List) { addAll(elements.filter { !it.isEmpty() }) } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibraryReader.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibraryReader.kt index c59c6e84798..7273f34bb1f 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibraryReader.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibraryReader.kt @@ -22,9 +22,11 @@ import org.jetbrains.kotlin.konan.properties.Properties interface KonanLibraryReader { val libraryName: String + val uniqueName: String val bitcodePaths: List val includedPaths: List val linkerOpts: List + val dependencies: List val escapeAnalysis: ByteArray? val isNeededForLink: Boolean get() = true val isDefaultLink: Boolean get() = false diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibraryWriter.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibraryWriter.kt index 7a1f5867f06..e18c71d7c35 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibraryWriter.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/KonanLibraryWriter.kt @@ -23,6 +23,7 @@ interface KonanLibraryWriter { fun addNativeBitcode(library: String) fun addIncludedBinary(library: String) fun addKotlinBitcode(llvmModule: LLVMModuleRef) + fun addLinkDependencies(libraries: List) fun addManifestAddend(path: String) fun addEscapeAnalysis(escapeAnalysis: ByteArray) val mainBitcodeFileName: String diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibraryReaderImpl.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibraryReaderImpl.kt index b210f2ad357..99711bfa46c 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibraryReaderImpl.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibraryReaderImpl.kt @@ -56,6 +56,9 @@ class LibraryReaderImpl(var libraryFile: File, val currentAbiVersion: Int, override val libraryName get() = inPlace.libraryName + override val uniqueName + get() = manifestProperties.propertyString("unique_name")!! + override val bitcodePaths: List get() = (realFiles.kotlinDir.listFiles + realFiles.nativeDir.listFiles).map{it.absolutePath} @@ -65,6 +68,9 @@ class LibraryReaderImpl(var libraryFile: File, val currentAbiVersion: Int, override val linkerOpts: List get() = manifestProperties.propertyList("linkerOpts", target!!.detailedName) + override val dependencies: List + get() = manifestProperties.propertyList("dependencies") + val moduleHeaderData: ByteArray by lazy { reader.loadSerializedModule() } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibraryWriterImpl.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibraryWriterImpl.kt index b0650f8d1c0..98195539866 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibraryWriterImpl.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/library/impl/KonanLibraryWriterImpl.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.backend.konan.library.impl +import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader import llvm.LLVMModuleRef import llvm.LLVMWriteBitcodeToFile import org.jetbrains.kotlin.backend.konan.library.KonanLibrary @@ -29,13 +30,13 @@ abstract class FileBasedLibraryWriter ( val file: File, val currentAbiVersion: Int): KonanLibraryWriter { } -class LibraryWriterImpl(override val libDir: File, currentAbiVersion: Int, +class LibraryWriterImpl(override val libDir: File, moduleName: String, currentAbiVersion: Int, override val target: KonanTarget?, val nopack: Boolean = false): FileBasedLibraryWriter(libDir, currentAbiVersion), KonanLibrary { - public constructor(path: String, currentAbiVersion: Int, + public constructor(path: String, moduleName: String, currentAbiVersion: Int, target:KonanTarget?, nopack: Boolean): - this(File(path), currentAbiVersion, target, nopack) + this(File(path), moduleName, currentAbiVersion, target, nopack) override val libraryName = libDir.path val klibFile @@ -58,6 +59,8 @@ class LibraryWriterImpl(override val libDir: File, currentAbiVersion: Int, nativeDir.mkdirs() includedDir.mkdirs() resourcesDir.mkdirs() + // TODO: : will go somewhere around here. + manifestProperties.setProperty("unique_name", "$moduleName") manifestProperties.setProperty("abi_version", "$currentAbiVersion") } @@ -82,6 +85,11 @@ class LibraryWriterImpl(override val libDir: File, currentAbiVersion: Int, File(library).copyTo(File(includedDir, basename)) } + override fun addLinkDependencies(libraries: List) { + if (libraries.isEmpty()) return + manifestProperties.setProperty("dependencies", libraries .map { it.uniqueName } . joinToString(" ")) + } + override fun addManifestAddend(path: String) { val properties = File(path).loadProperties() manifestProperties.putAll(properties) @@ -102,17 +110,19 @@ class LibraryWriterImpl(override val libDir: File, currentAbiVersion: Int, internal fun buildLibrary( natives: List, - included: List, + included: List, + linkDependencies: List, linkData: LinkData, abiVersion: Int, target: KonanTarget, output: String, + moduleName: String, llvmModule: LLVMModuleRef, nopack: Boolean, manifest: String?, escapeAnalysis: ByteArray?): KonanLibraryWriter { - val library = LibraryWriterImpl(output, abiVersion, target, nopack) + val library = LibraryWriterImpl(output, moduleName, abiVersion, target, nopack) library.addKotlinBitcode(llvmModule) library.addLinkData(linkData) @@ -122,6 +132,7 @@ internal fun buildLibrary( included.forEach { library.addIncludedBinary(it) } + library.addLinkDependencies(linkDependencies) manifest ?.let { library.addManifestAddend(it) } escapeAnalysis?.let { library.addEscapeAnalysis(it) } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index b4a6fdc1d61..dcb801b401d 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -24,7 +24,6 @@ import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.backend.konan.ir.* -import org.jetbrains.kotlin.backend.konan.library.impl.buildLibrary import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation @@ -39,7 +38,6 @@ import org.jetbrains.kotlin.ir.util.getArguments import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid -import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils @@ -52,7 +50,6 @@ import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberType import org.jetbrains.kotlin.types.typeUtil.isTypeParameter import org.jetbrains.kotlin.types.typeUtil.isUnit - internal fun emitLLVM(context: Context) { val irModule = context.irModule!! @@ -89,59 +86,6 @@ internal fun emitLLVM(context: Context) { } } -internal fun produceOutput(context: Context) { - - val llvmModule = context.llvmModule!! - val config = context.config.configuration - - when (config.get(KonanConfigKeys.PRODUCE)) { - CompilerOutputKind.PROGRAM -> { - val program = context.config.outputName - val output = "$program.kt.bc" - context.bitcodeFileName = output - - PhaseManager(context).phase(KonanPhase.BITCODE_LINKER) { - for (library in context.config.nativeLibraries) { - val libraryModule = parseBitcodeFile(library) - val failed = LLVMLinkModules2(llvmModule, libraryModule) - if (failed != 0) { - throw Error("failed to link $library") // TODO: retrieve error message from LLVM. - } - } - } - - LLVMWriteBitcodeToFile(llvmModule, output) - } - CompilerOutputKind.LIBRARY -> { - val libraryName = context.config.outputName - val abiVersion = context.config.currentAbiVersion - val target = context.config.targetManager.target - val nopack = config.getBoolean(KonanConfigKeys.NOPACK) - val manifest = config.get(KonanConfigKeys.MANIFEST_FILE) - - val library = buildLibrary( - context.config.nativeLibraries, - context.config.includeBinaries, - context.serializedLinkData!!, - abiVersion, - target, - libraryName, - llvmModule, - nopack, - manifest, - context.moduleEscapeAnalysisResult.build().toByteArray()) - - context.library = library - context.bitcodeFileName = library.mainBitcodeFileName - } - CompilerOutputKind.BITCODE -> { - val output = context.config.outputFile - context.bitcodeFileName = output - LLVMWriteBitcodeToFile(llvmModule, output) - } - } -} - internal fun verifyModule(llvmModule: LLVMModuleRef, current: String = "") { memScoped { val errorRef = allocPointerTo()