Arm GNU Toolchain is the GNU Toolchain for the Arm Architecture released by Arm and traditionally used for embedded development.
Generally the LLVM Embedded toolchain tries to be a drop in replacement for the GNU toolchain, however there may be some missing features or small incompatibilities.
Some known differences and migration strategies are summarized below.
Using multiple toolchains to build a project benefits from different checks and warnings present in different compilers to catch more issues, particularly C and C++ standards compliance, during build time.
LLVM Embedded Toolchain provides support for multiple sanitizers and memory safety features to also catch typical issues at runtime during testing, see the Clang documentation and samples.
LLVM Embedded Toolchain provides superior performance when targeting the Armv8-M or later architecture, including the Arm Helium Technology (M-Profile Vector Extension, MVE).
Component | GNU toolchain (arm-none-eabi- ) |
LLVM toolchain |
---|---|---|
C, C++ compiler | gcc , g++ |
clang , clang++ |
Assembler | as |
clang integrated assembler |
Linker | ld |
lld |
Binutils | objdump , readelf , ... |
llvm-objdump , llvm-readelf , ... |
Compiler runtime library | libgcc |
compiler-rt |
Unwinder | libgcc |
libunwind |
C standard library | newlib , newlib-nano |
picolibc |
C++ ABI library | libsupc++.a |
libc++abi |
C++ standard library | libstdc++ |
libc++ |
Toolchain version macros:
Version number | GNU macro | LLVM macro |
---|---|---|
Major | __GNUC__ |
__clang_major__ |
Minor | __GNUC_MINOR__ |
__clang_minor__ |
Patch level | __GNUC_PATCHLEVEL__ |
__clang_patchlevel__ |
Note that clang
defines GNU macros for compatibility too:
__GNUC__
equal to 4
, __GNUC_MINOR__
equal to 2
,
and __GNUC_PATCHLEVEL__
equal to 1
.
Clang supports the majority of GNU C and C++ extensions as described in Clang Language Extensions.
The following feature checking macros can be used to test whether a particular feature is supported:
clang
should be used instead of arm-none-eabi-as
to compile assembly
(.s
and .S
) files.
There are minor differences in the assembly syntax between GNU and LLVM compilers, however most of the time it is possible to write code that is accepted by both.
For example, GNU and LLVM compilers differ in:
- Use of
.N
and.W
suffixes for Thumb instructions. - Use of
S
suffix for flag setting instructions.
LLVM toolchain provides multilib support similar to the GNU toolchain, see Using the toolchain section in the README, however uses different command line options to control selection of semihosting.
Use case | GNU options | LLVM options |
---|---|---|
No semihosting | --specs=nosys.specs |
-lcrt0 |
Semihosting | --specs=rdimon.specs |
-lcrt0-semihost -lsemihost |
Newlib-nano | --specs=nano.specs |
Not available: picolibc is an equivalent of newlib-nano . |
lld
is designed as a drop in replacement for GNU ld
,
however there are some known differences to take into account, see:
- Linker Script implementation notes and policy in the LLD documentation.
- The LLD and GNU linker incompatibilities blog post.
Refer to Using Picolibc in Embedded Systems
for the details of how picolibc
handles initialization.
By default, picolibc
provides an interrupt vector table. To replace it,
the application interrupt vector table should be placed into the init
linker script
section and referenced by the __interrupt_vector
symbol.
See Picolibc and Operating Systems
for the details on redirecting stdin
, stdout
and stderr
.
The baremetal-uart
sample
provides a basic code example for redirecting stdout
.