clang : 지원되는 대상 아키텍처를 나열하는 방법은 무엇입니까?


97

현재 저는 ARM, 특히 아이폰 / 안드로이드 타겟에 관심이 있습니다. 그러나 나는 clang에 대해 더 많이 알고 싶습니다. 앞으로 몇 년 동안 중요한 역할을 할 것 같기 때문입니다.

나는 시도했다

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)

clang에 -triplet 매개 변수가 있다는 것을 알고 있지만 가능한 모든 값을 나열하려면 어떻게해야합니까? 나는 clang이 크로스 컴파일과 관련하여 gcc와 매우 다르다는 것을 발견했습니다. GCC 세계에서는 PLATFORM_make 또는 PLATFORM_ld (i * 86-pc-cygwin i * 86-*-linux-gnu 등)와 같은 모든 것에 대해 별도의 바이너리가 있어야합니다. http : //git.savannah.gnu.org/cgit/libtool.git/tree/doc/PLATFORMS )

clang 세계에서는 (일부 포럼에서 읽은 것처럼) 단 하나의 바이너리입니다. 하지만 지원되는 대상 목록은 어떻게 얻습니까? 그리고 내 대상이 내 배포판 (linux / windows / macos / whatever)에서 지원되지 않는 경우 더 많은 플랫폼을 지원하는 대상을 어떻게 얻을 수 있습니까?

다음과 같이 최신 clang을 SVN하면

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

대부분의 플랫폼을 얻을 수 있습니까? Clang이 바로 크로스 컴파일을 염두에두고 빌드되지 않은 것처럼 보이지만 llvm 기반이기 때문에 이론상 매우 크로스 친화적이어야합니까? 감사합니다!


8
하지 완전한 대답하지만, LLC --version 당신에게 목표를 줄 것이다
old_timer

1
트리플을 보려면 소스를 봐야한다고 생각합니다. 그리고 내가 이해하는대로 clang의 기본 빌드에는 크로스 컴파일에 대한 기본 지원이 포함됩니다. 기본 지원은 코드를 객체 파일로만 변환합니다 (통합 어셈블러가 트리플을 지원하는 한, 그렇지 않으면 .s 파일을 가져와야합니다). 헤더, 라이브러리, 링커 (어쨌든 작동 할 때까지) 등을 제공해야합니다.
bames53

1
기본 설치에는 clang 및 clang ++ 실행 파일 만 있지만 다른 플랫폼과 마찬가지로 이름에 인코딩 된 트리플 및 쿼드를 사용하여 복사본이나 하드 링크를 만들 수 있습니다. clang ++ 및 clang은 실제로 서로의 복사본 일 뿐이며 실행 파일의 이름을 확인하여 입력을 처리하는 방법을 확인합니다.
LB-- 2013-06-06

답변:


55

내가 말할 수있는 한, 주어진 clang바이너리가 지원 하는 아키텍처를 나열하는 명령 줄 옵션이 없으며 심지어 실행 strings하는 것도 실제로 도움이되지 않습니다. Clang은 본질적으로 C to LLVM 번역기이며 실제 기계 코드 생성의 핵심을 다루는 것은 LLVM 자체이므로 Clang이 기본 아키텍처에 많은 관심을 기울이지 않는다는 것이 전혀 놀라운 일이 아닙니다.

다른 사람들이 이미 언급했듯이 llc지원하는 아키텍처를 물어볼 수 있습니다 . 이것은 이러한 LLVM 구성 요소가 설치되지 않았기 때문이 아니라 검색 경로 및 패키징 시스템의 변동으로 인해 사용자 llcclang바이너리가 동일한 버전의 LLVM에 해당하지 않을 수 있습니다.

그러나 논쟁을 위해 LLVM과 Clang을 모두 직접 컴파일했거나 LLVM 바이너리를 충분히 만족스럽게 받아 들였다고 가정 해 보겠습니다.

  • llc --version지원하는 모든 아키텍처 목록을 제공합니다. 기본적으로 모든 아키텍처를 지원하도록 컴파일됩니다. ARM과 같은 단일 아키텍처로 생각할 수있는 것은 일반 ARM, Thumb 및 AArch64와 같은 여러 LLVM 아키텍처가있을 수 있습니다. 다른 실행 모드는 명령어 인코딩과 의미가 매우 다르기 때문에 이는 주로 구현 편의를위한 것입니다.
  • 나열된 각 아키텍처에 대해 llc -march=ARCH -mattr=help"사용 가능한 CPU"및 "사용 가능한 기능"이 나열 됩니다. CPU는 일반적으로 기본 기능 모음을 설정하는 편리한 방법입니다.

하지만 지금은 나쁜 소식입니다. Clang 또는 LLVM에는 덤프 할 수있는 편리한 트리플 테이블이 없습니다. 아키텍처 별 백엔드에는 트리플 문자열을 llvm::Triple객체 로 구문 분석하는 옵션이 있기 때문입니다 ( include / llvm / ADT / Triple.h에 정의 ). 즉, 사용 가능한 모든 트리플을 덤프하려면 중지 문제를 해결해야합니다. 예를 들어 llvm::ARM_MC::ParseARMTriple(...)문자열을 구문 분석하는 특수 사례 를 참조하십시오 "generic".

