Always link bitcode files specified with -nativelibrary

This commit is contained in:
Svyatoslav Scherbina
2017-03-29 17:46:26 +03:00
committed by SvyatoslavScherbina
parent fb08c25633
commit f564bd7707
9 changed files with 45 additions and 30 deletions
+2 -1
View File
@@ -127,7 +127,8 @@ List<String> llvmLinkerOpts() {
'-lLLVMMC',
'-lLLVMCore',
'-lLLVMSupport',
'-lLLVMDebugInfoCodeView'
'-lLLVMDebugInfoCodeView',
'-lLLVMLinker'
]
final List<String> res = new ArrayList<>()
@@ -37,7 +37,7 @@ public class K2NativeCompilerArguments extends CommonCompilerArguments {
@ValueDescription("<path>")
public String[] libraries;
@Argument(value = "nativelibrary", alias = "nl", description = "Link with the native library")
@Argument(value = "nativelibrary", alias = "nl", description = "Include the native library")
@ValueDescription("<path>")
public String[] nativeLibraries;
@@ -39,8 +39,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
private val loadedDescriptors = loadLibMetadata(libraries)
internal val librariesToLink: List<String>
get() = libraries + configuration.getList(KonanConfigKeys.NATIVE_LIBRARY_FILES)
internal val nativeLibraries: List<String> = configuration.getList(KonanConfigKeys.NATIVE_LIBRARY_FILES)
val moduleId: String
get() = configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)
@@ -52,6 +52,7 @@ enum class KonanPhase(val description: String,
/* ... ... */ RTTI("RTTI Generation"),
/* ... ... */ CODEGEN("Code Generation"),
/* ... ... */ METADATOR("Metadata Generation"),
/* ... ... */ BITCODE_LINKER("Bitcode linking"),
/* */ LINK_STAGE("Link stage"),
/* ... */ OBJECT_FILES("Bitcode to object file"),
/* ... */ LINKER("Linker");
@@ -194,7 +194,7 @@ internal class LinkStage(val context: Context) {
val optimize = config.get(KonanConfigKeys.OPTIMIZATION) ?: false
val emitted = config.get(KonanConfigKeys.BITCODE_FILE)!!
val nomain = config.get(KonanConfigKeys.NOMAIN) ?: false
val libraries = context.config.librariesToLink
val libraries = context.config.libraries
fun llvmLto(files: List<BitcodeFile>): ObjectFile {
val tmpCombined = File.createTempFile("combined", ".o")
@@ -76,6 +76,16 @@ internal fun emitLLVM(context: Context) {
irModule.acceptVoid(MetadatorVisitor(context))
}
phaser.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.
}
}
}
val outFile = context.config.configuration.get(KonanConfigKeys.BITCODE_FILE)!!
LLVMWriteBitcodeToFile(llvmModule, outFile)
}
@@ -216,4 +216,28 @@ fun getStructElements(type: LLVMTypeRef): List<LLVMTypeRef> {
return (0 until count).map {
LLVMStructGetTypeAtIndex(type, it)!!
}
}
}
fun parseBitcodeFile(path: String): LLVMModuleRef = memScoped {
val bufRef = alloc<LLVMMemoryBufferRefVar>()
val errorRef = allocPointerTo<CInt8Var>()
val res = LLVMCreateMemoryBufferWithContentsOfFile(path, bufRef.ptr, errorRef.ptr)
if (res != 0) {
throw Error(errorRef.value?.toKString())
}
val memoryBuffer = bufRef.value
try {
val moduleRef = alloc<LLVMModuleRefVar>()
val parseRes = LLVMParseBitcode2(memoryBuffer, moduleRef.ptr)
if (parseRes != 0) {
throw Error(parseRes.toString())
}
moduleRef.value!!
} finally {
LLVMDisposeMemoryBuffer(memoryBuffer)
}
}
@@ -26,29 +26,8 @@ interface RuntimeAware {
val runtime: Runtime
}
class Runtime(private val bitcodeFile: String) {
val llvmModule: LLVMModuleRef
init {
llvmModule = memScoped {
val bufRef = alloc<LLVMMemoryBufferRefVar>()
val errorRef = allocPointerTo<CInt8Var>()
val res = LLVMCreateMemoryBufferWithContentsOfFile(bitcodeFile, bufRef.ptr, errorRef.ptr)
if (res != 0) {
throw Error(errorRef.value?.toKString())
}
val moduleRef = alloc<LLVMModuleRefVar>()
val parseRes = LLVMParseBitcode2(bufRef.value, moduleRef.ptr)
if (parseRes != 0) {
throw Error(parseRes.toString())
}
moduleRef.value!!
}
}
class Runtime(bitcodeFile: String) {
val llvmModule: LLVMModuleRef = parseBitcodeFile(bitcodeFile)
private fun getStructType(name: String) = LLVMGetTypeByName(llvmModule, "struct.$name")!!
+2 -1
View File
@@ -1,4 +1,5 @@
headers = llvm-c/Core.h llvm-c/ExecutionEngine.h llvm-c/Target.h llvm-c/Analysis.h llvm-c/BitWriter.h llvm-c/BitReader.h
headers = llvm-c/Core.h llvm-c/ExecutionEngine.h llvm-c/Target.h llvm-c/Analysis.h llvm-c/BitWriter.h \
llvm-c/BitReader.h llvm-c/Linker.h
compilerOpts = -std=c99 -fPIC \
-Wall -W -Wno-unused-parameter -Wwrite-strings -Wmissing-field-initializers \