Cross compiling

Building Clang-based cross compiler

Understanding target triples

See “Getting Started with LLVM Core Libraries” page 203: * Build is the platform where the cross-compiler is built * Host designates the platform where the cross-compiler will run * Target refers to the platform where executables or libraries generated by the cross-compiler run GNU tools accept triples like <arch>-<sys/vendor>-<other>-<other> format, such as arm-linux-eabi, mips-liinux-gnu, x86_64-linux-gnu, and sparc-elf. Clang will internally canonicalize these triples into its own pattern <arch><sub>-<vendor>-<sys>-<abi>. See <llvm source>/include/llvm/ADT/Triple.h for triple details.

class Triple {
public:
  enum ArchType {
    UnknownArch,

    arm,            // ARM (little endian): arm, armv.*, xscale
    ppc,            // PPC: powerpc
    ppc64,          // PPC64: powerpc64, ppu
    x86,            // X86: i[3-9]86
    x86_64,         // X86-64: amd64, x86_64
...
    LastArchType = renderscript64
  };

Recipe 1

$ cd <llvm_build_dir>
$ <PATH_TO_SOURCE>/configure --enable-targets=arm --disable-optimized --prefix=/usr/local/llvm-arm --target=armv7a-unknown-linux-gnueabi
$ make && sudo make install
& export PATH=$PATH:/usr/local/llvm-arm
$armv7a-unknown-linux-gnueabi-clang sum.c -o sum
$file sum
sum: ELF 32-bit LSB executable, ARM, version 1(SYSV)

Suppos that you compile and install extra ARM libraries and headers in the /opt/arm-extra-libs/include and /opt/arm-extra-libs/libdirectories, respectively. By using–with-c-include=dirs=/opt/arm-extra-libs/include, you can permanently add this directory to the Clang header search path; it is still necessary to add-L/opt/arm-extra-libs/lib` for proper linkage.

Similarly, we can add a sysroot (--sysroot) flag and also specify the GCC toolchain with --with-gcc-toolchain to be always used by the driver.

Recipe 2

The following packages need to be installed on your system (host platform): * cmake * ninja-build * 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 * installed llvm on your host platform

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 normal cmake build for LLVM:

-DCMAKE_CROSSCOMPILING=True
-DCMAKE_INSTALL_PREFIX=<path-where you want the toolchain>
-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>
$ ninja
$ ninja install

This will create a sysroot on the install-dir location if you have specified the DCMAKE_INSTALL_PREFIX options. The cmake 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.

Dependencies

To install a GCC cross-compiler for ARM with a hard floating-point ABI, use the following command:

$ apt search arm-linux-gnueabihf
$ apt-get install g++-7-arm-linux-gnueabihf gcc-7-arm-linux-gnueabihf

To install a GCC cross-compiler for ARM with a soft floating-point ABI, use the following command:

$ apt-get install g++-7-arm-linux-gnueabi gcc-7-arm-linux-gnueabi

Although apt-get automatically installs the toolchain prerequisites, the basic packages needed and recommend for a Clang-based C/C++ ARM cross-compiler are the following:

How To Cross-Compile Clang/LLVM using Clang/LLVM

LLVM doc

Makefile Examples