@@ -25,12 +25,16 @@ using as many of the LLVM tools as we can, but it is possible to use GNU
2525equivalents.
2626
2727You will need:
28- * A build of LLVM for the llvm-tools and `` llvm-config `` .
28+ * A build of LLVM for the llvm-tools and LLVM CMake files .
2929 * A clang executable with support for the ``ARM `` target.
30- * compiler-rt sources.
30+ * `` compiler-rt `` sources.
3131 * The ``qemu-arm `` user mode emulator.
3232 * An ``arm-linux-gnueabihf `` sysroot.
3333
34+ .. note ::
35+ An existing sysroot is required because some of the builtins include C library
36+ headers and a sysroot is the easiest way to get those.
37+
3438In this example we will be using ``ninja `` as the build tool.
3539
3640See https://compiler-rt.llvm.org/ for information about the dependencies
@@ -52,78 +56,94 @@ toolchain from https://developer.arm.com/open-source/gnu-toolchain/gnu-a/downloa
5256Building compiler-rt builtins for Arm
5357=====================================
5458
55- We will be doing a standalone build of compiler-rt using the following cmake
56- options::
59+ We will be doing a standalone build of compiler-rt. The command is shown below.
60+ Shell variables are used to simplify some of the options::
61+
62+ LLVM_TOOLCHAIN=<path-to-llvm-install>/
63+ TARGET_TRIPLE=arm-none-linux-gnueabihf
64+ GCC_TOOLCHAIN=<path-to-gcc-toolchain>
65+ SYSROOT=${GCC_TOOLCHAIN}/${TARGET_TRIPLE}/libc
66+ COMPILE_FLAGS="-march=armv7-a"
5767
58- cmake path/to /compiler-rt \
68+ cmake ../llvm-project /compiler-rt \
5969 -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" \
70+ -DCMAKE_AR=${LLVM_TOOLCHAIN}/bin/llvm-ar \
71+ -DCMAKE_NM=${LLVM_TOOLCHAIN}/bin/llvm-nm \
72+ -DCMAKE_RANLIB=${LLVM_TOOLCHAIN}/bin/llvm-ranlib \
73+ -DLLVM_CMAKE_DIR="${LLVM_TOOLCHAIN}/lib/cmake/llvm" \
74+ -DCMAKE_SYSROOT="${SYSROOT}" \
75+ -DCMAKE_ASM_COMPILER_TARGET="${TARGET_TRIPLE}" \
76+ -DCMAKE_ASM_FLAGS="${COMPILE_FLAGS}" \
77+ -DCMAKE_C_COMPILER_TARGET="${TARGET_TRIPLE}" \
78+ -DCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN=${GCC_TOOLCHAIN} \
79+ -DCMAKE_C_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
80+ -DCMAKE_C_FLAGS="${COMPILE_FLAGS}" \
81+ -DCMAKE_CXX_COMPILER_TARGET="${TARGET_TRIPLE}" \
82+ -DCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN=${GCC_TOOLCHAIN} \
83+ -DCMAKE_CXX_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
84+ -DCMAKE_CXX_FLAGS="${COMPILE_FLAGS}" \
6685 -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" \
67- -DCMAKE_NM=/path/to/llvm-nm \
68- -DCMAKE_RANLIB=/path/to/llvm-ranlib \
6986 -DCOMPILER_RT_BUILD_BUILTINS=ON \
7087 -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
7188 -DCOMPILER_RT_BUILD_MEMPROF=OFF \
7289 -DCOMPILER_RT_BUILD_PROFILE=OFF \
90+ -DCOMPILER_RT_BUILD_CTX_PROFILE=OFF \
7391 -DCOMPILER_RT_BUILD_SANITIZERS=OFF \
7492 -DCOMPILER_RT_BUILD_XRAY=OFF \
93+ -DCOMPILER_RT_BUILD_ORC=OFF \
94+ -DCOMPILER_RT_BUILD_CRT=OFF \
7595 -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
76- -DLLVM_CONFIG_PATH=/path/to/llvm-config
96+ -DCOMPILER_RT_EMULATOR="qemu-arm -L ${SYSROOT}" \
97+ -DCOMPILER_RT_INCLUDE_TESTS=ON \
98+ -DCOMPILER_RT_TEST_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
99+ -DCOMPILER_RT_TEST_COMPILER_CFLAGS="--target=${TARGET_TRIPLE} ${COMPILE_FLAGS} --gcc-toolchain=${GCC_TOOLCHAIN} --sysroot=${SYSROOT} -fuse-ld=lld"
77100
78- The ``build-c-flags `` need to be sufficient to pass the C-make compiler check,
79- compile compiler-rt, and if you are running the tests, compile and link the
80- tests. When cross-compiling with clang we will need to pass sufficient
81- information to generate code for the Arm architecture we are targeting.
101+ .. note ::
102+ The command above also enables tests. Enabling tests is not required, more details
103+ in the testing section.
82104
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 ``) .
105+ `` CMAKE_<LANGUAGE>_<OPTION> `` options are set so that the correct `` --target ``,
106+ `` --sysroot ``, ``--gcc-toolchain `` and `` -march `` options will be given to the
107+ compilers .
86108
87- When using a GCC `` arm-linux-gnueabihf `` toolchain the following flags are
88- needed to pick up the includes and libraries:
109+ The combination of these settings needs to be enough to pass CMake's compiler
110+ checks, compile compiler-rt and build the test cases.
89111
90- * ``--gcc-toolchain=/path/to/dir/toolchain ``
91- * ``--sysroot=/path/to/toolchain/arm-linux-gnueabihf/libc ``
112+ The flags need to select:
113+ * The Arm target (``--target arm-none-linux-gnueabihf ``)
114+ * The Arm architecture level (``-march=armv7-a ``)
115+ * Whether to generate Arm (``-marm ``, the default) or Thumb (``-mthumb ``) instructions.
92116
93- In this example we will be adding all of the command line options to both
94- ``CMAKE_C_FLAGS `` and ``CMAKE_ASM_FLAGS ``. There are cmake flags to pass some of
95- these options individually which can be used to simplify the ``build-c-flags ``::
117+ It is possible to pass all these flags to CMake using ``CMAKE_<LANGUAGE>_FLAGS ``,
118+ but the command above uses standard CMake options instead. If you need to
119+ add flags that CMake cannot generate automatically, add them to
120+ ``CMAKE_<LANGUAGE>_FLAGS ``.
96121
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
122+ When CMake has finished, build with Ninja::
101123
102- Once cmake has completed the builtins can be built with `` ninja builtins ``
124+ ninja builtins
103125
104126Testing compiler-rt builtins using qemu-arm
105127===========================================
106128
107- To test the builtins library we need to add a few more cmake flags to enable
108- testing and set up the compiler and flags for test case. We must also tell
109- cmake that we wish to run the tests on ``qemu-arm ``::
129+ The following options are required to enable tests::
130+
131+ -DCOMPILER_RT_EMULATOR="qemu-arm -L ${SYSROOT}" \
132+ -DCOMPILER_RT_INCLUDE_TESTS=ON \
133+ -DCOMPILER_RT_TEST_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
134+ -DCOMPILER_RT_TEST_COMPILER_CFLAGS="--target=${TARGET_TRIPLE} -march=armv7-a --gcc-toolchain=${GCC_TOOLCHAIN} --sysroot=${SYSROOT} -fuse-ld=lld"
110135
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"
136+ This tells compiler-rt that we want to run tests on ``qemu-arm ``. If you do not
137+ want to run tests, remove these options from the CMake command.
115138
116- The ``/path/to/armhf/sysroot `` should be the same as the one passed to
117- ``--sysroot `` in the ``build-c-flags ``.
139+ Note that ``COMPILER_RT_TEST_COMPILER_CFLAGS `` contains the equivalent of the
140+ options CMake generated for us with the first command. We must pass them
141+ manually here because standard options like ``CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN ``
142+ do not apply here.
118143
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
121- ``CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN `` do not apply when building the tests. If
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 ``.
144+ When CMake has finished, run the tests::
124145
125- Once cmake has completed the tests can be built and run using
126- ``ninja check-builtins ``
146+ ninja check-builtins
127147
128148Troubleshooting
129149===============
@@ -133,9 +153,10 @@ The cmake try compile stage fails
133153At an early stage cmake will attempt to compile and link a simple C program to
134154test if the toolchain is working.
135155
136- This stage can often fail at link time if the ``--sysroot= `` and
156+ This stage can often fail at link time if the ``--sysroot= ``, `` --target `` or
137157``--gcc-toolchain= `` options are not passed to the compiler. Check the
138- ``CMAKE_C_FLAGS `` and ``CMAKE_C_COMPILER_TARGET `` flags.
158+ ``CMAKE_<LANGUAGE>_FLAGS `` and ``CMAKE_<LANGAUGE>_COMPILER_TARGET `` flags along
159+ with any of the specific CMake sysroot and toolchain options.
139160
140161It can be useful to build a simple example outside of cmake with your toolchain
141162to make sure it is working. For example::
@@ -179,10 +200,10 @@ The flags used to build the tests are not the same as those used to build the
179200builtins. The c flags are provided by ``COMPILER_RT_TEST_COMPILE_CFLAGS `` and
180201the ``CMAKE_C_COMPILER_TARGET ``, ``CMAKE_ASM_COMPILER_TARGET ``,
181202``CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN `` and ``CMAKE_SYSROOT `` flags are not
182- applied.
203+ applied to tests .
183204
184205Make sure that ``COMPILER_RT_TEST_COMPILE_CFLAGS `` contains all the necessary
185- information .
206+ flags .
186207
187208
188209Modifications for other Targets
@@ -206,13 +227,13 @@ You will need to use an ``arm-linux-gnueabi`` GNU toolchain for soft-float.
206227AArch64 Target
207228--------------
208229The instructions for Arm can be used for AArch64 by substituting AArch64
209- equivalents for the sysroot, emulator and target.
230+ equivalents for the sysroot, emulator and target::
210231
211- * `` -DCMAKE_C_COMPILER_TARGET=aarch64-linux-gnu ``
212- * `` -DCOMPILER_RT_EMULATOR="qemu-aarch64 -L /path/to/aarch64/sysroot ``
232+ -DCMAKE_C_COMPILER_TARGET=aarch64-linux-gnu
233+ -DCOMPILER_RT_EMULATOR="qemu-aarch64 -L /path/to/aarch64/sysroot
213234
214- The CMAKE_C_FLAGS and COMPILER_RT_TEST_COMPILER_CFLAGS may also need:
215- `` "--sysroot=/path/to/aarch64/sysroot --gcc-toolchain=/path/to/gcc-toolchain" ``
235+ You will also have to update any use of the target triple in compiler flags.
236+ For instance in `` CMAKE_C_FLAGS `` and `` COMPILER_RT_TEST_COMPILER_CFLAGS ``.
216237
217238Armv6-m, Armv7-m and Armv7E-M targets
218239-------------------------------------
@@ -221,7 +242,7 @@ but more difficult. The main problems are:
221242
222243* There is not a ``qemu-arm `` user-mode emulator for bare-metal systems.
223244 ``qemu-system-arm `` can be used but this is significantly more difficult
224- to setup.
245+ to setup. This document does not explain how to do this.
225246* The targets to compile compiler-rt have the suffix ``-none-eabi ``. This uses
226247 the BareMetal driver in clang and by default will not find the libraries
227248 needed to pass the cmake compiler check.
@@ -235,31 +256,68 @@ into a binary and execute the tests correctly but it will not catch if the
235256builtins use instructions that are supported on Armv7-A but not Armv6-M,
236257Armv7-M and Armv7E-M.
237258
238- To get the cmake compile test to pass you will need to pass the libraries
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"
259+ This requires a second ``arm-none-eabi `` toolchain for building the builtins.
260+ Using a bare-metal toolchain ensures that the target and C library details are
261+ specific to bare-metal instead of using Linux settings. This means that some
262+ tests may behave differently compared to real hardware, but at least the content
263+ of the builtins library is correct.
264+
265+ Below is an example that builds the builtins for Armv7-M, but runs the tests
266+ as Armv7-A. It is presented in full, but is very similar to the earlier
267+ command for Armv7-A build and test::
268+
269+ LLVM_TOOLCHAIN=<path to llvm install>/
270+
271+ # For the builtins.
272+ TARGET_TRIPLE=arm-none-eabi
273+ GCC_TOOLCHAIN=<path to arm-none-eabi toolchain>/
274+ SYSROOT=${GCC_TOOLCHAIN}/${TARGET_TRIPLE}/libc
275+ COMPILE_FLAGS="-march=armv7-m -mfpu=vfpv2"
276+
277+ # For the test cases.
278+ A_PROFILE_TARGET_TRIPLE=arm-none-linux-gnueabihf
279+ A_PROFILE_GCC_TOOLCHAIN=<path to arm-none-linux-gnueabihf toolchain>/
280+ A_PROFILE_SYSROOT=${A_PROFILE_GCC_TOOLCHAIN}/${A_PROFILE_TARGET_TRIPLE}/libc
281+
282+ cmake ../llvm-project/compiler-rt \
283+ -G Ninja \
284+ -DCMAKE_AR=${LLVM_TOOLCHAIN}/bin/llvm-ar \
285+ -DCMAKE_NM=${LLVM_TOOLCHAIN}/bin/llvm-nm \
286+ -DCMAKE_RANLIB=${LLVM_TOOLCHAIN}/bin/llvm-ranlib \
287+ -DLLVM_CMAKE_DIR="${LLVM_TOOLCHAIN}/lib/cmake/llvm" \
288+ -DCMAKE_SYSROOT="${SYSROOT}" \
289+ -DCMAKE_ASM_COMPILER_TARGET="${TARGET_TRIPLE}" \
290+ -DCMAKE_ASM_FLAGS="${COMPILE_FLAGS}" \
291+ -DCMAKE_C_COMPILER_TARGET="${TARGET_TRIPLE}" \
292+ -DCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN=${GCC_TOOLCHAIN} \
293+ -DCMAKE_C_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
294+ -DCMAKE_C_FLAGS="${COMPILE_FLAGS}" \
295+ -DCMAKE_CXX_COMPILER_TARGET="${TARGET_TRIPLE}" \
296+ -DCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN=${GCC_TOOLCHAIN} \
297+ -DCMAKE_CXX_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
298+ -DCMAKE_CXX_FLAGS="${COMPILE_FLAGS}" \
299+ -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" \
300+ -DCOMPILER_RT_BUILD_BUILTINS=ON \
301+ -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
302+ -DCOMPILER_RT_BUILD_MEMPROF=OFF \
303+ -DCOMPILER_RT_BUILD_PROFILE=OFF \
304+ -DCOMPILER_RT_BUILD_CTX_PROFILE=OFF \
305+ -DCOMPILER_RT_BUILD_SANITIZERS=OFF \
306+ -DCOMPILER_RT_BUILD_XRAY=OFF \
307+ -DCOMPILER_RT_BUILD_ORC=OFF \
308+ -DCOMPILER_RT_BUILD_CRT=OFF \
309+ -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
310+ -DCOMPILER_RT_EMULATOR="qemu-arm -L ${A_PROFILE_SYSROOT}" \
311+ -DCOMPILER_RT_INCLUDE_TESTS=ON \
312+ -DCOMPILER_RT_TEST_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
313+ -DCOMPILER_RT_TEST_COMPILER_CFLAGS="--target=${A_PROFILE_TARGET_TRIPLE} -march=armv7-a --gcc-toolchain=${A_PROFILE_GCC_TOOLCHAIN} --sysroot=${A_PROFILE_SYSROOT} -fuse-ld=lld" \
314+ -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
315+ -DCOMPILER_RT_OS_DIR="baremetal" \
316+ -DCOMPILER_RT_BAREMETAL_BUILD=ON
317+
318+ .. note ::
319+ The sysroot used for compiling the tests is ``arm-linux-gnueabihf ``, not
320+ ``arm-none-eabi `` which is used when compiling the builtins.
263321
264322The Armv6-M builtins will use the soft-float ABI. When compiling the tests for
265323Armv7-A we must include ``"-mthumb -mfloat-abi=soft -mfpu=none" `` in the
@@ -270,19 +328,3 @@ mismatches between the M-profile objects from compiler-rt and the A-profile
270328objects from the test. The lld linker does not check the profile
271329BuildAttribute so it can be used to link the tests by adding ``-fuse-ld=lld `` to the
272330``COMPILER_RT_TEST_COMPILER_CFLAGS ``.
273-
274- Alternative using a cmake cache
275- -------------------------------
276- If you wish to build, but not test compiler-rt for Armv6-M, Armv7-M or Armv7E-M
277- the easiest way is to use the ``BaremetalARM.cmake `` recipe in ``clang/cmake/caches ``.
278-
279- You will need a bare metal sysroot such as that provided by the GNU ARM Embedded
280- toolchain.
281-
282- The libraries can be built with the cmake options::
283-
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