@@ -25,9 +25,9 @@ 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
@@ -52,78 +52,94 @@ toolchain from https://developer.arm.com/open-source/gnu-toolchain/gnu-a/downloa
5252Building compiler-rt builtins for Arm
5353=====================================
5454
55- We will be doing a standalone build of compiler-rt using the following cmake
56- options::
55+ We will be doing a standalone build of compiler-rt. The command is shown below.
56+ Shell variables are used to simplify some of the options::
5757
58- cmake path/to/compiler-rt \
58+ LLVM_TOOLCHAIN=<path-to-llvm-install>/
59+ TARGET_TRIPLE=arm-none-linux-gnueabihf
60+ GCC_TOOLCHAIN=<path-to-gcc-toolchain>
61+ SYSROOT=${GCC_TOOLCHAIN}/${TARGET_TRIPLE}/libc
62+ COMPILE_FLAGS="-march=armv7-a"
63+
64+ cmake ../llvm-project/compiler-rt \
5965 -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_AR=${LLVM_TOOLCHAIN}/bin/llvm-ar \
67+ -DCMAKE_NM=${LLVM_TOOLCHAIN}/bin/llvm-nm \
68+ -DCMAKE_RANLIB=${LLVM_TOOLCHAIN}/bin/llvm-ranlib \
69+ -DLLVM_CMAKE_DIR="${LLVM_TOOLCHAIN}/lib/cmake/llvm" \
70+ -DCMAKE_SYSROOT="${SYSROOT}" \
71+ -DCMAKE_ASM_COMPILER_TARGET="${TARGET_TRIPLE}" \
72+ -DCMAKE_ASM_FLAGS="${COMPILE_FLAGS}" \
73+ -DCMAKE_C_COMPILER_TARGET="${TARGET_TRIPLE}" \
74+ -DCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN=${GCC_TOOLCHAIN} \
75+ -DCMAKE_C_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
76+ -DCMAKE_C_FLAGS="${COMPILE_FLAGS}" \
77+ -DCMAKE_CXX_COMPILER_TARGET="${TARGET_TRIPLE}" \
78+ -DCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN=${GCC_TOOLCHAIN} \
79+ -DCMAKE_CXX_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
80+ -DCMAKE_CXX_FLAGS="${COMPILE_FLAGS}" \
6681 -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" \
67- -DCMAKE_NM=/path/to/llvm-nm \
68- -DCMAKE_RANLIB=/path/to/llvm-ranlib \
6982 -DCOMPILER_RT_BUILD_BUILTINS=ON \
7083 -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
7184 -DCOMPILER_RT_BUILD_MEMPROF=OFF \
7285 -DCOMPILER_RT_BUILD_PROFILE=OFF \
86+ -DCOMPILER_RT_BUILD_CTX_PROFILE=OFF \
7387 -DCOMPILER_RT_BUILD_SANITIZERS=OFF \
7488 -DCOMPILER_RT_BUILD_XRAY=OFF \
89+ -DCOMPILER_RT_BUILD_ORC=OFF \
90+ -DCOMPILER_RT_BUILD_CRT=OFF \
7591 -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
76- -DLLVM_CONFIG_PATH=/path/to/llvm-config
92+ -DCOMPILER_RT_EMULATOR="qemu-arm -L ${SYSROOT}" \
93+ -DCOMPILER_RT_INCLUDE_TESTS=ON \
94+ -DCOMPILER_RT_TEST_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
95+ -DCOMPILER_RT_TEST_COMPILER_CFLAGS="--target=${TARGET_TRIPLE} ${COMPILE_FLAGS} --gcc-toolchain=${GCC_TOOLCHAIN} --sysroot=${SYSROOT} -fuse-ld=lld"
7796
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.
97+ .. note ::
98+ The command above also enables tests. Enabling tests is not required, more details
99+ in the testing section.
82100
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 ``) .
101+ `` CMAKE_<LANGUAGE>_<OPTION> `` options are set so that the correct `` --target ``,
102+ `` --sysroot ``, ``--gcc-toolchain `` and `` -march `` options will be given to the
103+ compilers .
86104
87- When using a GCC `` arm-linux-gnueabihf `` toolchain the following flags are
88- needed to pick up the includes and libraries:
105+ The combination of these settings needs to be enough to pass CMake's compiler
106+ checks, compile compiler-rt and build the test cases.
89107
90- * ``--gcc-toolchain=/path/to/dir/toolchain ``
91- * ``--sysroot=/path/to/toolchain/arm-linux-gnueabihf/libc ``
108+ The flags need to select:
109+ * The Arm target (``--target arm-none-linux-gnueabihf ``)
110+ * The Arm architecture level (``-march=armv7-a ``)
111+ * Whether to generate Arm (``-marm ``, the default) or Thumb (``-mthumb ``) instructions.
92112
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 ``::
113+ It is possible to pass all these flags to CMake using ``CMAKE_<LANGUAGE>_FLAGS ``,
114+ but the command above uses standard CMake options instead. If you need to
115+ add flags that CMake cannot generate automatically, add them to
116+ ``CMAKE_<LANGUAGE>_FLAGS ``.
96117
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
118+ When CMake has finished, build with Ninja::
101119
102- Once cmake has completed the builtins can be built with `` ninja builtins ``
120+ ninja builtins
103121
104122Testing compiler-rt builtins using qemu-arm
105123===========================================
106124
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 ``::
125+ The following options are required to enable tests::
126+
127+ -DCOMPILER_RT_EMULATOR="qemu-arm -L ${SYSROOT}" \
128+ -DCOMPILER_RT_INCLUDE_TESTS=ON \
129+ -DCOMPILER_RT_TEST_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
130+ -DCOMPILER_RT_TEST_COMPILER_CFLAGS="--target=${TARGET_TRIPLE} -march=armv7-a --gcc-toolchain=${GCC_TOOLCHAIN} --sysroot=${SYSROOT} -fuse-ld=lld"
110131
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"
132+ This tells compiler-rt that we want to run tests on ``qemu-arm ``. If you do not
133+ want to run tests, remove these options from the CMake command.
115134
116- The ``/path/to/armhf/sysroot `` should be the same as the one passed to
117- ``--sysroot `` in the ``build-c-flags ``.
135+ Note that ``COMPILER_RT_TEST_COMPILER_CFLAGS `` contains the equivalent of the
136+ options CMake generated for us with the first command. We must pass them
137+ manually here because standard options like ``CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN ``
138+ do not apply here.
118139
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 ``.
140+ When CMake has finished, run the tests::
124141
125- Once cmake has completed the tests can be built and run using
126- ``ninja check-builtins ``
142+ ninja check-builtins
127143
128144Troubleshooting
129145===============
@@ -133,9 +149,10 @@ The cmake try compile stage fails
133149At an early stage cmake will attempt to compile and link a simple C program to
134150test if the toolchain is working.
135151
136- This stage can often fail at link time if the ``--sysroot= `` and
152+ This stage can often fail at link time if the ``--sysroot= ``, `` --target `` or
137153``--gcc-toolchain= `` options are not passed to the compiler. Check the
138- ``CMAKE_C_FLAGS `` and ``CMAKE_C_COMPILER_TARGET `` flags.
154+ ``CMAKE_<LANGUAGE>_FLAGS `` and ``CMAKE_<LANGAUGE>_COMPILER_TARGET `` flags along
155+ with any of the specific CMake sysroot and toolchain options.
139156
140157It can be useful to build a simple example outside of cmake with your toolchain
141158to make sure it is working. For example::
@@ -179,10 +196,10 @@ The flags used to build the tests are not the same as those used to build the
179196builtins. The c flags are provided by ``COMPILER_RT_TEST_COMPILE_CFLAGS `` and
180197the ``CMAKE_C_COMPILER_TARGET ``, ``CMAKE_ASM_COMPILER_TARGET ``,
181198``CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN `` and ``CMAKE_SYSROOT `` flags are not
182- applied.
199+ applied to tests .
183200
184201Make sure that ``COMPILER_RT_TEST_COMPILE_CFLAGS `` contains all the necessary
185- information .
202+ flags .
186203
187204
188205Modifications for other Targets
@@ -206,13 +223,13 @@ You will need to use an ``arm-linux-gnueabi`` GNU toolchain for soft-float.
206223AArch64 Target
207224--------------
208225The instructions for Arm can be used for AArch64 by substituting AArch64
209- equivalents for the sysroot, emulator and target.
226+ equivalents for the sysroot, emulator and target::
210227
211- * `` -DCMAKE_C_COMPILER_TARGET=aarch64-linux-gnu ``
212- * `` -DCOMPILER_RT_EMULATOR="qemu-aarch64 -L /path/to/aarch64/sysroot ``
228+ -DCMAKE_C_COMPILER_TARGET=aarch64-linux-gnu
229+ -DCOMPILER_RT_EMULATOR="qemu-aarch64 -L /path/to/aarch64/sysroot
213230
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" ``
231+ You will also have to update any use of the target triple in compiler flags.
232+ For instance in `` CMAKE_C_FLAGS `` and `` COMPILER_RT_TEST_COMPILER_CFLAGS ``.
216233
217234Armv6-m, Armv7-m and Armv7E-M targets
218235-------------------------------------
@@ -235,31 +252,55 @@ into a binary and execute the tests correctly but it will not catch if the
235252builtins use instructions that are supported on Armv7-A but not Armv6-M,
236253Armv7-M and Armv7E-M.
237254
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"
255+ Below is an example that builds the builtins for Armv7-M, but runs the tests
256+ as Armv7-A. It is presented in full, but is very similar to the earlier
257+ command for Armv7-A build and test::
258+
259+ LLVM_TOOLCHAIN=<path-to-llvm-install>/
260+ TARGET_TRIPLE=arm-none-eabi
261+ GCC_TOOLCHAIN=<path-to-gcc-toolchain>
262+ SYSROOT=${GCC_TOOLCHAIN}/${TARGET_TRIPLE}/libc
263+ COMPILE_FLAGS="-march=armv7-m -mfpu=vfpv2"
264+
265+ cmake ../llvm-project/compiler-rt \
266+ -G Ninja \
267+ -DCMAKE_AR=${LLVM_TOOLCHAIN}/bin/llvm-ar \
268+ -DCMAKE_NM=${LLVM_TOOLCHAIN}/bin/llvm-nm \
269+ -DCMAKE_RANLIB=${LLVM_TOOLCHAIN}/bin/llvm-ranlib \
270+ -DLLVM_CMAKE_DIR="${LLVM_TOOLCHAIN}/lib/cmake/llvm" \
271+ -DCMAKE_SYSROOT="${SYSROOT}" \
272+ -DCMAKE_ASM_COMPILER_TARGET="${TARGET_TRIPLE}" \
273+ -DCMAKE_ASM_FLAGS="${COMPILE_FLAGS}" \
274+ -DCMAKE_C_COMPILER_TARGET="${TARGET_TRIPLE}" \
275+ -DCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN=${GCC_TOOLCHAIN} \
276+ -DCMAKE_C_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
277+ -DCMAKE_C_FLAGS="${COMPILE_FLAGS}" \
278+ -DCMAKE_CXX_COMPILER_TARGET="${TARGET_TRIPLE}" \
279+ -DCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN=${GCC_TOOLCHAIN} \
280+ -DCMAKE_CXX_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
281+ -DCMAKE_CXX_FLAGS="${COMPILE_FLAGS}" \
282+ -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" \
283+ -DCOMPILER_RT_BUILD_BUILTINS=ON \
284+ -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
285+ -DCOMPILER_RT_BUILD_MEMPROF=OFF \
286+ -DCOMPILER_RT_BUILD_PROFILE=OFF \
287+ -DCOMPILER_RT_BUILD_CTX_PROFILE=OFF \
288+ -DCOMPILER_RT_BUILD_SANITIZERS=OFF \
289+ -DCOMPILER_RT_BUILD_XRAY=OFF \
290+ -DCOMPILER_RT_BUILD_ORC=OFF \
291+ -DCOMPILER_RT_BUILD_CRT=OFF \
292+ -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
293+ -DCOMPILER_RT_EMULATOR="qemu-arm -L <path to arm-none-linux-gnueabihf toolchain>/arm-none-linux-gnueabihf/libc" \
294+ -DCOMPILER_RT_INCLUDE_TESTS=ON \
295+ -DCOMPILER_RT_TEST_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
296+ -DCOMPILER_RT_TEST_COMPILER_CFLAGS="--target=arm-none-linux-gnueabihf -march=armv7-a --gcc-toolchain=<path to arm-none-linux-gnueabihf toolchain> --sysroot=<path to arm-none-linux-gnueabihf toolchain>/arm-none-linux-gnueabihf/libc -fuse-ld=lld" \
297+ -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
298+ -DCOMPILER_RT_OS_DIR="baremetal" \
299+ -DCOMPILER_RT_BAREMETAL_BUILD=ON
300+
301+ .. note ::
302+ The sysroot used for compiling the tests is ``arm-linux-gnueabihf ``, not
303+ ``arm-none-eabi `` which is used when compiling the builtins.
263304
264305The Armv6-M builtins will use the soft-float ABI. When compiling the tests for
265306Armv7-A we must include ``"-mthumb -mfloat-abi=soft -mfpu=none" `` in the
@@ -270,19 +311,3 @@ mismatches between the M-profile objects from compiler-rt and the A-profile
270311objects from the test. The lld linker does not check the profile
271312BuildAttribute so it can be used to link the tests by adding ``-fuse-ld=lld `` to the
272313``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