From 7a19558d541b70e0634ea87da72b9ed7b39b8061 Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Thu, 26 Mar 2020 15:23:03 +0700 Subject: [PATCH] Refactoring: Put KonanTarget & related classes into separate .kt files --- .../kotlin/konan/target/Architecture.kt | 16 + .../kotlin/konan/target/CompilerOutputKind.kt | 41 ++ .../jetbrains/kotlin/konan/target/Family.kt | 27 ++ .../kotlin/konan/target/HostManager.kt | 214 ++++++++++ .../kotlin/konan/target/KonanTarget.kt | 383 ++---------------- .../kotlin/konan/target/TargetManager.kt | 43 ++ .../jetbrains/kotlin/konan/target/utils.kt | 23 ++ 7 files changed, 389 insertions(+), 358 deletions(-) create mode 100644 native/utils/src/org/jetbrains/kotlin/konan/target/Architecture.kt create mode 100644 native/utils/src/org/jetbrains/kotlin/konan/target/CompilerOutputKind.kt create mode 100644 native/utils/src/org/jetbrains/kotlin/konan/target/Family.kt create mode 100644 native/utils/src/org/jetbrains/kotlin/konan/target/HostManager.kt create mode 100644 native/utils/src/org/jetbrains/kotlin/konan/target/TargetManager.kt create mode 100644 native/utils/src/org/jetbrains/kotlin/konan/target/utils.kt diff --git a/native/utils/src/org/jetbrains/kotlin/konan/target/Architecture.kt b/native/utils/src/org/jetbrains/kotlin/konan/target/Architecture.kt new file mode 100644 index 00000000000..ac80ee8c6dc --- /dev/null +++ b/native/utils/src/org/jetbrains/kotlin/konan/target/Architecture.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.konan.target + +enum class Architecture(val bitness: Int) { + X64(64), + X86(32), + ARM64(64), + ARM32(32), + MIPS32(32), + MIPSEL32(32), + WASM32(32); +} diff --git a/native/utils/src/org/jetbrains/kotlin/konan/target/CompilerOutputKind.kt b/native/utils/src/org/jetbrains/kotlin/konan/target/CompilerOutputKind.kt new file mode 100644 index 00000000000..dc0a41015e5 --- /dev/null +++ b/native/utils/src/org/jetbrains/kotlin/konan/target/CompilerOutputKind.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.konan.target + +enum class CompilerOutputKind { + PROGRAM { + override fun suffix(target: KonanTarget?) = ".${target!!.family.exeSuffix}" + }, + DYNAMIC { + override fun suffix(target: KonanTarget?) = ".${target!!.family.dynamicSuffix}" + override fun prefix(target: KonanTarget?) = target!!.family.dynamicPrefix + }, + STATIC { + override fun suffix(target: KonanTarget?) = ".${target!!.family.staticSuffix}" + override fun prefix(target: KonanTarget?) = target!!.family.staticPrefix + }, + FRAMEWORK { + override fun suffix(target: KonanTarget?): String = ".framework" + }, + LIBRARY { + override fun suffix(target: KonanTarget?) = ".klib" + }, + BITCODE { + override fun suffix(target: KonanTarget?) = ".bc" + }, + + DYNAMIC_CACHE { + override fun suffix(target: KonanTarget?) = ".${target!!.family.dynamicSuffix}" + override fun prefix(target: KonanTarget?) = target!!.family.dynamicPrefix + }, + STATIC_CACHE { + override fun suffix(target: KonanTarget?) = ".${target!!.family.staticSuffix}" + override fun prefix(target: KonanTarget?) = target!!.family.staticPrefix + }; + + abstract fun suffix(target: KonanTarget? = null): String + open fun prefix(target: KonanTarget? = null): String = "" +} diff --git a/native/utils/src/org/jetbrains/kotlin/konan/target/Family.kt b/native/utils/src/org/jetbrains/kotlin/konan/target/Family.kt new file mode 100644 index 00000000000..c283bca5785 --- /dev/null +++ b/native/utils/src/org/jetbrains/kotlin/konan/target/Family.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.konan.target + +enum class Family( + val exeSuffix: String, + val dynamicPrefix: String, + val dynamicSuffix: String, + val staticPrefix: String, + val staticSuffix: String +) { + OSX("kexe", "lib", "dylib", "lib", "a"), + IOS("kexe", "lib", "dylib", "lib", "a"), + TVOS("kexe", "lib", "dylib", "lib", "a"), + WATCHOS("kexe", "lib", "dylib", "lib", "a"), + LINUX("kexe", "lib", "so", "lib", "a"), + MINGW("exe", "", "dll", "lib", "a"), + ANDROID("so", "lib", "so", "lib", "a"), + WASM("wasm", "", "wasm", "", "wasm"), + ZEPHYR("o", "lib", "a", "lib", "a"); + + val isAppleFamily: Boolean + get() = this == OSX || this == IOS || this == TVOS || this == WATCHOS +} diff --git a/native/utils/src/org/jetbrains/kotlin/konan/target/HostManager.kt b/native/utils/src/org/jetbrains/kotlin/konan/target/HostManager.kt new file mode 100644 index 00000000000..b57f90dfcc8 --- /dev/null +++ b/native/utils/src/org/jetbrains/kotlin/konan/target/HostManager.kt @@ -0,0 +1,214 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.konan.target + +import org.jetbrains.kotlin.konan.target.KonanTarget.* +import java.lang.Exception + +open class HostManager(protected val distribution: Distribution = Distribution(), experimental: Boolean = false) { + + fun targetManager(userRequest: String? = null): TargetManager = TargetManagerImpl(userRequest, this) + + // TODO: need a better way to enumerated predefined targets. + private val predefinedTargets = listOf( + ANDROID_ARM32, ANDROID_ARM64, ANDROID_X86, ANDROID_X64, + IOS_ARM32, IOS_ARM64, IOS_X64, + WATCHOS_ARM32, WATCHOS_ARM64, + WATCHOS_X86, WATCHOS_X64, + TVOS_ARM64, TVOS_X64, + LINUX_X64, LINUX_ARM32_HFP, LINUX_ARM64, LINUX_MIPS32, LINUX_MIPSEL32, + MINGW_X64, MINGW_X86, + MACOS_X64, + WASM32) + + private val zephyrSubtargets = distribution.availableSubTarget("zephyr").map { ZEPHYR(it) } + private val experimentalEnabled = experimental || distribution.experimentalEnabled + private val configurableSubtargets = zephyrSubtargets + + val targetValues: List by lazy { predefinedTargets + configurableSubtargets } + + val targets = targetValues.associateBy { it.visibleName } + + fun toKonanTargets(names: Iterable): List { + return names.map { + if (it == "host") host else targets.getValue(known(resolveAlias(it))) + } + } + + fun known(name: String): String { + if (targets[name] == null) { + throw TargetSupportException("Unknown target: $name. Use -list_targets to see the list of available targets") + } + return name + } + + fun targetByName(name: String): KonanTarget { + if (name == "host") return host + return targets[resolveAlias(name)] ?: throw TargetSupportException("Unknown target name: $name") + } + + val enabledRegularByHost: Map> = mapOf( + LINUX_X64 to setOf( + LINUX_X64, + LINUX_ARM32_HFP, + LINUX_ARM64, + LINUX_MIPS32, + LINUX_MIPSEL32, + ANDROID_X86, + ANDROID_X64, + ANDROID_ARM32, + ANDROID_ARM64, + WASM32 + ), + MINGW_X64 to setOf( + MINGW_X64, + MINGW_X86, + LINUX_X64, + LINUX_ARM32_HFP, + LINUX_ARM64, + ANDROID_X86, + ANDROID_X64, + ANDROID_ARM32, + ANDROID_ARM64, + WASM32 + ), + MACOS_X64 to setOf( + MACOS_X64, + IOS_ARM32, + IOS_ARM64, + IOS_X64, + WATCHOS_ARM32, + WATCHOS_ARM64, + WATCHOS_X86, + WATCHOS_X64, + TVOS_ARM64, + TVOS_X64, + LINUX_X64, + LINUX_ARM32_HFP, + LINUX_ARM64, + ANDROID_X86, + ANDROID_X64, + ANDROID_ARM32, + ANDROID_ARM64, + WASM32 + ) + ) + + val enabledExperimentalByHost: Map> = mapOf( + LINUX_X64 to setOf(MINGW_X86, MINGW_X64) + zephyrSubtargets, + MACOS_X64 to setOf(MINGW_X86, MINGW_X64) + zephyrSubtargets, + MINGW_X64 to setOf() + zephyrSubtargets + ) + + val enabledByHost: Map> by lazy { + val result = enabledRegularByHost.toMutableMap() + if (experimentalEnabled) { + enabledExperimentalByHost.forEach { (k, v) -> + result.merge(k, v) { old, new -> old + new } + } + } + result.toMap() + } + + val enabledRegular: List by lazy { + enabledRegularByHost[host]?.toList() ?: throw TargetSupportException("Unknown host platform: $host") + } + + val enabledExperimental: List by lazy { + enabledExperimentalByHost[host]?.toList() ?: throw TargetSupportException("Unknown host platform: $host") + } + + val enabled : List + get() = if (experimentalEnabled) enabledRegular + enabledExperimental else enabledRegular + + fun isEnabled(target: KonanTarget) = enabled.contains(target) + + companion object { + fun host_os(): String { + val javaOsName = System.getProperty("os.name") + return when { + javaOsName == "Mac OS X" -> "osx" + javaOsName == "Linux" -> "linux" + javaOsName.startsWith("Windows") -> "windows" + else -> throw TargetSupportException("Unknown operating system: $javaOsName") + } + } + + @JvmStatic + fun simpleOsName(): String { + val hostOs = host_os() + return if (hostOs == "osx") "macos" else hostOs + } + + val jniHostPlatformIncludeDir: String + get() = when (host) { + MACOS_X64 -> "darwin" + LINUX_X64 -> "linux" + MINGW_X64 -> "win32" + else -> throw TargetSupportException("Unknown host: $host.") + } + + fun host_arch(): String { + val javaArch = System.getProperty("os.arch") + return when (javaArch) { + "x86_64" -> "x86_64" + "amd64" -> "x86_64" + "arm64" -> "arm64" + else -> throw TargetSupportException("Unknown hardware platform: $javaArch") + } + } + + val host: KonanTarget = when (host_os()) { + "osx" -> MACOS_X64 + "linux" -> LINUX_X64 + "windows" -> MINGW_X64 + else -> throw TargetSupportException("Unknown host target: ${host_os()} ${host_arch()}") + } + + // Note Hotspot-specific VM option enforcing C1-only, critical for decent compilation speed. + val defaultJvmArgs = listOf("-XX:TieredStopAtLevel=1", "-ea", "-Dfile.encoding=UTF-8") + val regularJvmArgs = defaultJvmArgs + "-Xmx3G" + + val hostIsMac = (host.family == Family.OSX) + val hostIsLinux = (host.family == Family.LINUX) + val hostIsMingw = (host.family == Family.MINGW) + + val hostSuffix get() = host.name + + @JvmStatic + val hostName get() = host.name + + val knownTargetTemplates = listOf("zephyr") + + private val targetAliasResolutions = mapOf( + "linux" to "linux_x64", + "macbook" to "macos_x64", + "macos" to "macos_x64", + "imac" to "macos_x64", + "raspberrypi" to "linux_arm32_hfp", + "iphone32" to "ios_arm32", + "iphone" to "ios_arm64", + "ipad" to "ios_arm64", + "ios" to "ios_arm64", + "iphone_sim" to "ios_x64", + "mingw" to "mingw_x64" + ) + + private val targetAliases: Map> by lazy { + val result = mutableMapOf>() + targetAliasResolutions.entries.forEach { + result.getOrPut(it.value, { mutableListOf() } ).add(it.key) + } + result + } + + fun resolveAlias(request: String): String = targetAliasResolutions[request] ?: request + + fun listAliases(target: String): List = targetAliases[target] ?: emptyList() + } +} + +class TargetSupportException(message: String = "", cause: Throwable? = null) : Exception(message, cause) diff --git a/native/utils/src/org/jetbrains/kotlin/konan/target/KonanTarget.kt b/native/utils/src/org/jetbrains/kotlin/konan/target/KonanTarget.kt index 2ab9d0e0567..6c0cbed0c34 100644 --- a/native/utils/src/org/jetbrains/kotlin/konan/target/KonanTarget.kt +++ b/native/utils/src/org/jetbrains/kotlin/konan/target/KonanTarget.kt @@ -1,372 +1,39 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.konan.target -import org.jetbrains.kotlin.konan.target.KonanTarget.* import org.jetbrains.kotlin.konan.util.Named -import java.io.Serializable -import java.lang.Exception - -enum class Family(val exeSuffix:String, val dynamicPrefix: String, val dynamicSuffix: String, - val staticPrefix: String, val staticSuffix: String) { - OSX ("kexe", "lib", "dylib", "lib", "a"), - IOS ("kexe", "lib", "dylib", "lib", "a"), - TVOS ("kexe", "lib", "dylib", "lib", "a"), - WATCHOS ("kexe", "lib", "dylib", "lib", "a"), - LINUX ("kexe", "lib", "so" , "lib", "a"), - MINGW ("exe" , "" , "dll" , "lib", "a"), - ANDROID ("so" , "lib", "so" , "lib", "a"), - WASM ("wasm", "" , "wasm" , "", "wasm"), - ZEPHYR ("o" , "lib", "a" , "lib", "a"); - - val isAppleFamily: Boolean - get() = this == OSX - || this == IOS - || this == TVOS - || this == WATCHOS -} - -enum class Architecture(val bitness: Int) { - X64(64), - X86(32), - ARM64(64), - ARM32(32), - MIPS32(32), - MIPSEL32(32), - WASM32(32); -} sealed class KonanTarget(override val name: String, val family: Family, val architecture: Architecture) : Named { - object ANDROID_X64 : KonanTarget( "android_x64", Family.ANDROID, Architecture.X64) - object ANDROID_X86 : KonanTarget( "android_x86", Family.ANDROID, Architecture.X86) - object ANDROID_ARM32 : KonanTarget( "android_arm32", Family.ANDROID, Architecture.ARM32) - object ANDROID_ARM64 : KonanTarget( "android_arm64", Family.ANDROID, Architecture.ARM64) - object IOS_ARM32 : KonanTarget( "ios_arm32", Family.IOS, Architecture.ARM32) - object IOS_ARM64 : KonanTarget( "ios_arm64", Family.IOS, Architecture.ARM64) - object IOS_X64 : KonanTarget( "ios_x64", Family.IOS, Architecture.X64) - object WATCHOS_ARM32 : KonanTarget( "watchos_arm32", Family.WATCHOS, Architecture.ARM32) - object WATCHOS_ARM64 : KonanTarget( "watchos_arm64", Family.WATCHOS, Architecture.ARM64) - object WATCHOS_X86 : KonanTarget( "watchos_x86", Family.WATCHOS, Architecture.X86) - object WATCHOS_X64 : KonanTarget( "watchos_x64", Family.WATCHOS, Architecture.X64) - object TVOS_ARM64 : KonanTarget( "tvos_arm64", Family.TVOS, Architecture.ARM64) - object TVOS_X64 : KonanTarget( "tvos_x64", Family.TVOS, Architecture.X64) - object LINUX_X64 : KonanTarget( "linux_x64", Family.LINUX, Architecture.X64) - object MINGW_X86 : KonanTarget( "mingw_x86", Family.MINGW, Architecture.X86) - object MINGW_X64 : KonanTarget( "mingw_x64", Family.MINGW, Architecture.X64) - object MACOS_X64 : KonanTarget( "macos_x64", Family.OSX, Architecture.X64) - object LINUX_ARM64 : KonanTarget( "linux_arm64", Family.LINUX, Architecture.ARM64) - object LINUX_ARM32_HFP :KonanTarget( "linux_arm32_hfp", Family.LINUX, Architecture.ARM32) - object LINUX_MIPS32 : KonanTarget( "linux_mips32", Family.LINUX, Architecture.MIPS32) - object LINUX_MIPSEL32 : KonanTarget( "linux_mipsel32", Family.LINUX, Architecture.MIPSEL32) - object WASM32 : KonanTarget( "wasm32", Family.WASM, Architecture.WASM32) + object ANDROID_X64 : KonanTarget("android_x64", Family.ANDROID, Architecture.X64) + object ANDROID_X86 : KonanTarget("android_x86", Family.ANDROID, Architecture.X86) + object ANDROID_ARM32 : KonanTarget("android_arm32", Family.ANDROID, Architecture.ARM32) + object ANDROID_ARM64 : KonanTarget("android_arm64", Family.ANDROID, Architecture.ARM64) + object IOS_ARM32 : KonanTarget("ios_arm32", Family.IOS, Architecture.ARM32) + object IOS_ARM64 : KonanTarget("ios_arm64", Family.IOS, Architecture.ARM64) + object IOS_X64 : KonanTarget("ios_x64", Family.IOS, Architecture.X64) + object WATCHOS_ARM32 : KonanTarget("watchos_arm32", Family.WATCHOS, Architecture.ARM32) + object WATCHOS_ARM64 : KonanTarget("watchos_arm64", Family.WATCHOS, Architecture.ARM64) + object WATCHOS_X86 : KonanTarget("watchos_x86", Family.WATCHOS, Architecture.X86) + object WATCHOS_X64 : KonanTarget("watchos_x64", Family.WATCHOS, Architecture.X64) + object TVOS_ARM64 : KonanTarget("tvos_arm64", Family.TVOS, Architecture.ARM64) + object TVOS_X64 : KonanTarget("tvos_x64", Family.TVOS, Architecture.X64) + object LINUX_X64 : KonanTarget("linux_x64", Family.LINUX, Architecture.X64) + object MINGW_X86 : KonanTarget("mingw_x86", Family.MINGW, Architecture.X86) + object MINGW_X64 : KonanTarget("mingw_x64", Family.MINGW, Architecture.X64) + object MACOS_X64 : KonanTarget("macos_x64", Family.OSX, Architecture.X64) + object LINUX_ARM64 : KonanTarget("linux_arm64", Family.LINUX, Architecture.ARM64) + object LINUX_ARM32_HFP : KonanTarget("linux_arm32_hfp", Family.LINUX, Architecture.ARM32) + object LINUX_MIPS32 : KonanTarget("linux_mips32", Family.LINUX, Architecture.MIPS32) + object LINUX_MIPSEL32 : KonanTarget("linux_mipsel32", Family.LINUX, Architecture.MIPSEL32) + object WASM32 : KonanTarget("wasm32", Family.WASM, Architecture.WASM32) // Tunable targets - class ZEPHYR(val subName: String, val genericName: String = "zephyr") : KonanTarget("${genericName}_$subName", Family.ZEPHYR, Architecture.ARM32) + class ZEPHYR(val subName: String, val genericName: String = "zephyr") : + KonanTarget("${genericName}_$subName", Family.ZEPHYR, Architecture.ARM32) override fun toString() = name } - -fun hostTargetSuffix(host: KonanTarget, target: KonanTarget) = - if (target == host) host.name else "${host.name}-${target.name}" - -enum class CompilerOutputKind { - PROGRAM { - override fun suffix(target: KonanTarget?) = ".${target!!.family.exeSuffix}" - }, - DYNAMIC { - override fun suffix(target: KonanTarget?) = ".${target!!.family.dynamicSuffix}" - override fun prefix(target: KonanTarget?) = "${target!!.family.dynamicPrefix}" - }, - STATIC { - override fun suffix(target: KonanTarget?) = ".${target!!.family.staticSuffix}" - override fun prefix(target: KonanTarget?) = "${target!!.family.staticPrefix}" - }, - FRAMEWORK { - override fun suffix(target: KonanTarget?): String = ".framework" - }, - LIBRARY { - override fun suffix(target: KonanTarget?) = ".klib" - }, - BITCODE { - override fun suffix(target: KonanTarget?) = ".bc" - }, - - DYNAMIC_CACHE { - override fun suffix(target: KonanTarget?) = ".${target!!.family.dynamicSuffix}" - override fun prefix(target: KonanTarget?) = "${target!!.family.dynamicPrefix}" - }, - STATIC_CACHE { - override fun suffix(target: KonanTarget?) = ".${target!!.family.staticSuffix}" - override fun prefix(target: KonanTarget?) = "${target!!.family.staticPrefix}" - }, - - ; - - abstract fun suffix(target: KonanTarget? = null): String - open fun prefix(target: KonanTarget? = null): String = "" -} - -interface TargetManager { - val target: KonanTarget - val targetName : String - fun list() : Unit - val hostTargetSuffix: String - val targetSuffix: String -} - -private class TargetManagerImpl(val userRequest: String?, val hostManager: HostManager): TargetManager { - override val target = determineCurrent() - override val targetName - get() = target.visibleName - - override fun list() { - hostManager.enabled.forEach { - val isDefault = if (it == target) "(default)" else "" - val aliasList = HostManager.listAliases(it.visibleName).joinToString(", ") - println(String.format("%1$-30s%2$-10s%3\$s", "${it.visibleName}:", "$isDefault", aliasList)) - } - } - - fun determineCurrent(): KonanTarget { - return if (userRequest == null || userRequest == "host") { - HostManager.host - } else { - val resolvedAlias = HostManager.resolveAlias(userRequest) - hostManager.targets[hostManager.known(resolvedAlias)]!! - } - } - - override val hostTargetSuffix get() = hostTargetSuffix(HostManager.host, target) - override val targetSuffix get() = target.name -} - -open class HostManager(protected val distribution: Distribution = Distribution(), experimental: Boolean = false) { - - fun targetManager(userRequest: String? = null): TargetManager = TargetManagerImpl(userRequest, this) - - // TODO: need a better way to enumerated predefined targets. - private val predefinedTargets = listOf( - ANDROID_ARM32, ANDROID_ARM64, ANDROID_X86, ANDROID_X64, - IOS_ARM32, IOS_ARM64, IOS_X64, - WATCHOS_ARM32, WATCHOS_ARM64, - WATCHOS_X86, WATCHOS_X64, - TVOS_ARM64, TVOS_X64, - LINUX_X64, LINUX_ARM32_HFP, LINUX_ARM64, LINUX_MIPS32, LINUX_MIPSEL32, - MINGW_X64, MINGW_X86, - MACOS_X64, - WASM32) - - private val zephyrSubtargets = distribution.availableSubTarget("zephyr").map { ZEPHYR(it) } - - private val experimentalEnabled = experimental || distribution.experimentalEnabled - - private val configurableSubtargets = zephyrSubtargets - - val targetValues: List by lazy { - predefinedTargets + configurableSubtargets - } - - val targets = targetValues.associate{ it.visibleName to it } - - fun toKonanTargets(names: Iterable): List { - return names.map { - if (it == "host") HostManager.host - else targets[known(resolveAlias(it))]!! - } - } - - fun known(name: String): String { - if (targets[name] == null) { - throw TargetSupportException("Unknown target: $name. Use -list_targets to see the list of available targets") - } - return name - } - - fun targetByName(name: String): KonanTarget { - if (name == "host") return host - val target = targets[resolveAlias(name)] - if (target == null) throw TargetSupportException("Unknown target name: $name") - return target - } - - val enabledRegularByHost: Map> = mapOf( - LINUX_X64 to setOf( - LINUX_X64, - LINUX_ARM32_HFP, - LINUX_ARM64, - LINUX_MIPS32, - LINUX_MIPSEL32, - ANDROID_X86, - ANDROID_X64, - ANDROID_ARM32, - ANDROID_ARM64, - WASM32 - ), - MINGW_X64 to setOf( - MINGW_X64, - MINGW_X86, - LINUX_X64, - LINUX_ARM32_HFP, - LINUX_ARM64, - ANDROID_X86, - ANDROID_X64, - ANDROID_ARM32, - ANDROID_ARM64, - WASM32 - ), - MACOS_X64 to setOf( - MACOS_X64, - IOS_ARM32, - IOS_ARM64, - IOS_X64, - WATCHOS_ARM32, - WATCHOS_ARM64, - WATCHOS_X86, - WATCHOS_X64, - TVOS_ARM64, - TVOS_X64, - LINUX_X64, - LINUX_ARM32_HFP, - LINUX_ARM64, - ANDROID_X86, - ANDROID_X64, - ANDROID_ARM32, - ANDROID_ARM64, - WASM32 - ) - ) - - val enabledExperimentalByHost: Map> = mapOf( - LINUX_X64 to setOf(MINGW_X86, MINGW_X64) + zephyrSubtargets, - MACOS_X64 to setOf(MINGW_X86, MINGW_X64) + zephyrSubtargets, - MINGW_X64 to setOf() + zephyrSubtargets - ) - - val enabledByHost: Map> by lazy { - val result = enabledRegularByHost.toMutableMap() - if (experimentalEnabled) { - enabledExperimentalByHost.forEach { (k, v) -> - result.merge(k, v) { old, new -> old + new } - } - } - result.toMap() - } - - val enabledRegular: List by lazy { - enabledRegularByHost[host]?.toList() ?: throw TargetSupportException("Unknown host platform: $host") - } - - val enabledExperimental: List by lazy { - enabledExperimentalByHost[host]?.toList() ?: throw TargetSupportException("Unknown host platform: $host") - } - - val enabled : List - get() = if (experimentalEnabled) enabledRegular + enabledExperimental else enabledRegular - - fun isEnabled(target: KonanTarget) = enabled.contains(target) - - companion object { - fun host_os(): String { - val javaOsName = System.getProperty("os.name") - return when { - javaOsName == "Mac OS X" -> "osx" - javaOsName == "Linux" -> "linux" - javaOsName.startsWith("Windows") -> "windows" - else -> throw TargetSupportException("Unknown operating system: ${javaOsName}") - } - } - - @JvmStatic - fun simpleOsName(): String { - val hostOs = host_os() - return if (hostOs == "osx") "macos" else hostOs - } - - val jniHostPlatformIncludeDir: String - get() = when(host) { - KonanTarget.MACOS_X64 -> "darwin" - KonanTarget.LINUX_X64 -> "linux" - KonanTarget.MINGW_X64 ->"win32" - else -> throw TargetSupportException("Unknown host: $host.") - } - - fun host_arch(): String { - val javaArch = System.getProperty("os.arch") - return when (javaArch) { - "x86_64" -> "x86_64" - "amd64" -> "x86_64" - "arm64" -> "arm64" - else -> throw TargetSupportException("Unknown hardware platform: ${javaArch}") - } - } - - val host: KonanTarget = when (host_os()) { - "osx" -> KonanTarget.MACOS_X64 - "linux" -> KonanTarget.LINUX_X64 - "windows" -> KonanTarget.MINGW_X64 - else -> throw TargetSupportException("Unknown host target: ${host_os()} ${host_arch()}") - } - - // Note Hotspot-specific VM option enforcing C1-only, critical for decent compilation speed. - val defaultJvmArgs = listOf("-XX:TieredStopAtLevel=1", "-ea", "-Dfile.encoding=UTF-8") - val regularJvmArgs = defaultJvmArgs + "-Xmx3G" - - val hostIsMac = (host.family == Family.OSX) - val hostIsLinux = (host.family == Family.LINUX) - val hostIsMingw = (host.family == Family.MINGW) - - val hostSuffix get() = host.name - @JvmStatic - val hostName get() = host.name - - val knownTargetTemplates = listOf("zephyr") - - private val targetAliasResolutions = mapOf( - "linux" to "linux_x64", - "macbook" to "macos_x64", - "macos" to "macos_x64", - "imac" to "macos_x64", - "raspberrypi" to "linux_arm32_hfp", - "iphone32" to "ios_arm32", - "iphone" to "ios_arm64", - "ipad" to "ios_arm64", - "ios" to "ios_arm64", - "iphone_sim" to "ios_x64", - "mingw" to "mingw_x64" - ) - - private val targetAliases: Map> by lazy { - val result = mutableMapOf>() - targetAliasResolutions.entries.forEach { - result.getOrPut(it.value, { mutableListOf() } ).add(it.key) - } - result - } - - fun resolveAlias(request: String): String = targetAliasResolutions[request] ?: request - - fun listAliases(target: String): List = targetAliases[target] ?: emptyList() - } -} - -/** - * Name of a preset used in the 'kotlin-multiplatform' Gradle plugin to represent this target. - */ -val KonanTarget.presetName: String - get() = when (this) { - ANDROID_ARM32 -> "androidNativeArm32" - ANDROID_ARM64 -> "androidNativeArm64" - ANDROID_X86 -> "androidNativeX86" - ANDROID_X64 -> "androidNativeX64" - else -> evaluatePresetName(this.name) - } - -private fun evaluatePresetName(targetName: String): String { - val nameParts = targetName.split('_').mapNotNull { it.takeIf(String::isNotEmpty) } - return nameParts.asSequence().drop(1).joinToString("", nameParts.firstOrNull().orEmpty(), transform = String::capitalize) -} - -class TargetSupportException (message: String = "", cause: Throwable? = null) : Exception(message, cause) diff --git a/native/utils/src/org/jetbrains/kotlin/konan/target/TargetManager.kt b/native/utils/src/org/jetbrains/kotlin/konan/target/TargetManager.kt new file mode 100644 index 00000000000..585e164930a --- /dev/null +++ b/native/utils/src/org/jetbrains/kotlin/konan/target/TargetManager.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.konan.target + +interface TargetManager { + val target: KonanTarget + val targetName: String + fun list() + val hostTargetSuffix: String + val targetSuffix: String +} + +internal class TargetManagerImpl(val userRequest: String?, val hostManager: HostManager) : TargetManager { + override val target = determineCurrent() + override val targetName + get() = target.visibleName + + override fun list() { + hostManager.enabled.forEach { + val isDefault = if (it == target) "(default)" else "" + val aliasList = HostManager.listAliases(it.visibleName).joinToString(", ") + println(String.format("%1$-30s%2$-10s%3\$s", "${it.visibleName}:", isDefault, aliasList)) + } + } + + fun determineCurrent(): KonanTarget { + return if (userRequest == null || userRequest == "host") { + HostManager.host + } else { + val resolvedAlias = HostManager.resolveAlias(userRequest) + hostManager.targets.getValue(hostManager.known(resolvedAlias)) + } + } + + override val hostTargetSuffix get() = hostTargetSuffix(HostManager.host, target) + override val targetSuffix get() = target.name +} + +fun hostTargetSuffix(host: KonanTarget, target: KonanTarget) = + if (target == host) host.name else "${host.name}-${target.name}" diff --git a/native/utils/src/org/jetbrains/kotlin/konan/target/utils.kt b/native/utils/src/org/jetbrains/kotlin/konan/target/utils.kt new file mode 100644 index 00000000000..4b35065f10d --- /dev/null +++ b/native/utils/src/org/jetbrains/kotlin/konan/target/utils.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.konan.target + +/** + * Name of a preset used in the 'kotlin-multiplatform' Gradle plugin to represent this target. + */ +val KonanTarget.presetName: String + get() = when (this) { + KonanTarget.ANDROID_ARM32 -> "androidNativeArm32" + KonanTarget.ANDROID_ARM64 -> "androidNativeArm64" + KonanTarget.ANDROID_X86 -> "androidNativeX86" + KonanTarget.ANDROID_X64 -> "androidNativeX64" + else -> evaluatePresetName(this.name) + } + +private fun evaluatePresetName(targetName: String): String { + val nameParts = targetName.split('_').mapNotNull { it.takeIf(String::isNotEmpty) } + return nameParts.asSequence().drop(1).joinToString("", nameParts.firstOrNull().orEmpty(), transform = String::capitalize) +}