Add basic support for Windows with mingw-w64

This commit is contained in:
Svyatoslav Scherbina
2017-05-27 10:37:50 +03:00
committed by SvyatoslavScherbina
parent ed60732058
commit d6b8b4fb0f
17 changed files with 224 additions and 55 deletions
@@ -62,9 +62,11 @@ class Distribution(val config: CompilerConfiguration) {
val llvmLib = "$llvmHome/lib"
val llvmLto = "$llvmBin/llvm-lto"
val libLTO = when (TargetManager.host) {
KonanTarget.MACBOOK -> "$llvmLib/libLTO.dylib"
KonanTarget.LINUX -> "$llvmLib/libLTO.so"
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")}"
}
@@ -23,6 +23,7 @@ enum class KonanTarget(val suffix: String, var enabled: Boolean = false) {
IPHONE("ios"),
IPHONE_SIM("ios_sim"),
LINUX("linux"),
MINGW("mingw"),
MACBOOK("osx"),
RASPBERRYPI("raspberrypi")
}
@@ -40,6 +41,9 @@ class TargetManager(val config: CompilerConfiguration) {
KonanTarget.RASPBERRYPI.enabled = true
KonanTarget.ANDROID_ARM32.enabled = true
}
KonanTarget.MINGW -> {
KonanTarget.MINGW.enabled = true
}
KonanTarget.MACBOOK -> {
KonanTarget.MACBOOK.enabled = true
KonanTarget.IPHONE.enabled = true
@@ -88,10 +92,11 @@ class TargetManager(val config: CompilerConfiguration) {
companion object {
fun host_os(): String {
val javaOsName = System.getProperty("os.name")
return when (javaOsName) {
"Mac OS X" -> "osx"
"Linux" -> "linux"
else -> error("Unknown operating system: ${javaOsName}")
return when {
javaOsName == "Mac OS X" -> "osx"
javaOsName == "Linux" -> "linux"
javaOsName.startsWith("Windows") -> "windows"
else -> error("Unknown operating system: ${javaOsName}")
}
}
@@ -108,6 +113,7 @@ class TargetManager(val config: CompilerConfiguration) {
val host: KonanTarget = when (host_os()) {
"osx" -> KonanTarget.MACBOOK
"linux" -> KonanTarget.LINUX
"windows" -> KonanTarget.MINGW
else -> error("Unknown host target: ${host_os()} ${host_arch()}")
}
}
@@ -45,6 +45,8 @@ internal abstract class PlatformFlags(val distribution: Distribution) {
open val linkerKonanFlags
= propertyTargetList("linkerKonanFlags")
open val useCompilerDriverAsLinker: Boolean get() = false // TODO: refactor.
abstract fun linkCommand(objectFiles: List<ObjectFile>,
executable: ExecutableFile, optimize: Boolean): List<String>
@@ -65,6 +67,8 @@ internal open class AndroidPlatform(distribution: Distribution)
private val prefix = "${distribution.targetToolchain}/bin/"
private val clang = "$prefix/clang"
override val useCompilerDriverAsLinker: Boolean get() = true
override fun linkCommand(objectFiles: List<String>, executable: String, optimize: Boolean): List<String> {
return mutableListOf<String>(clang, "-o", executable, "-fPIC", "-shared") +
objectFiles +
@@ -140,6 +144,21 @@ internal open class LinuxBasedPlatform(distribution: Distribution)
}
}
internal open class MingwPlatform(distribution: Distribution)
: PlatformFlags(distribution) {
val linker = "${distribution.targetToolchain}/bin/clang++"
override val useCompilerDriverAsLinker: Boolean get() = true
override fun linkCommand(objectFiles: List<String>, executable: String, optimize: Boolean): List<String> {
return listOf(linker, "-o", executable) +
objectFiles +
(if (optimize) linkerOptimizationFlags else {listOf<String>()}) +
linkerKonanFlags
}
}
internal class LinkStage(val context: Context) {
val config = context.config.configuration
@@ -153,6 +172,8 @@ internal class LinkStage(val context: Context) {
MacOSBasedPlatform(distribution)
KonanTarget.ANDROID_ARM32 ->
AndroidPlatform(distribution)
KonanTarget.MINGW ->
MingwPlatform(distribution)
else ->
error("Unexpected target platform: ${context.config.targetManager.current}")
}
@@ -182,6 +203,10 @@ internal class LinkStage(val context: Context) {
}
fun asLinkerArgs(args: List<String>): List<String> {
if (platform.useCompilerDriverAsLinker) {
return args
}
val result = mutableListOf<String>()
for (arg in args) {
// If user passes compiler arguments to us - transform them to linker ones.
@@ -20,6 +20,7 @@ package org.jetbrains.kotlin.backend.konan.llvm
import kotlinx.cinterop.*
import llvm.*
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.KonanTarget
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -151,7 +152,9 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
private val needSlots: Boolean
get() {
return slotCount > 1 || localAllocs > 0
return slotCount > 1 || localAllocs > 0 ||
// Prevent empty cleanup on mingw to workaround LLVM bug:
context.config.targetManager.current == KonanTarget.MINGW
}
private fun releaseVars() {
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.backend.konan.llvm
import kotlinx.cinterop.*
import llvm.*
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.KonanTarget
import org.jetbrains.kotlin.backend.konan.hash.GlobalHash
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
@@ -258,7 +259,12 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
val throwExceptionFunction = importRtFunction("ThrowException")
val appendToInitalizersTail = importRtFunction("AppendToInitializersTail")
val gxxPersonalityFunction = externalNounwindFunction("__gxx_personality_v0", functionType(int32Type, true))
private val personalityFunctionName = when (context.config.targetManager.current) {
KonanTarget.MINGW -> "__gxx_personality_seh0"
else -> "__gxx_personality_v0"
}
val gxxPersonalityFunction = externalNounwindFunction(personalityFunctionName, functionType(int32Type, true))
val cxaBeginCatchFunction = externalNounwindFunction("__cxa_begin_catch", functionType(int8TypePtr, false, int8TypePtr))
val cxaEndCatchFunction = externalNounwindFunction("__cxa_end_catch", functionType(voidType, false))
+22 -2
View File
@@ -15,10 +15,10 @@
#
# TODO: Do we need a $variable substitution mechanism here?
llvmVersion = 3.9.0
dependenciesUrl = http://download.jetbrains.com/kotlin/native
# Mac OS X.
llvmVersion.osx = 3.9.0
llvmHome.osx = clang-llvm-3.9.0-darwin-macos
targetToolchain.osx = clang-llvm-3.9.0-darwin-macos
@@ -79,6 +79,7 @@ osVersionMinFlagClang.ios_sim = -mios-simulator-version-min
osVersionMin.ios_sim = 8.0
# Linux x86-64.
llvmVersion.linux = 3.9.0
llvmHome.linux = clang-llvm-3.9.0-linux-x86-64
targetToolchain.linux = target-gcc-toolchain-3-linux-x86-64/x86_64-unknown-linux-gnu
@@ -150,4 +151,23 @@ entrySelector.android_arm32 = -Wl,--defsym -Wl,main=Konan_main
llvmLtoFlags.android_arm32 = -exported-symbol=Konan_main -emulated-tls
targetSysRoot.android_arm32 = target-sysroot-21-android_arm32
libffiDir.android_arm32 = libffi-3.2.1-2-android_arm32
linkerKonanFlags.android_arm32 = -lm -latomic -lstdc++
linkerKonanFlags.android_arm32 = -lm -latomic -lstdc++
# Windows x86-64, based on mingw-w64.
llvmVersion.mingw = 3.9.1
llvmHome.mingw = msys2-mingw-w64-x86_64-gcc-6.3.0-clang-llvm-3.9.1-windows-x86-64
targetToolchain.mingw = msys2-mingw-w64-x86_64-gcc-6.3.0-clang-llvm-3.9.1-windows-x86-64
quadruple.mingw = x86_64-w64-mingw32
targetSysRoot.mingw = msys2-mingw-w64-x86_64-gcc-6.3.0-clang-llvm-3.9.1-windows-x86-64
libffiDir.mingw = libffi-3.2.1-mingw-w64-x86-64
llvmLtoFlags.mingw = -exported-symbol=Konan_main
llvmLtoOptFlags.mingw = -O3 -function-sections
llvmLtoNooptFlags.mingw = -O1
linkerKonanFlags.mingw = -static-libgcc -static-libstdc++ \
-Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive,-Bdynamic
linkerOptimizationFlags.mingw = -Wl,--gc-sections
entrySelector.mingw = -Wl,--defsym,main=Konan_main
dependencies.mingw = \
msys2-mingw-w64-x86_64-gcc-6.3.0-clang-llvm-3.9.1-windows-x86-64 \
libffi-3.2.1-mingw-w64-x86-64
+3
View File
@@ -30,6 +30,9 @@ linkerOpts.linux=\
-Wl,-z,noexecstack \
-lrt -ldl -lpthread -lz -lm
linkerOpts.mingw = -lole32 -luuid -static-libgcc -static-libstdc++ \
-Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive,-Bdynamic
excludedFunctions = LLVMInitializeAllAsmParsers LLVMInitializeAllAsmPrinters LLVMInitializeAllDisassemblers \
LLVMInitializeAllTargetInfos LLVMInitializeAllTargetMCs LLVMInitializeAllTargets LLVMInitializeNativeTarget \
LLVMInitializeNativeAsmParser LLVMInitializeNativeAsmPrinter LLVMInitializeNativeDisassembler
+22 -1
View File
@@ -367,11 +367,19 @@ task hello3(type: RunKonanTest) {
}
task hello4(type: RunKonanTest) {
if (isWindows()) {
// To be investigated.
disabled = true
}
goldValue = "Hello\nПока\n"
source = "runtime/basic/hello4.kt"
}
task tostring0(type: RunKonanTest) {
if (isWindows()) {
// To be investigated.
disabled = true
}
goldValue = "127\n-1\n239\nA\nЁ\nト\n1122334455\n112233445566778899\n3.14159\n1E+27\n1E-300\ntrue\nfalse\n"
source = "runtime/basic/tostring0.kt"
}
@@ -387,6 +395,10 @@ task tostring2(type: RunKonanTest) {
}
task tostring3(type: RunKonanTest) {
if (isWindows()) {
// Double.toString()
disabled = true
}
goldValue = "-128\n127\n-32768\n32767\n" +
"-2147483648\n2147483647\n-9223372036854775808\n9223372036854775807\n" +
"1.4013E-45\n3.40282E+38\n-INF\nINF\n" +
@@ -1212,11 +1224,19 @@ task moderately_large_array1(type: RunKonanTest) {
}
task string_builder0(type: RunKonanTest) {
if (isWindows()) {
// To be investigated.
disabled = true
}
goldValue = "OK\n"
source = "runtime/text/string_builder0.kt"
}
task string0(type: RunKonanTest) {
if (isWindows()) {
// To be investigated.
disabled = true
}
goldValue = "true\ntrue\nПРИВЕТ\nпривет\nПока\ntrue\n"
source = "runtime/text/string0.kt"
}
@@ -1860,7 +1880,8 @@ task interop4(type: RunInteropKonanTest) {
}
task interop_echo_server(type: RunInteropKonanTest) {
if (isLinux()) {
if (!isMac()) {
// Not supported or not tested.
disabled = true
}
run = false