Skip to content

[llvm][docs] Update CMake commands for cross compiling Arm builtins #151544

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

DavidSpickett
Copy link
Collaborator

@DavidSpickett DavidSpickett commented Jul 31, 2025

This does a few things:

  • LLVM_CONFIG_PATH is deprecated, use LLVM_CMAKE_DIR instead.
  • Don't use $ before command examples. I would normally, but the key cmake commands didn't use it so I removed it from all commands.
  • Makes the commands shown full commands, so you don't have to piece them together.
  • Uses shell variables to cut down on repetition and make this easier to port to other targets.
  • Adds a few options to disable more compiler-rt things.
  • Use the built in cmake options for sysroot and toolchains.
  • Include test options in the first cmake command, so you don't have to re-do the whole thing after you read the testing section.
  • Removes the section about using BaremetalARM.cmake.

The closest I got to getting that cache to work was:

SYSROOT=/home/david.spickett/arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-eabi/arm-none-eabi/libc
LLVM_TOOLCHAIN=/home/david.spickett/LLVM-20.1.8-Linux-X64/

cmake \
  -G Ninja \
  -DCMAKE_C_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
  -DBAREMETAL_ARMV6M_SYSROOT=${SYSROOT} \
  -DBAREMETAL_ARMV7M_SYSROOT=${SYSROOT} \
  -DBAREMETAL_ARMV7EM_SYSROOT=${SYSROOT} \
  -DCMAKE_BUILD_TYPE=Release \
  -DLLVM_ENABLE_RUNTIMES="compiler-rt" \
  -C ../llvm-project/clang/cmake/caches/BaremetalARM.cmake \
  -DCOMPILER_RT_BUILD_BUILTINS=ON \
  -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
  -DCOMPILER_RT_BUILD_MEMPROF=OFF \
  -DCOMPILER_RT_BUILD_PROFILE=OFF \
  -DCOMPILER_RT_BUILD_CTX_PROFILE=OFF \
  -DCOMPILER_RT_BUILD_SANITIZERS=OFF \
  -DCOMPILER_RT_BUILD_XRAY=OFF \
  -DCOMPILER_RT_BUILD_ORC=OFF \
  -DCOMPILER_RT_BUILD_CRT=OFF \
  ../llvm-project/runtimes

All this does is build the x86 builtins. I tried forcing the issue with:

  -DBUILTIN_SUPPORTED_ARCH="armv7m;armv6m;armv7em" \

But again, just x86.

It's probably something deep in compiler-rt failing a compiler check for the Arm targets. Even if that's the case, fixing that means adding more options to the cmake command.

I can't find evidence of a full command using this cache file since the commit that introduced it and that command no longer works.

I think if you ever got this to work again the command would be as long and complex as the ones already shown in the document.

I would also argue that some of the other caches, for example Fuschia's, are much better example of multi-target runtimes builds. If what's in this document isn't enough, folks should be learning from those files and about the runtimes build overall before attempting anything complex (though it does not take much to be "complex").

This does a few things:
* LLVM_CONFIG_PATH is deprecated, use LLVM_CMAKE_DIR instead.
* Don't use $ before command examples. I would normally, but the
  key cmake commands didn't use it so I removed it from all commands.
* Makes the commands shown full commands, so you don't have to piece
  them together.
* Uses shell variables to cut down on repetition and make this
  easier to port to other targets.
* Adds a few options to disable more compiler-rt things.
* Include test options in the first cmake command, so you don't
  have to re-do the whole thing after you read the testing section.
* Removes the section about using BaremetalARM.cmake.

The closest I got to getting that cache to work was:
```
SYSROOT=/home/david.spickett/arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-eabi/arm-none-eabi/libc
LLVM_TOOLCHAIN=/home/david.spickett/LLVM-20.1.8-Linux-X64/

cmake \
  -G Ninja \
  -DCMAKE_C_COMPILER=${LLVM_TOOLCHAIN}/bin/clang \
  -DBAREMETAL_ARMV6M_SYSROOT=${SYSROOT} \
  -DBAREMETAL_ARMV7M_SYSROOT=${SYSROOT} \
  -DBAREMETAL_ARMV7EM_SYSROOT=${SYSROOT} \
  -DCMAKE_BUILD_TYPE=Release \
  -DLLVM_ENABLE_RUNTIMES="compiler-rt" \
  -C ../llvm-project/clang/cmake/caches/BaremetalARM.cmake \
  -DCOMPILER_RT_BUILD_BUILTINS=ON \
  -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
  -DCOMPILER_RT_BUILD_MEMPROF=OFF \
  -DCOMPILER_RT_BUILD_PROFILE=OFF \
  -DCOMPILER_RT_BUILD_CTX_PROFILE=OFF \
  -DCOMPILER_RT_BUILD_SANITIZERS=OFF \
  -DCOMPILER_RT_BUILD_XRAY=OFF \
  -DCOMPILER_RT_BUILD_ORC=OFF \
  -DCOMPILER_RT_BUILD_CRT=OFF \
  ../llvm-project/runtimes
```
All this does is build the x86 builtins. I tried forcing the issue with:
```
  -DBUILTIN_SUPPORTED_ARCH="armv7m;armv6m;armv7em" \
```
But again, just x86.

It's probably something deep in compiler-rt failing a compiler check
for the Arm targets. Even if that's the case, fixing that means adding
more options to the cmake command.

I can't find evidence of a full command using this cache file since
the commit that introduced it and that command no longer works.

I think if you ever got this to work again the command would be as
long and complex as the ones already shown in the document.

I would also argue that some of the other caches, for example Fuschia's,
are much better example of multi-target runtimes builds. If what's
in this document isn't enough, folks should be learning from those
files and about the runtimes build overall before attempting anything
complex (though it does not take much to be "complex").
@DavidSpickett
Copy link
Collaborator Author

DavidSpickett commented Jul 31, 2025

I looked at whether it should use the runtimes build and maybe it will eventually but it's easier to not have to explain any of that here. It's still valid, as far as I know, to configure using compiler-rt/.

-DCOMPILER_RT_BUILD_ORC=OFF \
-DCOMPILER_RT_BUILD_CRT=OFF \
-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
-DCOMPILER_RT_EMULATOR="qemu-arm -L <path to arm-none-linux-gnueabihf toolchain>/arm-none-linux-gnueabihf/libc" \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a variable for <path to arm-none-linux-gnueabihf toolchain>, since you're using it in multiple places?

And maybe a brief explanation of why you need the baremetal toolchain, since it isn't obvious (ref #127227).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the variables.

There's two parts to why we need so many sysroots. The first is needing C library headers at all, so I've added a note at the beginning of the doc saying that.

The second is making sure the toolchain is set up for the correct target so you don't build "bare metal" builtins that actually make some Linux assumption. That I have noted in this section in a new paragraph before the cmake command.

I was actually able to use the A profile toolchain for both builtins (M profile target) and tests (A profile target). I don't want to recommend that though because it seems like a compatibility issue waiting to happen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants