Cross-compiling Clang/LLVM
By cross-compiling we mean building a binary on one platform (for example, x86) that will be run on another platform (for example, ARM). The machine on which we build the binary is called the host, and the machine on which the generated binary will run is called the target. The compiler that builds code for the same platform on which it is running (the host and target platforms are the same) is called a native assembler, whereas the compiler that builds code for a target platform different from the host platform is called a cross-compiler.
In this recipe, cross-compilation of LLVM for a platform different than the host platform will be shown, so that you can use the built binaries for the required target platform. Here, cross-compiling will be shown using an example where cross-compilation from host platform x86_64 for target platform ARM will be done. The binaries thus generated can be used on a platform with ARM architecture.
Getting ready
The following packages need to be installed on your system (host platform):
cmake
ninja-build
(from backports in Ubuntu)gcc-4.x-arm-linux-gnueabihf
gcc-4.x-multilib-arm-linux-gnueabihf
binutils-arm-linux-gnueabihf
libgcc1-armhf-cross
libsfgcc1-armhf-cross
libstdc++6-armhf-cross
libstdc++6-4.x-dev-armhf-cross
install llvm on your host platform
How to do it...
To compile for the ARM target from the host architecture, that is X86_64 here, you need to perform the following steps:
- Add the following
cmake
flags to the normalcmake
build for LLVM:-DCMAKE_CROSSCOMPILING=True -DCMAKE_INSTALL_PREFIX= path-where-you-want-the-toolchain(optional) -DLLVM_TABLEGEN=<path-to-host-installed-llvm-toolchain-bin>/llvm-tblgen -DCLANG_TABLEGEN=< path-to-host-installed-llvm-toolchain-bin >/clang-tblgen -DLLVM_DEFAULT_TARGET_TRIPLE=arm-linux-gnueabihf -DLLVM_TARGET_ARCH=ARM -DLLVM_TARGETS_TO_BUILD=ARM -DCMAKE_CXX_FLAGS='-target armv7a-linux-gnueabihf -mcpu=cortex-a9 -I/usr/arm-linux-gnueabihf/include/c++/4.x.x/arm-linux-gnueabihf/ -I/usr/arm-linux-gnueabihf/include/ -mfloat-abi=hard -ccc-gcc-name arm-linux-gnueabihf-gcc'
- If using your platform compiler, run:
$ cmake -G Ninja <llvm-source-dir> <options above>
If using Clang as the cross-compiler, run:
$ CC='clang' CXX='clang++' cmake -G Ninja <source-dir> <options above>
If you have clang/Clang++ on the path, it should work fine.
- To build LLVM, simply type:
$ ninja
- After the LLVM/Clang has built successfully, install it with the following command:
$ ninja install
This will create a sysroot
on the install-dir
location if you have specified the DCMAKE_INSTALL_PREFIX
options
How it works...
The cmake
package builds the toolchain for the required platform by making the use of option flags passed to cmake
, and the tblgen
tools are used to translate the target description files into C++ code. Thus, by using it, the information about targets is obtained, for example—what instructions are available on the target, the number of registers, and so on.
Note
If Clang is used as the cross-compiler, there is a problem in the LLVM ARM backend that produces absolute relocations on position-independent code (PIC), so as a workaround, disable PIC at the moment.
The ARM libraries will not be available on the host system. So, either download a copy of them or build them on your system.