LLVM Embedded Toolchain for Arm
This repository contains build scripts and auxiliary material for building a bare-metal LLVM based toolchain targeting Arm based on:
- clang + llvm
The goal is to provide an LLVM based bare-metal toolchain that can target the Arm architecture family from Armv6-M and newer. The toolchain follows the ABI for the Arm Architecture and attempts to provide typical features needed for embedded and realtime operating systems.
- Armv8-M Mainline
- Armv8.1-M Mainline
- AArch64 armv8.0 (experimental)
The LLVM Embedded Toolchain for Arm relies on the following upstream components
C++ is partially supported with the use of libc++ and libc++abi from LLVM. Features that are not supported include:
- Locales and input/output streams
- C++17's aligned operator new
Content of this repository is licensed under Apache-2.0. See
The resulting binaries are covered under their respective open source licenses, see component links above.
In addition, if the toolchain is cross-compiled to run on Windows (see
Cross-compiling the toolchain for Windows
for details) several Mingw-w64 runtime libraries residing on your machine
may be copied to the
bin directory of the toolchain and included in the
.tar.gz archive if you choose to do so.
The following three libraries are used:
The libraries are covered under their respective open source licenses.
Contributions and Pull Requests
Contributions are accepted under Apache-2.0. Only submit contributions where you have authored all of the code.
The project uses the PEP 8 style guide for all Python scripts. The scripts also must pass pylint and flake8 checks as well as type-checking with mypy.
Use the following commands to check the scripts before submitting a pull request:
$ ./setup.sh $ ./run-precommit-checks.sh
How to provide feedback/report an issue
Please raise an issue via https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/issues
The LLVM Embedded Toolchain for Arm has been built and tested on Linux/Ubuntu 18.04.5 LTS.
Build the toolchain
- a suitable compiler toolchain:
- Clang 6.0.0 or above, or
- GCC 5.1.0 or above
- CMake 3.13.4 or above
- Python version 3.6 or above and python3-venv
- GNU Make
- Install typically missing packages. There might be others depending on your setup.
# apt-get install clang # If the Clang version installed by the package manager is older than 6.0.0, download a recent version from https://releases.llvm.org or build from source # apt-get install python3 # apt-get install python3-venv # apt-get install git # apt-get install make # apt-get install cmake # If the CMake version installed by the package manager is older than 3.13.4, download a recent version from https://cmake.org/download and add it to PATH
- Install the build scripts in a python virtual env (in directory
- Activate the virtual environment:
$ . ./venv/bin/activate
- Build the toolchain with:
The script supports various command line options. To get a description of all options run:
$ build.py -h
Some notable options include:
--revisionthe LLVM Embedded Toolchain for Arm version. Default version is
13.0.0. The available versions are:
13.0.0- based on LLVM 13.0.0 and newlib 4.1.0
branch-13- based on the tip of the LLVM 13 branch and newlib 4.1.0
HEAD- based on the latest commits in the LLVM and newlib repositories
--host-toolchainthe toolchain type. The supported values are:
clangClang (the default)
mingwMingw-w64 (used for cross-compilation, see Cross-compiling the toolchain for Windows)
--host-toolchain-dirthe directory from Step 0 that the toolchain resides in. Default is
--install-dirthe LLVM Embedded Toolchain for Arm installation directory. Default is
The build script can optionally take advantage of some tools to speed up the
build. Currently, these tools are
$ build.py --use-ccache --use-ninja
- By now, you should have a working toolchain in directory
Use the toolchain
Once built, you can use the generated config files to configure the compiler
correctly. The available config files can be listed with
$ PATH=<install-dir>/LLVMEmbeddedToolchainForArm-<revision>/bin:$PATH $ clang --config armv6m_soft_nofp_rdimon -o example example.c
Note that configurations under the
require the linker script to be specified with
$ PATH=<install-dir>/LLVMEmbeddedToolchainForArm-<revision>/bin:$PATH $ clang --config armv6m_soft_nofp_nosys -T device.ld -o example example.c
Test the toolchain
Once the toolchain is built, you can build smoke tests:
$ build.py test
If QEMU is installed and present in your system path, these tests will also be run.
Furthermore, see the
samples folder for sample code and instructions on
building, running and debugging.
Cross-compiling the toolchain for Windows
The LLVM Embedded Toolchain for Arm can be cross-compiled to run on Windows. The compilation itself still happens on Linux. In addition to the prerequisites mentioned in the Build the toolchain section you will also need a Mingw-w64 toolchain based on GCC 5.1.0 or above installed. For example, to install it on Ubuntu Linux use the following command:
# apt-get install mingw-w64
build.py to build the toolchain:
$ build.py --host-toolchain mingw
Cross-compilation still requires a native toolchain, i.e. a compiler toolchain that produces binaries that run on the build machine. The native toolchain can be specified using the following options:
--native-toolchainthe toolchain type. Either
gcc. Default is
--native-toolchain-dirthe directory that the toolchain resides in. Default is
$ build.py --host-toolchain mingw \ --native-toolchain gcc \ --native-toolchain-dir /opt/gcc-latest/bin
The script will prompt you whether it should copy the Mingw-w64 runtime
libraries from your local machine to the toolchain
bin directory. The
libraries are distributed under their own licenses, this needs to
be taken into consideration if you decide to redistribute the built toolchain.
To avoid an interactive prompt use the
--copy-runtime-dlls command line
option, for example:
$ build.py --host-toolchain mingw --copy-runtime-dlls no
- Depending on the state of the components, build errors may occur when
--revision HEADis used.
Divergences from upstream
- Clang does not support the
nakedattribute on C functions, breaking the Linux startup (out of scope).
- Target triple ending with eabi is not considered an ELF target.
- Recognize [email protected] in a config file argument to mean the directory of the config file, allowing toolchain relative paths.