Actuellement, je suis intéressé par ARM en général et plus particulièrement pour les cibles iphone/Android. Mais je veux juste en savoir plus sur clang, car il me semble important de jouer un rôle important dans les années à venir.
J'ai essayé
clang -cc1 --help|grep -i list
clang -cc1 --help|grep Arch|grep -v search
clang -cc1 --help|grep target
-triple <value> Specify target triple (e.g. i686-Apple-darwin9)
Je sais que clang a un paramètre -triplet, mais comment puis-je en lister toutes les valeurs possibles? J'ai trouvé que clang est très différent de gcc en ce qui concerne la compilation croisée. Dans le monde GCC, vous devez avoir un binaire séparé pour tout, comme PLATFORM_make ou PLATFORM_ld (i * 86-pc-cygwin i * 86 - * - linux-gnu, etc. - http://git.savannah.gnu.org/cgit/libtool.git/tree/doc/PLATFORMS )
dans le monde de clang, ce n'est qu'un binaire (comme je l'ai lu sur certains forums). Mais comment puis-je obtenir la liste des cibles prises en charge? Et si ma cible n’est pas supportée par ma distribution (linux/windows/macos/peu importe), comment puis-je obtenir celle qui prend en charge davantage de plates-formes?
si je SVN dernier clang comme ceci:
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
vais-je avoir la plupart des plateformes? Il semblerait que Clang n’ait pas été construit dans l’intérêt de la compilation croisée, mais comme il est basé sur llvm, il devrait être très convivial en théorie. Je vous remercie!
Autant que je sache, il n’existe aucune option de ligne de commande permettant de répertorier les architectures prises en charge par un binaire clang
donné, et même l’exécution de strings
n’aide en rien. Clang est essentiellement un traducteur C vers LLVM, et c'est LLVM lui-même qui traite de la complexité de la génération de code machine réel. Il n'est donc pas surprenant que Clang ne prête pas beaucoup d'attention à l'architecture sous-jacente.
Comme d'autres l'ont déjà noté, vous pouvez demander à llc
quelles architectures sont supportées. Ce n’est pas très utile non seulement parce que ces composants LLVM pourraient ne pas être installés, mais à cause des aléas des chemins de recherche et des systèmes de packaging, vos binaires llc
et clang
pourraient ne pas correspondre à la même version de LLVM.
Toutefois, à titre d’argumentation, supposons que vous ayez vous-même compilé LLVM et Clang ou que vous soyez autrement heureux d’accepter vos fichiers binaires LLVM comme suffisants:
llc --version
Donnera une liste de toutes les architectures qu'il supporte. Par défaut, il est compilé pour prendre en charge toutes les architectures. Ce que vous pouvez considérer comme une architecture unique telle que ARM peut avoir plusieurs architectures LLVM telles que ARM, Thumb et AArch64 standard. Ceci est principalement destiné à faciliter la mise en œuvre car les différents modes d'exécution ont des instructions très différentes codages et sémantique.llc -march=Arch -mattr=help
Listera les "CPU disponibles" et les "fonctionnalités disponibles". Les processeurs ne constituent généralement qu'un moyen pratique de définir une collection de fonctionnalités par défaut.Mais maintenant pour les mauvaises nouvelles. Il n’existe aucune table commode de triplets dans Clang ou LLVM pouvant être vidés, car les serveurs spécifiques à l’architecture ont la possibilité d’analyser la chaîne triple en un objet llvm::Triple
(Défini dans include/llvm/ADT/Triple.h ). En d'autres termes, vider tous les triples disponibles nécessite de résoudre le problème Halting. Voir, par exemple, llvm::ARM_MC::ParseARMTriple(...)
quels cas particuliers analysent la chaîne "generic"
.
En fin de compte, cependant, le "triple" est principalement une fonctionnalité de compatibilité ascendante permettant de faire de Clang un remplaçant instantané de GCC. Vous n'avez donc généralement pas besoin de faire très attention à cela sauf si vous portez Clang ou LLVM sur une nouvelle plate-forme. ou de l'architecture. Au lieu de cela, vous constaterez probablement que la sortie de llc -march=arm -mattr=help
Est ahurissante et que le nombre impressionnant de fonctions ARM) est plus utile dans vos enquêtes.
Bonne chance dans vos recherches!
J'utilise Clang 3.3, je pense que le meilleur moyen d'obtenir la réponse est de lire le code source. dans llvm/ADT/Triple.h ( http://llvm.org/doxygen/Triple_8h_source.html ):
enum ArchType {
UnknownArch,
arm, // ARM: arm, armv.*, xscale
aarch64, // AArch64: aarch64
hexagon, // Hexagon: hexagon
mips, // MIPS: mips, mipsallegrex
mipsel, // MIPSEL: mipsel, mipsallegrexel
mips64, // MIPS64: mips64
mips64el,// MIPS64EL: mips64el
msp430, // MSP430: msp430
ppc, // PPC: powerpc
ppc64, // PPC64: powerpc64, ppu
r600, // R600: AMD GPUs HD2XXX - HD6XXX
sparc, // Sparc: sparc
sparcv9, // Sparcv9: Sparcv9
systemz, // SystemZ: s390x
tce, // TCE (http://tce.cs.tut.fi/): tce
thumb, // Thumb: thumb, thumbv.*
x86, // X86: i[3-9]86
x86_64, // X86-64: AMD64, x86_64
xcore, // XCore: xcore
mblaze, // MBlaze: mblaze
nvptx, // NVPTX: 32-bit
nvptx64, // NVPTX: 64-bit
le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
amdil, // amdil: AMD IL
spir, // SPIR: standard portable IR for OpenCL 32-bit version
spir64 // SPIR: standard portable IR for OpenCL 64-bit version
};
et dans clang/lib/Driver/ToolChains.cpp, il est question de bras.
static const char *GetArmArchForMArch(StringRef Value) {
return llvm::StringSwitch<const char*>(Value)
.Case("armv6k", "armv6")
.Case("armv6m", "armv6m")
.Case("armv5tej", "armv5")
.Case("xscale", "xscale")
.Case("armv4t", "armv4t")
.Case("armv7", "armv7")
.Cases("armv7a", "armv7-a", "armv7")
.Cases("armv7r", "armv7-r", "armv7")
.Cases("armv7em", "armv7e-m", "armv7em")
.Cases("armv7f", "armv7-f", "armv7f")
.Cases("armv7k", "armv7-k", "armv7k")
.Cases("armv7m", "armv7-m", "armv7m")
.Cases("armv7s", "armv7-s", "armv7s")
.Default(0);
}
static const char *GetArmArchForMCpu(StringRef Value) {
return llvm::StringSwitch<const char *>(Value)
.Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "arm926ej-s","armv5")
.Cases("arm10e", "arm10tdmi", "armv5")
.Cases("arm1020t", "arm1020e", "arm1022e", "arm1026ej-s", "armv5")
.Case("xscale", "xscale")
.Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "arm1176jzf-s", "armv6")
.Case("cortex-m0", "armv6m")
.Cases("cortex-a8", "cortex-r4", "cortex-a9", "cortex-a15", "armv7")
.Case("cortex-a9-mp", "armv7f")
.Case("cortex-m3", "armv7m")
.Case("cortex-m4", "armv7em")
.Case("Swift", "armv7s")
.Default(0);
}
Un conseil que vous pouvez faire: si vous essayez de trouver un triple cible particulier, vous devez installer llvm sur ce système puis effectuez une
$ llc --version | grep Default
Default target: x86_64-Apple-darwin16.1.0
ou bien:
$ llvm-config --Host-target
x86_64-Apple-darwin16.0.0
or
$ clang -v 2>&1 | grep Target
Target: x86_64-Apple-darwin16.1.0
Ensuite, vous savez quand même comment le cibler lors de la compilation croisée.
Apparemment, il y a "beaucoup" de cibles, voici une liste, n'hésitez pas à ajouter du style wiki à la communauté:
arm-none-eabi
armv7a-none-eabi
arm-linux-gnueabihf
arm-none-linux-gnueabi
i386-pc-linux-gnu
x86_64-Apple-darwin10
i686-w64-windows-gnu # same as i686-w64-mingw32
x86_64-pc-linux-gnu # from ubuntu 64 bit
x86_64-unknown-windows-cygnus # cygwin 64-bit
x86_64-w64-windows-gnu # same as x86_64-w64-mingw32
i686-pc-windows-gnu # MSVC
x86_64-pc-windows-gnu # MSVC 64-BIT
Voici ce que la liste docs est quand même (apparemment c'est un quadruple [ou quintuple?] Au lieu d'un triple ces jours-ci):
The triple has the general format <Arch><sub>-<vendor>-<sys>-<abi>, where:
Arch = x86, arm, thumb, mips, etc.
sub = for ex. on ARM: v5, v6m, v7a, v7m, etc.
vendor = pc, Apple, nvidia, ibm, etc.
sys = none, linux, win32, darwin, cuda, etc.
abi = eabi, gnu, Android, macho, elf, etc.
et vous pouvez même affiner spécifier un cpu cible au-delà, même s’il utilise une valeur par défaut raisonnable pour le cpu cible basé sur le triple.
Parfois, les cibles "se résolvent" à la même chose, donc pour voir en quoi une cible est réellement traitée:
$ clang -target x86_64-w64-mingw32 -v 2>&1 | grep Target
Target: x86_64-w64-windows-gnu
Selon Jonathan Roelofs dans cette conférence "Quelles cibles est-ce que Clang soutient?" :
$ llc --version
LLVM (http://llvm.org/):
LLVM version 3.6.0
Optimized build with assertions.
Built Apr 2 2015 (01:25:22).
Default target: x86_64-Apple-darwin12.6.0
Host CPU: corei7-avx
Registered Targets:
aarch64 - AArch64 (little endian)
aarch64_be - AArch64 (big endian)
amdgcn - AMD GCN GPUs
arm - ARM
arm64 - ARM64 (little endian)
armeb - ARM (big endian)
cpp - C++ backend
hexagon - Hexagon
mips - Mips
mips64 - Mips64 [experimental]
mips64el - Mips64el [experimental]
mipsel - Mipsel
msp430 - MSP430 [experimental]
nvptx - NVIDIA PTX 32-bit
nvptx64 - NVIDIA PTX 64-bit
ppc32 - PowerPC 32
ppc64 - PowerPC 64
ppc64le - PowerPC 64 LE
r600 - AMD GPUs HD2XXX-HD6XXX
sparc - Sparc
sparcv9 - Sparc V9
systemz - SystemZ
thumb - Thumb
thumbeb - Thumb (big endian)
x86 - 32-bit X86: Pentium-Pro and above
x86-64 - 64-bit X86: EM64T and AMD64
xcore - XCore
Les versions futures de Clang peuvent fournir les éléments suivants. Ils sont répertoriés comme "proposés" bien qu'ils ne soient pas encore disponibles au moins à partir de la version 3.9.0:
$ clang -target <target_from_list_above> --print-multi-libs
$ clang -print-supported-archs
$ clang -march x86 -print-supported-systems
$ clang -march x86 -print-available-systems
Essayez aussi
> llc -mattr=help
Available CPUs for this target:
amdfam10 - Select the amdfam10 processor.
athlon - Select the athlon processor.
athlon-4 - Select the athlon-4 processor.
athlon-fx - Select the athlon-fx processor.
athlon-mp - Select the athlon-mp processor.
athlon-tbird - Select the athlon-tbird processor.
athlon-xp - Select the athlon-xp processor.
athlon64 - Select the athlon64 processor.
athlon64-sse3 - Select the athlon64-sse3 processor.
atom - Select the atom processor.
...
Available features for this target:
16bit-mode - 16-bit mode (i8086).
32bit-mode - 32-bit mode (80386).
3dnow - Enable 3DNow! instructions.
3dnowa - Enable 3DNow! Athlon instructions.
64bit - Support 64-bit instructions.
64bit-mode - 64-bit mode (x86_64).
adx - Support ADX instructions.
...
Il ne listera pas tous les triples, mais
llvm-as < /dev/null | llc -mcpu=help
listera au moins tous les processeurs.