Link stage fixes for "produce dynamic".

This commit is contained in:
Alexander Gorshenev
2017-11-15 17:42:36 +03:00
committed by alexander-gorshenev
parent 6061c50887
commit 0d0a2b4c99
7 changed files with 28 additions and 10 deletions
@@ -27,6 +27,7 @@ internal fun produceOutput(context: Context) {
val config = context.config.configuration val config = context.config.configuration
when (config.get(KonanConfigKeys.PRODUCE)) { when (config.get(KonanConfigKeys.PRODUCE)) {
CompilerOutputKind.DYNAMIC,
CompilerOutputKind.PROGRAM -> { CompilerOutputKind.PROGRAM -> {
val program = context.config.outputName val program = context.config.outputName
val output = "$program.kt.bc" val output = "$program.kt.bc"
@@ -86,7 +86,8 @@ object KonanPhases {
KonanPhase.SERIALIZER.enabled = KonanPhase.SERIALIZER.enabled =
(get(PRODUCE) == CompilerOutputKind.LIBRARY) (get(PRODUCE) == CompilerOutputKind.LIBRARY)
KonanPhase.LINK_STAGE.enabled = KonanPhase.LINK_STAGE.enabled =
(get(PRODUCE) == CompilerOutputKind.PROGRAM) (get(PRODUCE) == CompilerOutputKind.PROGRAM ||
get(PRODUCE) == CompilerOutputKind.DYNAMIC)
KonanPhase.TEST_PROCESSOR.enabled = getBoolean(GENERATE_TEST_RUNNER) KonanPhase.TEST_PROCESSOR.enabled = getBoolean(GENERATE_TEST_RUNNER)
@@ -32,10 +32,12 @@ internal abstract class PlatformFlags(val properties: KonanProperties) {
val llvmLtoNooptFlags = properties.llvmLtoNooptFlags val llvmLtoNooptFlags = properties.llvmLtoNooptFlags
val llvmLtoOptFlags = properties.llvmLtoOptFlags val llvmLtoOptFlags = properties.llvmLtoOptFlags
val llvmLtoFlags = properties.llvmLtoFlags val llvmLtoFlags = properties.llvmLtoFlags
val llvmLtoDynamicFlags = properties.llvmLtoDynamicFlags
val entrySelector = properties.entrySelector val entrySelector = properties.entrySelector
val linkerOptimizationFlags = properties.linkerOptimizationFlags val linkerOptimizationFlags = properties.linkerOptimizationFlags
val linkerKonanFlags = properties.linkerKonanFlags val linkerKonanFlags = properties.linkerKonanFlags
val linkerDebugFlags = properties.linkerDebugFlags val linkerDebugFlags = properties.linkerDebugFlags
val linkerDynamicFlags = properties.linkerDynamicFlags
val llvmDebugOptFlags = properties.llvmDebugOptFlags val llvmDebugOptFlags = properties.llvmDebugOptFlags
val s2wasmFlags = properties.s2wasmFlags val s2wasmFlags = properties.s2wasmFlags
val targetToolchain = properties.absoluteTargetToolchain val targetToolchain = properties.absoluteTargetToolchain
@@ -46,7 +48,7 @@ internal abstract class PlatformFlags(val properties: KonanProperties) {
open val useCompilerDriverAsLinker: Boolean get() = false // TODO: refactor. open val useCompilerDriverAsLinker: Boolean get() = false // TODO: refactor.
abstract fun linkCommand(objectFiles: List<ObjectFile>, abstract fun linkCommand(objectFiles: List<ObjectFile>,
executable: ExecutableFile, optimize: Boolean, debug: Boolean): List<String> executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): List<String>
open fun linkCommandSuffix(): List<String> = emptyList() open fun linkCommandSuffix(): List<String> = emptyList()
@@ -77,7 +79,7 @@ internal open class AndroidPlatform(distribution: Distribution)
override fun filterStaticLibraries(binaries: List<String>) override fun filterStaticLibraries(binaries: List<String>)
= binaries.filter { it.isUnixStaticLib } = binaries.filter { it.isUnixStaticLib }
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean): List<String> { override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): List<String> {
// liblog.so must be linked in, as we use its functionality in runtime. // liblog.so must be linked in, as we use its functionality in runtime.
return mutableListOf(clang).apply{ return mutableListOf(clang).apply{
add("-o") add("-o")
@@ -88,6 +90,7 @@ internal open class AndroidPlatform(distribution: Distribution)
addAll(objectFiles) addAll(objectFiles)
if (optimize) addAll(linkerOptimizationFlags) if (optimize) addAll(linkerOptimizationFlags)
if (!debug) addAll(linkerDebugFlags) if (!debug) addAll(linkerDebugFlags)
if (dynamic) addAll(linkerDynamicFlags)
addAll(linkerKonanFlags) addAll(linkerKonanFlags)
} }
} }
@@ -110,7 +113,7 @@ internal open class MacOSBasedPlatform(distribution: Distribution)
override fun filterStaticLibraries(binaries: List<String>) override fun filterStaticLibraries(binaries: List<String>)
= binaries.filter { it.isUnixStaticLib } = binaries.filter { it.isUnixStaticLib }
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean): List<String> { override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): List<String> {
return mutableListOf(linker).apply { return mutableListOf(linker).apply {
add("-demangle") add("-demangle")
addAll(listOf("-object_path_lto", "temporary.o", "-lto_library", libLTO)) addAll(listOf("-object_path_lto", "temporary.o", "-lto_library", libLTO))
@@ -120,6 +123,7 @@ internal open class MacOSBasedPlatform(distribution: Distribution)
addAll(objectFiles) addAll(objectFiles)
if (optimize) addAll(linkerOptimizationFlags) if (optimize) addAll(linkerOptimizationFlags)
if (!debug) addAll(linkerDebugFlags) if (!debug) addAll(linkerDebugFlags)
if (dynamic) addAll(linkerDynamicFlags)
addAll(linkerKonanFlags) addAll(linkerKonanFlags)
add("-lSystem") add("-lSystem")
} }
@@ -144,7 +148,7 @@ internal open class LinuxBasedPlatform(val distribution: Distribution)
override fun filterStaticLibraries(binaries: List<String>) override fun filterStaticLibraries(binaries: List<String>)
= binaries.filter { it.isUnixStaticLib } = binaries.filter { it.isUnixStaticLib }
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean): List<String> { override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): List<String> {
// TODO: Can we extract more to the konan.properties? // TODO: Can we extract more to the konan.properties?
return mutableListOf(linker).apply { return mutableListOf(linker).apply {
addAll(listOf("--sysroot=${targetSysRoot}", addAll(listOf("--sysroot=${targetSysRoot}",
@@ -162,6 +166,7 @@ internal open class LinuxBasedPlatform(val distribution: Distribution)
addAll(objectFiles) addAll(objectFiles)
if (optimize) addAll(linkerOptimizationFlags) if (optimize) addAll(linkerOptimizationFlags)
if (!debug) addAll(linkerDebugFlags) if (!debug) addAll(linkerDebugFlags)
if (dynamic) addAll(linkerDynamicFlags)
addAll(linkerKonanFlags) addAll(linkerKonanFlags)
addAll(listOf("-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", addAll(listOf("-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed",
"-lc", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", "-lc", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed",
@@ -181,12 +186,13 @@ internal open class MingwPlatform(distribution: Distribution)
override fun filterStaticLibraries(binaries: List<String>) override fun filterStaticLibraries(binaries: List<String>)
= binaries.filter { it.isWindowsStaticLib || it.isUnixStaticLib } = binaries.filter { it.isWindowsStaticLib || it.isUnixStaticLib }
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean): List<String> { override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): List<String> {
return mutableListOf(linker).apply { return mutableListOf(linker).apply {
addAll(listOf("-o", executable)) addAll(listOf("-o", executable))
addAll(objectFiles) addAll(objectFiles)
if (optimize) addAll(linkerOptimizationFlags) if (optimize) addAll(linkerOptimizationFlags)
if (!debug) addAll(linkerDebugFlags) if (!debug) addAll(linkerDebugFlags)
if (dynamic) addAll(linkerDynamicFlags)
} }
} }
@@ -203,7 +209,7 @@ internal open class WasmPlatform(distribution: Distribution)
override fun filterStaticLibraries(binaries: List<String>) override fun filterStaticLibraries(binaries: List<String>)
= emptyList<String>() = emptyList<String>()
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean): List<String> { override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): List<String> {
//No link stage for WASM yet, just give '.wasm' as output. //No link stage for WASM yet, just give '.wasm' as output.
return mutableListOf("/bin/cp", objectFiles.single(), executable) return mutableListOf("/bin/cp", objectFiles.single(), executable)
@@ -233,6 +239,7 @@ internal class LinkStage(val context: Context) {
private val optimize = config.get(KonanConfigKeys.OPTIMIZATION) ?: false private val optimize = config.get(KonanConfigKeys.OPTIMIZATION) ?: false
private val debug = config.get(KonanConfigKeys.DEBUG) ?: false private val debug = config.get(KonanConfigKeys.DEBUG) ?: false
private val dynamic = config.get(KonanConfigKeys.PRODUCE) == CompilerOutputKind.DYNAMIC
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.llvm.librariesToLink private val libraries = context.llvm.librariesToLink
@@ -251,6 +258,7 @@ internal class LinkStage(val context: Context) {
debug -> command.addNonEmpty(platform.llvmDebugOptFlags) debug -> command.addNonEmpty(platform.llvmDebugOptFlags)
else -> command.addNonEmpty(platform.llvmLtoNooptFlags) else -> command.addNonEmpty(platform.llvmLtoNooptFlags)
} }
command.addNonEmpty(platform.llvmLtoDynamicFlags)
command.addNonEmpty(files) command.addNonEmpty(files)
runTool(*command.toTypedArray()) runTool(*command.toTypedArray())
@@ -322,7 +330,7 @@ internal class LinkStage(val context: Context) {
private fun link(objectFiles: List<ObjectFile>, includedBinaries: List<String>, libraryProvidedLinkerFlags: List<String>): ExecutableFile? { private fun link(objectFiles: List<ObjectFile>, includedBinaries: List<String>, libraryProvidedLinkerFlags: List<String>): ExecutableFile? {
val executable = context.config.outputFile val executable = context.config.outputFile
val linkCommand = platform.linkCommand(objectFiles, executable, optimize, debug) + val linkCommand = platform.linkCommand(objectFiles, executable, optimize, debug, dynamic) +
platform.targetLibffi + platform.targetLibffi +
asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) + asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) +
entryPointSelector + entryPointSelector +
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.target.CompilerOutputKind.*
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
@@ -36,7 +37,8 @@ import org.jetbrains.kotlin.utils.alwaysTrue
internal fun findMainEntryPoint(context: Context): FunctionDescriptor? { internal fun findMainEntryPoint(context: Context): FunctionDescriptor? {
val config = context.config.configuration val config = context.config.configuration
if (config.get(KonanConfigKeys.PRODUCE) != CompilerOutputKind.PROGRAM) return null if (config.get(KonanConfigKeys.PRODUCE) != PROGRAM &&
config.get(KonanConfigKeys.PRODUCE) != DYNAMIC) return null
val entryPoint = FqName(config.get(KonanConfigKeys.ENTRY) ?: val entryPoint = FqName(config.get(KonanConfigKeys.ENTRY) ?:
if (context.shouldGenerateTestRunner()) testEntryName else defaultEntryName) if (context.shouldGenerateTestRunner()) testEntryName else defaultEntryName)
+4
View File
@@ -38,9 +38,11 @@ libffiDir.osx = libffi-3.2.1-2-darwin-macos
llvmLtoFlags.osx = llvmLtoFlags.osx =
llvmLtoOptFlags.osx = -O3 -function-sections llvmLtoOptFlags.osx = -O3 -function-sections
llvmLtoNooptFlags.osx = -O1 llvmLtoNooptFlags.osx = -O1
llvmLtoDynamicFlags.osx = -relocation-model=pic
linkerKonanFlags.osx = -lc++ -lobjc linkerKonanFlags.osx = -lc++ -lobjc
linkerOptimizationFlags.osx = -dead_strip linkerOptimizationFlags.osx = -dead_strip
linkerDebugFlags.osx = -S linkerDebugFlags.osx = -S
linkerDynamicFlags.osx = -S -dylib
osVersionMinFlagLd.osx = -macosx_version_min osVersionMinFlagLd.osx = -macosx_version_min
osVersionMinFlagClang.osx = -mmacosx-version-min osVersionMinFlagClang.osx = -mmacosx-version-min
osVersionMin.osx = 10.11 osVersionMin.osx = 10.11
@@ -105,10 +107,12 @@ libGcc.linux = ../../lib/gcc/x86_64-unknown-linux-gnu/4.8.5
llvmLtoFlags.linux = llvmLtoFlags.linux =
llvmLtoOptFlags.linux = -O3 -function-sections llvmLtoOptFlags.linux = -O3 -function-sections
llvmLtoNooptFlags.linux = -O1 llvmLtoNooptFlags.linux = -O1
llvmLtoDynamicFlags.linux = -relocation-model=pic
llvmLlcFlags.linux = -march=x86-64 llvmLlcFlags.linux = -march=x86-64
linkerKonanFlags.linux = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthread linkerKonanFlags.linux = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthread
linkerOptimizationFlags.linux = --gc-sections linkerOptimizationFlags.linux = --gc-sections
linkerDebugFlags.linux = -S linkerDebugFlags.linux = -S
linkerDynamicFlags.linux = -shared
pluginOptimizationFlags.linux = -plugin-opt=mcpu=x86-64 -plugin-opt=O3 pluginOptimizationFlags.linux = -plugin-opt=mcpu=x86-64 -plugin-opt=O3
dynamicLinker.linux = /lib64/ld-linux-x86-64.so.2 dynamicLinker.linux = /lib64/ld-linux-x86-64.so.2
entrySelector.linux = --defsym main=Konan_main entrySelector.linux = --defsym main=Konan_main
@@ -38,10 +38,12 @@ class KonanProperties(val target: KonanTarget, val properties: Properties, val b
val llvmLtoNooptFlags get() = targetList("llvmLtoNooptFlags") val llvmLtoNooptFlags get() = targetList("llvmLtoNooptFlags")
val llvmLtoOptFlags get() = targetList("llvmLtoOptFlags") val llvmLtoOptFlags get() = targetList("llvmLtoOptFlags")
val llvmLtoFlags get() = targetList("llvmLtoFlags") val llvmLtoFlags get() = targetList("llvmLtoFlags")
val llvmLtoDynamicFlags get() = targetList("llvmLtoDynamicFlags")
val entrySelector get() = targetList("entrySelector") val entrySelector get() = targetList("entrySelector")
val linkerOptimizationFlags get() = targetList("linkerOptimizationFlags") val linkerOptimizationFlags get() = targetList("linkerOptimizationFlags")
val linkerKonanFlags get() = targetList("linkerKonanFlags") val linkerKonanFlags get() = targetList("linkerKonanFlags")
val linkerDebugFlags get() = targetList("linkerDebugFlags") val linkerDebugFlags get() = targetList("linkerDebugFlags")
val linkerDynamicFlags get() = targetList("linkerDynamicFlags")
val llvmDebugOptFlags get() = targetList("llvmDebugOptFlags") val llvmDebugOptFlags get() = targetList("llvmDebugOptFlags")
val s2wasmFlags get() = targetList("s2wasmFlags") val s2wasmFlags get() = targetList("s2wasmFlags")
@@ -61,7 +61,7 @@ enum class CompilerOutputKind {
override fun suffix(target: KonanTarget?) = ".${target!!.family.exeSuffix}" override fun suffix(target: KonanTarget?) = ".${target!!.family.exeSuffix}"
}, },
DYNAMIC { DYNAMIC {
override fun suffix(target: KonanTarget?) = ".${target!!.family.dynamicSuffix!!}" override fun suffix(target: KonanTarget?) = ".${target!!.family.dynamicSuffix}"
}, },
LIBRARY { LIBRARY {
override fun suffix(target: KonanTarget?) = ".klib" override fun suffix(target: KonanTarget?) = ".klib"