# How to Cross Compile Compiler-rt Builtins For Arm
## Introduction
This document contains information about building and testing the builtins part
of compiler-rt for an Arm target, from an x86_64 Linux machine.
While this document concentrates on Arm and Linux, the general principles should
apply to other targets supported by compiler-rt. Further contributions for other
targets are welcome.
The instructions in this document depend on libraries and programs external to
LLVM. There are many ways to install and configure these dependencies, so you
may need to adapt the instructions here to fit your own situation.
## Prerequisites
In this use case, we will be using cmake on a Debian-based Linux system,
cross-compiling from an x86_64 host to a hard-float Armv7-A target. We will be
using as many of the LLVM tools as we can, but it is possible to use GNU
equivalents.
You will need:
: - A build of LLVM for the llvm-tools and LLVM CMake files.
- A clang executable with support for the `ARM` target.
- `compiler-rt` sources.
- The `qemu-arm` user mode emulator.
- An `arm-linux-gnueabihf` sysroot.
:::{note}
An existing sysroot is required because some of the builtins include C library
headers and a sysroot is the easiest way to get those.
:::
In this example, we will be using `ninja` as the build tool.
See for information about the dependencies
on clang and LLVM.
See for information about obtaining
the source for LLVM and compiler-rt.
`qemu-arm` should be available as a package for your Linux distribution.
The most complicated of the prerequisites to satisfy is the `arm-linux-gnueabihf`
sysroot. In theory, it is possible to use the Linux distributions multiarch
support to fulfill the dependencies for building but unfortunately due to
`/usr/local/include` being added some host includes are selected.
The easiest way to supply a sysroot is to download an `arm-linux-gnueabihf`
toolchain from .
## Building compiler-rt builtins for Arm
We will be doing a standalone build of compiler-rt. The command is shown below.
Shell variables are used to simplify some of the options:
```
LLVM_TOOLCHAIN=/
TARGET_TRIPLE=arm-none-linux-gnueabihf
GCC_TOOLCHAIN=
SYSROOT=${GCC_TOOLCHAIN}/${TARGET_TRIPLE}/libc
COMPILE_FLAGS="-march=armv7-a"
cmake ../llvm-project/compiler-rt \
-G Ninja \
-DCMAKE_AR=${LLVM_TOOLCHAIN}/bin/llvm-ar \
-DCMAKE_NM=${LLVM_TOOLCHAIN}/bin/llvm-nm \
-DCMAKE_RANLIB=${LLVM_TOOLCHAIN}/bin/llvm-ranlib \
-DLLVM_CMAKE_DIR="${LLVM_TOOLCHAIN}/lib/cmake/llvm" \
-DCMAKE_SYSROOT="${SYSROOT}" \
-DCMAKE_ASM_COMPILER_TARGET="${TARGET_TRIPLE}" \
-DCMAKE_ASM_FLAGS="${COMPILE_FLAGS}" \
-DCMAKE_C_COMPILER_TARGET="${TARGET_TRIPLE}" \
-DCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN=${GCC_TOOLCHAIN} \
-DCMAKE_C_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
-DCMAKE_C_FLAGS="${COMPILE_FLAGS}" \
-DCMAKE_CXX_COMPILER_TARGET="${TARGET_TRIPLE}" \
-DCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN=${GCC_TOOLCHAIN} \
-DCMAKE_CXX_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
-DCMAKE_CXX_FLAGS="${COMPILE_FLAGS}" \
-DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" \
-DCOMPILER_RT_BUILD_BUILTINS=ON \
-DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
-DCOMPILER_RT_BUILD_MEMPROF=OFF \
-DCOMPILER_RT_BUILD_PROFILE=OFF \
-DCOMPILER_RT_BUILD_CTX_PROFILE=OFF \
-DCOMPILER_RT_BUILD_SANITIZERS=OFF \
-DCOMPILER_RT_BUILD_XRAY=OFF \
-DCOMPILER_RT_BUILD_ORC=OFF \
-DCOMPILER_RT_BUILD_CRT=OFF \
-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
-DCOMPILER_RT_EMULATOR="qemu-arm -L ${SYSROOT}" \
-DCOMPILER_RT_INCLUDE_TESTS=ON \
-DCOMPILER_RT_TEST_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
-DCOMPILER_RT_TEST_COMPILER_CFLAGS="--target=${TARGET_TRIPLE} ${COMPILE_FLAGS} --gcc-toolchain=${GCC_TOOLCHAIN} --sysroot=${SYSROOT} -fuse-ld=lld"
```
:::{note}
The command above also enables tests. Enabling tests is not required, more details
in the testing section.
:::
`CMAKE__