Always link bitcode files specified with -nativelibrary
This commit is contained in:
committed by
SvyatoslavScherbina
parent
fb08c25633
commit
f564bd7707
@@ -127,7 +127,8 @@ List<String> llvmLinkerOpts() {
|
|||||||
'-lLLVMMC',
|
'-lLLVMMC',
|
||||||
'-lLLVMCore',
|
'-lLLVMCore',
|
||||||
'-lLLVMSupport',
|
'-lLLVMSupport',
|
||||||
'-lLLVMDebugInfoCodeView'
|
'-lLLVMDebugInfoCodeView',
|
||||||
|
'-lLLVMLinker'
|
||||||
]
|
]
|
||||||
|
|
||||||
final List<String> res = new ArrayList<>()
|
final List<String> res = new ArrayList<>()
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ public class K2NativeCompilerArguments extends CommonCompilerArguments {
|
|||||||
@ValueDescription("<path>")
|
@ValueDescription("<path>")
|
||||||
public String[] libraries;
|
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>")
|
@ValueDescription("<path>")
|
||||||
public String[] nativeLibraries;
|
public String[] nativeLibraries;
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -39,8 +39,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
|
|
||||||
private val loadedDescriptors = loadLibMetadata(libraries)
|
private val loadedDescriptors = loadLibMetadata(libraries)
|
||||||
|
|
||||||
internal val librariesToLink: List<String>
|
internal val nativeLibraries: List<String> = configuration.getList(KonanConfigKeys.NATIVE_LIBRARY_FILES)
|
||||||
get() = libraries + configuration.getList(KonanConfigKeys.NATIVE_LIBRARY_FILES)
|
|
||||||
|
|
||||||
val moduleId: String
|
val moduleId: String
|
||||||
get() = configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)
|
get() = configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)
|
||||||
|
|||||||
+1
@@ -52,6 +52,7 @@ enum class KonanPhase(val description: String,
|
|||||||
/* ... ... */ RTTI("RTTI Generation"),
|
/* ... ... */ RTTI("RTTI Generation"),
|
||||||
/* ... ... */ CODEGEN("Code Generation"),
|
/* ... ... */ CODEGEN("Code Generation"),
|
||||||
/* ... ... */ METADATOR("Metadata Generation"),
|
/* ... ... */ METADATOR("Metadata Generation"),
|
||||||
|
/* ... ... */ BITCODE_LINKER("Bitcode linking"),
|
||||||
/* */ LINK_STAGE("Link stage"),
|
/* */ LINK_STAGE("Link stage"),
|
||||||
/* ... */ OBJECT_FILES("Bitcode to object file"),
|
/* ... */ OBJECT_FILES("Bitcode to object file"),
|
||||||
/* ... */ LINKER("Linker");
|
/* ... */ LINKER("Linker");
|
||||||
|
|||||||
+1
-1
@@ -194,7 +194,7 @@ internal class LinkStage(val context: Context) {
|
|||||||
val optimize = config.get(KonanConfigKeys.OPTIMIZATION) ?: false
|
val optimize = config.get(KonanConfigKeys.OPTIMIZATION) ?: false
|
||||||
val emitted = config.get(KonanConfigKeys.BITCODE_FILE)!!
|
val emitted = config.get(KonanConfigKeys.BITCODE_FILE)!!
|
||||||
val nomain = config.get(KonanConfigKeys.NOMAIN) ?: false
|
val nomain = config.get(KonanConfigKeys.NOMAIN) ?: false
|
||||||
val libraries = context.config.librariesToLink
|
val libraries = context.config.libraries
|
||||||
|
|
||||||
fun llvmLto(files: List<BitcodeFile>): ObjectFile {
|
fun llvmLto(files: List<BitcodeFile>): ObjectFile {
|
||||||
val tmpCombined = File.createTempFile("combined", ".o")
|
val tmpCombined = File.createTempFile("combined", ".o")
|
||||||
|
|||||||
+10
@@ -76,6 +76,16 @@ internal fun emitLLVM(context: Context) {
|
|||||||
irModule.acceptVoid(MetadatorVisitor(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)!!
|
val outFile = context.config.configuration.get(KonanConfigKeys.BITCODE_FILE)!!
|
||||||
LLVMWriteBitcodeToFile(llvmModule, outFile)
|
LLVMWriteBitcodeToFile(llvmModule, outFile)
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-1
@@ -216,4 +216,28 @@ fun getStructElements(type: LLVMTypeRef): List<LLVMTypeRef> {
|
|||||||
return (0 until count).map {
|
return (0 until count).map {
|
||||||
LLVMStructGetTypeAtIndex(type, it)!!
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+2
-23
@@ -26,29 +26,8 @@ interface RuntimeAware {
|
|||||||
val runtime: Runtime
|
val runtime: Runtime
|
||||||
}
|
}
|
||||||
|
|
||||||
class Runtime(private val bitcodeFile: String) {
|
class Runtime(bitcodeFile: String) {
|
||||||
val llvmModule: LLVMModuleRef
|
val llvmModule: LLVMModuleRef = parseBitcodeFile(bitcodeFile)
|
||||||
|
|
||||||
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!!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getStructType(name: String) = LLVMGetTypeByName(llvmModule, "struct.$name")!!
|
private fun getStructType(name: String) = LLVMGetTypeByName(llvmModule, "struct.$name")!!
|
||||||
|
|
||||||
|
|||||||
@@ -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 \
|
compilerOpts = -std=c99 -fPIC \
|
||||||
-Wall -W -Wno-unused-parameter -Wwrite-strings -Wmissing-field-initializers \
|
-Wall -W -Wno-unused-parameter -Wwrite-strings -Wmissing-field-initializers \
|
||||||
|
|||||||
Reference in New Issue
Block a user