Splitted KonanProperties into Configurables hierarchy.
Untangled Platfrom classes from the LinkStage and Distribution. Simplified clang management a little.
This commit is contained in:
committed by
alexander-gorshenev
parent
c5276cf6da
commit
d4b47ac709
@@ -72,7 +72,7 @@ model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
binaries.all {
|
binaries.all {
|
||||||
cCompiler.args hostCompilerArgsForJni
|
cCompiler.args hostPlatform.clang.hostCompilerArgsForJni
|
||||||
cCompiler.args.addAll(cflags)
|
cCompiler.args.addAll(cflags)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,4 +157,4 @@ task updatePrebuilt {
|
|||||||
into 'prebuilt/nativeInteropStubs/c'
|
into 'prebuilt/nativeInteropStubs/c'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ model {
|
|||||||
|
|
||||||
def hostLibffiDir = rootProject.ext.get("${host}LibffiDir")
|
def hostLibffiDir = rootProject.ext.get("${host}LibffiDir")
|
||||||
|
|
||||||
cCompiler.args hostCompilerArgsForJni
|
cCompiler.args hostPlatform.clang.hostCompilerArgsForJni
|
||||||
cCompiler.args "-I$hostLibffiDir/include"
|
cCompiler.args "-I$hostLibffiDir/include"
|
||||||
|
|
||||||
linker.args "$hostLibffiDir/lib/libffi.a"
|
linker.args "$hostLibffiDir/lib/libffi.a"
|
||||||
|
|||||||
+14
-13
@@ -16,10 +16,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.native.interop.tool
|
package org.jetbrains.kotlin.native.interop.tool
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.file.*
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
import org.jetbrains.kotlin.konan.properties.*
|
import org.jetbrains.kotlin.konan.properties.loadProperties
|
||||||
import org.jetbrains.kotlin.konan.target.*
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import org.jetbrains.kotlin.konan.util.*
|
import org.jetbrains.kotlin.konan.target.PlatformManager
|
||||||
|
import org.jetbrains.kotlin.konan.target.TargetManager
|
||||||
|
import org.jetbrains.kotlin.konan.util.DependencyProcessor
|
||||||
|
import org.jetbrains.kotlin.konan.util.visibleName
|
||||||
|
|
||||||
class ToolConfig(userProvidedTargetName: String?, userProvidedKonanProperties: String?, runnerProvidedKonanHome: String) {
|
class ToolConfig(userProvidedTargetName: String?, userProvidedKonanProperties: String?, runnerProvidedKonanHome: String) {
|
||||||
|
|
||||||
@@ -33,23 +36,21 @@ class ToolConfig(userProvidedTargetName: String?, userProvidedKonanProperties: S
|
|||||||
|
|
||||||
private val dependencies = DependencyProcessor.defaultDependenciesRoot
|
private val dependencies = DependencyProcessor.defaultDependenciesRoot
|
||||||
|
|
||||||
private val targetProperties = KonanProperties(target, properties, dependencies.path)
|
private val platform = PlatformManager(properties, dependencies.path).platform(target)
|
||||||
|
|
||||||
val substitutions = mapOf<String, String> (
|
val substitutions = mapOf<String, String> (
|
||||||
"target" to target.detailedName,
|
"target" to target.detailedName,
|
||||||
"arch" to target.architecture.visibleName)
|
"arch" to target.architecture.visibleName)
|
||||||
|
|
||||||
fun downloadDependencies() = targetProperties.downloadDependencies()
|
fun downloadDependencies() = platform.downloadDependencies()
|
||||||
|
|
||||||
val llvmHome = targetProperties.absoluteLlvmHome
|
val defaultCompilerOpts =
|
||||||
|
platform.clang.targetLibclangArgs.toList()
|
||||||
|
|
||||||
val sysRoot get() = targetProperties.absoluteTargetSysRoot
|
val llvmHome = platform.absoluteLlvmHome
|
||||||
|
val sysRoot = platform.absoluteTargetSysRoot
|
||||||
|
|
||||||
val defaultCompilerOpts = ClangManager(properties, dependencies.path)
|
val libclang = when (host) {
|
||||||
.targetLibclangArgs(targetProperties.target).toList()
|
|
||||||
|
|
||||||
|
|
||||||
val libclang = when (host) {
|
|
||||||
KonanTarget.MINGW -> "$llvmHome/bin/libclang.dll"
|
KonanTarget.MINGW -> "$llvmHome/bin/libclang.dll"
|
||||||
else -> "$llvmHome/lib/${System.mapLibraryName("clang")}"
|
else -> "$llvmHome/lib/${System.mapLibraryName("clang")}"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.konan.exec.*
|
|||||||
import org.jetbrains.kotlin.konan.target.*
|
import org.jetbrains.kotlin.konan.target.*
|
||||||
import org.jetbrains.kotlin.konan.file.*
|
import org.jetbrains.kotlin.konan.file.*
|
||||||
|
|
||||||
fun produceCAdapterBitcode(clang: TargetClang, cppFileName: String, bitcodeFileName: String) {
|
fun produceCAdapterBitcode(clang: ClangArgs, cppFileName: String, bitcodeFileName: String) {
|
||||||
val clangCommand = clang.clangCXX("-std=c++11", cppFileName, "-emit-llvm", "-c", "-o", bitcodeFileName)
|
val clangCommand = clang.clangCXX("-std=c++11", cppFileName, "-emit-llvm", "-c", "-o", bitcodeFileName)
|
||||||
Command(clangCommand).execute()
|
Command(clangCommand).execute()
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-25
@@ -16,21 +16,15 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.konan
|
package org.jetbrains.kotlin.backend.konan
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.target.*
|
|
||||||
import org.jetbrains.kotlin.konan.file.*
|
import org.jetbrains.kotlin.konan.file.*
|
||||||
import org.jetbrains.kotlin.konan.properties.*
|
import org.jetbrains.kotlin.konan.properties.*
|
||||||
|
import org.jetbrains.kotlin.konan.target.*
|
||||||
|
import org.jetbrains.kotlin.konan.util.visibleName
|
||||||
import org.jetbrains.kotlin.konan.util.DependencyProcessor
|
import org.jetbrains.kotlin.konan.util.DependencyProcessor
|
||||||
|
|
||||||
class Distribution(val targetManager: TargetManager,
|
class Distribution(val target: KonanTarget,
|
||||||
val propertyFileOverride: String? = null,
|
propertyFileOverride: String? = null,
|
||||||
val runtimeFileOverride: String? = null) {
|
runtimeFileOverride: String? = null) {
|
||||||
|
|
||||||
val target = targetManager.target
|
|
||||||
val targetName = targetManager.targetName
|
|
||||||
val host = TargetManager.host
|
|
||||||
val hostSuffix = TargetManager.hostSuffix
|
|
||||||
val hostTargetSuffix = targetManager.hostTargetSuffix
|
|
||||||
val targetSuffix = targetManager.targetSuffix
|
|
||||||
|
|
||||||
val localKonanDir = "${File.userHome}/.konan"
|
val localKonanDir = "${File.userHome}/.konan"
|
||||||
|
|
||||||
@@ -46,22 +40,10 @@ class Distribution(val targetManager: TargetManager,
|
|||||||
|
|
||||||
val klib = "$konanHome/klib"
|
val klib = "$konanHome/klib"
|
||||||
val stdlib = "$klib/common/stdlib"
|
val stdlib = "$klib/common/stdlib"
|
||||||
|
|
||||||
|
val targetName = target.visibleName
|
||||||
val defaultNatives = "$konanHome/konan/targets/${targetName}/native"
|
val defaultNatives = "$konanHome/konan/targets/${targetName}/native"
|
||||||
val runtime = runtimeFileOverride ?: "$stdlib/targets/${targetName}/native/runtime.bc"
|
val runtime = runtimeFileOverride ?: "$stdlib/targets/${targetName}/native/runtime.bc"
|
||||||
|
|
||||||
val dependenciesDir = DependencyProcessor.defaultDependenciesRoot.absolutePath
|
val dependenciesDir = DependencyProcessor.defaultDependenciesRoot.absolutePath
|
||||||
|
|
||||||
val targetProperties = KonanProperties(target, properties, dependenciesDir)
|
|
||||||
|
|
||||||
val llvmHome = targetProperties.absoluteLlvmHome
|
|
||||||
val llvmBin = "$llvmHome/bin"
|
|
||||||
val llvmLib = "$llvmHome/lib"
|
|
||||||
val llvmLto = "$llvmBin/llvm-lto"
|
|
||||||
|
|
||||||
private val libLTODir = when (TargetManager.host) {
|
|
||||||
KonanTarget.MACBOOK, KonanTarget.LINUX -> llvmLib
|
|
||||||
KonanTarget.MINGW -> llvmBin
|
|
||||||
else -> error("Don't know libLTO location for this platform.")
|
|
||||||
}
|
|
||||||
val libLTO = "$libLTODir/${System.mapLibraryName("LTO")}"
|
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-10
@@ -52,19 +52,17 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
|
|
||||||
val indirectBranchesAreAllowed = target != KonanTarget.WASM32
|
val indirectBranchesAreAllowed = target != KonanTarget.WASM32
|
||||||
|
|
||||||
private fun Distribution.prepareDependencies(checkDependencies: Boolean) {
|
internal val distribution = Distribution(target,
|
||||||
if (checkDependencies) {
|
configuration.get(KonanConfigKeys.PROPERTY_FILE),
|
||||||
targetProperties.downloadDependencies()
|
configuration.get(KonanConfigKeys.RUNTIME_FILE))
|
||||||
|
|
||||||
|
internal val platform = PlatformManager(distribution.properties, distribution.dependenciesDir).platform(target).apply {
|
||||||
|
if (configuration.getBoolean(KonanConfigKeys.CHECK_DEPENDENCIES)) {
|
||||||
|
downloadDependencies()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val distribution = Distribution(targetManager,
|
internal val clang = platform.clang
|
||||||
configuration.get(KonanConfigKeys.PROPERTY_FILE),
|
|
||||||
configuration.get(KonanConfigKeys.RUNTIME_FILE)).apply {
|
|
||||||
prepareDependencies(configuration.getBoolean(KonanConfigKeys.CHECK_DEPENDENCIES))
|
|
||||||
}
|
|
||||||
|
|
||||||
internal val clang = TargetClang(distribution.properties, distribution.dependenciesDir, target)
|
|
||||||
|
|
||||||
internal val produce get() = configuration.get(KonanConfigKeys.PRODUCE)!!
|
internal val produce get() = configuration.get(KonanConfigKeys.PRODUCE)!!
|
||||||
private val prefix = produce.prefix(target)
|
private val prefix = produce.prefix(target)
|
||||||
|
|||||||
+15
-304
@@ -16,310 +16,21 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.konan
|
package org.jetbrains.kotlin.backend.konan
|
||||||
|
|
||||||
import java.lang.ProcessBuilder
|
|
||||||
import java.lang.ProcessBuilder.Redirect
|
|
||||||
import org.jetbrains.kotlin.konan.KonanExternalToolFailure
|
import org.jetbrains.kotlin.konan.KonanExternalToolFailure
|
||||||
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.*
|
||||||
import org.jetbrains.kotlin.konan.properties.*
|
|
||||||
import org.jetbrains.kotlin.konan.target.*
|
import org.jetbrains.kotlin.konan.target.*
|
||||||
|
|
||||||
typealias BitcodeFile = String
|
typealias BitcodeFile = String
|
||||||
typealias ObjectFile = String
|
typealias ObjectFile = String
|
||||||
typealias ExecutableFile = String
|
typealias ExecutableFile = String
|
||||||
|
|
||||||
// Use "clang -v -save-temps" to write linkCommand() method
|
|
||||||
// for another implementation of this class.
|
|
||||||
internal abstract class PlatformFlags(val properties: KonanProperties) {
|
|
||||||
val llvmLtoNooptFlags = properties.llvmLtoNooptFlags
|
|
||||||
val llvmLtoOptFlags = properties.llvmLtoOptFlags
|
|
||||||
val llvmLtoFlags = properties.llvmLtoFlags
|
|
||||||
val llvmLtoDynamicFlags = properties.llvmLtoDynamicFlags
|
|
||||||
val entrySelector = properties.entrySelector
|
|
||||||
val linkerOptimizationFlags = properties.linkerOptimizationFlags
|
|
||||||
val linkerKonanFlags = properties.linkerKonanFlags
|
|
||||||
val linkerNoDebugFlags = properties.linkerNoDebugFlags
|
|
||||||
val linkerDynamicFlags = properties.linkerDynamicFlags
|
|
||||||
val llvmDebugOptFlags = properties.llvmDebugOptFlags
|
|
||||||
val s2wasmFlags = properties.s2wasmFlags
|
|
||||||
val targetToolchain = properties.absoluteTargetToolchain
|
|
||||||
val targetSysRoot = properties.absoluteTargetSysRoot
|
|
||||||
|
|
||||||
val targetLibffi = properties.libffiDir ?.let { listOf("${properties.absoluteLibffiDir}/lib/libffi.a") } ?: emptyList()
|
|
||||||
|
|
||||||
open val useCompilerDriverAsLinker: Boolean get() = false // TODO: refactor.
|
|
||||||
|
|
||||||
abstract fun linkCommand(objectFiles: List<ObjectFile>,
|
|
||||||
executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): Command
|
|
||||||
|
|
||||||
open fun linkCommandSuffix(): List<String> = emptyList()
|
|
||||||
|
|
||||||
protected fun propertyTargetString(name: String)
|
|
||||||
= properties.targetString(name)!!
|
|
||||||
protected fun propertyTargetList(name: String)
|
|
||||||
= properties.targetList(name)
|
|
||||||
|
|
||||||
abstract fun filterStaticLibraries(binaries: List<String>): List<String>
|
|
||||||
|
|
||||||
open fun linkStaticLibraries(binaries: List<String>): List<String> {
|
|
||||||
val libraries = filterStaticLibraries(binaries)
|
|
||||||
// Let's just pass them as absolute paths
|
|
||||||
return libraries
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
internal open class AndroidPlatform(distribution: Distribution)
|
|
||||||
: PlatformFlags(distribution.targetProperties) {
|
|
||||||
|
|
||||||
private val prefix = "$targetToolchain/bin/"
|
|
||||||
private val clang = "$prefix/clang"
|
|
||||||
|
|
||||||
override val useCompilerDriverAsLinker: Boolean get() = true
|
|
||||||
|
|
||||||
override fun filterStaticLibraries(binaries: List<String>)
|
|
||||||
= binaries.filter { it.isUnixStaticLib }
|
|
||||||
|
|
||||||
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): Command {
|
|
||||||
// liblog.so must be linked in, as we use its functionality in runtime.
|
|
||||||
return Command(clang).apply {
|
|
||||||
+ "-o"
|
|
||||||
+ executable
|
|
||||||
+ "-fPIC"
|
|
||||||
+ "-shared"
|
|
||||||
+ "-llog"
|
|
||||||
+ objectFiles
|
|
||||||
if (optimize) + linkerOptimizationFlags
|
|
||||||
if (!debug) + linkerNoDebugFlags
|
|
||||||
if (dynamic) + linkerDynamicFlags
|
|
||||||
+ linkerKonanFlags
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal open class MacOSBasedPlatform(distribution: Distribution)
|
|
||||||
: PlatformFlags(distribution.targetProperties) {
|
|
||||||
|
|
||||||
private val linker = "$targetToolchain/usr/bin/ld"
|
|
||||||
internal val dsymutil = "${distribution.llvmBin}/llvm-dsymutil"
|
|
||||||
internal val libLTO = distribution.libLTO
|
|
||||||
|
|
||||||
open val osVersionMin by lazy {
|
|
||||||
listOf(
|
|
||||||
propertyTargetString("osVersionMinFlagLd"),
|
|
||||||
properties.osVersionMin!! + ".0")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun filterStaticLibraries(binaries: List<String>)
|
|
||||||
= binaries.filter { it.isUnixStaticLib }
|
|
||||||
|
|
||||||
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): Command {
|
|
||||||
return object : Command(linker) {} .apply {
|
|
||||||
+ "-demangle"
|
|
||||||
+ listOf("-object_path_lto", "temporary.o", "-lto_library", libLTO)
|
|
||||||
+ listOf("-dynamic", "-arch", propertyTargetString("arch"))
|
|
||||||
+ osVersionMin
|
|
||||||
+ listOf("-syslibroot", targetSysRoot, "-o", executable)
|
|
||||||
+ objectFiles
|
|
||||||
if (optimize) + linkerOptimizationFlags
|
|
||||||
if (!debug) + linkerNoDebugFlags
|
|
||||||
if (dynamic) + linkerDynamicFlags
|
|
||||||
+ linkerKonanFlags
|
|
||||||
+ "-lSystem"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun dsymUtilCommand(executable: ExecutableFile, outputDsymBundle: String) =
|
|
||||||
object : Command(dsymutilCommand(executable, outputDsymBundle)) {
|
|
||||||
override fun runProcess(): Int =
|
|
||||||
executeCommandWithFilter(command)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: consider introducing a better filtering directly in Command.
|
|
||||||
private fun executeCommandWithFilter(command: List<String>): Int {
|
|
||||||
val builder = ProcessBuilder(command)
|
|
||||||
|
|
||||||
// Inherit main process output streams.
|
|
||||||
val isDsymUtil = (command[0] == dsymutil)
|
|
||||||
|
|
||||||
builder.redirectOutput(Redirect.INHERIT)
|
|
||||||
builder.redirectInput(Redirect.INHERIT)
|
|
||||||
if (!isDsymUtil)
|
|
||||||
builder.redirectError(Redirect.INHERIT)
|
|
||||||
|
|
||||||
val process = builder.start()
|
|
||||||
if (isDsymUtil) {
|
|
||||||
/**
|
|
||||||
* llvm-lto has option -alias that lets tool to know which symbol we use instead of _main,
|
|
||||||
* llvm-dsym doesn't have such a option, so we ignore annoying warning manually.
|
|
||||||
*/
|
|
||||||
val errorStream = process.errorStream
|
|
||||||
val outputStream = bufferedReader(errorStream)
|
|
||||||
while (true) {
|
|
||||||
val line = outputStream.readLine() ?: break
|
|
||||||
if (!line.contains("warning: could not find object file symbol for symbol _main"))
|
|
||||||
System.err.println(line)
|
|
||||||
}
|
|
||||||
outputStream.close()
|
|
||||||
}
|
|
||||||
val exitCode = process.waitFor()
|
|
||||||
return exitCode
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun dsymutilCommand(executable: ExecutableFile, outputDsymBundle: String): List<String> =
|
|
||||||
listOf(dsymutil, executable, "-o", outputDsymBundle)
|
|
||||||
|
|
||||||
open fun dsymutilDryRunVerboseCommand(executable: ExecutableFile): List<String> =
|
|
||||||
listOf(dsymutil, "-dump-debug-map" ,executable)
|
|
||||||
}
|
|
||||||
|
|
||||||
internal open class LinuxBasedPlatform(val distribution: Distribution)
|
|
||||||
: PlatformFlags(distribution.targetProperties) {
|
|
||||||
|
|
||||||
private val llvmLib = distribution.llvmLib
|
|
||||||
private val libGcc = "$targetSysRoot/${propertyTargetString("libGcc")}"
|
|
||||||
private val linker = "$targetToolchain/bin/ld.gold"
|
|
||||||
private val pluginOptimizationFlags = propertyTargetList("pluginOptimizationFlags")
|
|
||||||
private val specificLibs
|
|
||||||
= propertyTargetList("abiSpecificLibraries").map { "-L${targetSysRoot}/$it" }
|
|
||||||
|
|
||||||
override fun filterStaticLibraries(binaries: List<String>)
|
|
||||||
= binaries.filter { it.isUnixStaticLib }
|
|
||||||
|
|
||||||
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): Command {
|
|
||||||
val isMips = (distribution.target == KonanTarget.LINUX_MIPS32 ||
|
|
||||||
distribution.target == KonanTarget.LINUX_MIPSEL32)
|
|
||||||
// TODO: Can we extract more to the konan.properties?
|
|
||||||
return Command(linker).apply {
|
|
||||||
+ "--sysroot=${targetSysRoot}"
|
|
||||||
+ "-export-dynamic"
|
|
||||||
+ "-z"
|
|
||||||
+ "relro"
|
|
||||||
+ "--build-id"
|
|
||||||
+ "--eh-frame-hdr"
|
|
||||||
// + "-m"
|
|
||||||
// + "elf_x86_64",
|
|
||||||
+ "-dynamic-linker"
|
|
||||||
+ propertyTargetString("dynamicLinker")
|
|
||||||
+ "-o"
|
|
||||||
+ executable
|
|
||||||
if (!dynamic) + "$targetSysRoot/usr/lib64/crt1.o"
|
|
||||||
+ "$targetSysRoot/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$targetSysRoot/../lib", "-L$targetSysRoot/lib", "-L$targetSysRoot/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"
|
|
||||||
+ "$targetSysRoot/usr/lib64/crtn.o"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal open class MingwPlatform(distribution: Distribution)
|
|
||||||
: PlatformFlags(distribution.targetProperties) {
|
|
||||||
|
|
||||||
private val linker = "$targetToolchain/bin/clang++"
|
|
||||||
|
|
||||||
override val useCompilerDriverAsLinker: Boolean get() = true
|
|
||||||
|
|
||||||
override fun filterStaticLibraries(binaries: List<String>)
|
|
||||||
= binaries.filter { it.isWindowsStaticLib || it.isUnixStaticLib }
|
|
||||||
|
|
||||||
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): Command {
|
|
||||||
return Command(linker).apply {
|
|
||||||
+ listOf("-o", executable)
|
|
||||||
+ objectFiles
|
|
||||||
if (optimize) + linkerOptimizationFlags
|
|
||||||
if (!debug) + linkerNoDebugFlags
|
|
||||||
if (dynamic) + linkerDynamicFlags
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun linkCommandSuffix() = linkerKonanFlags
|
|
||||||
}
|
|
||||||
|
|
||||||
internal open class WasmPlatform(distribution: Distribution)
|
|
||||||
: PlatformFlags(distribution.targetProperties) {
|
|
||||||
|
|
||||||
private val clang = "clang"
|
|
||||||
|
|
||||||
override val useCompilerDriverAsLinker: Boolean get() = false
|
|
||||||
|
|
||||||
override fun filterStaticLibraries(binaries: List<String>)
|
|
||||||
= binaries.filter{it.isJavaScript}
|
|
||||||
|
|
||||||
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): Command {
|
|
||||||
return object: Command("") {
|
|
||||||
override fun execute() {
|
|
||||||
val src = File(objectFiles.single())
|
|
||||||
val dst = File(executable)
|
|
||||||
src.recursiveCopyTo(dst)
|
|
||||||
javaScriptLink(args, executable)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun javaScriptLink(jsFiles: List<String>, executable: String): String {
|
|
||||||
val linkedJavaScript = File("$executable.js")
|
|
||||||
|
|
||||||
val linkerHeader = "var konan = { libraries: [] };\n"
|
|
||||||
val linkerFooter = """|if (isBrowser()) {
|
|
||||||
| konan.moduleEntry([]);
|
|
||||||
|} else {
|
|
||||||
| konan.moduleEntry(arguments);
|
|
||||||
|}""".trimMargin()
|
|
||||||
|
|
||||||
linkedJavaScript.writeBytes(linkerHeader.toByteArray());
|
|
||||||
|
|
||||||
jsFiles.forEach {
|
|
||||||
linkedJavaScript.appendBytes(File(it).readBytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
linkedJavaScript.appendBytes(linkerFooter.toByteArray());
|
|
||||||
return linkedJavaScript.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class LinkStage(val context: Context) {
|
internal class LinkStage(val context: Context) {
|
||||||
|
|
||||||
val config = context.config.configuration
|
private val config = context.config.configuration
|
||||||
val target = context.config.targetManager.target
|
private val target = context.config.targetManager.target
|
||||||
|
private val platform = context.config.platform
|
||||||
private val distribution = context.config.distribution
|
private val linker = platform.linker
|
||||||
|
|
||||||
private val platform = when (target) {
|
|
||||||
KonanTarget.LINUX, KonanTarget.RASPBERRYPI,
|
|
||||||
KonanTarget.LINUX_MIPS32, KonanTarget.LINUX_MIPSEL32 ->
|
|
||||||
LinuxBasedPlatform(distribution)
|
|
||||||
KonanTarget.MACBOOK, KonanTarget.IPHONE, KonanTarget.IPHONE_SIM ->
|
|
||||||
MacOSBasedPlatform(distribution)
|
|
||||||
KonanTarget.ANDROID_ARM32, KonanTarget.ANDROID_ARM64 ->
|
|
||||||
AndroidPlatform(distribution)
|
|
||||||
KonanTarget.MINGW ->
|
|
||||||
MingwPlatform(distribution)
|
|
||||||
KonanTarget.WASM32 ->
|
|
||||||
WasmPlatform(distribution)
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
||||||
@@ -341,7 +52,7 @@ internal class LinkStage(val context: Context) {
|
|||||||
private fun llvmLto(files: List<BitcodeFile>): ObjectFile {
|
private fun llvmLto(files: List<BitcodeFile>): ObjectFile {
|
||||||
val combined = temporary("combined", ".o")
|
val combined = temporary("combined", ".o")
|
||||||
|
|
||||||
val tool = distribution.llvmLto
|
val tool = "${platform.absoluteLlvmHome}/bin/llvm-lto"
|
||||||
val command = mutableListOf(tool, "-o", combined)
|
val command = mutableListOf(tool, "-o", combined)
|
||||||
command.addNonEmpty(platform.llvmLtoFlags)
|
command.addNonEmpty(platform.llvmLtoFlags)
|
||||||
when {
|
when {
|
||||||
@@ -363,12 +74,12 @@ internal class LinkStage(val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun targetTool(tool: String, vararg arg: String) {
|
private fun targetTool(tool: String, vararg arg: String) {
|
||||||
val absoluteToolName = "${platform.targetToolchain}/bin/$tool"
|
val absoluteToolName = "${platform.absoluteTargetToolchain}/bin/$tool"
|
||||||
runTool(absoluteToolName, *arg)
|
runTool(absoluteToolName, *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hostLlvmTool(tool: String, args: List<String>) {
|
private fun hostLlvmTool(tool: String, args: List<String>) {
|
||||||
val absoluteToolName = "${distribution.llvmBin}/$tool"
|
val absoluteToolName = "${platform.absoluteLlvmHome}/bin/$tool"
|
||||||
val command = listOf(absoluteToolName) + args
|
val command = listOf(absoluteToolName) + args
|
||||||
runTool(command)
|
runTool(command)
|
||||||
}
|
}
|
||||||
@@ -380,7 +91,7 @@ internal class LinkStage(val context: Context) {
|
|||||||
val combinedS = temporary("combined", ".s")
|
val combinedS = temporary("combined", ".s")
|
||||||
targetTool("llc", combinedBc, "-o", combinedS)
|
targetTool("llc", combinedBc, "-o", combinedS)
|
||||||
|
|
||||||
val s2wasmFlags = platform.s2wasmFlags.toTypedArray()
|
val s2wasmFlags = (platform.configurables as WasmConfigurables).s2wasmFlags.toTypedArray()
|
||||||
val combinedWast = temporary( "combined", ".wast")
|
val combinedWast = temporary( "combined", ".wast")
|
||||||
targetTool("s2wasm", combinedS, "-o", combinedWast, *s2wasmFlags)
|
targetTool("s2wasm", combinedS, "-o", combinedWast, *s2wasmFlags)
|
||||||
|
|
||||||
@@ -392,7 +103,7 @@ internal class LinkStage(val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun asLinkerArgs(args: List<String>): List<String> {
|
private fun asLinkerArgs(args: List<String>): List<String> {
|
||||||
if (platform.useCompilerDriverAsLinker) {
|
if (linker.useCompilerDriverAsLinker) {
|
||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,21 +151,21 @@ internal class LinkStage(val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
platform.linkCommand(objectFiles, executable, optimize, debug, dynamic).apply {
|
linker.linkCommand(objectFiles, executable, optimize, debug, dynamic).apply {
|
||||||
+ platform.targetLibffi
|
+ linker.targetLibffi
|
||||||
+ asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS))
|
+ asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS))
|
||||||
+ entryPointSelector
|
+ entryPointSelector
|
||||||
+ frameworkLinkerArgs
|
+ frameworkLinkerArgs
|
||||||
+ platform.linkCommandSuffix()
|
+ linker.linkCommandSuffix()
|
||||||
+ platform.linkStaticLibraries(includedBinaries)
|
+ linker.linkStaticLibraries(includedBinaries)
|
||||||
+ libraryProvidedLinkerFlags
|
+ libraryProvidedLinkerFlags
|
||||||
logger = context::log
|
logger = context::log
|
||||||
}.execute()
|
}.execute()
|
||||||
|
|
||||||
if (debug && platform is MacOSBasedPlatform) {
|
if (debug && linker is MacOSBasedLinker) {
|
||||||
val outputDsymBundle = context.config.outputFile + ".dSYM" // `outputFile` is either binary or bundle.
|
val outputDsymBundle = context.config.outputFile + ".dSYM" // `outputFile` is either binary or bundle.
|
||||||
|
|
||||||
platform.dsymUtilCommand(executable, outputDsymBundle)
|
linker.dsymUtilCommand(executable, outputDsymBundle)
|
||||||
.logWith(context::log)
|
.logWith(context::log)
|
||||||
.execute()
|
.execute()
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-5
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.backend.konan.util.suffixIfNot
|
|||||||
import org.jetbrains.kotlin.konan.file.File
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import org.jetbrains.kotlin.konan.target.TargetManager
|
import org.jetbrains.kotlin.konan.target.TargetManager
|
||||||
|
import org.jetbrains.kotlin.konan.util.visibleName
|
||||||
|
|
||||||
interface SearchPathResolver {
|
interface SearchPathResolver {
|
||||||
val searchRoots: List<File>
|
val searchRoots: List<File>
|
||||||
@@ -30,13 +31,13 @@ interface SearchPathResolver {
|
|||||||
fun defaultLinks(nostdlib: Boolean, noDefaultLibs: Boolean): List<File>
|
fun defaultLinks(nostdlib: Boolean, noDefaultLibs: Boolean): List<File>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun defaultResolver(repositories: List<String>, targetManager: TargetManager): SearchPathResolver =
|
fun defaultResolver(repositories: List<String>, target: KonanTarget): SearchPathResolver =
|
||||||
defaultResolver(repositories, Distribution(targetManager))
|
defaultResolver(repositories, Distribution(target))
|
||||||
|
|
||||||
fun defaultResolver(repositories: List<String>, distribution: Distribution): SearchPathResolver =
|
fun defaultResolver(repositories: List<String>, distribution: Distribution): SearchPathResolver =
|
||||||
KonanLibrarySearchPathResolver(
|
KonanLibrarySearchPathResolver(
|
||||||
repositories,
|
repositories,
|
||||||
distribution.targetManager,
|
distribution.target,
|
||||||
distribution.klib,
|
distribution.klib,
|
||||||
distribution.localKonanDir
|
distribution.localKonanDir
|
||||||
)
|
)
|
||||||
@@ -133,7 +134,7 @@ fun SearchPathResolver.resolveLibrariesRecursive(libraryNames: List<String>,
|
|||||||
|
|
||||||
class KonanLibrarySearchPathResolver(
|
class KonanLibrarySearchPathResolver(
|
||||||
repositories: List<String>,
|
repositories: List<String>,
|
||||||
val targetManager: TargetManager?,
|
val target: KonanTarget?,
|
||||||
val distributionKlib: String?,
|
val distributionKlib: String?,
|
||||||
val localKonanDir: String?,
|
val localKonanDir: String?,
|
||||||
val skipCurrentDir: Boolean = false
|
val skipCurrentDir: Boolean = false
|
||||||
@@ -146,7 +147,7 @@ class KonanLibrarySearchPathResolver(
|
|||||||
get() = distributionKlib?.File()?.child("common")
|
get() = distributionKlib?.File()?.child("common")
|
||||||
|
|
||||||
val distPlatformHead: File?
|
val distPlatformHead: File?
|
||||||
get() = targetManager?.let { distributionKlib?.File()?.child("platform")?.child(targetManager.targetName) }
|
get() = target?.let { distributionKlib?.File()?.child("platform")?.child(target.visibleName) }
|
||||||
|
|
||||||
val currentDirHead: File?
|
val currentDirHead: File?
|
||||||
get() = if (!skipCurrentDir) File.userDir else null
|
get() = if (!skipCurrentDir) File.userDir else null
|
||||||
|
|||||||
+3
-1
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
|||||||
import org.jetbrains.kotlin.konan.file.File
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
|
import org.jetbrains.kotlin.konan.target.AppleConfigurables
|
||||||
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.name.isSubpackageOf
|
import org.jetbrains.kotlin.name.isSubpackageOf
|
||||||
@@ -102,7 +103,8 @@ internal class ObjCExport(val context: Context) {
|
|||||||
KonanTarget.MACBOOK -> "MacOSX"
|
KonanTarget.MACBOOK -> "MacOSX"
|
||||||
else -> error(target)
|
else -> error(target)
|
||||||
}
|
}
|
||||||
val minimumOsVersion = context.config.distribution.targetProperties.osVersionMin!!
|
val properties = context.config.platform.configurables as AppleConfigurables
|
||||||
|
val minimumOsVersion = properties.osVersionMin!!
|
||||||
|
|
||||||
val contents = StringBuilder()
|
val contents = StringBuilder()
|
||||||
contents.append("""
|
contents.append("""
|
||||||
|
|||||||
@@ -193,9 +193,11 @@ targetToolchain.linux-linux_mips32 = target-gcc-toolchain-2-linux-mips/x86_64-un
|
|||||||
dependencies.linux-linux_mips32 = \
|
dependencies.linux-linux_mips32 = \
|
||||||
clang-llvm-5.0.0-linux-x86-64 \
|
clang-llvm-5.0.0-linux-x86-64 \
|
||||||
target-gcc-toolchain-2-linux-mips \
|
target-gcc-toolchain-2-linux-mips \
|
||||||
|
target-gcc-toolchain-3-linux-x86-64 \
|
||||||
target-sysroot-2-mips \
|
target-sysroot-2-mips \
|
||||||
libffi-3.2.1-2-linux-x86-64 \
|
libffi-3.2.1-2-linux-x86-64 \
|
||||||
libffi-3.2.1-2-linux-mips
|
libffi-3.2.1-2-linux-mips
|
||||||
|
|
||||||
quadruple.linux_mips32 = mips-unknown-linux-gnu
|
quadruple.linux_mips32 = mips-unknown-linux-gnu
|
||||||
entrySelector.linux_mips32 = --defsym main=Konan_main
|
entrySelector.linux_mips32 = --defsym main=Konan_main
|
||||||
linkerOptimizationFlags.linux_mips32 = --gc-sections
|
linkerOptimizationFlags.linux_mips32 = --gc-sections
|
||||||
@@ -220,6 +222,7 @@ targetToolchain.linux-linux_mipsel32 = target-gcc-toolchain-2-linux-mips/x86_64-
|
|||||||
dependencies.linux-linux_mipsel32 = \
|
dependencies.linux-linux_mipsel32 = \
|
||||||
clang-llvm-5.0.0-linux-x86-64 \
|
clang-llvm-5.0.0-linux-x86-64 \
|
||||||
target-gcc-toolchain-2-linux-mips \
|
target-gcc-toolchain-2-linux-mips \
|
||||||
|
target-gcc-toolchain-3-linux-x86-64 \
|
||||||
target-sysroot-2-mipsel \
|
target-sysroot-2-mipsel \
|
||||||
libffi-3.2.1-2-linux-x86-64 \
|
libffi-3.2.1-2-linux-x86-64 \
|
||||||
libffi-3.2.1-2-linux-mipsel
|
libffi-3.2.1-2-linux-mipsel
|
||||||
|
|||||||
+4
-4
@@ -39,7 +39,7 @@ ext {
|
|||||||
|
|
||||||
distDir = file('dist')
|
distDir = file('dist')
|
||||||
dependenciesDir = DependencyProcessor.defaultDependenciesRoot
|
dependenciesDir = DependencyProcessor.defaultDependenciesRoot
|
||||||
clangManager = new ClangManager(konanProperties, dependenciesDir.absolutePath)
|
platformManager = new PlatformManager(konanProperties, dependenciesDir.absolutePath)
|
||||||
kotlinCompilerModule="org.jetbrains.kotlin:kotlin-compiler:${kotlinCompilerVersion}"
|
kotlinCompilerModule="org.jetbrains.kotlin:kotlin-compiler:${kotlinCompilerVersion}"
|
||||||
kotlinStdLibModule="org.jetbrains.kotlin:kotlin-stdlib:${kotlinStdLibVersion}"
|
kotlinStdLibModule="org.jetbrains.kotlin:kotlin-stdlib:${kotlinStdLibVersion}"
|
||||||
kotlinReflectModule="org.jetbrains.kotlin:kotlin-reflect:${kotlinReflectVersion}"
|
kotlinReflectModule="org.jetbrains.kotlin:kotlin-reflect:${kotlinReflectVersion}"
|
||||||
@@ -71,7 +71,7 @@ void setupHostAndTarget() {
|
|||||||
|
|
||||||
void setupClang(Project project) {
|
void setupClang(Project project) {
|
||||||
|
|
||||||
project.convention.plugins.clangManager = project.rootProject.ext.clangManager
|
project.convention.plugins.platformManager = project.rootProject.ext.platformManager
|
||||||
project.convention.plugins.execClang = new org.jetbrains.kotlin.ExecClang(project)
|
project.convention.plugins.execClang = new org.jetbrains.kotlin.ExecClang(project)
|
||||||
|
|
||||||
project.plugins.withType(NativeComponentPlugin) {
|
project.plugins.withType(NativeComponentPlugin) {
|
||||||
@@ -98,13 +98,13 @@ void setupClang(Project project) {
|
|||||||
|
|
||||||
toolChains {
|
toolChains {
|
||||||
clang(Clang) {
|
clang(Clang) {
|
||||||
hostClang.hostClangPath.each {
|
hostPlatform.clang.clangPaths.each {
|
||||||
path it
|
path it
|
||||||
}
|
}
|
||||||
|
|
||||||
eachPlatform { // TODO: will not work when cross-compiling
|
eachPlatform { // TODO: will not work when cross-compiling
|
||||||
[cCompiler, cppCompiler, linker].each {
|
[cCompiler, cppCompiler, linker].each {
|
||||||
it.withArguments { it.addAll(project.hostClangArgs) }
|
it.withArguments { it.addAll(project.hostPlatform.clang.clangArgs) }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class ExecClang {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<String> konanArgs(KonanTarget target) {
|
private List<String> konanArgs(KonanTarget target) {
|
||||||
return project.rootProject.targetClangArgsForKonanSources(target)
|
return project.rootProject.platform(target).clang.clangArgsForKonanSources
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> konanArgs(String target) {
|
private List<String> konanArgs(String target) {
|
||||||
@@ -95,7 +95,7 @@ class ExecClang {
|
|||||||
throw new GradleException("unsupported clang executable: $executable")
|
throw new GradleException("unsupported clang executable: $executable")
|
||||||
}
|
}
|
||||||
|
|
||||||
environment["PATH"] = project.files(project.hostClang.hostClangPath).asPath +
|
environment["PATH"] = project.files(project.hostPlatform.clang.clangPaths).asPath +
|
||||||
File.pathSeparator + environment["PATH"]
|
File.pathSeparator + environment["PATH"]
|
||||||
args defaultArgs
|
args defaultArgs
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ class NamedNativeInteropConfig implements Named {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: the interop plugin should probably be reworked to execute clang from build scripts directly
|
// TODO: the interop plugin should probably be reworked to execute clang from build scripts directly
|
||||||
environment['PATH'] = project.files(project.hostClang.hostClangPath).asPath +
|
environment['PATH'] = project.files(project.hostPlatform.clang.clangPaths).asPath +
|
||||||
File.pathSeparator + environment['PATH']
|
File.pathSeparator + environment['PATH']
|
||||||
|
|
||||||
args compilerOpts.collectMany { ['-copt', it] }
|
args compilerOpts.collectMany { ['-copt', it] }
|
||||||
|
|||||||
Vendored
+5
-5
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.konan.target.*
|
|||||||
import org.jetbrains.kotlin.konan.util.DependencyProcessor
|
import org.jetbrains.kotlin.konan.util.DependencyProcessor
|
||||||
import static org.jetbrains.kotlin.konan.target.KonanTarget.*
|
import static org.jetbrains.kotlin.konan.target.KonanTarget.*
|
||||||
import static org.jetbrains.kotlin.konan.util.VisibleNamedKt.*
|
import static org.jetbrains.kotlin.konan.util.VisibleNamedKt.*
|
||||||
import org.jetbrains.kotlin.konan.properties.KonanProperties
|
import org.jetbrains.kotlin.konan.properties.KonanPropertiesLoader
|
||||||
import org.jetbrains.kotlin.konan.properties.*
|
import org.jetbrains.kotlin.konan.properties.*
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
@@ -210,14 +210,14 @@ class HelperNativeDep extends TgzNativeDep {
|
|||||||
|
|
||||||
enum DependencyKind {
|
enum DependencyKind {
|
||||||
LLVM( "llvm", { it.llvmHome }, { "llvmDir" } ),
|
LLVM( "llvm", { it.llvmHome }, { "llvmDir" } ),
|
||||||
GCC_TOOLCHAIN( "gccToolchain", { it.gccToolchain }, { "gccToolchainDir" }),
|
GCC_TOOLCHAIN( "gccToolchain", { (it instanceof LinuxBasedConfigurables) ? it.gccToolchain : null }, { "gccToolchainDir" }),
|
||||||
SYSROOT( "sysroot", { it.targetSysRoot } ),
|
SYSROOT( "sysroot", { it.targetSysRoot } ),
|
||||||
LIBFFI( "libffi", { it.libffiDir } ),
|
LIBFFI( "libffi", { it.libffiDir } ),
|
||||||
TARGET_TOOLCHAIN("targetToolchain", { it.targetToolchain } )
|
TARGET_TOOLCHAIN("targetToolchain", { it.targetToolchain } )
|
||||||
|
|
||||||
|
|
||||||
DependencyKind(String name,
|
DependencyKind(String name,
|
||||||
@ClosureParams(value = FromString.class, options = "KonanProperties") Closure<String> dirGetter,
|
@ClosureParams(value = FromString.class, options = "KonanPropertiesLoader") Closure<String> dirGetter,
|
||||||
@ClosureParams(value = FromString.class, options = "KonanTarget") Closure<String> propertyNameGetter =
|
@ClosureParams(value = FromString.class, options = "KonanTarget") Closure<String> propertyNameGetter =
|
||||||
{target -> "${getVisibleName(target)}${name.capitalize()}Dir"}) {
|
{target -> "${getVisibleName(target)}${name.capitalize()}Dir"}) {
|
||||||
this.name = name
|
this.name = name
|
||||||
@@ -229,7 +229,7 @@ enum DependencyKind {
|
|||||||
private Closure<String> dirGetter // KonanProperties -> String
|
private Closure<String> dirGetter // KonanProperties -> String
|
||||||
private Closure<String> propertyNameGetter // KonanTarget -> String
|
private Closure<String> propertyNameGetter // KonanTarget -> String
|
||||||
|
|
||||||
String getDirectory(KonanProperties properties) {
|
String getDirectory(KonanPropertiesLoader properties) {
|
||||||
return dirGetter(properties)
|
return dirGetter(properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,7 +241,7 @@ enum DependencyKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TargetManager.enabled.each { target ->
|
TargetManager.enabled.each { target ->
|
||||||
def konanProperties = new KonanProperties(target,
|
def konanProperties = new KonanPropertiesLoader(target,
|
||||||
rootProject.ext.konanProperties,
|
rootProject.ext.konanProperties,
|
||||||
rootProject.ext.dependenciesDir.canonicalPath
|
rootProject.ext.dependenciesDir.canonicalPath
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ val currentAbiVersion = 1
|
|||||||
fun libraryInRepo(repository: File, name: String): File {
|
fun libraryInRepo(repository: File, name: String): File {
|
||||||
val resolver = KonanLibrarySearchPathResolver(
|
val resolver = KonanLibrarySearchPathResolver(
|
||||||
repositories = listOf(repository.absolutePath),
|
repositories = listOf(repository.absolutePath),
|
||||||
targetManager = null,
|
target = null,
|
||||||
distributionKlib = null,
|
distributionKlib = null,
|
||||||
localKonanDir = null,
|
localKonanDir = null,
|
||||||
skipCurrentDir = true
|
skipCurrentDir = true
|
||||||
@@ -146,7 +146,7 @@ fun libraryInRepo(repository: File, name: String): File {
|
|||||||
fun libraryInCurrentDir(name: String): File {
|
fun libraryInCurrentDir(name: String): File {
|
||||||
val resolver = KonanLibrarySearchPathResolver(
|
val resolver = KonanLibrarySearchPathResolver(
|
||||||
repositories = emptyList(),
|
repositories = emptyList(),
|
||||||
targetManager = null,
|
target = null,
|
||||||
distributionKlib = null,
|
distributionKlib = null,
|
||||||
localKonanDir = null
|
localKonanDir = null
|
||||||
)
|
)
|
||||||
@@ -156,7 +156,7 @@ fun libraryInCurrentDir(name: String): File {
|
|||||||
fun libraryInRepoOrCurrentDir(repository: File, name: String): File {
|
fun libraryInRepoOrCurrentDir(repository: File, name: String): File {
|
||||||
val resolver = KonanLibrarySearchPathResolver(
|
val resolver = KonanLibrarySearchPathResolver(
|
||||||
repositories = listOf(repository.absolutePath),
|
repositories = listOf(repository.absolutePath),
|
||||||
targetManager = null,
|
target = null,
|
||||||
distributionKlib = null,
|
distributionKlib = null,
|
||||||
localKonanDir = null
|
localKonanDir = null
|
||||||
)
|
)
|
||||||
|
|||||||
+1
-2
@@ -14,8 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.backend.konan
|
package org.jetbrains.kotlin.konan.file
|
||||||
|
|
||||||
|
|
||||||
val String.isJavaScript
|
val String.isJavaScript
|
||||||
get() = this.endsWith(".js")
|
get() = this.endsWith(".js")
|
||||||
@@ -16,70 +16,70 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.konan.target
|
package org.jetbrains.kotlin.konan.target
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.properties.KonanProperties
|
|
||||||
import org.jetbrains.kotlin.konan.file.File
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
|
|
||||||
class ClangTargetArgs(val target: KonanTarget, konanProperties: KonanProperties) {
|
class ClangArgs(private val configurables: Configurables) : Configurables by configurables {
|
||||||
|
|
||||||
val sysRoot = konanProperties.absoluteTargetSysRoot
|
val targetArg = if (configurables is NonAppleConfigurables)
|
||||||
val targetArg = konanProperties.targetArg
|
configurables.targetArg
|
||||||
|
else null
|
||||||
|
|
||||||
val specificClangArgs: List<String> get() {
|
val specificClangArgs: List<String> get() {
|
||||||
val result = when (target) {
|
val result = when (target) {
|
||||||
KonanTarget.LINUX ->
|
KonanTarget.LINUX ->
|
||||||
listOf("--sysroot=$sysRoot")
|
listOf("--sysroot=$absoluteTargetSysRoot")
|
||||||
KonanTarget.RASPBERRYPI ->
|
KonanTarget.RASPBERRYPI ->
|
||||||
listOf("-target", targetArg!!,
|
listOf("-target", targetArg!!,
|
||||||
"-mfpu=vfp", "-mfloat-abi=hard",
|
"-mfpu=vfp", "-mfloat-abi=hard",
|
||||||
"--sysroot=$sysRoot",
|
"--sysroot=$absoluteTargetSysRoot",
|
||||||
// TODO: those two are hacks.
|
// TODO: those two are hacks.
|
||||||
"-I$sysRoot/usr/include/c++/4.8.3",
|
"-I$absoluteTargetSysRoot/usr/include/c++/4.8.3",
|
||||||
"-I$sysRoot/usr/include/c++/4.8.3/arm-linux-gnueabihf")
|
"-I$absoluteTargetSysRoot/usr/include/c++/4.8.3/arm-linux-gnueabihf")
|
||||||
|
|
||||||
KonanTarget.LINUX_MIPS32 ->
|
KonanTarget.LINUX_MIPS32 ->
|
||||||
listOf("-target", targetArg!!,
|
listOf("-target", targetArg!!,
|
||||||
"--sysroot=$sysRoot",
|
"--sysroot=$absoluteTargetSysRoot",
|
||||||
"-I$sysRoot/usr/include/c++/4.9.4",
|
"-I$absoluteTargetSysRoot/usr/include/c++/4.9.4",
|
||||||
"-I$sysRoot/usr/include/c++/4.9.4/mips-unknown-linux-gnu")
|
"-I$absoluteTargetSysRoot/usr/include/c++/4.9.4/mips-unknown-linux-gnu")
|
||||||
|
|
||||||
KonanTarget.LINUX_MIPSEL32 ->
|
KonanTarget.LINUX_MIPSEL32 ->
|
||||||
listOf("-target", targetArg!!,
|
listOf("-target", targetArg!!,
|
||||||
"--sysroot=$sysRoot",
|
"--sysroot=$absoluteTargetSysRoot",
|
||||||
"-I$sysRoot/usr/include/c++/4.9.4",
|
"-I$absoluteTargetSysRoot/usr/include/c++/4.9.4",
|
||||||
"-I$sysRoot/usr/include/c++/4.9.4/mipsel-unknown-linux-gnu")
|
"-I$absoluteTargetSysRoot/usr/include/c++/4.9.4/mipsel-unknown-linux-gnu")
|
||||||
|
|
||||||
KonanTarget.MINGW ->
|
KonanTarget.MINGW ->
|
||||||
listOf("-target", targetArg!!, "--sysroot=$sysRoot", "-Xclang", "-flto-visibility-public-std")
|
listOf("-target", targetArg!!, "--sysroot=$absoluteTargetSysRoot", "-Xclang", "-flto-visibility-public-std")
|
||||||
|
|
||||||
KonanTarget.MACBOOK ->
|
KonanTarget.MACBOOK ->
|
||||||
listOf("--sysroot=$sysRoot", "-mmacosx-version-min=10.11")
|
listOf("--sysroot=$absoluteTargetSysRoot", "-mmacosx-version-min=10.11")
|
||||||
|
|
||||||
KonanTarget.IPHONE ->
|
KonanTarget.IPHONE ->
|
||||||
listOf("-stdlib=libc++", "-arch", "arm64", "-isysroot", sysRoot, "-miphoneos-version-min=8.0.0")
|
listOf("-stdlib=libc++", "-arch", "arm64", "-isysroot", absoluteTargetSysRoot, "-miphoneos-version-min=8.0.0")
|
||||||
|
|
||||||
KonanTarget.IPHONE_SIM ->
|
KonanTarget.IPHONE_SIM ->
|
||||||
listOf("-stdlib=libc++", "-isysroot", sysRoot, "-miphoneos-version-min=8.0.0")
|
listOf("-stdlib=libc++", "-isysroot", absoluteTargetSysRoot, "-miphoneos-version-min=8.0.0")
|
||||||
|
|
||||||
KonanTarget.ANDROID_ARM32 ->
|
KonanTarget.ANDROID_ARM32 ->
|
||||||
listOf("-target", targetArg!!,
|
listOf("-target", targetArg!!,
|
||||||
"--sysroot=$sysRoot",
|
"--sysroot=$absoluteTargetSysRoot",
|
||||||
// HACKS!
|
// HACKS!
|
||||||
"-I$sysRoot/usr/include/c++/4.9.x",
|
"-I$absoluteTargetSysRoot/usr/include/c++/4.9.x",
|
||||||
"-I$sysRoot/usr/include/c++/4.9.x/arm-linux-androideabi")
|
"-I$absoluteTargetSysRoot/usr/include/c++/4.9.x/arm-linux-androideabi")
|
||||||
|
|
||||||
KonanTarget.ANDROID_ARM64 ->
|
KonanTarget.ANDROID_ARM64 ->
|
||||||
listOf("-target", targetArg!!,
|
listOf("-target", targetArg!!,
|
||||||
"--sysroot=$sysRoot",
|
"--sysroot=$absoluteTargetSysRoot",
|
||||||
// HACKS!
|
// HACKS!
|
||||||
"-I$sysRoot/usr/include/c++/4.9.x",
|
"-I$absoluteTargetSysRoot/usr/include/c++/4.9.x",
|
||||||
"-I$sysRoot/usr/include/c++/4.9.x/aarch64-linux-android")
|
"-I$absoluteTargetSysRoot/usr/include/c++/4.9.x/aarch64-linux-android")
|
||||||
|
|
||||||
KonanTarget.WASM32 ->
|
KonanTarget.WASM32 ->
|
||||||
listOf("-target", targetArg!!, "-O1", "-fno-rtti", "-fno-exceptions",
|
listOf("-target", targetArg!!, "-O1", "-fno-rtti", "-fno-exceptions",
|
||||||
"-D_LIBCPP_ABI_VERSION=2", "-D_LIBCPP_NO_EXCEPTIONS=1",
|
"-D_LIBCPP_ABI_VERSION=2", "-D_LIBCPP_NO_EXCEPTIONS=1",
|
||||||
"-nostdinc", "-Xclang", "-nobuiltininc", "-Xclang", "-nostdsysteminc",
|
"-nostdinc", "-Xclang", "-nobuiltininc", "-Xclang", "-nostdsysteminc",
|
||||||
"-Xclang", "-isystem$sysRoot/include/libcxx", "-Xclang", "-isystem$sysRoot/lib/libcxxabi/include",
|
"-Xclang", "-isystem$absoluteTargetSysRoot/include/libcxx", "-Xclang", "-isystem$absoluteTargetSysRoot/lib/libcxxabi/include",
|
||||||
"-Xclang", "-isystem$sysRoot/include/compat", "-Xclang", "-isystem$sysRoot/include/libc")
|
"-Xclang", "-isystem$absoluteTargetSysRoot/include/compat", "-Xclang", "-isystem$absoluteTargetSysRoot/include/libc")
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@@ -119,35 +119,58 @@ class ClangTargetArgs(val target: KonanTarget, konanProperties: KonanProperties)
|
|||||||
listOf("-DKONAN_WASM=1", "-DKONAN_NO_FFI=1", "-DKONAN_NO_THREADS=1", "-DKONAN_NO_EXCEPTIONS=1",
|
listOf("-DKONAN_WASM=1", "-DKONAN_NO_FFI=1", "-DKONAN_NO_THREADS=1", "-DKONAN_NO_EXCEPTIONS=1",
|
||||||
"-DKONAN_INTERNAL_DLMALLOC=1", "-DKONAN_INTERNAL_SNPRINTF=1", "-DKONAN_INTERNAL_NOW=1")
|
"-DKONAN_INTERNAL_DLMALLOC=1", "-DKONAN_INTERNAL_SNPRINTF=1", "-DKONAN_INTERNAL_NOW=1")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class ClangHostArgs(val hostProperties: KonanProperties) {
|
private val host = TargetManager.host
|
||||||
|
|
||||||
val targetToolchain get() = hostProperties.absoluteTargetToolchain
|
private val binDir = when(host) {
|
||||||
val gccToolchain get() = hostProperties.absoluteGccToolchain
|
KonanTarget.LINUX -> "$absoluteTargetToolchain/bin"
|
||||||
val sysRoot get() = hostProperties.absoluteTargetSysRoot
|
KonanTarget.MINGW -> "$absoluteTargetToolchain/bin"
|
||||||
val llvmDir get() = hostProperties.absoluteLlvmHome
|
KonanTarget.MACBOOK -> "$absoluteTargetToolchain/usr/bin"
|
||||||
|
|
||||||
val binDir = when(TargetManager.host) {
|
|
||||||
KonanTarget.LINUX -> "$targetToolchain/bin"
|
|
||||||
KonanTarget.MINGW -> "$sysRoot/bin"
|
|
||||||
KonanTarget.MACBOOK -> "$targetToolchain/usr/bin"
|
|
||||||
else -> throw TargetSupportException("Unexpected host platform")
|
else -> throw TargetSupportException("Unexpected host platform")
|
||||||
}
|
}
|
||||||
|
|
||||||
private val extraHostClangArgs =
|
private val extraHostClangArgs =
|
||||||
if (TargetManager.host == KonanTarget.LINUX) {
|
if (configurables is LinuxBasedConfigurables) {
|
||||||
listOf("--gcc-toolchain=$gccToolchain")
|
listOf("--gcc-toolchain=${configurables.absoluteGccToolchain}")
|
||||||
} else {
|
} else {
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
val commonClangArgs = listOf("-B$binDir") + extraHostClangArgs
|
val commonClangArgs = listOf("-B$binDir") + extraHostClangArgs
|
||||||
|
|
||||||
val hostClangPath = listOf("$llvmDir/bin", binDir)
|
val clangPaths = listOf("$absoluteLlvmHome/bin", binDir)
|
||||||
|
|
||||||
private val jdkHome = File.jdkHome.absoluteFile.parent
|
private val jdkHome = File.jdkHome.absoluteFile.parent
|
||||||
|
|
||||||
val hostCompilerArgsForJni = listOf("", TargetManager.jniHostPlatformIncludeDir).map { "-I$jdkHome/include/$it" }
|
val hostCompilerArgsForJni = listOf("", TargetManager.jniHostPlatformIncludeDir).map { "-I$jdkHome/include/$it" }.toTypedArray()
|
||||||
|
|
||||||
|
val clangArgs =
|
||||||
|
(commonClangArgs + specificClangArgs).toTypedArray()
|
||||||
|
|
||||||
|
val clangArgsForKonanSources =
|
||||||
|
clangArgs + clangArgsSpecificForKonanSources
|
||||||
|
|
||||||
|
val targetLibclangArgs: List<String> get() {
|
||||||
|
// libclang works not exactly the same way as the clang binary and
|
||||||
|
// (in particular) uses different default header search path.
|
||||||
|
// See e.g. http://lists.llvm.org/pipermail/cfe-dev/2013-November/033680.html
|
||||||
|
// We workaround the problem with -isystem flag below.
|
||||||
|
val llvmVersion = llvmVersion
|
||||||
|
val llvmHome = absoluteLlvmHome
|
||||||
|
val isystemArgs = listOf("-isystem", "$llvmHome/lib/clang/$llvmVersion/include")
|
||||||
|
|
||||||
|
return isystemArgs + clangArgs.toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
val targetClangCmd
|
||||||
|
= listOf("${absoluteLlvmHome}/bin/clang") + clangArgs
|
||||||
|
|
||||||
|
val targetClangXXCmd
|
||||||
|
= listOf("${absoluteLlvmHome}/bin/clang++") + clangArgs
|
||||||
|
|
||||||
|
fun clangC(vararg userArgs: String) = targetClangCmd + userArgs.asList()
|
||||||
|
|
||||||
|
fun clangCXX(vararg userArgs: String) = targetClangXXCmd + userArgs.asList()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed -> in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.konan.target
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.properties.*
|
|
||||||
|
|
||||||
class ClangManager(val properties: Properties, val baseDir: String) {
|
|
||||||
private val host = TargetManager.host
|
|
||||||
private val enabledTargets = TargetManager.enabled
|
|
||||||
private val konanProperties = enabledTargets.map {
|
|
||||||
it to KonanProperties(it, properties, baseDir)
|
|
||||||
}.toMap()
|
|
||||||
|
|
||||||
private val targetClangArgs = enabledTargets.map {
|
|
||||||
it to ClangTargetArgs(it, konanProperties[it]!!)
|
|
||||||
}.toMap()
|
|
||||||
|
|
||||||
private val hostClang = ClangHostArgs(konanProperties[host]!!)
|
|
||||||
|
|
||||||
// These are converted to arrays to be convenient
|
|
||||||
// in groovy plugins.
|
|
||||||
val hostClangArgs = (hostClang.commonClangArgs + targetClangArgs[host]!!.specificClangArgs).toTypedArray()
|
|
||||||
|
|
||||||
fun targetClangArgs(target: KonanTarget)
|
|
||||||
= (hostClang.commonClangArgs + targetClangArgs[target]!!.specificClangArgs).toTypedArray()
|
|
||||||
|
|
||||||
fun targetClangArgsForKonanSources(target: KonanTarget) =
|
|
||||||
targetClangArgs(target) + targetClangArgs[target]!!.clangArgsSpecificForKonanSources
|
|
||||||
|
|
||||||
val hostCompilerArgsForJni = hostClang.hostCompilerArgsForJni.toTypedArray()
|
|
||||||
|
|
||||||
fun targetLibclangArgs(target: KonanTarget): List<String> {
|
|
||||||
// libclang works not exactly the same way as the clang binary and
|
|
||||||
// (in particular) uses different default header search path.
|
|
||||||
// See e.g. http://lists.llvm.org/pipermail/cfe-dev/2013-November/033680.html
|
|
||||||
// We workaround the problem with -isystem flag below.
|
|
||||||
val llvmVersion = properties.hostString("llvmVersion")!!
|
|
||||||
val llvmHome = konanProperties[target]!!.absoluteLlvmHome
|
|
||||||
val isystemArgs = listOf("-isystem", "$llvmHome/lib/clang/$llvmVersion/include")
|
|
||||||
|
|
||||||
return isystemArgs + targetClangArgs(target).toList()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun targetClangCmd(target: KonanTarget)
|
|
||||||
= listOf("${hostClang.llvmDir}/bin/clang") + targetClangArgs(target)
|
|
||||||
|
|
||||||
fun targetClangXXCmd(target: KonanTarget)
|
|
||||||
= listOf("${hostClang.llvmDir}/bin/clang++") + targetClangArgs(target)
|
|
||||||
}
|
|
||||||
|
|
||||||
class TargetClang(private val clangManager: ClangManager, private val target: KonanTarget) {
|
|
||||||
constructor (properties: Properties, baseDir: String, target: KonanTarget)
|
|
||||||
: this (ClangManager(properties, baseDir), target)
|
|
||||||
|
|
||||||
fun clangC(vararg userArgs: String) = clangManager.targetClangCmd(target) + userArgs.asList()
|
|
||||||
|
|
||||||
fun clangCXX(vararg userArgs: String) = clangManager.targetClangXXCmd(target) + userArgs.asList()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed -> in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.konan.target
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.konan.properties.*
|
||||||
|
|
||||||
|
interface Configurables : TargetableExternalStorage {
|
||||||
|
|
||||||
|
val target: KonanTarget
|
||||||
|
|
||||||
|
val llvmHome get() = hostString("llvmHome")
|
||||||
|
val llvmVersion get() = hostString("llvmVersion")
|
||||||
|
|
||||||
|
// TODO: Delegate to a map?
|
||||||
|
val llvmLtoNooptFlags get() = targetList("llvmLtoNooptFlags")
|
||||||
|
val llvmLtoOptFlags get() = targetList("llvmLtoOptFlags")
|
||||||
|
val llvmLtoFlags get() = targetList("llvmLtoFlags")
|
||||||
|
val llvmLtoDynamicFlags get() = targetList("llvmLtoDynamicFlags")
|
||||||
|
val entrySelector get() = targetList("entrySelector")
|
||||||
|
val linkerOptimizationFlags get() = targetList("linkerOptimizationFlags")
|
||||||
|
val linkerKonanFlags get() = targetList("linkerKonanFlags")
|
||||||
|
val linkerNoDebugFlags get() = targetList("linkerNoDebugFlags")
|
||||||
|
val linkerDynamicFlags get() = targetList("linkerDynamicFlags")
|
||||||
|
val llvmDebugOptFlags get() = targetList("llvmDebugOptFlags")
|
||||||
|
val targetSysRoot get() = targetString("targetSysRoot")
|
||||||
|
val libffiDir get() = targetString("libffiDir")
|
||||||
|
|
||||||
|
// Notice: these ones are host-target.
|
||||||
|
val targetToolchain get() = hostTargetString("targetToolchain")
|
||||||
|
|
||||||
|
val absoluteTargetSysRoot get() = absolute(targetSysRoot)
|
||||||
|
val absoluteTargetToolchain get() = absolute(targetToolchain)
|
||||||
|
val absoluteLlvmHome get() = absolute(llvmHome)
|
||||||
|
val absoluteLibffiDir get() = absolute(libffiDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface NonAppleConfigurables : Configurables {
|
||||||
|
val targetArg get() = targetString("quadruple")
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AppleConfigurables : Configurables {
|
||||||
|
val arch get() = targetString("arch")!!
|
||||||
|
val osVersionMin get() = targetString("osVersionMin")!!
|
||||||
|
val osVersionMinFlagLd get() = targetString("osVersionMinFlagLd")!!
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MingwConfigurables : NonAppleConfigurables
|
||||||
|
|
||||||
|
interface LinuxBasedConfigurables : NonAppleConfigurables {
|
||||||
|
val gccToolchain get() = hostString("gccToolchain")
|
||||||
|
val absoluteGccToolchain get() = absolute(gccToolchain)
|
||||||
|
|
||||||
|
val libGcc get() = targetString("libGcc")!!
|
||||||
|
val dynamicLinker get() = targetString("dynamicLinker")!!
|
||||||
|
val pluginOptimizationFlags get() = targetList("pluginOptimizationFlags")
|
||||||
|
val abiSpecificLibraries get() = targetList("abiSpecificLibraries")
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LinuxConfigurables : LinuxBasedConfigurables
|
||||||
|
interface LinuxMIPSConfigurables : LinuxBasedConfigurables
|
||||||
|
interface RaspberryPiConfigurables : LinuxBasedConfigurables
|
||||||
|
interface AndroidConfigurables : NonAppleConfigurables
|
||||||
|
|
||||||
|
interface WasmConfigurables : NonAppleConfigurables {
|
||||||
|
val s2wasmFlags get() = targetList("s2wasmFlags")
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed -> in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.konan.target
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.konan.properties.*
|
||||||
|
|
||||||
|
class LinuxConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?)
|
||||||
|
: LinuxConfigurables, KonanPropertiesLoader(target, properties, baseDir)
|
||||||
|
|
||||||
|
class LinuxMIPSConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?)
|
||||||
|
: LinuxMIPSConfigurables, KonanPropertiesLoader(target, properties, baseDir)
|
||||||
|
|
||||||
|
class AndroidConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?)
|
||||||
|
: AndroidConfigurables, KonanPropertiesLoader(target, properties, baseDir)
|
||||||
|
|
||||||
|
class AppleConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?)
|
||||||
|
: AppleConfigurables, KonanPropertiesLoader(target, properties, baseDir)
|
||||||
|
|
||||||
|
class MingwConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?)
|
||||||
|
: MingwConfigurables, KonanPropertiesLoader(target, properties, baseDir)
|
||||||
|
|
||||||
|
class WasmConfigurablesImpl(target: KonanTarget, properties: Properties, baseDir: String?)
|
||||||
|
: WasmConfigurables, KonanPropertiesLoader(target, properties, baseDir)
|
||||||
|
|
||||||
|
|
||||||
|
fun loadConfigurables(target: KonanTarget, properties: Properties, baseDir: String?) = when (target) {
|
||||||
|
KonanTarget.LINUX, KonanTarget.RASPBERRYPI ->
|
||||||
|
LinuxConfigurablesImpl(target, properties, baseDir)
|
||||||
|
KonanTarget.LINUX_MIPS32, KonanTarget.LINUX_MIPSEL32 ->
|
||||||
|
LinuxMIPSConfigurablesImpl(target, properties, baseDir)
|
||||||
|
KonanTarget.MACBOOK, KonanTarget.IPHONE, KonanTarget.IPHONE_SIM ->
|
||||||
|
AppleConfigurablesImpl(target, properties, baseDir)
|
||||||
|
KonanTarget.ANDROID_ARM32, KonanTarget.ANDROID_ARM64 ->
|
||||||
|
AndroidConfigurablesImpl(target, properties, baseDir)
|
||||||
|
KonanTarget.MINGW ->
|
||||||
|
MingwConfigurablesImpl(target, properties, baseDir)
|
||||||
|
KonanTarget.WASM32 ->
|
||||||
|
WasmConfigurablesImpl(target, properties, baseDir)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -16,73 +16,44 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.konan.properties
|
package org.jetbrains.kotlin.konan.properties
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.file.*
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import org.jetbrains.kotlin.konan.target.*
|
import org.jetbrains.kotlin.konan.target.Configurables
|
||||||
import org.jetbrains.kotlin.konan.util.DependencyProcessor
|
import org.jetbrains.kotlin.konan.util.DependencyProcessor
|
||||||
|
|
||||||
class KonanProperties(val target: KonanTarget, val properties: Properties, val baseDir: String? = null) {
|
interface TargetableExternalStorage {
|
||||||
|
fun targetString(key: String): String?
|
||||||
|
fun targetList(key: String): List<String>
|
||||||
|
fun hostString(key: String): String?
|
||||||
|
fun hostList(key: String): List<String>
|
||||||
|
fun hostTargetString(key: String): String?
|
||||||
|
fun hostTargetList(key: String): List<String>
|
||||||
|
fun absolute(value: String?): String
|
||||||
|
fun downloadDependencies()
|
||||||
|
}
|
||||||
|
|
||||||
fun downloadDependencies() {
|
open class KonanPropertiesLoader(override val target: KonanTarget, val properties: Properties, val baseDir: String? = null) : Configurables {
|
||||||
|
val dependencies get() = hostTargetList("dependencies")
|
||||||
|
|
||||||
|
override fun downloadDependencies() {
|
||||||
dependencyProcessor!!.run()
|
dependencyProcessor!!.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun targetString(key: String): String?
|
override fun targetString(key: String): String?
|
||||||
= properties.targetString(key, target)
|
= properties.targetString(key, target)
|
||||||
fun targetList(key: String): List<String>
|
override fun targetList(key: String): List<String>
|
||||||
= properties.targetList(key, target)
|
= properties.targetList(key, target)
|
||||||
fun hostString(key: String): String?
|
override fun hostString(key: String): String?
|
||||||
= properties.hostString(key)
|
= properties.hostString(key)
|
||||||
fun hostList(key: String): List<String>
|
override fun hostList(key: String): List<String>
|
||||||
= properties.hostList(key)
|
= properties.hostList(key)
|
||||||
fun hostTargetString(key: String): String?
|
override fun hostTargetString(key: String): String?
|
||||||
= properties.hostTargetString(key, target)
|
= properties.hostTargetString(key, target)
|
||||||
fun hostTargetList(key: String): List<String>
|
override fun hostTargetList(key: String): List<String>
|
||||||
= properties.hostTargetList(key, target)
|
= properties.hostTargetList(key, target)
|
||||||
|
override fun absolute(value: String?): String =
|
||||||
val llvmHome get() = hostString("llvmHome")
|
|
||||||
|
|
||||||
// TODO: Delegate to a map?
|
|
||||||
val llvmLtoNooptFlags get() = targetList("llvmLtoNooptFlags")
|
|
||||||
val llvmLtoOptFlags get() = targetList("llvmLtoOptFlags")
|
|
||||||
val llvmLtoFlags get() = targetList("llvmLtoFlags")
|
|
||||||
val llvmLtoDynamicFlags get() = targetList("llvmLtoDynamicFlags")
|
|
||||||
val entrySelector get() = targetList("entrySelector")
|
|
||||||
val linkerOptimizationFlags get() = targetList("linkerOptimizationFlags")
|
|
||||||
val linkerKonanFlags get() = targetList("linkerKonanFlags")
|
|
||||||
val linkerNoDebugFlags get() = targetList("linkerNoDebugFlags")
|
|
||||||
val linkerDynamicFlags get() = targetList("linkerDynamicFlags")
|
|
||||||
val llvmDebugOptFlags get() = targetList("llvmDebugOptFlags")
|
|
||||||
val s2wasmFlags get() = targetList("s2wasmFlags")
|
|
||||||
|
|
||||||
val targetSysRoot get() = targetString("targetSysRoot")
|
|
||||||
val libffiDir get() = targetString("libffiDir")
|
|
||||||
val gccToolchain get() = targetString("gccToolchain")
|
|
||||||
val targetArg get() = targetString("quadruple")
|
|
||||||
// Notice: these ones are host-target.
|
|
||||||
val targetToolchain get() = hostTargetString("targetToolchain")
|
|
||||||
val dependencies get() = hostTargetList("dependencies")
|
|
||||||
|
|
||||||
private fun absolute(value: String?): String =
|
|
||||||
dependencyProcessor!!.resolveRelative(value!!).absolutePath
|
dependencyProcessor!!.resolveRelative(value!!).absolutePath
|
||||||
|
private val dependencyProcessor by lazy {
|
||||||
val absoluteTargetSysRoot get() = absolute(targetSysRoot)
|
baseDir?.let { DependencyProcessor(java.io.File(it), this) }
|
||||||
val absoluteTargetToolchain get() = absolute(targetToolchain)
|
}
|
||||||
val absoluteGccToolchain get() = absolute(gccToolchain)
|
|
||||||
val absoluteLlvmHome get() = absolute(llvmHome)
|
|
||||||
val absoluteLibffiDir get() = absolute(libffiDir)
|
|
||||||
|
|
||||||
val mingwWithLlvm: String?
|
|
||||||
get() {
|
|
||||||
if (target != KonanTarget.MINGW) {
|
|
||||||
error("Only mingw target can have '.mingwWithLlvm' property")
|
|
||||||
}
|
|
||||||
// TODO: make it a property in the konan.properties.
|
|
||||||
// Use (equal) llvmHome fow now.
|
|
||||||
return targetString("llvmHome")
|
|
||||||
}
|
|
||||||
|
|
||||||
val osVersionMin: String? get() = targetString("osVersionMin")
|
|
||||||
|
|
||||||
private val dependencyProcessor = baseDir?.let { DependencyProcessor(java.io.File(it), this) }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,303 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.konan.target
|
||||||
|
|
||||||
|
import java.lang.ProcessBuilder
|
||||||
|
import java.lang.ProcessBuilder.Redirect
|
||||||
|
import org.jetbrains.kotlin.konan.exec.Command
|
||||||
|
import org.jetbrains.kotlin.konan.file.*
|
||||||
|
|
||||||
|
typealias BitcodeFile = String
|
||||||
|
typealias ObjectFile = String
|
||||||
|
typealias ExecutableFile = String
|
||||||
|
|
||||||
|
// Use "clang -v -save-temps" to write linkCommand() method
|
||||||
|
// for another implementation of this class.
|
||||||
|
abstract class LinkerFlags(val configurables: Configurables)
|
||||||
|
/* : Configurables by configurables */{
|
||||||
|
|
||||||
|
protected val llvmBin = "${configurables.absoluteLlvmHome}/bin"
|
||||||
|
protected val llvmLib = "${configurables.absoluteLlvmHome}/lib"
|
||||||
|
|
||||||
|
private val libLTODir = when (TargetManager.host) {
|
||||||
|
KonanTarget.MACBOOK, KonanTarget.LINUX -> llvmLib
|
||||||
|
KonanTarget.MINGW -> llvmBin
|
||||||
|
else -> error("Don't know libLTO location for this platform.")
|
||||||
|
}
|
||||||
|
|
||||||
|
val libLTO = "$libLTODir/${System.mapLibraryName("LTO")}"
|
||||||
|
|
||||||
|
val targetLibffi = configurables.libffiDir ?.let { listOf("${configurables.absoluteLibffiDir}/lib/libffi.a") } ?: emptyList()
|
||||||
|
|
||||||
|
open val useCompilerDriverAsLinker: Boolean get() = false // TODO: refactor.
|
||||||
|
|
||||||
|
abstract fun linkCommand(objectFiles: List<ObjectFile>,
|
||||||
|
executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): Command
|
||||||
|
|
||||||
|
open fun linkCommandSuffix(): List<String> = emptyList()
|
||||||
|
|
||||||
|
abstract fun filterStaticLibraries(binaries: List<String>): List<String>
|
||||||
|
|
||||||
|
open fun linkStaticLibraries(binaries: List<String>): List<String> {
|
||||||
|
val libraries = filterStaticLibraries(binaries)
|
||||||
|
// Let's just pass them as absolute paths
|
||||||
|
return libraries
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class AndroidLinker(targetProperties: AndroidConfigurables)
|
||||||
|
: LinkerFlags(targetProperties), AndroidConfigurables by targetProperties {
|
||||||
|
|
||||||
|
private val prefix = "$absoluteTargetToolchain/bin/"
|
||||||
|
private val clang = "$prefix/clang"
|
||||||
|
|
||||||
|
override val useCompilerDriverAsLinker: Boolean get() = true
|
||||||
|
|
||||||
|
override fun filterStaticLibraries(binaries: List<String>)
|
||||||
|
= binaries.filter { it.isUnixStaticLib }
|
||||||
|
|
||||||
|
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): Command {
|
||||||
|
// liblog.so must be linked in, as we use its functionality in runtime.
|
||||||
|
return Command(clang).apply {
|
||||||
|
+ "-o"
|
||||||
|
+ executable
|
||||||
|
+ "-fPIC"
|
||||||
|
+ "-shared"
|
||||||
|
+ "-llog"
|
||||||
|
+ objectFiles
|
||||||
|
if (optimize) + linkerOptimizationFlags
|
||||||
|
if (!debug) + linkerNoDebugFlags
|
||||||
|
if (dynamic) + linkerDynamicFlags
|
||||||
|
+ linkerKonanFlags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class MacOSBasedLinker(targetProperties: AppleConfigurables)
|
||||||
|
: LinkerFlags(targetProperties), AppleConfigurables by targetProperties {
|
||||||
|
|
||||||
|
private val linker = "$absoluteTargetToolchain/usr/bin/ld"
|
||||||
|
internal val dsymutil = "$absoluteLlvmHome/bin/llvm-dsymutil"
|
||||||
|
|
||||||
|
open val osVersionMinFlags: List<String> by lazy {
|
||||||
|
listOf(
|
||||||
|
osVersionMinFlagLd,
|
||||||
|
osVersionMin + ".0")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun filterStaticLibraries(binaries: List<String>)
|
||||||
|
= binaries.filter { it.isUnixStaticLib }
|
||||||
|
|
||||||
|
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): Command {
|
||||||
|
return object : 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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun dsymUtilCommand(executable: ExecutableFile, outputDsymBundle: String) =
|
||||||
|
object : Command(dsymutilCommand(executable, outputDsymBundle)) {
|
||||||
|
override fun runProcess(): Int =
|
||||||
|
executeCommandWithFilter(command)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: consider introducing a better filtering directly in Command.
|
||||||
|
private fun executeCommandWithFilter(command: List<String>): Int {
|
||||||
|
val builder = ProcessBuilder(command)
|
||||||
|
|
||||||
|
// Inherit main process output streams.
|
||||||
|
val isDsymUtil = (command[0] == dsymutil)
|
||||||
|
|
||||||
|
builder.redirectOutput(Redirect.INHERIT)
|
||||||
|
builder.redirectInput(Redirect.INHERIT)
|
||||||
|
if (!isDsymUtil)
|
||||||
|
builder.redirectError(Redirect.INHERIT)
|
||||||
|
|
||||||
|
val process = builder.start()
|
||||||
|
if (isDsymUtil) {
|
||||||
|
/**
|
||||||
|
* llvm-lto has option -alias that lets tool to know which symbol we use instead of _main,
|
||||||
|
* llvm-dsym doesn't have such a option, so we ignore annoying warning manually.
|
||||||
|
*/
|
||||||
|
val errorStream = process.errorStream
|
||||||
|
val outputStream = bufferedReader(errorStream)
|
||||||
|
while (true) {
|
||||||
|
val line = outputStream.readLine() ?: break
|
||||||
|
if (!line.contains("warning: could not find object file symbol for symbol _main"))
|
||||||
|
System.err.println(line)
|
||||||
|
}
|
||||||
|
outputStream.close()
|
||||||
|
}
|
||||||
|
val exitCode = process.waitFor()
|
||||||
|
return exitCode
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun dsymutilCommand(executable: ExecutableFile, outputDsymBundle: String): List<String> =
|
||||||
|
listOf(dsymutil, executable, "-o", outputDsymBundle)
|
||||||
|
|
||||||
|
open fun dsymutilDryRunVerboseCommand(executable: ExecutableFile): List<String> =
|
||||||
|
listOf(dsymutil, "-dump-debug-map" ,executable)
|
||||||
|
}
|
||||||
|
|
||||||
|
open class LinuxBasedLinker(targetProperties: LinuxBasedConfigurables)
|
||||||
|
: LinkerFlags(targetProperties), LinuxBasedConfigurables by targetProperties {
|
||||||
|
|
||||||
|
override val libGcc: String = "$absoluteTargetSysRoot/${super.libGcc}"
|
||||||
|
private val linker = "$absoluteTargetToolchain/bin/ld.gold"
|
||||||
|
private val specificLibs
|
||||||
|
= abiSpecificLibraries.map { "-L${absoluteTargetSysRoot}/$it" }
|
||||||
|
|
||||||
|
override fun filterStaticLibraries(binaries: List<String>)
|
||||||
|
= binaries.filter { it.isUnixStaticLib }
|
||||||
|
|
||||||
|
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): Command {
|
||||||
|
val isMips = (configurables is LinuxMIPSConfigurables)
|
||||||
|
|
||||||
|
// TODO: Can we extract more to the konan.configurables?
|
||||||
|
return 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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class MingwLinker(targetProperties: MingwConfigurables)
|
||||||
|
: LinkerFlags(targetProperties), MingwConfigurables by targetProperties {
|
||||||
|
|
||||||
|
private val linker = "$absoluteTargetToolchain/bin/clang++"
|
||||||
|
|
||||||
|
override val useCompilerDriverAsLinker: Boolean get() = true
|
||||||
|
|
||||||
|
override fun filterStaticLibraries(binaries: List<String>)
|
||||||
|
= binaries.filter { it.isWindowsStaticLib || it.isUnixStaticLib }
|
||||||
|
|
||||||
|
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): Command {
|
||||||
|
return Command(linker).apply {
|
||||||
|
+ listOf("-o", executable)
|
||||||
|
+ objectFiles
|
||||||
|
if (optimize) + linkerOptimizationFlags
|
||||||
|
if (!debug) + linkerNoDebugFlags
|
||||||
|
if (dynamic) + linkerDynamicFlags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun linkCommandSuffix() = linkerKonanFlags
|
||||||
|
}
|
||||||
|
|
||||||
|
open class WasmLinker(targetProperties: WasmConfigurables)
|
||||||
|
: LinkerFlags(targetProperties), WasmConfigurables by targetProperties {
|
||||||
|
|
||||||
|
private val clang = "clang"
|
||||||
|
|
||||||
|
override val useCompilerDriverAsLinker: Boolean get() = false
|
||||||
|
|
||||||
|
override fun filterStaticLibraries(binaries: List<String>)
|
||||||
|
= binaries.filter{it.isJavaScript}
|
||||||
|
|
||||||
|
override fun linkCommand(objectFiles: List<ObjectFile>, executable: ExecutableFile, optimize: Boolean, debug: Boolean, dynamic: Boolean): Command {
|
||||||
|
return object: Command("") {
|
||||||
|
override fun execute() {
|
||||||
|
val src = File(objectFiles.single())
|
||||||
|
val dst = File(executable)
|
||||||
|
src.recursiveCopyTo(dst)
|
||||||
|
javaScriptLink(args, executable)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun javaScriptLink(jsFiles: List<String>, executable: String): String {
|
||||||
|
val linkedJavaScript = File("$executable.js")
|
||||||
|
|
||||||
|
val linkerHeader = "var konan = { libraries: [] };\n"
|
||||||
|
val linkerFooter = """|if (isBrowser()) {
|
||||||
|
| konan.moduleEntry([]);
|
||||||
|
|} else {
|
||||||
|
| konan.moduleEntry(arguments);
|
||||||
|
|}""".trimMargin()
|
||||||
|
|
||||||
|
linkedJavaScript.writeBytes(linkerHeader.toByteArray());
|
||||||
|
|
||||||
|
jsFiles.forEach {
|
||||||
|
linkedJavaScript.appendBytes(File(it).readBytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
linkedJavaScript.appendBytes(linkerFooter.toByteArray());
|
||||||
|
return linkedJavaScript.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun linker(configurables: Configurables): LinkerFlags =
|
||||||
|
when (configurables.target) {
|
||||||
|
KonanTarget.LINUX, KonanTarget.RASPBERRYPI ->
|
||||||
|
LinuxBasedLinker(configurables as LinuxConfigurables)
|
||||||
|
KonanTarget.LINUX_MIPS32, KonanTarget.LINUX_MIPSEL32 ->
|
||||||
|
LinuxBasedLinker(configurables as LinuxMIPSConfigurables)
|
||||||
|
KonanTarget.MACBOOK, KonanTarget.IPHONE, KonanTarget.IPHONE_SIM ->
|
||||||
|
MacOSBasedLinker(configurables as AppleConfigurables)
|
||||||
|
KonanTarget.ANDROID_ARM32, KonanTarget.ANDROID_ARM64 ->
|
||||||
|
AndroidLinker(configurables as AndroidConfigurables)
|
||||||
|
KonanTarget.MINGW ->
|
||||||
|
MingwLinker(configurables as MingwConfigurables)
|
||||||
|
KonanTarget.WASM32 ->
|
||||||
|
WasmLinker(configurables as WasmConfigurables)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.konan.target
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.konan.properties.*
|
||||||
|
|
||||||
|
class Platform(val configurables: Configurables)
|
||||||
|
: Configurables by configurables {
|
||||||
|
|
||||||
|
val clang by lazy {
|
||||||
|
ClangArgs(configurables)
|
||||||
|
}
|
||||||
|
val linker by lazy {
|
||||||
|
linker(configurables)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PlatformManager(properties: Properties, baseDir: String) {
|
||||||
|
private val host = TargetManager.host
|
||||||
|
private val platforms = TargetManager.enabled.map {
|
||||||
|
it to Platform(loadConfigurables(it, properties, baseDir))
|
||||||
|
}.toMap()
|
||||||
|
|
||||||
|
fun platform(target: KonanTarget) = platforms[target]!!
|
||||||
|
val hostPlatform = platforms[host]!!
|
||||||
|
}
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.konan.util
|
package org.jetbrains.kotlin.konan.util
|
||||||
|
|
||||||
import org.jetbrains.kotlin.konan.file.use
|
import org.jetbrains.kotlin.konan.file.use
|
||||||
import org.jetbrains.kotlin.konan.properties.KonanProperties
|
import org.jetbrains.kotlin.konan.properties.KonanPropertiesLoader
|
||||||
import org.jetbrains.kotlin.konan.properties.Properties
|
import org.jetbrains.kotlin.konan.properties.Properties
|
||||||
import org.jetbrains.kotlin.konan.properties.propertyList
|
import org.jetbrains.kotlin.konan.properties.propertyList
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -69,11 +69,11 @@ private fun Properties.findCandidates(dependencies: List<String>): Map<String, L
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private val KonanProperties.dependenciesUrl : String get() = properties.dependenciesUrl
|
private val KonanPropertiesLoader.dependenciesUrl : String get() = properties.dependenciesUrl
|
||||||
private val KonanProperties.airplaneMode : Boolean get() = properties.airplaneMode
|
private val KonanPropertiesLoader.airplaneMode : Boolean get() = properties.airplaneMode
|
||||||
private val KonanProperties.downloadingAttempts : Int get() = properties.downloadingAttempts
|
private val KonanPropertiesLoader.downloadingAttempts : Int get() = properties.downloadingAttempts
|
||||||
private val KonanProperties.downloadingAttemptIntervalMs : Long get() = properties.downloadingAttemptIntervalMs
|
private val KonanPropertiesLoader.downloadingAttemptIntervalMs : Long get() = properties.downloadingAttemptIntervalMs
|
||||||
private val KonanProperties.homeDependencyCache : String get() = properties.homeDependencyCache
|
private val KonanPropertiesLoader.homeDependencyCache : String get() = properties.homeDependencyCache
|
||||||
|
|
||||||
sealed class DependencySource {
|
sealed class DependencySource {
|
||||||
data class Local(val path: File) : DependencySource()
|
data class Local(val path: File) : DependencySource()
|
||||||
@@ -114,7 +114,7 @@ class DependencyProcessor(dependenciesRoot: File,
|
|||||||
private val archiveExtension get() = extractor.archiveExtension
|
private val archiveExtension get() = extractor.archiveExtension
|
||||||
|
|
||||||
constructor(dependenciesRoot: File,
|
constructor(dependenciesRoot: File,
|
||||||
properties: KonanProperties,
|
properties: KonanPropertiesLoader,
|
||||||
dependenciesUrl: String = properties.dependenciesUrl,
|
dependenciesUrl: String = properties.dependenciesUrl,
|
||||||
keepUnstable:Boolean = true) : this(
|
keepUnstable:Boolean = true) : this(
|
||||||
dependenciesRoot,
|
dependenciesRoot,
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ fun invokeInterop(flavor: String, args: Array<String>): Array<String> {
|
|||||||
val manifest = File(buildDir, "manifest.properties")
|
val manifest = File(buildDir, "manifest.properties")
|
||||||
|
|
||||||
val targetManager = TargetManager(target)
|
val targetManager = TargetManager(target)
|
||||||
val resolver = defaultResolver(repos, targetManager)
|
val resolver = defaultResolver(repos, targetManager.target)
|
||||||
val allLibraries = resolver.resolveLibrariesRecursive(
|
val allLibraries = resolver.resolveLibrariesRecursive(
|
||||||
libraries, targetManager.target, noStdLib = true, noDefaultLibs = noDefaultLibs
|
libraries, targetManager.target, noStdLib = true, noDefaultLibs = noDefaultLibs
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user