Embed some linker options to static frameworks (#2828)
This commit is contained in:
committed by
GitHub
parent
6bb4171c60
commit
ed44620814
+27
@@ -6,6 +6,8 @@ package org.jetbrains.kotlin.backend.konan
|
|||||||
|
|
||||||
import llvm.*
|
import llvm.*
|
||||||
import org.jetbrains.kotlin.backend.konan.library.impl.buildLibrary
|
import org.jetbrains.kotlin.backend.konan.library.impl.buildLibrary
|
||||||
|
import org.jetbrains.kotlin.backend.konan.llvm.Llvm
|
||||||
|
import org.jetbrains.kotlin.backend.konan.llvm.embedLlvmLinkOptions
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.parseBitcodeFile
|
import org.jetbrains.kotlin.backend.konan.llvm.parseBitcodeFile
|
||||||
import org.jetbrains.kotlin.konan.CURRENT
|
import org.jetbrains.kotlin.konan.CURRENT
|
||||||
import org.jetbrains.kotlin.konan.KonanAbiVersion
|
import org.jetbrains.kotlin.konan.KonanAbiVersion
|
||||||
@@ -74,6 +76,10 @@ internal fun produceOutput(context: Context) {
|
|||||||
parseAndLinkBitcodeFile(context.llvmModule!!, library)
|
parseAndLinkBitcodeFile(context.llvmModule!!, library)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (produce == CompilerOutputKind.FRAMEWORK && context.config.produceStaticFramework) {
|
||||||
|
embedAppleLinkerOptionsToBitcode(context.llvm, context.config)
|
||||||
|
}
|
||||||
|
|
||||||
LLVMWriteBitcodeToFile(context.llvmModule!!, output)
|
LLVMWriteBitcodeToFile(context.llvmModule!!, output)
|
||||||
}
|
}
|
||||||
CompilerOutputKind.LIBRARY -> {
|
CompilerOutputKind.LIBRARY -> {
|
||||||
@@ -121,3 +127,24 @@ private fun parseAndLinkBitcodeFile(llvmModule: LLVMModuleRef, path: String) {
|
|||||||
throw Error("failed to link $path") // TODO: retrieve error message from LLVM.
|
throw Error("failed to link $path") // TODO: retrieve error message from LLVM.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun embedAppleLinkerOptionsToBitcode(llvm: Llvm, config: KonanConfig) {
|
||||||
|
fun findEmbeddableOptions(options: List<String>): List<List<String>> {
|
||||||
|
val result = mutableListOf<List<String>>()
|
||||||
|
val iterator = options.iterator()
|
||||||
|
loop@while (iterator.hasNext()) {
|
||||||
|
val option = iterator.next()
|
||||||
|
result += when {
|
||||||
|
option.startsWith("-l") -> listOf(option)
|
||||||
|
option == "-framework" && iterator.hasNext() -> listOf(option, iterator.next())
|
||||||
|
else -> break@loop // Ignore the rest.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
val optionsToEmbed = findEmbeddableOptions(config.platform.configurables.linkerKonanFlags) +
|
||||||
|
llvm.nativeDependenciesToLink.flatMap { findEmbeddableOptions(it.linkerOpts) }
|
||||||
|
|
||||||
|
embedLlvmLinkOptions(llvm.llvmModule, optionsToEmbed)
|
||||||
|
}
|
||||||
|
|||||||
+2
@@ -59,6 +59,8 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
|
|
||||||
internal val produce get() = configuration.get(KonanConfigKeys.PRODUCE)!!
|
internal val produce get() = configuration.get(KonanConfigKeys.PRODUCE)!!
|
||||||
|
|
||||||
|
internal val produceStaticFramework get() = configuration.getBoolean(KonanConfigKeys.STATIC_FRAMEWORK)
|
||||||
|
|
||||||
val outputFiles = OutputFiles(configuration.get(KonanConfigKeys.OUTPUT), target, produce)
|
val outputFiles = OutputFiles(configuration.get(KonanConfigKeys.OUTPUT), target, produce)
|
||||||
val tempFiles = TempFiles(outputFiles.outputName, configuration.get(KonanConfigKeys.TEMPORARY_FILES_DIR))
|
val tempFiles = TempFiles(outputFiles.outputName, configuration.get(KonanConfigKeys.TEMPORARY_FILES_DIR))
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ typealias ExecutableFile = String
|
|||||||
private fun determineLinkerOutput(context: Context): LinkerOutputKind =
|
private fun determineLinkerOutput(context: Context): LinkerOutputKind =
|
||||||
when (context.config.produce) {
|
when (context.config.produce) {
|
||||||
CompilerOutputKind.FRAMEWORK -> {
|
CompilerOutputKind.FRAMEWORK -> {
|
||||||
val staticFramework = context.config.configuration.getBoolean(KonanConfigKeys.STATIC_FRAMEWORK)
|
val staticFramework = context.config.produceStaticFramework
|
||||||
if (staticFramework) LinkerOutputKind.STATIC_LIBRARY else LinkerOutputKind.DYNAMIC_LIBRARY
|
if (staticFramework) LinkerOutputKind.STATIC_LIBRARY else LinkerOutputKind.DYNAMIC_LIBRARY
|
||||||
}
|
}
|
||||||
CompilerOutputKind.DYNAMIC -> LinkerOutputKind.DYNAMIC_LIBRARY
|
CompilerOutputKind.DYNAMIC -> LinkerOutputKind.DYNAMIC_LIBRARY
|
||||||
|
|||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.konan.llvm
|
||||||
|
|
||||||
|
import llvm.LLVMAddNamedMetadataOperand
|
||||||
|
import llvm.LLVMModuleRef
|
||||||
|
|
||||||
|
fun embedLlvmLinkOptions(module: LLVMModuleRef, options: List<List<String>>) {
|
||||||
|
options.forEach {
|
||||||
|
val node = node(*it.map { it.mdString() }.toTypedArray())
|
||||||
|
LLVMAddNamedMetadataOperand(module, "llvm.linker.options", node)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user