web-dev-qa-db-fra.com

clang: comment lister les architectures cibles supportées?

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!

75
exebook

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.
  • Pour chacune des architectures listées, 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!

40
pndc

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);
}
30
a'Q

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
15
rogerdpack

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 
10
jww

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.
  ...
5
Zinovy Nis

Il ne listera pas tous les triples, mais

llvm-as < /dev/null | llc -mcpu=help

listera au moins tous les processeurs.

1
bcmills