clang: ¿cómo enumerar las arquitecturas de destino compatibles?

98

Actualmente estoy interesado en ARM en general y específicamente en los objetivos de iPhone / Android. Pero solo quiero saber más sobre clang, ya que parece que jugará un papel importante en los próximos años.

Lo intenté

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)

Sé que clang tiene el parámetro -triplet, pero ¿cómo puedo enumerar todos los valores posibles para él? Descubrí que clang es muy diferente a gcc con respecto a la compilación cruzada, en el mundo de GCC deberías tener binarios separados para todo, como PLATFORM_make o PLATFORM_ld (i * 86-pc-cygwin i * 86 - * - linux-gnu etc. http : //git.savannah.gnu.org/cgit/libtool.git/tree/doc/PLATFORMS )

en el mundo clang, es solo un binario (como leí en algunos foros). Pero, ¿cómo obtengo la lista de objetivos admitidos? Y si mi objetivo no es compatible con mi distribución (linux / windows / macos / lo que sea), ¿cómo puedo obtener el que admita más plataformas?

si el último sonido de SVN es como este:

svn co http://llvm.org/svn/llvm-project/cfe/trunk clang

¿Obtendré la mayoría de las plataformas? Parece que Clang no se creó con la compilación cruzada en mente de inmediato, pero dado que está basado en llvm, ¿debería ser muy compatible con las cruzas en teoría? ¡gracias!

exebook
fuente
8
no es una respuesta completa, pero llc
versión
1
Creo que tendrás que mirar la fuente para ver los triples. Y según tengo entendido, una versión predeterminada de clang incluirá soporte básico para la compilación cruzada. El soporte básico solo convierte el código en archivos de objeto (siempre que el ensamblador integrado admita el triple, de lo contrario, tendrá que tomar archivos .s). Tendrá que proporcionar encabezados, bibliotecas, un enlazador (hasta que lld funcione, de todos modos), etc.
bames53
1
Aunque la instalación predeterminada solo tiene ejecutables clang y clang ++, al igual que otras plataformas, puede crear copias o enlaces duros de ellos con los triples y quads codificados en los nombres. clang ++ y clang son en realidad solo copias entre sí, verifica el nombre del ejecutable para ver cómo procesar la entrada.
LB--
1
Relacionados: ¿Qué objetivos admite Clang? .
Royi

Respuestas:

57

Por lo que puedo decir, no hay una opción de línea de comandos para enumerar qué arquitecturas clangadmite un binario dado , e incluso ejecutarlo stringsno ayuda realmente. Clang es esencialmente un traductor de C a LLVM, y es LLVM en sí mismo el que se ocupa de la esencia de generar código de máquina real, por lo que no es del todo sorprendente que Clang no esté prestando mucha atención a la arquitectura subyacente.

Como ya han señalado otros, puede preguntar llcqué arquitecturas admite. Esto no es tan útil no solo porque estos componentes de LLVM pueden no estar instalados, sino debido a los caprichos de las rutas de búsqueda y los sistemas de empaquetado, es posible que sus binarios llcy clangno correspondan a la misma versión de LLVM.

Sin embargo, por el bien de la discusión, digamos que compiló LLVM y Clang usted mismo o que, por lo demás, está feliz de aceptar sus binarios LLVM como lo suficientemente buenos:

  • llc --versionle dará una lista de todas las arquitecturas que admite. De forma predeterminada, está compilado para admitir todas las arquitecturas. Lo que puede considerar como una arquitectura única, como ARM, puede tener varias arquitecturas LLVM, como ARM normal, Thumb y AArch64. Esto se debe principalmente a la conveniencia de la implementación porque los diferentes modos de ejecución tienen codificaciones de instrucción y semánticas muy diferentes.
  • Para cada una de las arquitecturas enumeradas, llc -march=ARCH -mattr=help se enumerarán "CPU disponibles" y "funciones disponibles". Las CPU generalmente son solo una forma conveniente de configurar una colección predeterminada de funciones.

Pero ahora las malas noticias. No hay una tabla conveniente de triples en Clang o LLVM que se pueda volcar, porque los backends específicos de la arquitectura tienen la opción de analizar la cadena triple en un llvm::Tripleobjeto (definido en include / llvm / ADT / Triple.h ). En otras palabras, deshacerse de todos los triples disponibles requiere resolver el problema de detención. Vea, por ejemplo, llvm::ARM_MC::ParseARMTriple(...)qué casos especiales analizan la cadena "generic".

Sin embargo, en última instancia, el "triple" es principalmente una función de compatibilidad con versiones anteriores para hacer de Clang un reemplazo directo de GCC, por lo que generalmente no necesita prestarle mucha atención a menos que esté portando Clang o LLVM a una nueva plataforma. o arquitectura. En cambio, probablemente encontrará la salida dellc -march=arm -mattr=help y la confusión de la enorme variedad de funciones ARM diferentes le serán más útiles en sus investigaciones.

¡Buena suerte con tu investigación!

pndc
fuente
35

Estoy usando Clang 3.3, creo que la mejor manera de obtener la respuesta es leyendo el código fuente. en 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
  };

