From cebf815fed089a28ba691055e1428f9bbb37bf26 Mon Sep 17 00:00:00 2001 From: Sergey Bogolepov Date: Fri, 2 Apr 2021 13:48:05 +0700 Subject: [PATCH] Introduce a proper TargetTriple class. Target triple (like `arm64-apple-ios-simulator`) is a common way to represent any target platform. One of many useful properties: it allows to explicitly distinguish iOS arm64 simulator target and a real device. --- kotlin-native/konan/konan.properties | 46 ++++++++-------- .../kotlin/konan/target/ClangArgs.kt | 10 ++-- .../kotlin/konan/target/Configurables.kt | 20 +++---- .../jetbrains/kotlin/konan/target/Linker.kt | 14 ++--- .../kotlin/konan/target/TargetTriple.kt | 53 +++++++++++++++++++ 5 files changed, 96 insertions(+), 47 deletions(-) create mode 100644 kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/TargetTriple.kt diff --git a/kotlin-native/konan/konan.properties b/kotlin-native/konan/konan.properties index a50f358b200..d772dd7f5df 100644 --- a/kotlin-native/konan/konan.properties +++ b/kotlin-native/konan/konan.properties @@ -95,7 +95,7 @@ additionalToolsDir.macos_x64 = xcode-addon-xcode_12_2-macos_x64 targetToolchain.macos_arm64-macos_x64 = target-toolchain-xcode_12_2-macos_x64 -arch.macos_x64 = x86_64 +targetTriple.macos_x64 = x86_64-apple-macos targetSysRoot.macos_x64 = target-sysroot-xcode_12_2-macos_x64 targetCpu.macos_x64 = core2 clangFlags.macos_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir @@ -133,7 +133,7 @@ libffiDir.macos_arm64 = libffi-3.3-1-macos-arm64 additionalToolsDir.macos_arm64 = xcode-addon-xcode_12_2-macos_x64 targetToolchain.macos_x64-macos_arm64 = target-toolchain-xcode_12_2-macos_x64 -arch.macos_arm64 = arm64 +targetTriple.macos_arm64 = arm64-apple-macos targetSysRoot.macos_arm64 = target-sysroot-xcode_12_2-macos_x64 # TODO: Check Clang behaviour. targetCpu.macos_arm64 = cyclone @@ -173,7 +173,7 @@ targetToolchain.macos_arm64-ios_arm32 = target-toolchain-xcode_12_2-macos_x64 target-sysroot-xcode_12_2-ios_arm32.default = \ remote:internal -arch.ios_arm32 = armv7 +targetTriple.ios_arm32 = armv7-apple-ios # Shared with 64-bit version. targetSysRoot.ios_arm32 = target-sysroot-xcode_12_2-ios_arm64 targetCpu.ios_arm32 = generic @@ -205,7 +205,7 @@ targetToolchain.macos_arm64-ios_arm64 = target-toolchain-xcode_12_2-macos_x64 target-sysroot-xcode_12_2-ios_arm64.default = \ remote:internal -arch.ios_arm64 = arm64 +targetTriple.ios_arm64 = arm64-apple-ios targetSysRoot.ios_arm64 = target-sysroot-xcode_12_2-ios_arm64 targetCpu.ios_arm64 = cyclone clangFlags.ios_arm64 = -cc1 -emit-obj -disable-llvm-passes -x ir @@ -235,7 +235,7 @@ targetToolchain.macos_arm64-ios_x64 = target-toolchain-xcode_12_2-macos_x64 target-sysroot-xcode_12_2-ios_x64.default = \ remote:internal -arch.ios_x64 = x86_64 +targetTriple.ios_x64 = x86_64-apple-ios-simulator targetSysRoot.ios_x64 = target-sysroot-xcode_12_2-ios_x64 targetCpu.ios_x64 = core2 clangFlags.ios_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir @@ -261,7 +261,7 @@ targetToolchain.macos_arm64-tvos_x64 = target-toolchain-xcode_12_2-macos_x64 target-sysroot-xcode_12_2-tvos_x64.default = \ remote:internal -arch.tvos_x64 = x86_64 +targetTriple.tvos_x64 = x86_64-apple-tvos-simulator targetSysRoot.tvos_x64 = target-sysroot-xcode_12_2-tvos_x64 targetCpu.tvos_x64 = core2 clangFlags.tvos_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir -target-cpu $targetCpu.tvos_x64 @@ -287,7 +287,7 @@ targetToolchain.macos_arm64-tvos_arm64 = target-toolchain-xcode_12_2-macos_x64 target-sysroot-xcode_12_2-tvos_arm64.default = \ remote:internal -arch.tvos_arm64 = arm64 +targetTriple.tvos_arm64 = arm64-apple-tvos targetSysRoot.tvos_arm64 = target-sysroot-xcode_12_2-tvos_arm64 targetCpu.tvos_arm64 = cyclone clangFlags.tvos_arm64 = -cc1 -emit-obj -disable-llvm-passes -x ir @@ -313,7 +313,7 @@ targetToolchain.macos_arm64-watchos_arm32 = target-toolchain-xcode_12_2-macos_x6 target-sysroot-xcode_12_2-watchos_arm32.default = \ remote:internal -arch.watchos_arm32 = armv7k +targetTriple.watchos_arm32 = armv7k-apple-watchos targetSysRoot.watchos_arm32 = target-sysroot-xcode_12_2-watchos_arm32 targetCpu.watchos_arm32 = cortex-a7 clangFlags.watchos_arm32 = -cc1 -emit-obj -disable-llvm-passes -x ir @@ -341,7 +341,7 @@ targetToolchain.macos_arm64-watchos_arm64 = target-toolchain-xcode_12_2-macos_x6 target-sysroot-xcode_12_2-watchos_arm64.default = \ remote:internal -arch.watchos_arm64 = arm64_32 +targetTriple.watchos_arm64 = arm64_32-apple-watchos targetSysRoot.watchos_arm64 = target-sysroot-xcode_12_2-watchos_arm32 targetCpu.watchos_arm64 = cortex-a7 clangFlags.watchos_arm64 = -cc1 -emit-obj -disable-llvm-passes -x ir -mllvm -aarch64-watch-bitcode-compatibility \ @@ -370,7 +370,7 @@ targetToolchain.macos_arm64-watchos_x86 = target-toolchain-xcode_12_2-macos_x64 target-sysroot-xcode_12_2-watchos_x86.default = \ remote:internal -arch.watchos_x86 = i386 +targetTriple.watchos_x86 = i386-apple-watchos-simulator targetSysRoot.watchos_x86 = target-sysroot-xcode_12_2-watchos_x86 # -target-cpu pentium4 makes sure that code-generator knows which CPU flavour to emit code for. # Can be seen on optimized build and FP tests, where value is passed on stack @@ -400,7 +400,7 @@ targetToolchain.macos_arm64-watchos_x64 = target-toolchain-xcode_12_2-macos_x64 target-sysroot-xcode_12_2-watchos_x64.default = \ remote:internal -arch.watchos_x64 = x86_64 +targetTriple.watchos_x64 = x86_64-apple-watchos-simulator targetSysRoot.watchos_x64 = target-sysroot-xcode_12_2-watchos_x86 targetCpu.watchos_x64 = core2 clangFlags.watchos_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir -target-cpu $targetCpu.watchos_x64 @@ -441,7 +441,7 @@ targetToolchain.macos_arm64-linux_x64 = $llvmHome.macos_arm64 dependencies.macos_arm64-linux_x64 = \ x86_64-unknown-linux-gnu-gcc-8.3.0-glibc-2.19-kernel-4.9-2 -quadruple.linux_x64 = x86_64-unknown-linux-gnu +targetTriple.linux_x64 = x86_64-unknown-linux-gnu targetSysRoot.linux_x64 = $gccToolchain.linux_x64/x86_64-unknown-linux-gnu/sysroot # targetSysroot-relative. libGcc.linux_x64 = ../../lib/gcc/x86_64-unknown-linux-gnu/8.3.0 @@ -496,7 +496,7 @@ dependencies.macos_x64-linux_arm32_hfp = \ dependencies.macos_arm64-linux_arm32_hfp = \ arm-unknown-linux-gnueabihf-gcc-8.3.0-glibc-2.19-kernel-4.9-2 -quadruple.linux_arm32_hfp = arm-unknown-linux-gnueabihf +targetTriple.linux_arm32_hfp = arm-unknown-linux-gnueabihf linkerNoDebugFlags.linux_arm32_hfp = -S linkerDynamicFlags.linux_arm32_hfp = -shared linkerOptimizationFlags.linux_arm32_hfp = --gc-sections @@ -551,7 +551,7 @@ dependencies.macos_x64-linux_arm64 = \ dependencies.macos_arm64-linux_arm64 = \ aarch64-unknown-linux-gnu-gcc-8.3.0-glibc-2.25-kernel-4.9-2 -quadruple.linux_arm64 = aarch64-unknown-linux-gnu +targetTriple.linux_arm64 = aarch64-unknown-linux-gnu linkerNoDebugFlags.linux_arm64 = -S linkerDynamicFlags.linux_arm64 = -shared linkerOptimizationFlags.linux_arm64 = --gc-sections @@ -595,7 +595,7 @@ emulatorExecutable.linux_x64-linux_mips32 = qemu-mips-static-5.1.0-linux-2/qemu- dependencies.linux_x64-linux_mips32 = \ mips-unknown-linux-gnu-gcc-8.3.0-glibc-2.19-kernel-4.9-2 -quadruple.linux_mips32 = mips-unknown-linux-gnu +targetTriple.linux_mips32 = mips-unknown-linux-gnu linkerOptimizationFlags.linux_mips32 = --gc-sections linkerDynamicFlags.linux_mips32 = -shared targetSysRoot.linux_mips32 = $gccToolchain.linux_mips32/mips-unknown-linux-gnu/sysroot @@ -636,7 +636,7 @@ emulatorExecutable.linux_x64-linux_mipsel32 = qemu-mipsel-static-5.1.0-linux-2/q dependencies.linux_x64-linux_mipsel32 = \ mipsel-unknown-linux-gnu-gcc-8.3.0-glibc-2.19-kernel-4.9-2 -quadruple.linux_mipsel32 = mipsel-unknown-linux-gnu +targetTriple.linux_mipsel32 = mipsel-unknown-linux-gnu linkerOptimizationFlags.linux_mipsel32 = --gc-sections linkerDynamicFlags.linux_mipsel32 = -shared targetSysRoot.linux_mipsel32 = $gccToolchain.linux_mipsel32/mipsel-unknown-linux-gnu/sysroot @@ -682,7 +682,7 @@ dependencies.mingw_x64-android_arm32 = \ target-sysroot-1-android_ndk \ target-toolchain-2-windows-android_ndk -quadruple.android_arm32 = arm-linux-androideabi +targetTriple.android_arm32 = arm-unknown-linux-androideabi targetCpu.android_arm32 = arm7tdmi targetCpuFeatures.android_arm32 = +soft-float,+strict-align,-crypto,-neon,-thumb-mode clangFlags.android_arm32 = -cc1 -target-cpu $targetCpu.android_arm32 -emit-obj -disable-llvm-optzns -x ir -femulated-tls -mrelocation-model pic @@ -712,7 +712,7 @@ dependencies.mingw_x64-android_arm64 = \ target-sysroot-1-android_ndk \ target-toolchain-2-windows-android_ndk -quadruple.android_arm64 = aarch64-linux-android +targetTriple.android_arm64 = aarch64-unknown-linux-android targetCpu.android_arm64 = cortex-a57 clangFlags.android_arm64 = -cc1 -target-cpu $targetCpu.android_arm64 -emit-obj -disable-llvm-passes -x ir -femulated-tls -mrelocation-model pic clangOptFlags.android_arm64 = -O3 -ffunction-sections @@ -741,7 +741,7 @@ dependencies.mingw_x64-android_x86 = \ target-sysroot-1-android_ndk \ target-toolchain-2-windows-android_ndk -quadruple.android_x86 = i686-linux-android +targetTriple.android_x86 = i686-unknown-linux-android # -target-cpu pentium4 makes sure that cogenerator knows which CPU flavour to emit code for. # Can be seen on optimized build and FP tests, where value is passed on stack # by Kotlin and taken from SSE registers by C code. @@ -774,7 +774,7 @@ dependencies.mingw_x64-android_x64 = \ target-sysroot-1-android_ndk \ target-toolchain-2-windows-android_ndk -quadruple.android_x64 = x86_64-linux-android +targetTriple.android_x64 = x86_64-unknown-linux-android targetCpu.android_x64 = x86-64 clangFlags.android_x64 = -cc1 -target-cpu $targetCpu.android_x64 -emit-obj -disable-llvm-passes -x ir -femulated-tls -mrelocation-model pic clangOptFlags.android_x64 = -O3 -ffunction-sections @@ -796,7 +796,7 @@ targetToolchain.macos_x64-mingw_x64 = msys2-mingw-w64-x86_64-clang-llvm-lld-comp dependencies.mingw_x64 = \ lldb-2-windows -quadruple.mingw_x64 = x86_64-w64-mingw32 +targetTriple.mingw_x64 = x86_64-pc-windows-gnu targetSysRoot.mingw_x64 = msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1 targetCpu.mingw_x64 = x86-64 # For using with Universal Windows Platform (UWP) we need to use this slower option. @@ -827,7 +827,7 @@ dependencies.linux_x64-mingw_x86 = \ dependencies.macos_x64-mingw_x86 = \ msys2-mingw-w64-i686-clang-llvm-lld-compiler_rt-8.0.1 -quadruple.mingw_x86 = i686-w64-mingw32 +targetTriple.mingw_x86 = i686-pc-windows-gnu targetSysRoot.mingw_x86 = msys2-mingw-w64-i686-clang-llvm-lld-compiler_rt-8.0.1 # For using with Universal Windows Platform (UWP) we need to use slower -emulated-tls option. # See https://youtrack.jetbrains.com/issue/KT-27654. @@ -872,7 +872,7 @@ dependencies.mingw_x64-wasm32 = \ target-sysroot-4-embedded \ target-toolchain-2-mingw-wasm -quadruple.wasm32 = wasm32-unknown-unknown +targetTriple.wasm32 = wasm32-unknown-unknown targetSysRoot.wasm32 = target-sysroot-4-embedded targetCpu.wasm32 = generic clangFlags.wasm32 = -cc1 -emit-obj -disable-llvm-optzns -x ir diff --git a/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/ClangArgs.kt b/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/ClangArgs.kt index cec74bb325f..5ec0126aba5 100644 --- a/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/ClangArgs.kt +++ b/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/ClangArgs.kt @@ -33,10 +33,6 @@ internal object Android { class ClangArgs(private val configurables: Configurables) : Configurables by configurables { - private val targetArg = if (configurables is TargetableConfigurables) - configurables.targetArg - else null - private val clangArgsSpecificForKonanSources get() = runtimeDefinitions.map { "-D$it" } @@ -53,8 +49,8 @@ class ClangArgs(private val configurables: Configurables) : Configurables by con if (configurables is GccConfigurables) { add(listOf("--gcc-toolchain=${configurables.absoluteGccToolchain}")) } - if (configurables is TargetableConfigurables) { - add(listOf("-target", configurables.targetArg!!)) + if (configurables !is AppleConfigurables) { + add(listOf("-target", configurables.targetTriple.toString())) } if (configurables is AppleConfigurables) { val arch = when (target) { @@ -101,7 +97,7 @@ class ClangArgs(private val configurables: Configurables) : Configurables by con KonanTarget.ANDROID_ARM32, KonanTarget.ANDROID_ARM64, KonanTarget.ANDROID_X86, KonanTarget.ANDROID_X64 -> { - val clangTarget = targetArg!! + val clangTarget = targetTriple.toString() val architectureDir = Android.architectureDirForTarget(target) val toolchainSysroot = "$absoluteTargetToolchain/sysroot" listOf( diff --git a/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Configurables.kt b/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Configurables.kt index a49264bdac7..9bf00691b9d 100644 --- a/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Configurables.kt +++ b/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Configurables.kt @@ -52,6 +52,10 @@ interface LldFlags : TargetableExternalStorage { interface Configurables : TargetableExternalStorage, RelocationModeFlags { val target: KonanTarget + val targetTriple: TargetTriple + get() = targetString("targetTriple") + ?.let(TargetTriple.Companion::fromString) + ?: error("quadruple for $target is not set.") val llvmHome get() = hostString("llvmHome") val llvmVersion get() = hostString("llvmVersion") @@ -91,12 +95,8 @@ interface ConfigurablesWithEmulator : Configurables { val absoluteEmulatorExecutable get() = absolute(emulatorExecutable) } -interface TargetableConfigurables : Configurables { - val targetArg get() = targetString("quadruple") -} - interface AppleConfigurables : Configurables, ClangFlags { - val arch get() = targetString("arch")!! + val arch get() = targetTriple.architecture val osVersionMin get() = targetString("osVersionMin")!! val osVersionMinFlagLd get() = targetString("osVersionMinFlagLd")!! val osVersionMinFlagClang get() = targetString("osVersionMinFlagClang")!! @@ -105,9 +105,9 @@ interface AppleConfigurables : Configurables, ClangFlags { val absoluteAdditionalToolsDir get() = absolute(additionalToolsDir) } -interface MingwConfigurables : TargetableConfigurables, ClangFlags +interface MingwConfigurables : Configurables, ClangFlags -interface GccConfigurables : TargetableConfigurables, ClangFlags { +interface GccConfigurables : Configurables, ClangFlags { val gccToolchain get() = targetString("gccToolchain") val absoluteGccToolchain get() = absolute(gccToolchain) @@ -123,11 +123,11 @@ interface GccConfigurables : TargetableConfigurables, ClangFlags { val linkerGccFlags get() = targetList("linkerGccFlags") } -interface AndroidConfigurables : TargetableConfigurables, ClangFlags +interface AndroidConfigurables : Configurables, ClangFlags -interface WasmConfigurables : TargetableConfigurables, ClangFlags, LldFlags +interface WasmConfigurables : Configurables, ClangFlags, LldFlags -interface ZephyrConfigurables : TargetableConfigurables, ClangFlags { +interface ZephyrConfigurables : Configurables, ClangFlags { val boardSpecificClangFlags get() = targetList("boardSpecificClangFlags") val targetAbi get() = targetString("targetAbi") } \ No newline at end of file diff --git a/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Linker.kt b/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Linker.kt index dfaae46022c..0eb6fdee8b6 100644 --- a/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Linker.kt +++ b/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Linker.kt @@ -108,13 +108,13 @@ abstract class LinkerFlags(val configurables: Configurables) { class AndroidLinker(targetProperties: AndroidConfigurables) : LinkerFlags(targetProperties), AndroidConfigurables by targetProperties { - private val clangQuad = when (targetProperties.targetArg) { - "arm-linux-androideabi" -> "armv7a-linux-androideabi" - else -> targetProperties.targetArg + private val clangTarget = when (val targetString = targetProperties.targetTriple.toString()) { + "arm-unknown-linux-androideabi" -> "armv7a-unknown-linux-androideabi" + else -> targetString } - private val prefix = "$absoluteTargetToolchain/bin/${clangQuad}${Android.API}" + private val prefix = "$absoluteTargetToolchain/bin/${clangTarget}${Android.API}" private val clang = if (HostManager.hostIsMingw) "$prefix-clang.cmd" else "$prefix-clang" - private val ar = "$absoluteTargetToolchain/${targetProperties.targetArg}/bin/ar" + private val ar = "$absoluteTargetToolchain/${targetProperties.targetTriple}/bin/ar" override val useCompilerDriverAsLinker: Boolean get() = true @@ -136,7 +136,7 @@ class AndroidLinker(targetProperties: AndroidConfigurables) val toolchainSysroot = "${absoluteTargetToolchain}/sysroot" val architectureDir = Android.architectureDirForTarget(target) val apiSysroot = "$absoluteTargetSysRoot/$architectureDir" - val clangTarget = targetArg!! + val clangTarget = targetTriple.toString() val libDirs = listOf( "--sysroot=$apiSysroot", if (target == KonanTarget.ANDROID_X64) "-L$apiSysroot/usr/lib64" else "-L$apiSysroot/usr/lib", @@ -148,7 +148,7 @@ class AndroidLinker(targetProperties: AndroidConfigurables) +"-fPIC" +"-shared" +"-target" - +targetArg!! + +clangTarget +libDirs +objectFiles if (optimize) +linkerOptimizationFlags diff --git a/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/TargetTriple.kt b/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/TargetTriple.kt new file mode 100644 index 00000000000..2b7698385b1 --- /dev/null +++ b/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/TargetTriple.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2010-2021 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 + +/** + * Classical way to describe a target platform. + * Despite it's name, may contain more or less than 3 components. + * + * Example: arm64-apple-ios-simulator. + * - arm64 - target hardware. + * - apple - vendor. + * - ios - operating system. + * - simulator - environment. + * + * @see Clang documentation for target triple. + */ +data class TargetTriple( + val architecture: String, + val vendor: String, + val os: String, + val environment: String? +) { + companion object { + /** + * Parse --- [tripleString]. + * + * TODO: Support normalization like LLVM's Triple::normalize. + */ + fun fromString(tripleString: String): TargetTriple { + val components = tripleString.split('-') + // TODO: There might be other cases (e.g. of size 2 or 5), + // but let's support only these for now. + require(components.size == 3 || components.size == 4) { + "Malformed target triple: $tripleString. Expected format: ---." + } + return TargetTriple( + architecture = components[0], + vendor = components[1], + os = components[2], + environment = components.getOrNull(3) + ) + } + } + + override fun toString(): String { + val envSuffix = environment?.let { "-$environment" } + ?: "" + return "$architecture-$vendor-$os$envSuffix" + } +} \ No newline at end of file