Collect dependent libraries in the manifest.
Link dependencies recursively.
This commit is contained in:
committed by
alexander-gorshenev
parent
3b1428597b
commit
42cbf8428b
@@ -162,7 +162,7 @@ targetList.each { target ->
|
|||||||
"-Djava.library.path=${project.buildDir}/nativelibs",
|
"-Djava.library.path=${project.buildDir}/nativelibs",
|
||||||
"-Dfile.encoding=UTF-8"]
|
"-Dfile.encoding=UTF-8"]
|
||||||
|
|
||||||
def defaultArgs = ['-nopack', '-nostdlib','-ea' ]
|
def defaultArgs = ['-nopack', '-nostdlib', '-nodefaultlibs', '-ea' ]
|
||||||
if (target != "wasm32") defaultArgs += '-g'
|
if (target != "wasm32") defaultArgs += '-g'
|
||||||
def konanArgs = [*defaultArgs,
|
def konanArgs = [*defaultArgs,
|
||||||
'-target', target,
|
'-target', target,
|
||||||
@@ -176,7 +176,7 @@ targetList.each { target ->
|
|||||||
jvmArgs = konanJvmArgs
|
jvmArgs = konanJvmArgs
|
||||||
args = [*konanArgs,
|
args = [*konanArgs,
|
||||||
'-output', project(':runtime').file("build/${target}Stdlib"),
|
'-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/main/kotlin'),
|
||||||
project(':Interop:Runtime').file('src/native/kotlin'),
|
project(':Interop:Runtime').file('src/native/kotlin'),
|
||||||
project(':runtime').file('src/main/kotlin')]
|
project(':runtime').file('src/main/kotlin')]
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
|
|||||||
arguments.libraries.toNonNullList())
|
arguments.libraries.toNonNullList())
|
||||||
|
|
||||||
put(LINKER_ARGS, arguments.linkerArguments.toNonNullList())
|
put(LINKER_ARGS, arguments.linkerArguments.toNonNullList())
|
||||||
|
arguments.moduleName ?. let{ put(MODULE_NAME, it) }
|
||||||
arguments.target ?.let{ put(TARGET, it) }
|
arguments.target ?.let{ put(TARGET, it) }
|
||||||
|
|
||||||
put(INCLUDED_BINARY_FILES,
|
put(INCLUDED_BINARY_FILES,
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
@Argument(value = "-manifest", valueDescription = "<path>", description = "Provide a maniferst addend file")
|
@Argument(value = "-manifest", valueDescription = "<path>", description = "Provide a maniferst addend file")
|
||||||
var manifestFile: String? = null
|
var manifestFile: String? = null
|
||||||
|
|
||||||
|
@Argument(value = "-module_name", valueDescription = "<name>", description = "Spicify a name for the compilation module")
|
||||||
|
var moduleName: String? = null
|
||||||
|
|
||||||
@Argument(value = "-nativelibrary", shortName = "-nl", valueDescription = "<path>", description = "Include the native bitcode library")
|
@Argument(value = "-nativelibrary", shortName = "-nl", valueDescription = "<path>", description = "Include the native bitcode library")
|
||||||
var nativeLibraries: Array<String>? = null
|
var nativeLibraries: Array<String>? = null
|
||||||
|
|
||||||
|
|||||||
+87
@@ -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<KonanLibraryReader>.purgeUnneeded(): List<KonanLibraryReader> {
|
||||||
|
return this.map {
|
||||||
|
if (!it.isNeededForLink && it.isDefaultLink) null else it
|
||||||
|
}.filterNotNull()
|
||||||
|
}
|
||||||
+27
-7
@@ -71,15 +71,15 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
val outputFile = outputName.suffixIfNot(produce.suffix(targetManager.target))
|
val outputFile = outputName.suffixIfNot(produce.suffix(targetManager.target))
|
||||||
|
|
||||||
val moduleId: String
|
val moduleId: String
|
||||||
// This is a decision we could change
|
get() = configuration.get(KonanConfigKeys.MODULE_NAME) ?: File(outputName).name
|
||||||
get() = outputName
|
|
||||||
|
|
||||||
private val libraryNames: List<String>
|
private val libraryNames: List<String>
|
||||||
get() = configuration.getList(KonanConfigKeys.LIBRARY_FILES)
|
get() = configuration.getList(KonanConfigKeys.LIBRARY_FILES)
|
||||||
|
|
||||||
private val repositories = configuration.getList(KonanConfigKeys.REPOSITORIES)
|
private val repositories = configuration.getList(KonanConfigKeys.REPOSITORIES)
|
||||||
private val resolver = KonanLibrarySearchPathResolver(repositories, distribution.klib, distribution.localKonanDir)
|
private val resolver = KonanLibrarySearchPathResolver(repositories, distribution.klib, distribution.localKonanDir)
|
||||||
val libraries: List<KonanLibraryReader> by lazy {
|
|
||||||
|
val immediateLibraries: List<LibraryReaderImpl> by lazy {
|
||||||
val target = targetManager.target
|
val target = targetManager.target
|
||||||
|
|
||||||
val defaultLibraries = resolver.defaultLinks(
|
val defaultLibraries = resolver.defaultLinks(
|
||||||
@@ -91,10 +91,25 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
.map { resolver.resolve(it) }
|
.map { resolver.resolve(it) }
|
||||||
.map{ LibraryReaderImpl(it, currentAbiVersion, target) }
|
.map{ LibraryReaderImpl(it, currentAbiVersion, target) }
|
||||||
|
|
||||||
val resolvedLibraries = defaultLibraries + userProvidedLibraries
|
var resolvedLibraries = defaultLibraries + userProvidedLibraries
|
||||||
checkLibraryDuplicates(resolvedLibraries.map{it.libraryFile})
|
warnOnLibraryDuplicates(resolvedLibraries.map{ it.libraryFile })
|
||||||
|
resolvedLibraries.distinctBy { it.libraryFile.absolutePath }
|
||||||
|
}
|
||||||
|
|
||||||
resolvedLibraries
|
val libraries: List<LibraryReaderImpl> by lazy {
|
||||||
|
val result = mutableListOf<LibraryReaderImpl>()
|
||||||
|
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()
|
private val loadedDescriptors = loadLibMetadata()
|
||||||
@@ -144,7 +159,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
loadedDescriptors
|
loadedDescriptors
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkLibraryDuplicates(resolvedLibraries: List<File>) {
|
private fun warnOnLibraryDuplicates(resolvedLibraries: List<File>) {
|
||||||
val duplicates = resolvedLibraries.groupBy { it.absolutePath } .values.filter { it.size > 1 }
|
val duplicates = resolvedLibraries.groupBy { it.absolutePath } .values.filter { it.size > 1 }
|
||||||
duplicates.forEach {
|
duplicates.forEach {
|
||||||
configuration.report(STRONG_WARNING, "library included more than once: ${it.first().absolutePath}")
|
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 <T, K> List<T>.deleteMatching(other: List<T>, transform: (T) -> K): List<T> {
|
||||||
|
val transformed = other.map { transform(it) }
|
||||||
|
return this.filterNot { transformed.contains( transform(it) ) }
|
||||||
|
}
|
||||||
|
|
||||||
fun CompilerConfiguration.report(priority: CompilerMessageSeverity, message: String)
|
fun CompilerConfiguration.report(priority: CompilerMessageSeverity, message: String)
|
||||||
= this.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(priority, message)
|
= this.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(priority, message)
|
||||||
|
|||||||
+2
@@ -55,6 +55,8 @@ class KonanConfigKeys {
|
|||||||
= CompilerConfigurationKey.create("generate metadata")
|
= CompilerConfigurationKey.create("generate metadata")
|
||||||
val MODULE_KIND: CompilerConfigurationKey<ModuleKind>
|
val MODULE_KIND: CompilerConfigurationKey<ModuleKind>
|
||||||
= CompilerConfigurationKey.create("module kind")
|
= CompilerConfigurationKey.create("module kind")
|
||||||
|
val MODULE_NAME: CompilerConfigurationKey<String?>
|
||||||
|
= CompilerConfigurationKey.create("module name")
|
||||||
val NATIVE_LIBRARY_FILES: CompilerConfigurationKey<List<String>>
|
val NATIVE_LIBRARY_FILES: CompilerConfigurationKey<List<String>>
|
||||||
= CompilerConfigurationKey.create("native library file paths")
|
= CompilerConfigurationKey.create("native library file paths")
|
||||||
val NODEFAULTLIBS: CompilerConfigurationKey<Boolean>
|
val NODEFAULTLIBS: CompilerConfigurationKey<Boolean>
|
||||||
|
|||||||
-1
@@ -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.KonanSymbols
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.ModuleIndex
|
import org.jetbrains.kotlin.backend.konan.ir.ModuleIndex
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.emitLLVM
|
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.KonanSerializationUtil
|
||||||
import org.jetbrains.kotlin.backend.konan.serialization.markBackingFields
|
import org.jetbrains.kotlin.backend.konan.serialization.markBackingFields
|
||||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||||
|
|||||||
+1
-5
@@ -235,11 +235,7 @@ internal class LinkStage(val context: Context) {
|
|||||||
private val debug = config.get(KonanConfigKeys.DEBUG) ?: false
|
private val debug = config.get(KonanConfigKeys.DEBUG) ?: false
|
||||||
private val nomain = config.get(KonanConfigKeys.NOMAIN) ?: false
|
private val nomain = config.get(KonanConfigKeys.NOMAIN) ?: false
|
||||||
private val emitted = context.bitcodeFileName
|
private val emitted = context.bitcodeFileName
|
||||||
private val libraries = context.config.libraries
|
private val libraries = context.config.libraries.purgeUnneeded()
|
||||||
.map {
|
|
||||||
if (!it.isNeededForLink && it.isDefaultLink) null else it
|
|
||||||
}.filterNotNull()
|
|
||||||
|
|
||||||
private fun MutableList<String>.addNonEmpty(elements: List<String>) {
|
private fun MutableList<String>.addNonEmpty(elements: List<String>) {
|
||||||
addAll(elements.filter { !it.isEmpty() })
|
addAll(elements.filter { !it.isEmpty() })
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -22,9 +22,11 @@ import org.jetbrains.kotlin.konan.properties.Properties
|
|||||||
|
|
||||||
interface KonanLibraryReader {
|
interface KonanLibraryReader {
|
||||||
val libraryName: String
|
val libraryName: String
|
||||||
|
val uniqueName: String
|
||||||
val bitcodePaths: List<String>
|
val bitcodePaths: List<String>
|
||||||
val includedPaths: List<String>
|
val includedPaths: List<String>
|
||||||
val linkerOpts: List<String>
|
val linkerOpts: List<String>
|
||||||
|
val dependencies: List<String>
|
||||||
val escapeAnalysis: ByteArray?
|
val escapeAnalysis: ByteArray?
|
||||||
val isNeededForLink: Boolean get() = true
|
val isNeededForLink: Boolean get() = true
|
||||||
val isDefaultLink: Boolean get() = false
|
val isDefaultLink: Boolean get() = false
|
||||||
|
|||||||
+1
@@ -23,6 +23,7 @@ interface KonanLibraryWriter {
|
|||||||
fun addNativeBitcode(library: String)
|
fun addNativeBitcode(library: String)
|
||||||
fun addIncludedBinary(library: String)
|
fun addIncludedBinary(library: String)
|
||||||
fun addKotlinBitcode(llvmModule: LLVMModuleRef)
|
fun addKotlinBitcode(llvmModule: LLVMModuleRef)
|
||||||
|
fun addLinkDependencies(libraries: List<KonanLibraryReader>)
|
||||||
fun addManifestAddend(path: String)
|
fun addManifestAddend(path: String)
|
||||||
fun addEscapeAnalysis(escapeAnalysis: ByteArray)
|
fun addEscapeAnalysis(escapeAnalysis: ByteArray)
|
||||||
val mainBitcodeFileName: String
|
val mainBitcodeFileName: String
|
||||||
|
|||||||
+6
@@ -56,6 +56,9 @@ class LibraryReaderImpl(var libraryFile: File, val currentAbiVersion: Int,
|
|||||||
override val libraryName
|
override val libraryName
|
||||||
get() = inPlace.libraryName
|
get() = inPlace.libraryName
|
||||||
|
|
||||||
|
override val uniqueName
|
||||||
|
get() = manifestProperties.propertyString("unique_name")!!
|
||||||
|
|
||||||
override val bitcodePaths: List<String>
|
override val bitcodePaths: List<String>
|
||||||
get() = (realFiles.kotlinDir.listFiles + realFiles.nativeDir.listFiles).map{it.absolutePath}
|
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<String>
|
override val linkerOpts: List<String>
|
||||||
get() = manifestProperties.propertyList("linkerOpts", target!!.detailedName)
|
get() = manifestProperties.propertyList("linkerOpts", target!!.detailedName)
|
||||||
|
|
||||||
|
override val dependencies: List<String>
|
||||||
|
get() = manifestProperties.propertyList("dependencies")
|
||||||
|
|
||||||
val moduleHeaderData: ByteArray by lazy {
|
val moduleHeaderData: ByteArray by lazy {
|
||||||
reader.loadSerializedModule()
|
reader.loadSerializedModule()
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-5
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.konan.library.impl
|
package org.jetbrains.kotlin.backend.konan.library.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader
|
||||||
import llvm.LLVMModuleRef
|
import llvm.LLVMModuleRef
|
||||||
import llvm.LLVMWriteBitcodeToFile
|
import llvm.LLVMWriteBitcodeToFile
|
||||||
import org.jetbrains.kotlin.backend.konan.library.KonanLibrary
|
import org.jetbrains.kotlin.backend.konan.library.KonanLibrary
|
||||||
@@ -29,13 +30,13 @@ abstract class FileBasedLibraryWriter (
|
|||||||
val file: File, val currentAbiVersion: Int): KonanLibraryWriter {
|
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):
|
override val target: KonanTarget?, val nopack: Boolean = false):
|
||||||
FileBasedLibraryWriter(libDir, currentAbiVersion), KonanLibrary {
|
FileBasedLibraryWriter(libDir, currentAbiVersion), KonanLibrary {
|
||||||
|
|
||||||
public constructor(path: String, currentAbiVersion: Int,
|
public constructor(path: String, moduleName: String, currentAbiVersion: Int,
|
||||||
target:KonanTarget?, nopack: Boolean):
|
target:KonanTarget?, nopack: Boolean):
|
||||||
this(File(path), currentAbiVersion, target, nopack)
|
this(File(path), moduleName, currentAbiVersion, target, nopack)
|
||||||
|
|
||||||
override val libraryName = libDir.path
|
override val libraryName = libDir.path
|
||||||
val klibFile
|
val klibFile
|
||||||
@@ -58,6 +59,8 @@ class LibraryWriterImpl(override val libDir: File, currentAbiVersion: Int,
|
|||||||
nativeDir.mkdirs()
|
nativeDir.mkdirs()
|
||||||
includedDir.mkdirs()
|
includedDir.mkdirs()
|
||||||
resourcesDir.mkdirs()
|
resourcesDir.mkdirs()
|
||||||
|
// TODO: <name>:<hash> will go somewhere around here.
|
||||||
|
manifestProperties.setProperty("unique_name", "$moduleName")
|
||||||
manifestProperties.setProperty("abi_version", "$currentAbiVersion")
|
manifestProperties.setProperty("abi_version", "$currentAbiVersion")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,6 +85,11 @@ class LibraryWriterImpl(override val libDir: File, currentAbiVersion: Int,
|
|||||||
File(library).copyTo(File(includedDir, basename))
|
File(library).copyTo(File(includedDir, basename))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun addLinkDependencies(libraries: List<KonanLibraryReader>) {
|
||||||
|
if (libraries.isEmpty()) return
|
||||||
|
manifestProperties.setProperty("dependencies", libraries .map { it.uniqueName } . joinToString(" "))
|
||||||
|
}
|
||||||
|
|
||||||
override fun addManifestAddend(path: String) {
|
override fun addManifestAddend(path: String) {
|
||||||
val properties = File(path).loadProperties()
|
val properties = File(path).loadProperties()
|
||||||
manifestProperties.putAll(properties)
|
manifestProperties.putAll(properties)
|
||||||
@@ -102,17 +110,19 @@ class LibraryWriterImpl(override val libDir: File, currentAbiVersion: Int,
|
|||||||
|
|
||||||
internal fun buildLibrary(
|
internal fun buildLibrary(
|
||||||
natives: List<String>,
|
natives: List<String>,
|
||||||
included: List<String>,
|
included: List<String>,
|
||||||
|
linkDependencies: List<KonanLibraryReader>,
|
||||||
linkData: LinkData,
|
linkData: LinkData,
|
||||||
abiVersion: Int,
|
abiVersion: Int,
|
||||||
target: KonanTarget,
|
target: KonanTarget,
|
||||||
output: String,
|
output: String,
|
||||||
|
moduleName: String,
|
||||||
llvmModule: LLVMModuleRef,
|
llvmModule: LLVMModuleRef,
|
||||||
nopack: Boolean,
|
nopack: Boolean,
|
||||||
manifest: String?,
|
manifest: String?,
|
||||||
escapeAnalysis: ByteArray?): KonanLibraryWriter {
|
escapeAnalysis: ByteArray?): KonanLibraryWriter {
|
||||||
|
|
||||||
val library = LibraryWriterImpl(output, abiVersion, target, nopack)
|
val library = LibraryWriterImpl(output, moduleName, abiVersion, target, nopack)
|
||||||
|
|
||||||
library.addKotlinBitcode(llvmModule)
|
library.addKotlinBitcode(llvmModule)
|
||||||
library.addLinkData(linkData)
|
library.addLinkData(linkData)
|
||||||
@@ -122,6 +132,7 @@ internal fun buildLibrary(
|
|||||||
included.forEach {
|
included.forEach {
|
||||||
library.addIncludedBinary(it)
|
library.addIncludedBinary(it)
|
||||||
}
|
}
|
||||||
|
library.addLinkDependencies(linkDependencies)
|
||||||
manifest ?.let { library.addManifestAddend(it) }
|
manifest ?.let { library.addManifestAddend(it) }
|
||||||
escapeAnalysis?.let { library.addEscapeAnalysis(it) }
|
escapeAnalysis?.let { library.addEscapeAnalysis(it) }
|
||||||
|
|
||||||
|
|||||||
-56
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.backend.common.ir.ir2string
|
|||||||
import org.jetbrains.kotlin.backend.konan.*
|
import org.jetbrains.kotlin.backend.konan.*
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.*
|
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.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
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.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
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.konan.target.KonanTarget
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
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.isTypeParameter
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||||
|
|
||||||
|
|
||||||
internal fun emitLLVM(context: Context) {
|
internal fun emitLLVM(context: Context) {
|
||||||
val irModule = context.irModule!!
|
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 = "") {
|
internal fun verifyModule(llvmModule: LLVMModuleRef, current: String = "") {
|
||||||
memScoped {
|
memScoped {
|
||||||
val errorRef = allocPointerTo<ByteVar>()
|
val errorRef = allocPointerTo<ByteVar>()
|
||||||
|
|||||||
Reference in New Issue
Block a user