y en clang / lib / Driver / ToolChains.cpp, hay algo sobre arm.

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);
}
a'Q
fuente
5
¿Qué pasa con la segunda y tercera parte del Triple?
osgx
Y el analizador real del nombre de Arch en ArchType está en code.metager.de/source/xref/llvm/llvm/lib/Support/… - llvm / lib / Support / Triple.cpp function static Triple::ArchType parseArch(StringRef ArchName)
osgx
Que el binario clang esté disponible no significa que el usuario lo haya compilado desde la fuente.
Colin LeMahieu
Algunas descripciones de los objetivos y triples de clang : llvm.org/devmtg/2014-04/PDFs/LightningTalks/… , propuesto en 2014: "Target Triple: <arch> <sub> - <vendor> - <sys> - <abi> ; --print-supported-archs --print-supported-vendors --print-supported-systems --print-supported-abis --print-multi-libs --print-available-targets "y clang.llvm.org /UniversalDriver.html
osgx
20

Una pista que puede hacer: si está tratando de encontrar un triple objetivo en particular, es instalar llvm en ese sistema y luego hacer un

$ llc --version | grep Default
  Default target: x86_64-apple-darwin16.1.0

o alternativamente:

$ llvm-config --host-target
x86_64-apple-darwin16.0.0
or
$ clang -v 2>&1 | grep Target
Target: x86_64-apple-darwin16.1.0

Entonces sabrá cómo orientarlo al realizar la compilación cruzada de todos modos.

Aparentemente, hay "muchos" objetivos por ahí, aquí hay una lista, siéntase libre de agregarla, estilo wiki comunitario:

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

Esto es lo que enumeran los documentos de todos modos (aparentemente es un cuádruple [¿o quintuple?] En lugar de un triple en estos días):

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.

e incluso puede ajustar la especificación de una cpu de destino más allá de esto, aunque utiliza un valor predeterminado sensato para la cpu de destino basado en el triple.

A veces, los objetivos "resuelven" lo mismo, por lo que para ver cómo se trata realmente a un objetivo:

 $ clang -target x86_64-w64-mingw32 -v 2>&1 | grep Target
 Target: x86_64-w64-windows-gnu
6 revoluciones
fuente
¿Cuándo se dice mingw32que significa que no funcionará con MinGW64? ¿Hay algo que sea compatible con MSVC?
Royi
@Royi stackoverflow.com/q/39871656/32453 puede ser útil, ¡buena suerte!
rogerdpack
13

Según Jonathan Roelofs en esta charla "¿Qué objetivos admite Clang?" :

$ 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

Las versiones futuras de Clang pueden proporcionar lo siguiente. Se enumeran como "propuestos", aunque aún no están disponibles al menos a partir de la versión 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 
jww
fuente
Parece que no funciona en las versiones más recientes de Clang.
Royi
6

Intenta también

> 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.
  ...
Zinovy ​​Nis
fuente
6
clang estar disponible no significa que llc esté disponible.
Colin LeMahieu
1
parece que llc se instala comúnmente junto con clang, sin embargo ... y puede instalarlo si no desde su administrador de paquetes y debería alinearse, supongo ... sin embargo, esta lista parece serlo si desea apuntar a un CPU específica, no necesariamente una arquitectura "triple" diferente, como quería el OP ...
rogerdpack
5
Para enumerar opciones para otras arquitecturas, puede usar la -mtripleopción como en llc -mtriple=arm -mattr=help.
Lekensteyn
4

A partir de Clang 11 (troncal), la lista de arquitecturas de destino admitidas podría imprimirse cómodamente utilizando la -print-targetsbandera recién agregada :

$ clang-11 -print-targets
  Registered Targets:
    aarch64    - AArch64 (little endian)
    aarch64_32 - AArch64 (little endian ILP32)
    aarch64_be - AArch64 (big endian)
    amdgcn     - AMD GCN GPUs
    arm        - ARM
    arm64      - ARM64 (little endian)
    arm64_32   - ARM64 (little endian ILP32)
    armeb      - ARM (big endian)
    avr        - Atmel AVR Microcontroller
    bpf        - BPF (host endian)
    bpfeb      - BPF (big endian)
    bpfel      - BPF (little endian)
    hexagon    - Hexagon
    lanai      - Lanai
    mips       - MIPS (32-bit big endian)
    mips64     - MIPS (64-bit big endian)
    mips64el   - MIPS (64-bit little endian)
    mipsel     - MIPS (32-bit little endian)
    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
    riscv32    - 32-bit RISC-V
    riscv64    - 64-bit RISC-V
    sparc      - Sparc
    sparcel    - Sparc LE
    sparcv9    - Sparc V9
    systemz    - SystemZ
    thumb      - Thumb
    thumbeb    - Thumb (big endian)
    wasm32     - WebAssembly 32-bit
    wasm64     - WebAssembly 64-bit
    x86        - 32-bit X86: Pentium-Pro and above
    x86-64     - 64-bit X86: EM64T and AMD64
    xcore      - XCore

Referencias: LLVM PR , LLVM commit , documentación de Clang 11 .

valiano
fuente
3

No enumerará todos los triples, pero

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

al menos enumerará todas las CPU.

bcmills
fuente
1
Esto mostrará solo las opciones que se pueden aplicar al objetivo actual (predeterminado).
osgx
1

En caso de que esté interesado en qué destinos son compatibles con la creación de LLVM o Clang desde la fuente (los valores para -DLLVM_TARGETS_TO_BUILD), busque la lista de subdirectorios en la llvm/lib/Targetcarpeta en la distribución de la fuente. A partir de la versión 9.0.1 existen:

AArch64
AMDGPU
ARC
ARM
AVR
BPF
Hexagon
Lanai
MSP430
Mips
NVPTX
PowerPC
RISCV
Sparc
SystemZ
WebAssembly
X86
scrutari
fuente