Building compiler-rt for RISC-V?

My overall goal is locally building [1] an LLVM toolchain which compiles a mixture of C and supporting assembler for bare RISC-V development environments (no OS). Library support is required for some language features on some RISC-V targets, e.g. integer division when the “M” extension isn’t present.

From the details on I expected that something like this on release/12.x would build the support library for RISC-V:

cmake -G Ninja …/llvm -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=‘clang;lld;compiler-rt’ -DCMAKE_INSTALL_PREFIX=~/bin/s4e -DLLVM_TARGETS_TO_BUILD=‘RISCV’
ninja install

however although that yields the RISCV compiler target libraries (libLLVMRISCV*.a) it doesn’t install any obvious RISCV runtime libraries (only x86 ones) and linking a test program with integer division fails:

clang testdiv.c --target=riscv32 -march=rv32i
ld.lld: error: unable to find library -lc
ld.lld: error: unable to find library -lm
ld.lld: error: unable to find library -lclang_rt.builtins-riscv32

(using LLVM release/12.x on x86_64 release/12.x; also tried building all targets and also copying the cmake line from a build triggered by Phabricator for a RISC-V-related change to compiler-rt with the hope that some of the additional defines would prove the solution)

Thanks in advance for whatever advice you can provide for building the support libraries for RISC-V.

Tom Goodfellow

[1] in the very short-term obtaining working ones from another build would suffice, however I’ll be needing to modify them soon anyway.

Your --target= is not correct.

Normally, if you use --target=aarch64-linux-gnu, the clang driver will pick up crt1.o crti.o crtn.o libc libm from libc, crtbegin.o/crtend.o from aarch64-linux-gnu-gcc.
The libc and gcc paths are detected by locating aarch64-linux-gnu-gcc.
riscv may be more strange on some systems due to the complex multiarch/multilib scheme.

Thank you for the hint - while it’s certainly possible that with a better choice of target the link would attempt other libraries, there is no RISC-V compiler runtime library being built at all. Linking “testdiv.c” without libraries fails as would be expected with an undefined reference to the symbol “__divsi3”

Looking for this symbol across the release/12.0 installed binaries it’s only present in the x86 support:


perhaps suggesting that the list of LLVM_TARGETS_TO_BUILD isn’t applied to the compiler-rt build? However when building compiler-rt separately I didn’t yet find a working way to specify targets.

When compiling compiler-rt standalone (instead of as part of the
overall LLVM build) I have in the past used the following for the
rv32i build:

FLAGS="--target=riscv32-unknown-elf -march=rv32i -mabi=ilp32
--gcc-toolchain=$GCC_TOOLCHAIN --sysroot=$SYSROOT"

cmake $LLVM/compiler-rt \
  -G "Ninja" \
  -DCMAKE_AR=$LLVM_BUILD/bin/llvm-ar \
  -DCMAKE_NM=$LLVM_BUILD/bin/llvm-nm \
  -DCMAKE_RANLIB=$LLVM_BUILD/bin/llvm-ranlib \
  -DCMAKE_C_COMPILER_TARGET="riscv32-unknown-elf" \
  -DCMAKE_ASM_COMPILER_TARGET="riscv32-unknown-elf" \
  -DCOMPILER_RT_OS_DIR="baremetal" \

For compiling Compiler-RT as part of an integrated LLVM build, IIRC
you want to add it to the runtimes list (LLVM_ENABLE_RUNTIMES) and not
as a subproject. You can use cmake cache files to configure the
runtimes, and LLVM/compiler-rt has a weird setup for parsing cmake
settings of the form RUNTIMES_${target}_*. Check the existing cmake
cache files.

I hope that helps.


A very belated thanks and follow-up to your helpful mail:

Building standalone worked, but it feels inelegant to need the GCC RISCV toolchain present for building the LLVM equivalent (at least in shallow experiments it seems that the --gcc-toolchain really needs to point at a cross-target gcc). Is it planned that the build becomes self-sufficient?