[watchOS] Add support of watch_arm64 target. (#3404)
* [watchOS] Add support of watch_arm64 target. Since there is no support of `arm64_32` in LLVM 8 we compile bitcode that was generated for `watchos_arm32` to `arm64_32-apple-watchos`.
This commit is contained in:
+9
-1
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.native.interop.gen.wasm.processIdlLib
|
|||||||
import org.jetbrains.kotlin.native.interop.indexer.*
|
import org.jetbrains.kotlin.native.interop.indexer.*
|
||||||
import org.jetbrains.kotlin.native.interop.tool.*
|
import org.jetbrains.kotlin.native.interop.tool.*
|
||||||
import kotlinx.cli.ArgParser
|
import kotlinx.cli.ArgParser
|
||||||
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.IllegalArgumentException
|
import java.lang.IllegalArgumentException
|
||||||
import java.nio.file.*
|
import java.nio.file.*
|
||||||
@@ -219,6 +220,13 @@ private fun processCLib(args: Array<String>, additionalArgs: Map<String, Any> =
|
|||||||
|
|
||||||
val (nativeIndex, compilation) = buildNativeIndex(library, verbose)
|
val (nativeIndex, compilation) = buildNativeIndex(library, verbose)
|
||||||
|
|
||||||
|
// Our current approach to arm64_32 support is to compile armv7k version of bitcode
|
||||||
|
// for arm64_32. That's the reason for this substitution.
|
||||||
|
// TODO: Add proper support with the next LLVM update.
|
||||||
|
val target = when (tool.target) {
|
||||||
|
KonanTarget.WATCHOS_ARM64 -> KonanTarget.WATCHOS_ARM32
|
||||||
|
else -> tool.target
|
||||||
|
}
|
||||||
val configuration = InteropConfiguration(
|
val configuration = InteropConfiguration(
|
||||||
library = compilation,
|
library = compilation,
|
||||||
pkgName = outKtPkg,
|
pkgName = outKtPkg,
|
||||||
@@ -229,7 +237,7 @@ private fun processCLib(args: Array<String>, additionalArgs: Map<String, Any> =
|
|||||||
noStringConversion = def.config.noStringConversion.toSet(),
|
noStringConversion = def.config.noStringConversion.toSet(),
|
||||||
exportForwardDeclarations = def.config.exportForwardDeclarations,
|
exportForwardDeclarations = def.config.exportForwardDeclarations,
|
||||||
disableDesignatedInitializerChecks = def.config.disableDesignatedInitializerChecks,
|
disableDesignatedInitializerChecks = def.config.disableDesignatedInitializerChecks,
|
||||||
target = tool.target
|
target = target
|
||||||
)
|
)
|
||||||
|
|
||||||
outKtFile.parentFile.mkdirs()
|
outKtFile.parentFile.mkdirs()
|
||||||
|
|||||||
+10
-1
@@ -103,9 +103,18 @@ internal class BitcodeCompiler(val context: Context) {
|
|||||||
|
|
||||||
val profilingFlags = llvmProfilingFlags().map { listOf("-mllvm", it) }.flatten()
|
val profilingFlags = llvmProfilingFlags().map { listOf("-mllvm", it) }.flatten()
|
||||||
|
|
||||||
|
// LLVM we use does not have support for arm64_32.
|
||||||
|
// TODO: fix with LLVM update.
|
||||||
|
val targetTriple = when (context.config.target) {
|
||||||
|
KonanTarget.WATCHOS_ARM64 -> {
|
||||||
|
require(configurables is AppleConfigurables)
|
||||||
|
"arm64_32-apple-watchos${configurables.osVersionMin}"
|
||||||
|
}
|
||||||
|
else -> context.llvm.targetTriple
|
||||||
|
}
|
||||||
val flags = mutableListOf<String>().apply {
|
val flags = mutableListOf<String>().apply {
|
||||||
addNonEmpty(configurables.clangFlags)
|
addNonEmpty(configurables.clangFlags)
|
||||||
addNonEmpty(listOf("-triple", context.llvm.targetTriple))
|
addNonEmpty(listOf("-triple", targetTriple))
|
||||||
addNonEmpty(when {
|
addNonEmpty(when {
|
||||||
optimize -> configurables.clangOptFlags
|
optimize -> configurables.clangOptFlags
|
||||||
debug -> configurables.clangDebugFlags
|
debug -> configurables.clangDebugFlags
|
||||||
|
|||||||
+3
-3
@@ -41,8 +41,8 @@ private class LlvmPipelineConfiguration(context: Context) {
|
|||||||
|
|
||||||
val targetTriple: String = context.llvm.targetTriple
|
val targetTriple: String = context.llvm.targetTriple
|
||||||
|
|
||||||
// Most of these values are copied from corresponding runtime.bc
|
// Some of these values are copied from corresponding runtime.bc
|
||||||
// Which is using "generic" target CPU for many case.
|
// which is using "generic" target CPU for many case.
|
||||||
// This approach is suboptimal because target-cpu="generic" limits
|
// This approach is suboptimal because target-cpu="generic" limits
|
||||||
// the set of used cpu features.
|
// the set of used cpu features.
|
||||||
// TODO: refactor KonanTarget so that we can explicitly specify
|
// TODO: refactor KonanTarget so that we can explicitly specify
|
||||||
@@ -55,6 +55,7 @@ private class LlvmPipelineConfiguration(context: Context) {
|
|||||||
KonanTarget.TVOS_X64 -> "core2"
|
KonanTarget.TVOS_X64 -> "core2"
|
||||||
KonanTarget.WATCHOS_X86 -> "i386"
|
KonanTarget.WATCHOS_X86 -> "i386"
|
||||||
KonanTarget.WATCHOS_X64 -> "core2"
|
KonanTarget.WATCHOS_X64 -> "core2"
|
||||||
|
KonanTarget.WATCHOS_ARM64,
|
||||||
KonanTarget.WATCHOS_ARM32 -> "cortex-a7"
|
KonanTarget.WATCHOS_ARM32 -> "cortex-a7"
|
||||||
KonanTarget.LINUX_X64 -> "x86-64"
|
KonanTarget.LINUX_X64 -> "x86-64"
|
||||||
KonanTarget.MINGW_X86 -> "pentium4"
|
KonanTarget.MINGW_X86 -> "pentium4"
|
||||||
@@ -68,7 +69,6 @@ private class LlvmPipelineConfiguration(context: Context) {
|
|||||||
KonanTarget.ANDROID_X86 -> "i686"
|
KonanTarget.ANDROID_X86 -> "i686"
|
||||||
KonanTarget.LINUX_MIPS32 -> "mips32r2"
|
KonanTarget.LINUX_MIPS32 -> "mips32r2"
|
||||||
KonanTarget.LINUX_MIPSEL32 -> "mips32r2"
|
KonanTarget.LINUX_MIPSEL32 -> "mips32r2"
|
||||||
KonanTarget.WATCHOS_ARM64,
|
|
||||||
KonanTarget.WASM32,
|
KonanTarget.WASM32,
|
||||||
is KonanTarget.ZEPHYR -> error("There is no support for ${target.name} target yet.")
|
is KonanTarget.ZEPHYR -> error("There is no support for ${target.name} target yet.")
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -188,7 +188,7 @@ internal class BlockAdapterToFunctionGenerator(val objCExportCodeGenerator: ObjC
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun org.jetbrains.kotlin.backend.konan.Context.LongInt(value: Long) =
|
fun org.jetbrains.kotlin.backend.konan.Context.LongInt(value: Long) =
|
||||||
if (is64Bit()) Int64(value) else Int32(value.toInt())
|
if (is64BitNSInteger()) Int64(value) else Int32(value.toInt())
|
||||||
|
|
||||||
private fun generateDescriptorForBlockAdapterToFunction(bridge: BlockPointerBridge): ConstValue {
|
private fun generateDescriptorForBlockAdapterToFunction(bridge: BlockPointerBridge): ConstValue {
|
||||||
val numberOfParameters = bridge.numberOfParameters
|
val numberOfParameters = bridge.numberOfParameters
|
||||||
|
|||||||
+8
-4
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.ir.util.isInterface
|
|||||||
import org.jetbrains.kotlin.ir.util.isReal
|
import org.jetbrains.kotlin.ir.util.isReal
|
||||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||||
import org.jetbrains.kotlin.konan.target.Family
|
import org.jetbrains.kotlin.konan.target.Family
|
||||||
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
internal fun TypeBridge.makeNothing() = when (this) {
|
internal fun TypeBridge.makeNothing() = when (this) {
|
||||||
@@ -679,7 +680,7 @@ private fun ObjCExportCodeGenerator.generateObjCImp(
|
|||||||
MethodBridge.ReturnValue.Void -> null
|
MethodBridge.ReturnValue.Void -> null
|
||||||
MethodBridge.ReturnValue.HashCode -> {
|
MethodBridge.ReturnValue.HashCode -> {
|
||||||
val kotlinHashCode = targetResult!!
|
val kotlinHashCode = targetResult!!
|
||||||
if (codegen.context.is64Bit()) zext(kotlinHashCode, int64Type) else kotlinHashCode
|
if (codegen.context.is64BitNSInteger()) zext(kotlinHashCode, int64Type) else kotlinHashCode
|
||||||
}
|
}
|
||||||
is MethodBridge.ReturnValue.Mapped -> kotlinToObjC(targetResult!!, returnBridge.bridge)
|
is MethodBridge.ReturnValue.Mapped -> kotlinToObjC(targetResult!!, returnBridge.bridge)
|
||||||
MethodBridge.ReturnValue.WithError.Success -> Int8(1).llvm // true
|
MethodBridge.ReturnValue.WithError.Success -> Int8(1).llvm // true
|
||||||
@@ -781,7 +782,7 @@ private fun ObjCExportCodeGenerator.generateKotlinToObjCBridge(
|
|||||||
MethodBridge.ReturnValue.Void -> null
|
MethodBridge.ReturnValue.Void -> null
|
||||||
|
|
||||||
MethodBridge.ReturnValue.HashCode -> {
|
MethodBridge.ReturnValue.HashCode -> {
|
||||||
if (codegen.context.is64Bit()) {
|
if (codegen.context.is64BitNSInteger()) {
|
||||||
val low = trunc(targetResult, int32Type)
|
val low = trunc(targetResult, int32Type)
|
||||||
val high = trunc(shr(targetResult, 32, signed = false), int32Type)
|
val high = trunc(shr(targetResult, 32, signed = false), int32Type)
|
||||||
xor(low, high)
|
xor(low, high)
|
||||||
@@ -1256,7 +1257,7 @@ private val MethodBridgeParameter.objCType: LLVMTypeRef get() = when (this) {
|
|||||||
private fun MethodBridge.ReturnValue.objCType(context: Context): LLVMTypeRef {
|
private fun MethodBridge.ReturnValue.objCType(context: Context): LLVMTypeRef {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
MethodBridge.ReturnValue.Void -> voidType
|
MethodBridge.ReturnValue.Void -> voidType
|
||||||
MethodBridge.ReturnValue.HashCode -> if (context.is64Bit()) int64Type else int32Type
|
MethodBridge.ReturnValue.HashCode -> if (context.is64BitNSInteger()) int64Type else int32Type
|
||||||
is MethodBridge.ReturnValue.Mapped -> this.bridge.objCType
|
is MethodBridge.ReturnValue.Mapped -> this.bridge.objCType
|
||||||
MethodBridge.ReturnValue.WithError.Success -> ObjCValueType.BOOL.llvmType
|
MethodBridge.ReturnValue.WithError.Success -> ObjCValueType.BOOL.llvmType
|
||||||
|
|
||||||
@@ -1324,4 +1325,7 @@ private val TypeBridge.objCEncoding: String get() = when (this) {
|
|||||||
is ValueTypeBridge -> this.objCValueType.encoding
|
is ValueTypeBridge -> this.objCValueType.encoding
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Context.is64Bit(): Boolean = this.config.target.architecture.bitness == 64
|
internal fun Context.is64BitNSInteger(): Boolean = this.config.target.let {
|
||||||
|
// We work with watchos_arm64 the same as we work with watchos_arm32.
|
||||||
|
it.architecture.bitness == 64 && it != KonanTarget.WATCHOS_ARM64
|
||||||
|
}
|
||||||
|
|||||||
@@ -235,6 +235,33 @@ osVersionMinFlagLd.watchos_arm32 = -watchos_version_min
|
|||||||
osVersionMinFlagClang.watchos_arm32 = -mwatchos-version-min
|
osVersionMinFlagClang.watchos_arm32 = -mwatchos-version-min
|
||||||
osVersionMin.watchos_arm32 = 5.0
|
osVersionMin.watchos_arm32 = 5.0
|
||||||
|
|
||||||
|
# watchOS arm64_32
|
||||||
|
targetToolchain.macos_x64-watchos_arm64 = target-toolchain-10-macos_x64
|
||||||
|
dependencies.macos_x64-watchos_arm64 = \
|
||||||
|
libffi-3.2.1-3-darwin-macos \
|
||||||
|
clang-llvm-apple-8.0.0-darwin-macos
|
||||||
|
|
||||||
|
target-sysroot-10-watchos_arm64.default = \
|
||||||
|
remote:internal
|
||||||
|
|
||||||
|
arch.watchos_arm64 = arm64_32
|
||||||
|
targetSysRoot.watchos_arm64 = target-sysroot-10-watchos_arm32
|
||||||
|
|
||||||
|
clangFlags.watchos_arm64 = -cc1 -emit-obj -disable-llvm-passes -x ir -mllvm -aarch64-watch-bitcode-compatibility \
|
||||||
|
-mllvm -arm-bitcode-compatibility -mllvm -fast-isel=false -mllvm -global-isel=false
|
||||||
|
clangNooptFlags.watchos_arm64 = -O1
|
||||||
|
clangOptFlags.watchos_arm64 = -O3
|
||||||
|
clangDebugFlags.watchos_arm64 = -O0
|
||||||
|
clangDynamicFlags.watchos_arm64 =
|
||||||
|
|
||||||
|
linkerKonanFlags.watchos_arm64 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 6.0
|
||||||
|
linkerOptimizationFlags.watchos_arm64 = -dead_strip
|
||||||
|
linkerNoDebugFlags.watchos_arm64 = -S
|
||||||
|
linkerDynamicFlags.watchos_arm64 = -dylib
|
||||||
|
osVersionMinFlagLd.watchos_arm64 = -watchos_version_min
|
||||||
|
osVersionMinFlagClang.watchos_arm64 = -mwatchos-version-min
|
||||||
|
osVersionMin.watchos_arm64 = 5.0
|
||||||
|
|
||||||
# Apple's watchOS i386 simulator.
|
# Apple's watchOS i386 simulator.
|
||||||
targetToolchain.macos_x64-watchos_x86 = target-toolchain-10-macos_x64
|
targetToolchain.macos_x64-watchos_x86 = target-toolchain-10-macos_x64
|
||||||
dependencies.macos_x64-watchos_x86 = \
|
dependencies.macos_x64-watchos_x86 = \
|
||||||
|
|||||||
@@ -97,13 +97,13 @@ class ClangArgs(private val configurables: Configurables) : Configurables by con
|
|||||||
KonanTarget.TVOS_X64 ->
|
KonanTarget.TVOS_X64 ->
|
||||||
listOf("-stdlib=libc++", "-isysroot", absoluteTargetSysRoot, "-mtvos-simulator-version-min=$osVersionMin")
|
listOf("-stdlib=libc++", "-isysroot", absoluteTargetSysRoot, "-mtvos-simulator-version-min=$osVersionMin")
|
||||||
|
|
||||||
|
KonanTarget.WATCHOS_ARM64,
|
||||||
KonanTarget.WATCHOS_ARM32 ->
|
KonanTarget.WATCHOS_ARM32 ->
|
||||||
listOf("-stdlib=libc++", "-arch", "armv7k", "-isysroot", absoluteTargetSysRoot, "-mwatchos-version-min=$osVersionMin")
|
listOf("-stdlib=libc++", "-arch", "armv7k", "-isysroot", absoluteTargetSysRoot, "-mwatchos-version-min=$osVersionMin")
|
||||||
|
|
||||||
KonanTarget.WATCHOS_X86 ->
|
KonanTarget.WATCHOS_X86 ->
|
||||||
listOf("-stdlib=libc++", "-arch", "i386", "-isysroot", absoluteTargetSysRoot, "-mwatchos-simulator-version-min=$osVersionMin")
|
listOf("-stdlib=libc++", "-arch", "i386", "-isysroot", absoluteTargetSysRoot, "-mwatchos-simulator-version-min=$osVersionMin")
|
||||||
|
|
||||||
KonanTarget.WATCHOS_ARM64 -> TODO("implement me")
|
|
||||||
KonanTarget.WATCHOS_X64 -> TODO("implement me")
|
KonanTarget.WATCHOS_X64 -> TODO("implement me")
|
||||||
|
|
||||||
KonanTarget.ANDROID_ARM32, KonanTarget.ANDROID_ARM64,
|
KonanTarget.ANDROID_ARM32, KonanTarget.ANDROID_ARM64,
|
||||||
@@ -261,6 +261,7 @@ class ClangArgs(private val configurables: Configurables) : Configurables by con
|
|||||||
"-DKONAN_CORE_SYMBOLICATION=1",
|
"-DKONAN_CORE_SYMBOLICATION=1",
|
||||||
"-DKONAN_HAS_CXX11_EXCEPTION_FUNCTIONS=1")
|
"-DKONAN_HAS_CXX11_EXCEPTION_FUNCTIONS=1")
|
||||||
|
|
||||||
|
KonanTarget.WATCHOS_ARM64,
|
||||||
KonanTarget.WATCHOS_ARM32 ->
|
KonanTarget.WATCHOS_ARM32 ->
|
||||||
listOf("-DKONAN_OBJC_INTEROP=1",
|
listOf("-DKONAN_OBJC_INTEROP=1",
|
||||||
"-DKONAN_WATCHOS",
|
"-DKONAN_WATCHOS",
|
||||||
@@ -280,7 +281,6 @@ class ClangArgs(private val configurables: Configurables) : Configurables by con
|
|||||||
"-DKONAN_CORE_SYMBOLICATION=1",
|
"-DKONAN_CORE_SYMBOLICATION=1",
|
||||||
"-DKONAN_HAS_CXX11_EXCEPTION_FUNCTIONS=1")
|
"-DKONAN_HAS_CXX11_EXCEPTION_FUNCTIONS=1")
|
||||||
|
|
||||||
KonanTarget.WATCHOS_ARM64 -> TODO("implement me")
|
|
||||||
KonanTarget.WATCHOS_X64 -> TODO("implement me")
|
KonanTarget.WATCHOS_X64 -> TODO("implement me")
|
||||||
|
|
||||||
KonanTarget.ANDROID_ARM32 ->
|
KonanTarget.ANDROID_ARM32 ->
|
||||||
|
|||||||
@@ -49,6 +49,6 @@ class PlatformManager(distribution: Distribution = Distribution(), experimental:
|
|||||||
* TODO: Don't forget to delete this field and replace all its usages to `enabled`.
|
* TODO: Don't forget to delete this field and replace all its usages to `enabled`.
|
||||||
*/
|
*/
|
||||||
val filteredOutEnabledButNotSupported
|
val filteredOutEnabledButNotSupported
|
||||||
get() = enabled.filterNot { it == KonanTarget.WATCHOS_X64 || it == KonanTarget.WATCHOS_ARM64 }
|
get() = enabled.filterNot { it == KonanTarget.WATCHOS_X64 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user