Support static library production. (#1515)
This commit is contained in:
+1
-1
@@ -796,7 +796,7 @@ internal class CAdapterGenerator(
|
|||||||
output("#endif /* KONAN_${prefix.toUpperCase()}_H */")
|
output("#endif /* KONAN_${prefix.toUpperCase()}_H */")
|
||||||
|
|
||||||
outputStreamWriter.close()
|
outputStreamWriter.close()
|
||||||
println("Produced dynamic library API in ${prefix}_api.h")
|
println("Produced library API in ${prefix}_api.h")
|
||||||
|
|
||||||
outputStreamWriter = context.config.tempFiles
|
outputStreamWriter = context.config.tempFiles
|
||||||
.cAdapterCpp
|
.cAdapterCpp
|
||||||
|
|||||||
+4
-2
@@ -22,7 +22,8 @@ import org.jetbrains.kotlin.backend.konan.llvm.parseBitcodeFile
|
|||||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||||
|
|
||||||
val CompilerOutputKind.isNativeBinary: Boolean get() = when (this) {
|
val CompilerOutputKind.isNativeBinary: Boolean get() = when (this) {
|
||||||
CompilerOutputKind.PROGRAM, CompilerOutputKind.DYNAMIC, CompilerOutputKind.FRAMEWORK -> true
|
CompilerOutputKind.PROGRAM, CompilerOutputKind.DYNAMIC,
|
||||||
|
CompilerOutputKind.STATIC, CompilerOutputKind.FRAMEWORK -> true
|
||||||
CompilerOutputKind.LIBRARY, CompilerOutputKind.BITCODE -> false
|
CompilerOutputKind.LIBRARY, CompilerOutputKind.BITCODE -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,6 +35,7 @@ internal fun produceOutput(context: Context) {
|
|||||||
val produce = config.get(KonanConfigKeys.PRODUCE)
|
val produce = config.get(KonanConfigKeys.PRODUCE)
|
||||||
|
|
||||||
when (produce) {
|
when (produce) {
|
||||||
|
CompilerOutputKind.STATIC,
|
||||||
CompilerOutputKind.DYNAMIC,
|
CompilerOutputKind.DYNAMIC,
|
||||||
CompilerOutputKind.FRAMEWORK,
|
CompilerOutputKind.FRAMEWORK,
|
||||||
CompilerOutputKind.PROGRAM -> {
|
CompilerOutputKind.PROGRAM -> {
|
||||||
@@ -41,7 +43,7 @@ internal fun produceOutput(context: Context) {
|
|||||||
context.bitcodeFileName = output
|
context.bitcodeFileName = output
|
||||||
|
|
||||||
val generatedBitcodeFiles =
|
val generatedBitcodeFiles =
|
||||||
if (produce == CompilerOutputKind.DYNAMIC) {
|
if (produce == CompilerOutputKind.DYNAMIC || produce == CompilerOutputKind.STATIC) {
|
||||||
produceCAdapterBitcode(
|
produceCAdapterBitcode(
|
||||||
context.config.clang,
|
context.config.clang,
|
||||||
tempFiles.cAdapterCppName,
|
tempFiles.cAdapterCppName,
|
||||||
|
|||||||
+3
-2
@@ -394,8 +394,9 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
|||||||
|
|
||||||
lateinit var debugInfo: DebugInfo
|
lateinit var debugInfo: DebugInfo
|
||||||
|
|
||||||
val isDynamicLibrary: Boolean by lazy {
|
val isNativeLibrary: Boolean by lazy {
|
||||||
config.configuration.get(KonanConfigKeys.PRODUCE) == CompilerOutputKind.DYNAMIC
|
val kind = config.configuration.get(KonanConfigKeys.PRODUCE)
|
||||||
|
kind == CompilerOutputKind.DYNAMIC || kind == CompilerOutputKind.STATIC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+42
-43
@@ -35,8 +35,12 @@ 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 = context.config.produce == CompilerOutputKind.DYNAMIC ||
|
private val linkerOutput = when (context.config.produce) {
|
||||||
context.config.produce == CompilerOutputKind.FRAMEWORK
|
CompilerOutputKind.DYNAMIC, CompilerOutputKind.FRAMEWORK -> LinkerOutputKind.DYNAMIC_LIBRARY
|
||||||
|
CompilerOutputKind.STATIC -> LinkerOutputKind.STATIC_LIBRARY
|
||||||
|
CompilerOutputKind.PROGRAM -> LinkerOutputKind.EXECUTABLE
|
||||||
|
else -> TODO("${context.config.produce} should not reach native linker stage")
|
||||||
|
}
|
||||||
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
|
||||||
@@ -46,9 +50,9 @@ internal class LinkStage(val context: Context) {
|
|||||||
|
|
||||||
private fun runTool(command: List<String>) = runTool(*command.toTypedArray())
|
private fun runTool(command: List<String>) = runTool(*command.toTypedArray())
|
||||||
private fun runTool(vararg command: String) =
|
private fun runTool(vararg command: String) =
|
||||||
Command(*command)
|
Command(*command)
|
||||||
.logWith(context::log)
|
.logWith(context::log)
|
||||||
.execute()
|
.execute()
|
||||||
|
|
||||||
private fun llvmLto(files: List<BitcodeFile>): ObjectFile {
|
private fun llvmLto(files: List<BitcodeFile>): ObjectFile {
|
||||||
val combined = temporary("combined", ".o")
|
val combined = temporary("combined", ".o")
|
||||||
@@ -58,8 +62,8 @@ internal class LinkStage(val context: Context) {
|
|||||||
command.addNonEmpty(platform.llvmLtoFlags)
|
command.addNonEmpty(platform.llvmLtoFlags)
|
||||||
when {
|
when {
|
||||||
optimize -> command.addNonEmpty(platform.llvmLtoOptFlags)
|
optimize -> command.addNonEmpty(platform.llvmLtoOptFlags)
|
||||||
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(platform.llvmLtoDynamicFlags)
|
||||||
command.addNonEmpty(files)
|
command.addNonEmpty(files)
|
||||||
@@ -89,27 +93,27 @@ internal class LinkStage(val context: Context) {
|
|||||||
hostLlvmTool("llvm-link", *bitcodeFiles.toTypedArray(), "-o", combinedBc)
|
hostLlvmTool("llvm-link", *bitcodeFiles.toTypedArray(), "-o", combinedBc)
|
||||||
|
|
||||||
val optFlags = (configurables.optFlags + when {
|
val optFlags = (configurables.optFlags + when {
|
||||||
optimize -> configurables.optOptFlags
|
optimize -> configurables.optOptFlags
|
||||||
debug -> configurables.optDebugFlags
|
debug -> configurables.optDebugFlags
|
||||||
else -> configurables.optNooptFlags
|
else -> configurables.optNooptFlags
|
||||||
}).toTypedArray()
|
}).toTypedArray()
|
||||||
val optimizedBc = temporary("optimized", ".bc")
|
val optimizedBc = temporary("optimized", ".bc")
|
||||||
hostLlvmTool("opt", combinedBc, "-o", optimizedBc, *optFlags)
|
hostLlvmTool("opt", combinedBc, "-o", optimizedBc, *optFlags)
|
||||||
|
|
||||||
val llcFlags = (configurables.llcFlags + when {
|
val llcFlags = (configurables.llcFlags + when {
|
||||||
optimize -> configurables.llcOptFlags
|
optimize -> configurables.llcOptFlags
|
||||||
debug -> configurables.llcDebugFlags
|
debug -> configurables.llcDebugFlags
|
||||||
else -> configurables.llcNooptFlags
|
else -> configurables.llcNooptFlags
|
||||||
}).toTypedArray()
|
}).toTypedArray()
|
||||||
val combinedS = temporary("combined", ".s")
|
val combinedS = temporary("combined", ".s")
|
||||||
targetTool("llc", optimizedBc, "-o", combinedS, *llcFlags)
|
targetTool("llc", optimizedBc, "-o", combinedS, *llcFlags)
|
||||||
|
|
||||||
val s2wasmFlags = configurables.s2wasmFlags.toTypedArray()
|
val s2wasmFlags = configurables.s2wasmFlags.toTypedArray()
|
||||||
val combinedWast = temporary( "combined", ".wast")
|
val combinedWast = temporary("combined", ".wast")
|
||||||
targetTool("s2wasm", combinedS, "-o", combinedWast, *s2wasmFlags)
|
targetTool("s2wasm", combinedS, "-o", combinedWast, *s2wasmFlags)
|
||||||
|
|
||||||
val combinedWasm = temporary( "combined", ".wasm")
|
val combinedWasm = temporary("combined", ".wasm")
|
||||||
val combinedSmap = temporary( "combined", ".smap")
|
val combinedSmap = temporary("combined", ".smap")
|
||||||
targetTool("wasm-as", combinedWast, "-o", combinedWasm, "-g", "-s", combinedSmap)
|
targetTool("wasm-as", combinedWast, "-o", combinedWasm, "-g", "-s", combinedSmap)
|
||||||
|
|
||||||
return combinedWasm
|
return combinedWasm
|
||||||
@@ -153,9 +157,11 @@ internal class LinkStage(val context: Context) {
|
|||||||
// So we stick to "-alias _main _konan_main" on Mac.
|
// So we stick to "-alias _main _konan_main" on Mac.
|
||||||
// And just do the same on Linux.
|
// And just do the same on Linux.
|
||||||
private val entryPointSelector: List<String>
|
private val entryPointSelector: List<String>
|
||||||
get() = if (nomain || dynamic) emptyList() else platform.entrySelector
|
get() = if (nomain || linkerOutput != LinkerOutputKind.EXECUTABLE) emptyList() else platform.entrySelector
|
||||||
|
|
||||||
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 frameworkLinkerArgs: List<String>
|
val frameworkLinkerArgs: List<String>
|
||||||
val executable: String
|
val executable: String
|
||||||
|
|
||||||
@@ -177,23 +183,16 @@ internal class LinkStage(val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
linker.linkCommand(objectFiles, executable, optimize, debug, dynamic).apply {
|
File(executable).delete()
|
||||||
+ linker.targetLibffi
|
linker.linkCommands(objectFiles = objectFiles, executable = executable,
|
||||||
+ asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS))
|
libraries = linker.targetLibffi + linker.linkStaticLibraries(includedBinaries),
|
||||||
+ entryPointSelector
|
linkerArgs = entryPointSelector +
|
||||||
+ frameworkLinkerArgs
|
asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) +
|
||||||
+ linker.linkCommandSuffix()
|
libraryProvidedLinkerFlags + frameworkLinkerArgs,
|
||||||
+ linker.linkStaticLibraries(includedBinaries)
|
optimize = optimize, debug = debug, kind = linkerOutput,
|
||||||
+ libraryProvidedLinkerFlags
|
outputDsymBundle = context.config.outputFile + ".dSYM").forEach {
|
||||||
logger = context::log
|
it.logWith(context::log)
|
||||||
}.execute()
|
it.execute()
|
||||||
|
|
||||||
if (debug && linker is MacOSBasedLinker) {
|
|
||||||
val outputDsymBundle = context.config.outputFile + ".dSYM" // `outputFile` is either binary or bundle.
|
|
||||||
|
|
||||||
linker.dsymUtilCommand(executable, outputDsymBundle)
|
|
||||||
.logWith(context::log)
|
|
||||||
.execute()
|
|
||||||
}
|
}
|
||||||
} catch (e: KonanExternalToolFailure) {
|
} catch (e: KonanExternalToolFailure) {
|
||||||
context.reportCompilationError("${e.toolName} invocation reported errors")
|
context.reportCompilationError("${e.toolName} invocation reported errors")
|
||||||
@@ -204,27 +203,27 @@ internal class LinkStage(val context: Context) {
|
|||||||
|
|
||||||
fun linkStage() {
|
fun linkStage() {
|
||||||
val bitcodeFiles = listOf(emitted) +
|
val bitcodeFiles = listOf(emitted) +
|
||||||
libraries.map{it -> it.bitcodePaths}.flatten()
|
libraries.map { it -> it.bitcodePaths }.flatten()
|
||||||
|
|
||||||
val includedBinaries =
|
val includedBinaries =
|
||||||
libraries.map{it -> it.includedPaths}.flatten()
|
libraries.map { it -> it.includedPaths }.flatten()
|
||||||
|
|
||||||
val libraryProvidedLinkerFlags =
|
val libraryProvidedLinkerFlags =
|
||||||
libraries.map{it -> it.linkerOpts}.flatten()
|
libraries.map { it -> it.linkerOpts }.flatten()
|
||||||
|
|
||||||
val objectFiles: MutableList<String> = mutableListOf()
|
val objectFiles: MutableList<String> = mutableListOf()
|
||||||
|
|
||||||
val phaser = PhaseManager(context)
|
val phaser = PhaseManager(context)
|
||||||
phaser.phase(KonanPhase.OBJECT_FILES) {
|
phaser.phase(KonanPhase.OBJECT_FILES) {
|
||||||
objectFiles.add(
|
objectFiles.add(
|
||||||
when (platform.configurables) {
|
when (platform.configurables) {
|
||||||
is WasmConfigurables
|
is WasmConfigurables
|
||||||
-> bitcodeToWasm(bitcodeFiles)
|
-> bitcodeToWasm(bitcodeFiles)
|
||||||
is ZephyrConfigurables
|
is ZephyrConfigurables
|
||||||
-> llvmLinkAndLlc(bitcodeFiles)
|
-> llvmLinkAndLlc(bitcodeFiles)
|
||||||
else
|
else
|
||||||
-> llvmLto(bitcodeFiles)
|
-> llvmLto(bitcodeFiles)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
phaser.phase(KonanPhase.LINKER) {
|
phaser.phase(KonanPhase.LINKER) {
|
||||||
|
|||||||
+1
-1
@@ -348,7 +348,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
appendLlvmUsed("llvm.compiler.used", context.llvm.compilerUsedGlobals)
|
appendLlvmUsed("llvm.compiler.used", context.llvm.compilerUsedGlobals)
|
||||||
appendStaticInitializers()
|
appendStaticInitializers()
|
||||||
appendEntryPointSelector(context.ir.symbols.entryPoint?.owner)
|
appendEntryPointSelector(context.ir.symbols.entryPoint?.owner)
|
||||||
if (context.isDynamicLibrary) {
|
if (context.isNativeLibrary) {
|
||||||
appendCAdapters()
|
appendCAdapters()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,14 +19,15 @@ package org.jetbrains.kotlin.konan.target
|
|||||||
import org.jetbrains.kotlin.konan.target.KonanTarget.*
|
import org.jetbrains.kotlin.konan.target.KonanTarget.*
|
||||||
import org.jetbrains.kotlin.konan.util.Named
|
import org.jetbrains.kotlin.konan.util.Named
|
||||||
|
|
||||||
enum class Family(val exeSuffix:String, val dynamicPrefix: String, val dynamicSuffix: String) {
|
enum class Family(val exeSuffix:String, val dynamicPrefix: String, val dynamicSuffix: String,
|
||||||
OSX ("kexe", "lib", "dylib"),
|
val staticPrefix: String, val staticSuffix: String) {
|
||||||
IOS ("kexe", "lib", "dylib"),
|
OSX ("kexe", "lib", "dylib", "lib", "a"),
|
||||||
LINUX ("kexe", "lib", "so" ),
|
IOS ("kexe", "lib", "dylib", "lib", "a"),
|
||||||
MINGW ("exe" , "" , "dll" ),
|
LINUX ("kexe", "lib", "so" , "lib", "a"),
|
||||||
ANDROID ("so" , "lib", "so" ),
|
MINGW ("exe" , "" , "dll" , "lib", "a"),
|
||||||
WASM ("wasm", "" , "wasm" ),
|
ANDROID ("so" , "lib", "so" , "lib", "a"),
|
||||||
ZEPHYR ("o" , "lib", "a" )
|
WASM ("wasm", "" , "wasm" , "", "wasm"),
|
||||||
|
ZEPHYR ("o" , "lib", "a" , "lib", "a")
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class Architecture(val bitness: Int) {
|
enum class Architecture(val bitness: Int) {
|
||||||
@@ -68,6 +69,10 @@ enum class CompilerOutputKind {
|
|||||||
override fun suffix(target: KonanTarget?) = ".${target!!.family.dynamicSuffix}"
|
override fun suffix(target: KonanTarget?) = ".${target!!.family.dynamicSuffix}"
|
||||||
override fun prefix(target: KonanTarget?) = "${target!!.family.dynamicPrefix}"
|
override fun prefix(target: KonanTarget?) = "${target!!.family.dynamicPrefix}"
|
||||||
},
|
},
|
||||||
|
STATIC {
|
||||||
|
override fun suffix(target: KonanTarget?) = ".${target!!.family.staticSuffix}"
|
||||||
|
override fun prefix(target: KonanTarget?) = "${target!!.family.staticPrefix}"
|
||||||
|
},
|
||||||
FRAMEWORK {
|
FRAMEWORK {
|
||||||
override fun suffix(target: KonanTarget?): String = ".framework"
|
override fun suffix(target: KonanTarget?): String = ".framework"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,14 +21,19 @@ import java.lang.ProcessBuilder.Redirect
|
|||||||
import org.jetbrains.kotlin.konan.exec.Command
|
import org.jetbrains.kotlin.konan.exec.Command
|
||||||
import org.jetbrains.kotlin.konan.file.*
|
import org.jetbrains.kotlin.konan.file.*
|
||||||
|
|
||||||
typealias BitcodeFile = String
|
|
||||||
typealias ObjectFile = String
|
typealias ObjectFile = String
|
||||||
typealias ExecutableFile = String
|
typealias ExecutableFile = String
|
||||||
|
|
||||||
|
enum class LinkerOutputKind {
|
||||||
|
DYNAMIC_LIBRARY,
|
||||||
|
STATIC_LIBRARY,
|
||||||
|
EXECUTABLE
|
||||||
|
}
|
||||||
|
|
||||||
// Use "clang -v -save-temps" to write linkCommand() method
|
// Use "clang -v -save-temps" to write linkCommand() method
|
||||||
// for another implementation of this class.
|
// for another implementation of this class.
|
||||||
abstract class LinkerFlags(val configurables: Configurables)
|
abstract class LinkerFlags(val configurables: Configurables)
|
||||||
/* : Configurables by configurables */{
|
/* : Configurables by configurables */ {
|
||||||
|
|
||||||
protected val llvmBin = "${configurables.absoluteLlvmHome}/bin"
|
protected val llvmBin = "${configurables.absoluteLlvmHome}/bin"
|
||||||
protected val llvmLib = "${configurables.absoluteLlvmHome}/lib"
|
protected val llvmLib = "${configurables.absoluteLlvmHome}/lib"
|
||||||
@@ -41,55 +46,80 @@ abstract class LinkerFlags(val configurables: Configurables)
|
|||||||
|
|
||||||
val libLTO = "$libLTODir/${System.mapLibraryName("LTO")}"
|
val libLTO = "$libLTODir/${System.mapLibraryName("LTO")}"
|
||||||
|
|
||||||
val targetLibffi = configurables.libffiDir ?.let { listOf("${configurables.absoluteLibffiDir}/lib/libffi.a") } ?: emptyList()
|
val targetLibffi = configurables.libffiDir?.let { listOf("${configurables.absoluteLibffiDir}/lib/libffi.a") }
|
||||||
|
?: emptyList()
|
||||||
|
|
||||||
open val useCompilerDriverAsLinker: Boolean get() = false // TODO: refactor.
|
open val useCompilerDriverAsLinker: Boolean get() = false // TODO: refactor.
|
||||||
|
|
||||||
abstract fun linkCommand(objectFiles: List<ObjectFile>,
|
abstract fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
||||||
executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): Command
|
libraries: List<String>, linkerArgs: List<String>,
|
||||||
|
optimize: Boolean, debug: Boolean,
|
||||||
open fun linkCommandSuffix(): List<String> = emptyList()
|
kind: LinkerOutputKind, outputDsymBundle: String): List<Command>
|
||||||
|
|
||||||
abstract fun filterStaticLibraries(binaries: List<String>): List<String>
|
abstract fun filterStaticLibraries(binaries: List<String>): List<String>
|
||||||
|
|
||||||
open fun linkStaticLibraries(binaries: List<String>): List<String> {
|
open fun linkStaticLibraries(binaries: List<String>): List<String> {
|
||||||
val libraries = filterStaticLibraries(binaries)
|
val libraries = filterStaticLibraries(binaries)
|
||||||
// Let's just pass them as absolute paths
|
// Let's just pass them as absolute paths.
|
||||||
return libraries
|
return libraries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected fun postLinkGnuArCommand(ar: String, executable: ExecutableFile) =
|
||||||
|
Command("/bin/sh", "-c").apply {
|
||||||
|
+"/bin/echo -e 'create $executable\\naddlib $executable\\nsave\\nend' | $ar -M"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open class AndroidLinker(targetProperties: AndroidConfigurables)
|
open class AndroidLinker(targetProperties: AndroidConfigurables)
|
||||||
: LinkerFlags(targetProperties), AndroidConfigurables by targetProperties {
|
: LinkerFlags(targetProperties), AndroidConfigurables by targetProperties {
|
||||||
|
|
||||||
private val prefix = "$absoluteTargetToolchain/bin/"
|
private val prefix = "$absoluteTargetToolchain/bin/"
|
||||||
private val clang = "$prefix/clang"
|
private val clang = "$prefix/clang"
|
||||||
|
private val ar = "$prefix/ar"
|
||||||
|
|
||||||
override val useCompilerDriverAsLinker: Boolean get() = true
|
override val useCompilerDriverAsLinker: Boolean get() = true
|
||||||
|
|
||||||
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, dynamic: Boolean): Command {
|
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
||||||
// liblog.so must be linked in, as we use its functionality in runtime.
|
libraries: List<String>, linkerArgs: List<String>,
|
||||||
return Command(clang).apply {
|
optimize: Boolean, debug: Boolean,
|
||||||
+ "-o"
|
kind: LinkerOutputKind, outputDsymBundle: String): List<Command> {
|
||||||
+ executable
|
if (kind == LinkerOutputKind.STATIC_LIBRARY) {
|
||||||
+ "-fPIC"
|
// Here we take somewhat unexpected approach - we create the thin
|
||||||
+ "-shared"
|
// library, and then repack it during post-link phase.
|
||||||
+ "-llog"
|
// This way we ensure .a inputs are properly processed.
|
||||||
+ objectFiles
|
return listOf(
|
||||||
if (optimize) + linkerOptimizationFlags
|
Command(ar, "cqT", executable).apply {
|
||||||
if (!debug) + linkerNoDebugFlags
|
+objectFiles
|
||||||
if (dynamic) + linkerDynamicFlags
|
+libraries
|
||||||
+ linkerKonanFlags
|
},
|
||||||
|
postLinkGnuArCommand(ar, executable))
|
||||||
}
|
}
|
||||||
|
val dynamic = kind == LinkerOutputKind.DYNAMIC_LIBRARY
|
||||||
|
// liblog.so must be linked in, as we use its functionality in runtime.
|
||||||
|
return listOf(Command(clang).apply {
|
||||||
|
+"-o"
|
||||||
|
+executable
|
||||||
|
+"-fPIC"
|
||||||
|
+"-shared"
|
||||||
|
+"-llog"
|
||||||
|
+objectFiles
|
||||||
|
if (optimize) +linkerOptimizationFlags
|
||||||
|
if (!debug) +linkerNoDebugFlags
|
||||||
|
if (dynamic) +linkerDynamicFlags
|
||||||
|
+linkerKonanFlags
|
||||||
|
+libraries
|
||||||
|
+linkerArgs
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class MacOSBasedLinker(targetProperties: AppleConfigurables)
|
open class MacOSBasedLinker(targetProperties: AppleConfigurables)
|
||||||
: LinkerFlags(targetProperties), AppleConfigurables by targetProperties {
|
: LinkerFlags(targetProperties), AppleConfigurables by targetProperties {
|
||||||
|
|
||||||
|
private val libtool = "$absoluteTargetToolchain/usr/bin/libtool"
|
||||||
private val linker = "$absoluteTargetToolchain/usr/bin/ld"
|
private val linker = "$absoluteTargetToolchain/usr/bin/ld"
|
||||||
internal val dsymutil = "$absoluteLlvmHome/bin/llvm-dsymutil"
|
internal val dsymutil = "$absoluteLlvmHome/bin/llvm-dsymutil"
|
||||||
|
|
||||||
@@ -99,30 +129,42 @@ open class MacOSBasedLinker(targetProperties: AppleConfigurables)
|
|||||||
osVersionMin + ".0")
|
osVersionMin + ".0")
|
||||||
}
|
}
|
||||||
|
|
||||||
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, dynamic: Boolean): Command {
|
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
||||||
return object : Command(linker) {} .apply {
|
libraries: List<String>, linkerArgs: List<String>,
|
||||||
+ "-demangle"
|
optimize: Boolean, debug: Boolean, kind: LinkerOutputKind,
|
||||||
+ listOf("-object_path_lto", "temporary.o", "-lto_library", libLTO)
|
outputDsymBundle: String): List<Command> {
|
||||||
+ listOf("-dynamic", "-arch", arch)
|
if (kind == LinkerOutputKind.STATIC_LIBRARY)
|
||||||
+ osVersionMinFlags
|
return listOf(Command(libtool).apply {
|
||||||
+ listOf("-syslibroot", absoluteTargetSysRoot, "-o", executable)
|
+"-static"
|
||||||
+ objectFiles
|
+listOf("-o", executable)
|
||||||
if (optimize) + linkerOptimizationFlags
|
+objectFiles
|
||||||
if (!debug) + linkerNoDebugFlags
|
+libraries
|
||||||
if (dynamic) + linkerDynamicFlags
|
})
|
||||||
+ linkerKonanFlags
|
val dynamic = kind == LinkerOutputKind.DYNAMIC_LIBRARY
|
||||||
+ "-lSystem"
|
return listOf(Command(linker).apply {
|
||||||
}
|
+"-demangle"
|
||||||
|
+listOf("-object_path_lto", "temporary.o", "-lto_library", libLTO)
|
||||||
|
+listOf("-dynamic", "-arch", arch)
|
||||||
|
+osVersionMinFlags
|
||||||
|
+listOf("-syslibroot", absoluteTargetSysRoot, "-o", executable)
|
||||||
|
+objectFiles
|
||||||
|
if (optimize) +linkerOptimizationFlags
|
||||||
|
if (!debug) +linkerNoDebugFlags
|
||||||
|
if (dynamic) +linkerDynamicFlags
|
||||||
|
+linkerKonanFlags
|
||||||
|
+"-lSystem"
|
||||||
|
+libraries
|
||||||
|
+linkerArgs
|
||||||
|
}) + if (debug) listOf(dsymUtilCommand(executable, outputDsymBundle)) else emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dsymUtilCommand(executable: ExecutableFile, outputDsymBundle: String) =
|
fun dsymUtilCommand(executable: ExecutableFile, outputDsymBundle: String) =
|
||||||
object : Command(dsymutilCommand(executable, outputDsymBundle)) {
|
object : Command(dsymutilCommand(executable, outputDsymBundle)) {
|
||||||
override fun runProcess(): Int =
|
override fun runProcess(): Int =
|
||||||
executeCommandWithFilter(command)
|
executeCommandWithFilter(command)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: consider introducing a better filtering directly in Command.
|
// TODO: consider introducing a better filtering directly in Command.
|
||||||
private fun executeCommandWithFilter(command: List<String>): Int {
|
private fun executeCommandWithFilter(command: List<String>): Int {
|
||||||
@@ -156,105 +198,135 @@ open class MacOSBasedLinker(targetProperties: AppleConfigurables)
|
|||||||
}
|
}
|
||||||
|
|
||||||
open fun dsymutilCommand(executable: ExecutableFile, outputDsymBundle: String): List<String> =
|
open fun dsymutilCommand(executable: ExecutableFile, outputDsymBundle: String): List<String> =
|
||||||
listOf(dsymutil, executable, "-o", outputDsymBundle)
|
listOf(dsymutil, executable, "-o", outputDsymBundle)
|
||||||
|
|
||||||
open fun dsymutilDryRunVerboseCommand(executable: ExecutableFile): List<String> =
|
open fun dsymutilDryRunVerboseCommand(executable: ExecutableFile): List<String> =
|
||||||
listOf(dsymutil, "-dump-debug-map" ,executable)
|
listOf(dsymutil, "-dump-debug-map", executable)
|
||||||
}
|
}
|
||||||
|
|
||||||
open class LinuxBasedLinker(targetProperties: LinuxBasedConfigurables)
|
open class LinuxBasedLinker(targetProperties: LinuxBasedConfigurables)
|
||||||
: LinkerFlags(targetProperties), LinuxBasedConfigurables by targetProperties {
|
: LinkerFlags(targetProperties), LinuxBasedConfigurables by targetProperties {
|
||||||
|
|
||||||
|
private val ar = "$absoluteTargetToolchain/bin/ar"
|
||||||
override val libGcc: String = "$absoluteTargetSysRoot/${super.libGcc}"
|
override val libGcc: String = "$absoluteTargetSysRoot/${super.libGcc}"
|
||||||
private val linker = "$absoluteTargetToolchain/bin/ld.gold"
|
private val linker = "$absoluteTargetToolchain/bin/ld.gold"
|
||||||
private val specificLibs
|
private val specificLibs = abiSpecificLibraries.map { "-L${absoluteTargetSysRoot}/$it" }
|
||||||
= abiSpecificLibraries.map { "-L${absoluteTargetSysRoot}/$it" }
|
|
||||||
|
|
||||||
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, dynamic: Boolean): Command {
|
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
||||||
val isMips = (configurables is LinuxMIPSConfigurables)
|
libraries: List<String>, linkerArgs: List<String>,
|
||||||
|
optimize: Boolean, debug: Boolean,
|
||||||
// TODO: Can we extract more to the konan.configurables?
|
kind: LinkerOutputKind, outputDsymBundle: String): List<Command> {
|
||||||
return Command(linker).apply {
|
if (kind == LinkerOutputKind.STATIC_LIBRARY) {
|
||||||
+ "--sysroot=${absoluteTargetSysRoot}"
|
// Here we take somewhat unexpected approach - we create the thin
|
||||||
+ "-export-dynamic"
|
// library, and then repack it during post-link phase.
|
||||||
+ "-z"
|
// This way we ensure .a inputs are properly processed.
|
||||||
+ "relro"
|
return listOf(Command(ar, "cqT", executable).apply {
|
||||||
+ "--build-id"
|
+objectFiles
|
||||||
+ "--eh-frame-hdr"
|
+libraries
|
||||||
+ "-dynamic-linker"
|
},
|
||||||
+ dynamicLinker
|
postLinkGnuArCommand(ar, executable))
|
||||||
+ "-o"
|
|
||||||
+ executable
|
|
||||||
if (!dynamic) + "$absoluteTargetSysRoot/usr/lib64/crt1.o"
|
|
||||||
+ "$absoluteTargetSysRoot/usr/lib64/crti.o"
|
|
||||||
if (dynamic)
|
|
||||||
+ "$libGcc/crtbeginS.o"
|
|
||||||
else
|
|
||||||
+ "$libGcc/crtbegin.o"
|
|
||||||
+ "-L$llvmLib"
|
|
||||||
+ "-L$libGcc"
|
|
||||||
if (!isMips) + "--hash-style=gnu" // MIPS doesn't support hash-style=gnu
|
|
||||||
+ specificLibs
|
|
||||||
+ listOf("-L$absoluteTargetSysRoot/../lib", "-L$absoluteTargetSysRoot/lib", "-L$absoluteTargetSysRoot/usr/lib")
|
|
||||||
if (optimize) {
|
|
||||||
+ "-plugin"
|
|
||||||
+"$llvmLib/LLVMgold.so"
|
|
||||||
+ pluginOptimizationFlags
|
|
||||||
}
|
|
||||||
if (optimize) + linkerOptimizationFlags
|
|
||||||
if (!debug) + linkerNoDebugFlags
|
|
||||||
if (dynamic) + linkerDynamicFlags
|
|
||||||
+ objectFiles
|
|
||||||
+ linkerKonanFlags
|
|
||||||
+ listOf("-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed",
|
|
||||||
"-lc", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed")
|
|
||||||
if (dynamic)
|
|
||||||
+ "$libGcc/crtendS.o"
|
|
||||||
else
|
|
||||||
+ "$libGcc/crtend.o"
|
|
||||||
+ "$absoluteTargetSysRoot/usr/lib64/crtn.o"
|
|
||||||
}
|
}
|
||||||
|
val isMips = (configurables is LinuxMIPSConfigurables)
|
||||||
|
val dynamic = kind == LinkerOutputKind.DYNAMIC_LIBRARY
|
||||||
|
// TODO: Can we extract more to the konan.configurables?
|
||||||
|
return listOf(Command(linker).apply {
|
||||||
|
+"--sysroot=${absoluteTargetSysRoot}"
|
||||||
|
+"-export-dynamic"
|
||||||
|
+"-z"
|
||||||
|
+"relro"
|
||||||
|
+"--build-id"
|
||||||
|
+"--eh-frame-hdr"
|
||||||
|
+"-dynamic-linker"
|
||||||
|
+dynamicLinker
|
||||||
|
+"-o"
|
||||||
|
+executable
|
||||||
|
if (!dynamic) +"$absoluteTargetSysRoot/usr/lib64/crt1.o"
|
||||||
|
+"$absoluteTargetSysRoot/usr/lib64/crti.o"
|
||||||
|
+if (dynamic) "$libGcc/crtbeginS.o" else "$libGcc/crtbegin.o"
|
||||||
|
+"-L$llvmLib"
|
||||||
|
+"-L$libGcc"
|
||||||
|
if (!isMips) +"--hash-style=gnu" // MIPS doesn't support hash-style=gnu
|
||||||
|
+specificLibs
|
||||||
|
+listOf("-L$absoluteTargetSysRoot/../lib", "-L$absoluteTargetSysRoot/lib", "-L$absoluteTargetSysRoot/usr/lib")
|
||||||
|
if (optimize) {
|
||||||
|
+"-plugin"
|
||||||
|
+"$llvmLib/LLVMgold.so"
|
||||||
|
+pluginOptimizationFlags
|
||||||
|
}
|
||||||
|
if (optimize) +linkerOptimizationFlags
|
||||||
|
if (!debug) +linkerNoDebugFlags
|
||||||
|
if (dynamic) +linkerDynamicFlags
|
||||||
|
+objectFiles
|
||||||
|
+linkerKonanFlags
|
||||||
|
+listOf("-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed",
|
||||||
|
"-lc", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed")
|
||||||
|
+if (dynamic) "$libGcc/crtendS.o" else "$libGcc/crtend.o"
|
||||||
|
+"$absoluteTargetSysRoot/usr/lib64/crtn.o"
|
||||||
|
+libraries
|
||||||
|
+linkerArgs
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class MingwLinker(targetProperties: MingwConfigurables)
|
open class MingwLinker(targetProperties: MingwConfigurables)
|
||||||
: LinkerFlags(targetProperties), MingwConfigurables by targetProperties {
|
: LinkerFlags(targetProperties), MingwConfigurables by targetProperties {
|
||||||
|
|
||||||
|
private val ar = "$absoluteTargetToolchain\\bin\\ar"
|
||||||
private val linker = "$absoluteTargetToolchain/bin/clang++"
|
private val linker = "$absoluteTargetToolchain/bin/clang++"
|
||||||
|
|
||||||
override val useCompilerDriverAsLinker: Boolean get() = true
|
override val useCompilerDriverAsLinker: Boolean get() = true
|
||||||
|
|
||||||
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, dynamic: Boolean): Command {
|
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
||||||
return Command(linker).apply {
|
libraries: List<String>, linkerArgs: List<String>,
|
||||||
+ listOf("-o", executable)
|
optimize: Boolean, debug: Boolean,
|
||||||
+ objectFiles
|
kind: LinkerOutputKind, outputDsymBundle: String): List<Command> {
|
||||||
if (optimize) + linkerOptimizationFlags
|
if (kind == LinkerOutputKind.STATIC_LIBRARY) {
|
||||||
if (!debug) + linkerNoDebugFlags
|
// Here we take somewhat unexpected approach - we create the thin
|
||||||
if (dynamic) + linkerDynamicFlags
|
// library, and then repack it during post-link phase.
|
||||||
|
// This way we ensure .a inputs are properly processed.
|
||||||
|
val temp = executable.replace('/', '\\') + "__"
|
||||||
|
return listOf(
|
||||||
|
Command(ar, "-rucT", temp).apply {
|
||||||
|
+objectFiles
|
||||||
|
+libraries
|
||||||
|
},
|
||||||
|
Command("cmd", "/c").apply {
|
||||||
|
+"(echo create $executable & echo addlib ${temp} & echo save & echo end) | $ar -M"
|
||||||
|
},
|
||||||
|
Command("cmd", "/c", "del", "/q", temp))
|
||||||
}
|
}
|
||||||
|
val dynamic = kind == LinkerOutputKind.DYNAMIC_LIBRARY
|
||||||
|
return listOf(Command(linker).apply {
|
||||||
|
+listOf("-o", executable)
|
||||||
|
+objectFiles
|
||||||
|
if (optimize) +linkerOptimizationFlags
|
||||||
|
if (!debug) +linkerNoDebugFlags
|
||||||
|
if (dynamic) +linkerDynamicFlags
|
||||||
|
+libraries
|
||||||
|
+linkerArgs
|
||||||
|
+linkerKonanFlags
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun linkCommandSuffix() = linkerKonanFlags
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open class WasmLinker(targetProperties: WasmConfigurables)
|
open class WasmLinker(targetProperties: WasmConfigurables)
|
||||||
: LinkerFlags(targetProperties), WasmConfigurables by targetProperties {
|
: LinkerFlags(targetProperties), WasmConfigurables by targetProperties {
|
||||||
|
|
||||||
private val clang = "clang"
|
|
||||||
|
|
||||||
override val useCompilerDriverAsLinker: Boolean get() = false
|
override val useCompilerDriverAsLinker: Boolean get() = false
|
||||||
|
|
||||||
override fun filterStaticLibraries(binaries: List<String>)
|
override fun filterStaticLibraries(binaries: List<String>) = binaries.filter { it.isJavaScript }
|
||||||
= binaries.filter{it.isJavaScript}
|
|
||||||
|
|
||||||
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): Command {
|
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
||||||
return object: Command("") {
|
libraries: List<String>, linkerArgs: List<String>,
|
||||||
|
optimize: Boolean, debug: Boolean,
|
||||||
|
kind: LinkerOutputKind, outputDsymBundle: String): List<Command> {
|
||||||
|
if (kind != LinkerOutputKind.EXECUTABLE) throw Error("Unsupported linker output kind")
|
||||||
|
// TODO(horsh): make it proper list.
|
||||||
|
return listOf(object : Command() {
|
||||||
override fun execute() {
|
override fun execute() {
|
||||||
val src = File(objectFiles.single())
|
val src = File(objectFiles.single())
|
||||||
val dst = File(executable)
|
val dst = File(executable)
|
||||||
@@ -281,7 +353,7 @@ open class WasmLinker(targetProperties: WasmConfigurables)
|
|||||||
linkedJavaScript.appendBytes(linkerFooter.toByteArray());
|
linkedJavaScript.appendBytes(linkerFooter.toByteArray());
|
||||||
return linkedJavaScript.name
|
return linkedJavaScript.name
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,33 +364,38 @@ open class ZephyrLinker(targetProperties: ZephyrConfigurables)
|
|||||||
|
|
||||||
override val useCompilerDriverAsLinker: Boolean get() = false
|
override val useCompilerDriverAsLinker: Boolean get() = false
|
||||||
|
|
||||||
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, dynamic: Boolean): Command {
|
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
||||||
return Command(linker).apply {
|
libraries: List<String>, linkerArgs: List<String>,
|
||||||
+ listOf("-r", "--gc-sections", "--entry", "main")
|
optimize: Boolean, debug: Boolean,
|
||||||
+ listOf("-o", executable)
|
kind: LinkerOutputKind, outputDsymBundle: String): List<Command> {
|
||||||
+ objectFiles
|
if (kind != LinkerOutputKind.EXECUTABLE) throw Error("Unsupported linker output kind: $kind")
|
||||||
}
|
return listOf(Command(linker).apply {
|
||||||
|
+listOf("-r", "--gc-sections", "--entry", "main")
|
||||||
|
+listOf("-o", executable)
|
||||||
|
+objectFiles
|
||||||
|
+libraries
|
||||||
|
+linkerArgs
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun linker(configurables: Configurables): LinkerFlags =
|
fun linker(configurables: Configurables): LinkerFlags =
|
||||||
when (configurables.target) {
|
when (configurables.target) {
|
||||||
KonanTarget.LINUX_X64, KonanTarget.LINUX_ARM32_HFP ->
|
KonanTarget.LINUX_X64, KonanTarget.LINUX_ARM32_HFP ->
|
||||||
LinuxBasedLinker(configurables as LinuxConfigurables)
|
LinuxBasedLinker(configurables as LinuxConfigurables)
|
||||||
KonanTarget.LINUX_MIPS32, KonanTarget.LINUX_MIPSEL32 ->
|
KonanTarget.LINUX_MIPS32, KonanTarget.LINUX_MIPSEL32 ->
|
||||||
LinuxBasedLinker(configurables as LinuxMIPSConfigurables)
|
LinuxBasedLinker(configurables as LinuxMIPSConfigurables)
|
||||||
KonanTarget.MACOS_X64, KonanTarget.IOS_ARM64, KonanTarget.IOS_X64 ->
|
KonanTarget.MACOS_X64, KonanTarget.IOS_ARM64, KonanTarget.IOS_X64 ->
|
||||||
MacOSBasedLinker(configurables as AppleConfigurables)
|
MacOSBasedLinker(configurables as AppleConfigurables)
|
||||||
KonanTarget.ANDROID_ARM32, KonanTarget.ANDROID_ARM64 ->
|
KonanTarget.ANDROID_ARM32, KonanTarget.ANDROID_ARM64 ->
|
||||||
AndroidLinker(configurables as AndroidConfigurables)
|
AndroidLinker(configurables as AndroidConfigurables)
|
||||||
KonanTarget.MINGW_X64 ->
|
KonanTarget.MINGW_X64 ->
|
||||||
MingwLinker(configurables as MingwConfigurables)
|
MingwLinker(configurables as MingwConfigurables)
|
||||||
KonanTarget.WASM32 ->
|
KonanTarget.WASM32 ->
|
||||||
WasmLinker(configurables as WasmConfigurables)
|
WasmLinker(configurables as WasmConfigurables)
|
||||||
is KonanTarget.ZEPHYR ->
|
is KonanTarget.ZEPHYR ->
|
||||||
ZephyrLinker(configurables as ZephyrConfigurables)
|
ZephyrLinker(configurables as ZephyrConfigurables)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
@@ -110,6 +110,10 @@ class EnvVariableSpecification extends BaseKonanSpecification {
|
|||||||
prefix = target.family.dynamicPrefix
|
prefix = target.family.dynamicPrefix
|
||||||
suffix = target.family.dynamicSuffix
|
suffix = target.family.dynamicSuffix
|
||||||
break
|
break
|
||||||
|
case ArtifactType.STATIC:
|
||||||
|
prefix = target.family.staticPrefix
|
||||||
|
suffix = target.family.staticSuffix
|
||||||
|
break
|
||||||
case ArtifactType.FRAMEWORK:
|
case ArtifactType.FRAMEWORK:
|
||||||
suffix = "framework"
|
suffix = "framework"
|
||||||
}
|
}
|
||||||
@@ -194,6 +198,7 @@ class EnvVariableSpecification extends BaseKonanSpecification {
|
|||||||
files.contains(artifactFileName("program", ArtifactType.PROGRAM))
|
files.contains(artifactFileName("program", ArtifactType.PROGRAM))
|
||||||
files.contains(artifactFileName("library", ArtifactType.LIBRARY))
|
files.contains(artifactFileName("library", ArtifactType.LIBRARY))
|
||||||
files.contains(artifactFileName("dynamic", ArtifactType.DYNAMIC))
|
files.contains(artifactFileName("dynamic", ArtifactType.DYNAMIC))
|
||||||
|
files.contains(artifactFileName("static", ArtifactType.STATIC))
|
||||||
if (HostManager.hostIsMac) {
|
if (HostManager.hostIsMac) {
|
||||||
files.contains(artifactFileName("framework", ArtifactType.FRAMEWORK))
|
files.contains(artifactFileName("framework", ArtifactType.FRAMEWORK))
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -29,6 +29,7 @@ enum ArtifactType {
|
|||||||
BITCODE("bitcode"),
|
BITCODE("bitcode"),
|
||||||
INTEROP("interop"),
|
INTEROP("interop"),
|
||||||
DYNAMIC("dynamic"),
|
DYNAMIC("dynamic"),
|
||||||
|
STATIC("static"),
|
||||||
FRAMEWORK("framework")
|
FRAMEWORK("framework")
|
||||||
|
|
||||||
String type
|
String type
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ open class PropertiesAsEnvVariables {
|
|||||||
prefix = target.family.dynamicPrefix
|
prefix = target.family.dynamicPrefix
|
||||||
suffix = target.family.dynamicSuffix
|
suffix = target.family.dynamicSuffix
|
||||||
}
|
}
|
||||||
|
ArtifactType.STATIC -> {
|
||||||
|
prefix = target.family.staticPrefix
|
||||||
|
suffix = target.family.staticSuffix
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return "$prefix${baseName}.$suffix"
|
return "$prefix${baseName}.$suffix"
|
||||||
|
|||||||
Reference in New Issue
Block a user