Keywords: Clang | target architecture | cross-compilation
Abstract: This article explores methods for listing supported target architectures in the Clang compiler, focusing on the -print-targets flag introduced in Clang 11, which provides a convenient way to output all registered targets. It analyzes the limitations of traditional approaches such as using llc --version and explains the role of target triples in Clang and their relationship with LLVM backends. By comparing insights from various answers, the article also discusses Clang's cross-platform nature, how to obtain architecture support lists, and practical applications in cross-compilation. The content covers technical details, useful commands, and background knowledge, aiming to offer comprehensive guidance for developers.
Evolution and Query Methods for Target Architecture Support in Clang
In the Clang compiler ecosystem, querying supported target architectures has been a common yet challenging task. Traditionally, developers relied on the -triple parameter to specify target platforms, such as i686-apple-darwin9, but there was no direct command-line support to list all possible triple values. This reflects differences in cross-compilation design between Clang and GCC: GCC typically requires separate binaries for different platforms, while Clang, as a single binary, depends more on the underlying LLVM framework for architecture support.
Limitations of Traditional Methods
Early methods, like running clang -cc1 --help and filtering relevant options, often provided limited information. For example, -triple <value> only hints at the parameter's existence without listing specific values. Deeper attempts involved using llc --version to obtain architecture lists supported by LLVM backends, but this faced issues with version mismatches and installation dependencies. As noted in Answer 1, Clang is essentially a C-to-LLVM translator, with machine code generation handled by LLVM, so Clang itself does not directly maintain a complete architecture list. Moreover, triple parsing is scattered across LLVM backend code (e.g., llvm::ARM_MC::ParseARMTriple), making dynamic enumeration of all possible values complex, even analogized to the "Halting Problem."
Breakthrough in Clang 11: The -print-targets Flag
Clang 11 (trunk version) introduced the -print-targets flag, greatly simplifying this process. Running clang -print-targets outputs all registered target architectures, for example:
$ clang -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
This list covers a wide range of targets from traditional architectures like ARM and x86 to emerging platforms like WebAssembly, including variants such as different endianness (e.g., aarch64_be) and specific modes (e.g., thumb). This feature was implemented via LLVM PR D79565, marking a significant improvement in Clang's user experience.
Nature of Triples and Cross-Platform Support
Target triples (or quadruples/quintuples) follow the format <arch><sub>-<vendor>-<sys>-<abi>, e.g., x86_64-apple-darwin16.1.0. As described in Answer 4, this includes architecture (e.g., arm), sub-architecture (e.g., v7a), vendor (e.g., apple), system (e.g., linux), and ABI (e.g., gnu). Clang's single-binary design benefits from LLVM's modular backends, theoretically supporting highly cross-platform compilation, but actual support depends on build-time configuration. Fetching the latest Clang source via SVN (e.g., svn co http://llvm.org/svn/llvm-project/cfe/trunk clang) typically includes most platforms, but custom builds may be needed to enable specific targets.
Practical Commands and Supplementary Methods
In addition to -print-targets, other commands can assist in queries:
llc --version: Lists architectures supported by LLVM backends, but ensure version alignment with Clang.clang -v 2>&1 | grep Target: Displays the current default target, e.g.,Target: x86_64-apple-darwin16.1.0.llvm-config --host-target: Retrieves the host target triple.- For detailed features of specific architectures, use
llc -march=arm -mattr=helpto list available CPUs and features.
Answer 3 provides an underlying perspective through source code analysis (e.g., the ArchType enum in llvm/ADT/Triple.h), while Answer 5 mentions future possible commands like clang -print-supported-archs, which are not yet implemented.
Conclusion and Best Practices
For modern Clang users, -print-targets is the preferred method for querying supported architectures, offering clear and direct output. In cross-compilation scenarios, developers should combine target triples with architecture-specific options (e.g., -march and -mattr) for fine-grained control. Although Clang's LLVM-based design is theoretically cross-platform friendly, practical deployment requires attention to version compatibility and build configuration. As Clang continues to evolve, its toolchain is becoming more user-friendly, supporting a broader hardware and software ecosystem.