Skip to content

Commit c10736a

Browse files
[llvm][docs] Refresh Arm builtins cross compile guide (#150966)
Someone asked about this on Discord and it was a bit hard to follow. I found them a config that worked, but the doc was not as much help as it should have been. It probably needs some updates for the runtime build era, but for now, I'm just making it easier to read. I know the basic build can work at least. Some aspects of it may be literally wrong now, but I'll check that later. * Remove contractions. * Remove references to the old separate llvm repo layout. * Remove mentions of cmake versions older than what llvm requires now. * Make a bunch of things plain text. * Make a bunch of things code blocks so they are easier to copy and paste from.
1 parent 15f65af commit c10736a

File tree

1 file changed

+112
-115
lines changed

1 file changed

+112
-115
lines changed

llvm/docs/HowToCrossCompileBuiltinsOnArm.rst

Lines changed: 112 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -14,117 +14,113 @@ targets are welcome.
1414

1515
The instructions in this document depend on libraries and programs external to
1616
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.
17+
may need to adapt the instructions here to fit your own situation.
1818

1919
Prerequisites
2020
=============
2121

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
22+
In this use case we will 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 will be
2424
using as many of the LLVM tools as we can, but it is possible to use GNU
2525
equivalents.
2626

27-
* ``A build of LLVM/clang for the llvm-tools and llvm-config``
28-
* ``A clang executable with support for the ARM target``
29-
* ``compiler-rt sources``
30-
* ``The qemu-arm user mode emulator``
31-
* ``An arm-linux-gnueabihf sysroot``
27+
You will need:
28+
* A build of LLVM for the llvm-tools and ``llvm-config``.
29+
* A clang executable with support for the ``ARM`` target.
30+
* compiler-rt sources.
31+
* The ``qemu-arm`` user mode emulator.
32+
* An ``arm-linux-gnueabihf`` sysroot.
3233

33-
In this example we will be using ninja.
34+
In this example we will be using ``ninja`` as the build tool.
3435

35-
See https://compiler-rt.llvm.org/ for more information about the dependencies
36+
See https://compiler-rt.llvm.org/ for information about the dependencies
3637
on clang and LLVM.
3738

3839
See https://llvm.org/docs/GettingStarted.html for information about obtaining
39-
the source for LLVM and compiler-rt. Note that the getting started guide
40-
places compiler-rt in the projects subdirectory, but this is not essential and
41-
if you are using the BaremetalARM.cmake cache for v6-M, v7-M and v7-EM then
42-
compiler-rt must be placed in the runtimes directory.
40+
the source for LLVM and compiler-rt.
4341

4442
``qemu-arm`` should be available as a package for your Linux distribution.
4543

46-
The most complicated of the prerequisites to satisfy is the arm-linux-gnueabihf
44+
The most complicated of the prerequisites to satisfy is the ``arm-linux-gnueabihf``
4745
sysroot. In theory it is possible to use the Linux distributions multiarch
4846
support to fulfill the dependencies for building but unfortunately due to
49-
/usr/local/include being added some host includes are selected. The easiest way
50-
to supply a sysroot is to download the arm-linux-gnueabihf toolchain. This can
51-
be found at:
52-
* https://developer.arm.com/open-source/gnu-toolchain/gnu-a/downloads for gcc 8 and above
53-
* https://releases.linaro.org/components/toolchain/binaries/ for gcc 4.9 to 7.3
47+
``/usr/local/include`` being added some host includes are selected.
48+
49+
The easiest way to supply a sysroot is to download an ``arm-linux-gnueabihf``
50+
toolchain from https://developer.arm.com/open-source/gnu-toolchain/gnu-a/downloads.
5451

5552
Building compiler-rt builtins for Arm
5653
=====================================
54+
5755
We will be doing a standalone build of compiler-rt using the following cmake
58-
options.
59-
60-
* ``path/to/compiler-rt``
61-
* ``-G Ninja``
62-
* ``-DCMAKE_AR=/path/to/llvm-ar``
63-
* ``-DCMAKE_ASM_COMPILER_TARGET="arm-linux-gnueabihf"``
64-
* ``-DCMAKE_ASM_FLAGS="build-c-flags"``
65-
* ``-DCMAKE_C_COMPILER=/path/to/clang``
66-
* ``-DCMAKE_C_COMPILER_TARGET="arm-linux-gnueabihf"``
67-
* ``-DCMAKE_C_FLAGS="build-c-flags"``
68-
* ``-DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld"``
69-
* ``-DCMAKE_NM=/path/to/llvm-nm``
70-
* ``-DCMAKE_RANLIB=/path/to/llvm-ranlib``
71-
* ``-DCOMPILER_RT_BUILD_BUILTINS=ON``
72-
* ``-DCOMPILER_RT_BUILD_LIBFUZZER=OFF``
73-
* ``-DCOMPILER_RT_BUILD_MEMPROF=OFF``
74-
* ``-DCOMPILER_RT_BUILD_PROFILE=OFF``
75-
* ``-DCOMPILER_RT_BUILD_SANITIZERS=OFF``
76-
* ``-DCOMPILER_RT_BUILD_XRAY=OFF``
77-
* ``-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON``
78-
* ``-DLLVM_CONFIG_PATH=/path/to/llvm-config``
56+
options::
57+
58+
cmake path/to/compiler-rt \
59+
-G Ninja \
60+
-DCMAKE_AR=/path/to/llvm-ar \
61+
-DCMAKE_ASM_COMPILER_TARGET="arm-linux-gnueabihf" \
62+
-DCMAKE_ASM_FLAGS="build-c-flags" \
63+
-DCMAKE_C_COMPILER=/path/to/clang \
64+
-DCMAKE_C_COMPILER_TARGET="arm-linux-gnueabihf" \
65+
-DCMAKE_C_FLAGS="build-c-flags" \
66+
-DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" \
67+
-DCMAKE_NM=/path/to/llvm-nm \
68+
-DCMAKE_RANLIB=/path/to/llvm-ranlib \
69+
-DCOMPILER_RT_BUILD_BUILTINS=ON \
70+
-DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
71+
-DCOMPILER_RT_BUILD_MEMPROF=OFF \
72+
-DCOMPILER_RT_BUILD_PROFILE=OFF \
73+
-DCOMPILER_RT_BUILD_SANITIZERS=OFF \
74+
-DCOMPILER_RT_BUILD_XRAY=OFF \
75+
-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
76+
-DLLVM_CONFIG_PATH=/path/to/llvm-config
7977

8078
The ``build-c-flags`` need to be sufficient to pass the C-make compiler check,
8179
compile compiler-rt, and if you are running the tests, compile and link the
8280
tests. When cross-compiling with clang we will need to pass sufficient
83-
information to generate code for the Arm architecture we are targeting. We will
84-
need to select the Arm target, select the Armv7-A architecture and choose
85-
between using Arm or Thumb.
86-
instructions. For example:
81+
information to generate code for the Arm architecture we are targeting.
8782

88-
* ``--target=arm-linux-gnueabihf``
89-
* ``-march=armv7a``
90-
* ``-mthumb``
83+
We will need to select:
84+
* The Arm target and Armv7-A architecture with ``--target=arm-linux-gnueabihf -march=armv7a``.
85+
* Whether to generate Arm (the default) or Thumb instructions (``-mthumb``).
9186

92-
When using a GCC arm-linux-gnueabihf toolchain the following flags are
87+
When using a GCC ``arm-linux-gnueabihf`` toolchain the following flags are
9388
needed to pick up the includes and libraries:
9489

95-
* ``--gcc-toolchain=/path/to/dir/toolchain``
96-
* ``--sysroot=/path/to/toolchain/arm-linux-gnueabihf/libc``
90+
* ``--gcc-toolchain=/path/to/dir/toolchain``
91+
* ``--sysroot=/path/to/toolchain/arm-linux-gnueabihf/libc``
9792

9893
In this example we will be adding all of the command line options to both
9994
``CMAKE_C_FLAGS`` and ``CMAKE_ASM_FLAGS``. There are cmake flags to pass some of
100-
these options individually which can be used to simplify the ``build-c-flags``:
95+
these options individually which can be used to simplify the ``build-c-flags``::
10196

102-
* ``-DCMAKE_C_COMPILER_TARGET="arm-linux-gnueabihf"``
103-
* ``-DCMAKE_ASM_COMPILER_TARGET="arm-linux-gnueabihf"``
104-
* ``-DCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN=/path/to/dir/toolchain``
105-
* ``-DCMAKE_SYSROOT=/path/to/dir/toolchain/arm-linux-gnueabihf/libc``
97+
-DCMAKE_C_COMPILER_TARGET="arm-linux-gnueabihf"
98+
-DCMAKE_ASM_COMPILER_TARGET="arm-linux-gnueabihf"
99+
-DCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN=/path/to/dir/toolchain
100+
-DCMAKE_SYSROOT=/path/to/dir/toolchain/arm-linux-gnueabihf/libc
106101

107102
Once cmake has completed the builtins can be built with ``ninja builtins``
108103

109104
Testing compiler-rt builtins using qemu-arm
110105
===========================================
106+
111107
To test the builtins library we need to add a few more cmake flags to enable
112108
testing and set up the compiler and flags for test case. We must also tell
113-
cmake that we wish to run the tests on ``qemu-arm``.
109+
cmake that we wish to run the tests on ``qemu-arm``::
114110

115-
* ``-DCOMPILER_RT_EMULATOR="qemu-arm -L /path/to/armhf/sysroot``
116-
* ``-DCOMPILER_RT_INCLUDE_TESTS=ON``
117-
* ``-DCOMPILER_RT_TEST_COMPILER="/path/to/clang"``
118-
* ``-DCOMPILER_RT_TEST_COMPILER_CFLAGS="test-c-flags"``
111+
-DCOMPILER_RT_EMULATOR="qemu-arm -L /path/to/armhf/sysroot"
112+
-DCOMPILER_RT_INCLUDE_TESTS=ON
113+
-DCOMPILER_RT_TEST_COMPILER="/path/to/clang"
114+
-DCOMPILER_RT_TEST_COMPILER_CFLAGS="test-c-flags"
119115

120116
The ``/path/to/armhf/sysroot`` should be the same as the one passed to
121-
``--sysroot`` in the "build-c-flags".
117+
``--sysroot`` in the ``build-c-flags``.
122118

123-
The "test-c-flags" need to include the target, architecture, gcc-toolchain,
124-
sysroot and arm/thumb state. The additional cmake defines such as
119+
The ``test-c-flags`` need to include the target, architecture, gcc-toolchain,
120+
sysroot and Arm/Thumb state. The additional cmake defines such as
125121
``CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN`` do not apply when building the tests. If
126-
you have put all of these in "build-c-flags" then these can be repeated. If you
127-
wish to use lld to link the tests then add ``"-fuse-ld=lld``.
122+
you have put all of these in ``build-c-flags`` then these can be repeated. If you
123+
wish to use lld to link the tests then add ``-fuse-ld=lld``.
128124

129125
Once cmake has completed the tests can be built and run using
130126
``ninja check-builtins``
@@ -142,19 +138,21 @@ This stage can often fail at link time if the ``--sysroot=`` and
142138
``CMAKE_C_FLAGS`` and ``CMAKE_C_COMPILER_TARGET`` flags.
143139

144140
It can be useful to build a simple example outside of cmake with your toolchain
145-
to make sure it is working. For example: ``clang --target=arm-linux-gnueabi -march=armv7a --gcc-toolchain=/path/to/gcc-toolchain --sysroot=/path/to/gcc-toolchain/arm-linux-gnueabihf/libc helloworld.c``
141+
to make sure it is working. For example::
142+
143+
clang --target=arm-linux-gnueabi -march=armv7a --gcc-toolchain=/path/to/gcc-toolchain --sysroot=/path/to/gcc-toolchain/arm-linux-gnueabihf/libc helloworld.c
146144

147145
Clang uses the host header files
148146
--------------------------------
149147
On debian based systems it is possible to install multiarch support for
150-
arm-linux-gnueabi and arm-linux-gnueabihf. In many cases clang can successfully
148+
``arm-linux-gnueabi`` and ``arm-linux-gnueabihf``. In many cases clang can successfully
151149
use this multiarch support when ``--gcc-toolchain=`` and ``--sysroot=`` are not supplied.
152150
Unfortunately clang adds ``/usr/local/include`` before
153151
``/usr/include/arm-linux-gnueabihf`` leading to errors when compiling the hosts
154152
header files.
155153

156154
The multiarch support is not sufficient to build the builtins you will need to
157-
use a separate arm-linux-gnueabihf toolchain.
155+
use a separate ``arm-linux-gnueabihf`` toolchain.
158156

159157
No target passed to clang
160158
-------------------------
@@ -164,12 +162,13 @@ as ``error: unknown directive .syntax unified``.
164162

165163
You can check the clang invocation in the error message to see if there is no
166164
``--target`` or if it is set incorrectly. The cause is usually
167-
``CMAKE_ASM_FLAGS`` not containing ``--target`` or ``CMAKE_ASM_COMPILER_TARGET`` not being present.
165+
``CMAKE_ASM_FLAGS`` not containing ``--target`` or ``CMAKE_ASM_COMPILER_TARGET``
166+
not being present.
168167

169168
Arm architecture not given
170169
--------------------------
171-
The ``--target=arm-linux-gnueabihf`` will default to arm architecture v4t which
172-
cannot assemble the barrier instructions used in the synch_and_fetch source
170+
The ``--target=arm-linux-gnueabihf`` will default to Arm architecture v4t which
171+
cannot assemble the barrier instructions used in the ``synch_and_fetch`` source
173172
files.
174173

175174
The cause is usually a missing ``-march=armv7a`` from the ``CMAKE_ASM_FLAGS``.
@@ -202,7 +201,7 @@ may need extra c-flags such as ``-mfloat-abi=softfp`` for use of floating-point
202201
instructions, and ``-mfloat-abi=soft -mfpu=none`` for software floating-point
203202
emulation.
204203

205-
You will need to use an arm-linux-gnueabi GNU toolchain for soft-float.
204+
You will need to use an ``arm-linux-gnueabi`` GNU toolchain for soft-float.
206205

207206
AArch64 Target
208207
--------------
@@ -220,8 +219,12 @@ Armv6-m, Armv7-m and Armv7E-M targets
220219
To build and test the libraries using a similar method to Armv7-A is possible
221220
but more difficult. The main problems are:
222221

223-
* 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.
224-
* The targets 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.
222+
* There is not a ``qemu-arm`` user-mode emulator for bare-metal systems.
223+
``qemu-system-arm`` can be used but this is significantly more difficult
224+
to setup.
225+
* The targets to compile compiler-rt have the suffix ``-none-eabi``. This uses
226+
the BareMetal driver in clang and by default will not find the libraries
227+
needed to pass the cmake compiler check.
225228

226229
As the Armv6-M, Armv7-M and Armv7E-M builds of compiler-rt only use instructions
227230
that are supported on Armv7-A we can still get most of the value of running the
@@ -233,32 +236,30 @@ builtins use instructions that are supported on Armv7-A but not Armv6-M,
233236
Armv7-M and Armv7E-M.
234237

235238
To get the cmake compile test to pass you will need to pass the libraries
236-
needed to successfully link the cmake test via ``CMAKE_CFLAGS``. It is
237-
strongly recommended that you use version 3.6 or above of cmake so you can use
238-
``CMAKE_TRY_COMPILE_TARGET=STATIC_LIBRARY`` to skip the link step.
239-
240-
* ``-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY``
241-
* ``-DCOMPILER_RT_OS_DIR="baremetal"``
242-
* ``-DCOMPILER_RT_BUILD_BUILTINS=ON``
243-
* ``-DCOMPILER_RT_BUILD_SANITIZERS=OFF``
244-
* ``-DCOMPILER_RT_BUILD_XRAY=OFF``
245-
* ``-DCOMPILER_RT_BUILD_LIBFUZZER=OFF``
246-
* ``-DCOMPILER_RT_BUILD_PROFILE=OFF``
247-
* ``-DCMAKE_C_COMPILER=${host_install_dir}/bin/clang``
248-
* ``-DCMAKE_C_COMPILER_TARGET="your *-none-eabi target"``
249-
* ``-DCMAKE_ASM_COMPILER_TARGET="your *-none-eabi target"``
250-
* ``-DCMAKE_AR=/path/to/llvm-ar``
251-
* ``-DCMAKE_NM=/path/to/llvm-nm``
252-
* ``-DCMAKE_RANLIB=/path/to/llvm-ranlib``
253-
* ``-DCOMPILER_RT_BAREMETAL_BUILD=ON``
254-
* ``-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON``
255-
* ``-DLLVM_CONFIG_PATH=/path/to/llvm-config``
256-
* ``-DCMAKE_C_FLAGS="build-c-flags"``
257-
* ``-DCMAKE_ASM_FLAGS="build-c-flags"``
258-
* ``-DCOMPILER_RT_EMULATOR="qemu-arm -L /path/to/armv7-A/sysroot"``
259-
* ``-DCOMPILER_RT_INCLUDE_TESTS=ON``
260-
* ``-DCOMPILER_RT_TEST_COMPILER="/path/to/clang"``
261-
* ``-DCOMPILER_RT_TEST_COMPILER_CFLAGS="test-c-flags"``
239+
needed to successfully link the cmake test via ``CMAKE_CFLAGS``::
240+
241+
-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
242+
-DCOMPILER_RT_OS_DIR="baremetal" \
243+
-DCOMPILER_RT_BUILD_BUILTINS=ON \
244+
-DCOMPILER_RT_BUILD_SANITIZERS=OFF \
245+
-DCOMPILER_RT_BUILD_XRAY=OFF \
246+
-DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
247+
-DCOMPILER_RT_BUILD_PROFILE=OFF \
248+
-DCMAKE_C_COMPILER=${host_install_dir}/bin/clang \
249+
-DCMAKE_C_COMPILER_TARGET="your *-none-eabi target" \
250+
-DCMAKE_ASM_COMPILER_TARGET="your *-none-eabi target" \
251+
-DCMAKE_AR=/path/to/llvm-ar \
252+
-DCMAKE_NM=/path/to/llvm-nm \
253+
-DCMAKE_RANLIB=/path/to/llvm-ranlib \
254+
-DCOMPILER_RT_BAREMETAL_BUILD=ON \
255+
-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
256+
-DLLVM_CONFIG_PATH=/path/to/llvm-config \
257+
-DCMAKE_C_FLAGS="build-c-flags" \
258+
-DCMAKE_ASM_FLAGS="build-c-flags" \
259+
-DCOMPILER_RT_EMULATOR="qemu-arm -L /path/to/armv7-A/sysroot" \
260+
-DCOMPILER_RT_INCLUDE_TESTS=ON \
261+
-DCOMPILER_RT_TEST_COMPILER="/path/to/clang" \
262+
-DCOMPILER_RT_TEST_COMPILER_CFLAGS="test-c-flags"
262263

263264
The Armv6-M builtins will use the soft-float ABI. When compiling the tests for
264265
Armv7-A we must include ``"-mthumb -mfloat-abi=soft -mfpu=none"`` in the
@@ -267,25 +268,21 @@ test-c-flags. We must use an Armv7-A soft-float abi sysroot for ``qemu-arm``.
267268
Depending on the linker used for the test cases you may encounter BuildAttribute
268269
mismatches between the M-profile objects from compiler-rt and the A-profile
269270
objects from the test. The lld linker does not check the profile
270-
BuildAttribute so it can be used to link the tests by adding -fuse-ld=lld to the
271+
BuildAttribute so it can be used to link the tests by adding ``-fuse-ld=lld`` to the
271272
``COMPILER_RT_TEST_COMPILER_CFLAGS``.
272273

273274
Alternative using a cmake cache
274275
-------------------------------
275276
If you wish to build, but not test compiler-rt for Armv6-M, Armv7-M or Armv7E-M
276-
the easiest way is to use the BaremetalARM.cmake recipe in clang/cmake/caches.
277-
278-
You will need a bare metal sysroot such as that provided by the GNU ARM
279-
Embedded toolchain.
280-
281-
The libraries can be built with the cmake options:
277+
the easiest way is to use the ``BaremetalARM.cmake`` recipe in ``clang/cmake/caches``.
282278

283-
* ``-DBAREMETAL_ARMV6M_SYSROOT=/path/to/bare/metal/toolchain/arm-none-eabi``
284-
* ``-DBAREMETAL_ARMV7M_SYSROOT=/path/to/bare/metal/toolchain/arm-none-eabi``
285-
* ``-DBAREMETAL_ARMV7EM_SYSROOT=/path/to/bare/metal/toolchain/arm-none-eabi``
286-
* ``-C /path/to/llvm/source/tools/clang/cmake/caches/BaremetalARM.cmake``
287-
* ``/path/to/llvm``
279+
You will need a bare metal sysroot such as that provided by the GNU ARM Embedded
280+
toolchain.
288281

289-
**Note** that for the recipe to work the compiler-rt source must be checked out
290-
into the directory llvm/runtimes. You will also need clang and lld checked out.
282+
The libraries can be built with the cmake options::
291283

284+
-DBAREMETAL_ARMV6M_SYSROOT=/path/to/bare/metal/toolchain/arm-none-eabi \
285+
-DBAREMETAL_ARMV7M_SYSROOT=/path/to/bare/metal/toolchain/arm-none-eabi \
286+
-DBAREMETAL_ARMV7EM_SYSROOT=/path/to/bare/metal/toolchain/arm-none-eabi \
287+
-C /path/to/llvm/source/tools/clang/cmake/caches/BaremetalARM.cmake \
288+
/path/to/llvm

0 commit comments

Comments
 (0)