하지만 궁극적으로 "트리플"은 대부분 Clang을 GCC의 드롭 인 대체품으로 만드는 이전 버전과의 호환성 기능이므로 Clang 또는 LLVM을 새 플랫폼으로 이식하지 않는 한 일반적으로 많은주의를 기울일 필요가 없습니다. 또는 건축. 대신, llc -march=arm -mattr=help조사에 더 유용 할 수있는 다양한 ARM 기능의 방대한 배열에서 출력을 찾을 수있을 것입니다 .

연구에 행운을 빕니다!


34

저는 Clang 3.3을 사용하고 있습니다. 답을 얻는 가장 좋은 방법은 소스 코드를 읽는 것입니다. 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
  };

clang / lib / Driver / ToolChains.cpp에는 arm에 대한 sth가 있습니다.

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);
}

5
트리플의 두 번째와 세 번째 부분은 어떻습니까?
osgx 2014

그리고 ArchType에 대한 Arch 이름의 실제 파서는 code.metager.de/source/xref/llvm/llvm/lib/Support/…에 있습니다. -llvm / lib / Support / Triple.cpp 함수 static Triple::ArchType parseArch(StringRef ArchName)
osgx

clang 바이너리를 사용할 수 있다고해서 사용자가 소스에서 컴파일 한 것은 아닙니다.
Colin LeMahieu

clang의 타겟 및 트리플에 대한 몇 가지 설명 : llvm.org/devmtg/2014-04/PDFs/LightningTalks/… , 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 "및 clang.llvm.org /UniversalDriver.html
osgx

19

할 수있는 한 가지 힌트 : 특정 타겟 트리플을 찾으려고하는 경우 해당 시스템에 llvm을 설치 한 다음

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

또는 대안으로 :

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

그러면 어쨌든 크로스 컴파일 할 때 대상을 지정하는 방법을 알고 있습니다.

분명히 거기에는 "많은"대상이 있습니다. 여기에 목록이 있습니다. 자유롭게 추가 할 수 있습니다. 커뮤니티 위키 스타일 :

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

어쨌든 문서 목록 은 다음과 같습니다 (요즘에는 3 배가 아닌 4 배 [또는 5 배?]).

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.

트리플을 기반으로 대상 CPU에 대해 합리적인 기본값을 사용하지만이 이상의 대상 CPU를 미세 조정할 수도 있습니다.

때때로 대상은 동일한 대상으로 "해결"하여 대상이 실제로 무엇으로 취급되는지 확인합니다.

 $ clang -target x86_64-w64-mingw32 -v 2>&1 | grep Target
 Target: x86_64-w64-windows-gnu

라고 할 때 mingw32그것은 MinGW64 작동하지 않습니다 의미합니까? MSVC와 호환되는 것이 있습니까?
Royi

@Royi stackoverflow.com/q/39871656/32453 이 유용 할 수 있습니다. 행운을 빕니다!
rogerdpack

12

이 강연에서 Jonathan Roelofs에 따르면 "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

향후 버전의 Clang은 다음을 제공 할 수 있습니다. 적어도 v 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 

최신 Clang 버전에서 작동하지 않는 것 같습니다.
Royi

5

또한 시도

> 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.
  ...

6
clang을 사용할 수 있다고해서 llc를 사용할 수 있다는 의미는 아닙니다.
Colin LeMahieu

1
llc는 일반적으로 clang과 함께 설치되는 것처럼 보이지만 ... 패키지 관리자가 아닌 경우 설치할 수 있으며 정렬해야합니다.하지만이 목록은 특정 CPU, 반드시 다른 "트리플"아키텍처, 영업 이익은 원하는대로 ...
rogerdpack

5
다른 아키텍처에 대한 옵션을 나열하려면 -mtriple에서와 같이 옵션을 사용할 수 있습니다 llc -mtriple=arm -mattr=help.
Lekensteyn

3

Clang 11 (트렁크)을 시작하면 새로 추가 된 -print-targets플래그를 사용하여 지원되는 대상 아키텍처 목록을 간편하게 인쇄 할 수 있습니다 .

$ 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

참조 : LLVM PR , LLVM commit , Clang 11 documentation .


2

모든 트리플을 나열하지는 않지만

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

최소한 모든 CPU를 나열합니다.


1
현재 (기본) 대상에 적용 할 수있는 옵션 만 나열됩니다.
osgx

0

소스에서 LLVM 또는 Clang을 빌드하는 데 지원되는 대상 (의 값 -DLLVM_TARGETS_TO_BUILD)에 관심이있는 경우 다음에서 하위 디렉터리 목록을 찾습니다.llvm/lib/Target 소스 배포의 폴더에서 . 9.0.1부터는 다음이 있습니다.

AArch64
AMDGPU
ARC
ARM
AVR
BPF
Hexagon
Lanai
MSP430
Mips
NVPTX
PowerPC
RISCV
Sparc
SystemZ
WebAssembly
X86
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.