Skip to content

Commit 7411da5

Browse files
committed
[docs][ARM] Add HowTo for cross compiling and testing compiler-rt builtins
This document contains information on how to cross-compile the compiler-rt builtins library for several flavours of Arm target and how to test the libraries using qemu. Differential Revision: https://reviews.llvm.org/D39600 llvm-svn: 317554
1 parent c205548 commit 7411da5

File tree

2 files changed

+205
-0
lines changed

2 files changed

+205
-0
lines changed
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
===================================================================
2+
How to Cross Compile Compiler-rt Builtins For Arm
3+
===================================================================
4+
5+
Introduction
6+
============
7+
8+
This document contains information about building and testing the builtins part
9+
of compiler-rt for an Arm target, from an x86_64 Linux machine.
10+
11+
While this document concentrates on Arm and Linux the general principles should
12+
apply to other targets supported by compiler-rt. Further contributions for other
13+
targets are welcome.
14+
15+
The instructions in this document depend on libraries and programs external to
16+
LLVM, there are many ways to install and configure these dependencies so you
17+
may need to adapt the instructions here to fit your own local situation.
18+
19+
Prerequisites
20+
=============
21+
22+
In this use case we'll be using CMake on a Debian-based Linux system,
23+
cross-compiling from an x86_64 host to a hard-float Armv7-A target. We'll be
24+
using as many of the LLVM tools as we can, but it is possible to use GNU
25+
equivalents.
26+
27+
* ``A build of LLVM/clang for the llvm-tools and llvm-config``
28+
* ``The qemu-arm user mode emulator``
29+
* ``An arm-linux-gnueabihf sysroot``
30+
31+
See https://compiler-rt.llvm.org/ for more information about the dependencies
32+
on clang and LLVM.
33+
34+
``qemu-arm`` should be available as a package for your Linux distribution.
35+
36+
The most complicated of the prequisites to satisfy is the arm-linux-gnueabihf
37+
sysroot. The :doc:`HowToCrossCompileLLVM` has information about how to use the
38+
Linux distributions multiarch support to fulfill the dependencies for building
39+
LLVM. Alternatively, as building and testing just the compiler-rt builtins
40+
requires fewer dependencies than LLVM, it is possible to use the Linaro
41+
arm-linux-gnueabihf gcc installation as our sysroot.
42+
43+
Building compiler-rt builtins for Arm
44+
=====================================
45+
We will be doing a standalone build of compiler-rt using the following cmake
46+
options.
47+
48+
* ``path/to/llvm/projects/compiler-rt``
49+
* ``-DCOMPILER_RT_BUILD_BUILTINS=ON``
50+
* ``-DCOMPILER_RT_BUILD_SANITIZERS=OFF``
51+
* ``-DCOMPILER_RT_BUILD_XRAY=OFF``
52+
* ``-DCOMPILER_RT_BUILD_LIBFUZZER=OFF``
53+
* ``-DCOMPILER_RT_BUILD_PROFILE=OFF``
54+
* ``-DCMAKE_C_COMPILER=/path/to/clang``
55+
* ``-DCMAKE_AR=/path/to/llvm-ar``
56+
* ``-DCMAKE_NM=/path/to/llvm-nm``
57+
* ``-DCMAKE_RANLIB=/path/to/llvm-ranlib``
58+
* ``-DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld"``
59+
* ``-DCMAKE_C_COMPILER_TARGET="arm-linux-gnueabihf"``
60+
* ``-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON``
61+
* ``-DLLVM_CONFIG_PATH=/path/to/llvm-config``
62+
* ``-DCMAKE_C_FLAGS="build-c-flags"``
63+
64+
The build-c-flags need to be sufficient to pass the C-make compiler check and
65+
to compile compiler-rt. When using a GCC 7 Linaro arm-linux-gnueabihf
66+
installation the following flags are needed:
67+
68+
* ``--target=arm-linux-gnueabihf``
69+
* ``--march=armv7a``
70+
* ``--gcc-toolchain=/path/to/dir/toolchain``
71+
* ``--sysroot=/path/to/toolchain/arm-linux-gnueabihf/libc``
72+
73+
Depending on how your sysroot is laid out, you may not need ``--gcc-toolchain``.
74+
For example if you have added armhf as an architecture using your Linux
75+
distributions multiarch support then you should be able to use ``--sysroot=/``.
76+
77+
Once cmake has completed the builtins can be built with ``ninja builtins``
78+
79+
Testing compiler-rt builtins using qemu-arm
80+
===========================================
81+
To test the builtins library we need to add a few more cmake flags to enable
82+
testing and set up the compiler and flags for test case. We must also tell
83+
cmake that we wish to run the tests on ``qemu-arm``.
84+
85+
* ``-DCOMPILER_RT_EMULATOR="qemu-arm -L /path/to/armhf/sysroot``
86+
* ``-DCOMPILER_RT_INCLUDE_TESTS=ON``
87+
* ``-DCOMPILER_RT_TEST_COMPILER="/path/to/clang"``
88+
* ``-DCOMPILER_RT_TEST_COMPILER_CFLAGS="test-c-flags"``
89+
90+
The ``/path/to/armhf/sysroot`` should be the same as the one passed to
91+
``--sysroot`` in the "build-c-flags".
92+
93+
The "test-c-flags" can be the same as the "build-c-flags", with the addition
94+
of ``"-fuse-ld=lld`` if you wish to use lld to link the tests.
95+
96+
Once cmake has completed the tests can be built and run using
97+
``ninja check-builtins``
98+
99+
Modifications for other Targets
100+
===============================
101+
102+
Arm Soft-Float Target
103+
---------------------
104+
The instructions for the Arm hard-float target can be used for the soft-float
105+
target by substituting soft-float equivalents for the sysroot and target. The
106+
target to use is:
107+
108+
* ``-DCMAKE_C_COMPILER_TARGET=arm-linux-gnueabi``
109+
110+
Depending on whether you want to use floating point instructions or not you
111+
may need extra c-flags such as ``-mfloat-abi=softfp`` for use of floating-point
112+
instructions, and ``-mfloat-abi=soft -mfpu=none`` for software floating-point
113+
emulation.
114+
115+
AArch64 Target
116+
--------------
117+
The instructions for Arm can be used for AArch64 by substituting AArch64
118+
equivalents for the sysroot, emulator and target.
119+
120+
* ``-DCMAKE_C_COMPILER_TARGET=aarch64-linux-gnu``
121+
* ``-DCOMPILER_RT_EMULATOR="qemu-aarch64 -L /path/to/aarch64/sysroot``
122+
123+
The CMAKE_C_FLAGS and COMPILER_RT_TEST_COMPILER_CFLAGS may also need:
124+
``"--sysroot=/path/to/aarch64/sysroot --gcc-toolchain=/path/to/gcc-toolchain"``
125+
126+
Armv6-m, Armv7-m and Armv7E-M targets
127+
-------------------------------------
128+
If you wish to build, but not test compiler-rt for Armv6-M, Armv7-M or Armv7E-M
129+
then the easiest way is to use the BaremetalARM.cmake recipe in
130+
clang/cmake/caches.
131+
132+
You will need a bare metal sysroot such as that provided by the GNU ARM
133+
Embedded toolchain.
134+
135+
The libraries can be built with the cmake options:
136+
137+
* ``-DBAREMETAL_ARMV6M_SYSROOT=/path/to/bare/metal/sysroot``
138+
* ``-DBAREMETAL_ARMV7M_SYSROOT=/path/to/bare/metal/sysroot``
139+
* ``-DBAREMETAL_ARMV7EM_SYSROOT=/path/to/bare/metal/sysroot``
140+
* ``-C /path/to/llvm/source/tools/clang/cmake/caches/BaremetalARM.cmake``
141+
142+
**Note** that for the recipe to work the compiler-rt source must be checked out
143+
into the directory llvm/runtimes and not llvm/projects.
144+
145+
To build and test the libraries using a similar method to Armv7-A is possible
146+
but more difficult. The main problems are:
147+
148+
* There isn't a ``qemu-arm`` user-mode emulator for bare-metal systems. The ``qemu-system-arm`` can be used but this is significantly more difficult to setup.
149+
* The target to compile compiler-rt have the suffix -none-eabi. This uses the BareMetal driver in clang and by default won't find the libraries needed to pass the cmake compiler check.
150+
151+
As the Armv6-M, Armv7-M and Armv7E-M builds of compiler-rt only use instructions
152+
that are supported on Armv7-A we can still get most of the value of running the
153+
tests using the same ``qemu-arm`` that we used for Armv7-A by building and
154+
running the test cases for Armv7-A but using the builtins compiled for
155+
Armv6-M, Armv7-M or Armv7E-M. This will not catch instructions that are
156+
supported on Armv7-A but not Armv6-M, Armv7-M and Armv7E-M.
157+
158+
To get the cmake compile test to pass the libraries needed to successfully link
159+
the test application will need to be manually added to ``CMAKE_CFLAGS``.
160+
Alternatively if you are using version 3.6 or above of cmake you can use
161+
``CMAKE_TRY_COMPILE_TARGET=STATIC_LIBRARY`` to skip the link step.
162+
163+
* ``-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY``
164+
* ``-DCOMPILER_RT_OS_DIR="baremetal"``
165+
* ``-DCOMPILER_RT_BUILD_BUILTINS=ON``
166+
* ``-DCOMPILER_RT_BUILD_SANITIZERS=OFF``
167+
* ``-DCOMPILER_RT_BUILD_XRAY=OFF``
168+
* ``-DCOMPILER_RT_BUILD_LIBFUZZER=OFF``
169+
* ``-DCOMPILER_RT_BUILD_PROFILE=OFF``
170+
* ``-DCMAKE_C_COMPILER=${host_install_dir}/bin/clang``
171+
* ``-DCMAKE_C_COMPILER_TARGET="your *-none-eabi target"``
172+
* ``-DCMAKE_AR=/path/to/llvm-ar``
173+
* ``-DCMAKE_NM=/path/to/llvm-nm``
174+
* ``-DCMAKE_RANLIB=/path/to/llvm-ranlib``
175+
* ``-DCOMPILER_RT_BAREMETAL_BUILD=ON``
176+
* ``-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON``
177+
* ``-DLLVM_CONFIG_PATH=/path/to/llvm-config``
178+
* ``-DCMAKE_C_FLAGS="build-c-flags"``
179+
* ``-DCMAKE_ASM_FLAGS="${arm_cflags}"``
180+
* ``-DCOMPILER_RT_EMULATOR="qemu-arm -L /path/to/armv7-A/sysroot"``
181+
* ``-DCOMPILER_RT_INCLUDE_TESTS=ON``
182+
* ``-DCOMPILER_RT_TEST_COMPILER="/path/to/clang"``
183+
* ``-DCOMPILER_RT_TEST_COMPILER_CFLAGS="test-c-flags"``
184+
185+
The Armv6-M builtins will use the soft-float ABI. When compiling the tests for
186+
Armv7-A we must include ``"-mthumb -mfloat-abi=soft -mfpu=none"`` in the
187+
test-c-flags. We must use an Armv7-A soft-float abi sysroot for ``qemu-arm``.
188+
189+
Unfortunately at time of writing the Armv7-M and Armv7E-M builds of
190+
compiler-rt will always include assembler files including floating point
191+
instructions. This means that building for a cpu without a floating point unit
192+
requires something like removing the arm_Thumb1_VFPv2_SOURCES from the
193+
arm_Thumb1_SOURCES in builtins/CMakeLists.txt. The float-abi of the compiler-rt
194+
library must be matched by the float abi of the Armv7-A sysroot used by
195+
qemu-arm.
196+
197+
Depending on the linker used for the test cases you may encounter BuildAttribute
198+
mismatches between the M-profile objects from compiler-rt and the A-profile
199+
objects from the test. The lld linker does not check the BuildAttributes so it
200+
can be used to link the tests by adding -fuse-ld=lld to the
201+
``COMPILER_RT_TEST_COMPILER_CFLAGS``.

llvm/docs/index.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ representation.
6868
CMakePrimer
6969
AdvancedBuilds
7070
HowToBuildOnARM
71+
HowToCrossCompileBuiltinsOnArm
7172
HowToCrossCompileLLVM
7273
CommandGuide/index
7374
GettingStarted
@@ -105,6 +106,9 @@ representation.
105106
:doc:`HowToBuildOnARM`
106107
Notes on building and testing LLVM/Clang on ARM.
107108

109+
:doc:`HowToCrossCompileBuiltinsOnArm`
110+
Notes on cross-building and testing the compiler-rt builtins for Arm.
111+
108112
:doc:`HowToCrossCompileLLVM`
109113
Notes on cross-building and testing LLVM/Clang.
110114

0 commit comments

Comments
 (0)