Building runtimes and builtins for RISC-V baremetal target (riscv64-unknown-elf)

Hello, I am trying to bootstrap building runtimes and builtins (libc, libcxx, libcxxabi, libunwind, compiler-rt) for RISC-V baremetal target (riscv64-unknown-elf).

For libcxx, libcxxabi and libunwind I followed the instructions as described in Building libc++ — libc++ documentation. Basically, I set the CMake variable LLVM_ENABLE_RUNTIMES="libc;libcxx;libcxxabi;libunwind;compiler-rt".

cmake -G Ninja \
 -DCMAKE_INSTALL_PREFIX=/path/to/install \
 -DLLVM_DEFAULT_TARGET_TRIPLE=riscv64-unknown-elf \

I am running into different errors for each runtimes project:

  1. For libc:
CMake Error at libc/cmake/modules/LLVMLibCArchitectures.cmake:82 (message):
  libc build: Invalid or unknown libc compiler target triple:

I tried setting -DLLVM_RUNTIMES_TARGET=riscv64-unknown-elf but still get the same errors.

  1. For libcxx:
-- LLVM default target triple: riscv64-unknown-elf
-- Using libc++ testing configuration: libcxx/test/configs/
-- ABI list file not generated for configuration riscv64-unknown-elf.libcxxabi.v1.stable.exceptions.nonew, `check-cxx-abilist` will not be available.
-- Configuring done
CMake Error at libcxx/src/CMakeLists.txt:272 (add_custom_command):
  Error evaluating generator expression:


  Target "libcxx-abi-shared" not found
  1. For compiler-rt: For this, I built riscv-gnu-toolchain and tried passing it as sysroot for the build using the CMake variable -DRUNTIMES_CMAKE_ARGS="-DCMAKE_SYSROOT=/path/to/riscv-gnu-toolchain/riscv64-unknown-elf .
FAILED: CMakeFiles/clang_rt.builtins-riscv64.dir/enable_execute_stack.c.o
build/llvm/./bin/clang --target=riscv64-unknown-elf --sysroot=riscv-gnu-toolchain/riscv64-unknown-elf -DVISIBILITY_HIDDEN  -O3 -DNDEBUG -DCOMPILER_RT_HAS_FLOAT16 -std=c11 -fPIC -fno-builtin -fvisibility=hidden -fomit-frame-pointer -MD -MT CMakeFiles/clang_rt.builtins-riscv64.dir/enable_execute_stack.c.o -MF CMakeFiles/clang_rt.builtins-riscv64.dir/enable_execute_stack.c.o.d -o CMakeFiles/clang_rt.builtins-riscv64.dir/enable_execute_stack.c.o -c compiler-rt/lib/builtins/enable_execute_stack.c
compiler-rt/lib/builtins/enable_execute_stack.c:12:10: fatal error: 'sys/mman.h' file not found
#include <sys/mman.h>

And other errors such as:

error: unknown type name 'pthread_mutex_t'
error: use of undeclared identifier 'PTHREAD_MUTEX_INITIALIZER'
error: call to undeclared function 'pthread_setspecific'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
  pthread_setspecific(emutls_pthread_key, (void *)value);

My questions are:

  1. Are the instructions in Building libc++ — libc++ documentation sufficient to build libcxx, libcxxabi and libunwind?
  2. Where will the runtimes build pick up the required headers, libs, etc from? Are we supposed to provide it a sysroot? How should we specify the sysroot?
  3. Am I missing any other CMake flags that need to be set?

Tagging @petrhosek for attention as per our recent RISC-V sync up call.


1 Like

LLVM libc isn’t really production-ready, as far as I know.

For compiler-rt, you need C library headers from whatever libc you’re using.

For libcxx build, maybe try disabling LIBCXX_ENABLE_SHARED?

1 Like

compiler-rt needs COMPILER_RT_BAREMETAL_BUILD set to ON if you’re targeting a bare-metal environment.

1 Like

Thanks @efriedma-quic @jrtc27 for your suggestions.

After enabling COMPILER_RT_BAREMETAL_BUILD I am able to build compiler-rt!
Q: The compiler-rt lib that I built is named libclang_rt.builtins.a. How do I get the target name suffixed to the compiler-rt lib name (apart from manual post processing)? It seems clang-ld needs a library named libclang_rt.builtins-riscv64.a.

I haven’t had much luck on building libc++ yet. I tried disabling LIBCXX_ENABLE_SHARED but I run into thread-related errors like:

In file included from libcxx/src/filesystem/int128_builtins.cpp:16:
build/llvm/include/c++/v1/__config:941:8: error: "No thread API"
#      error "No thread API"

If I disable -DLIBCXX_ENABLE_THREADS I get errors like:

build/llvm/include/c++/v1/stdlib.h:150:34: error: unknown type name 'ldiv_t'
inline _LIBCPP_INLINE_VISIBILITY ldiv_t div(long __x, long __y) _NOEXCEPT {
build/llvm/include/c++/v1/stdlib.h:151:12: error: no member named 'ldiv' in the global namespace
  return ::ldiv(__x, __y);
build/llvm/include/c++/v1/stdlib.h:154:34: error: unknown type name 'lldiv_t'
inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x,
builtins/build/llvm/include/c++/v1/stdlib.h:156:12: error: no member named 'lldiv' in the global namespace
  return ::lldiv(__x, __y);
libcxx/src/verbose_abort.cpp:38:10: error: reference to unresolved using declaration
    std::vfprintf(stderr, format, list);
build/llvm/include/c++/v1/cstdio:130:1: note: using declaration annotated with 'using_if_exists' here
using ::vfprintf _LIBCPP_USING_IF_EXISTS;
libcxx/src/verbose_abort.cpp:38:19: error: use of undeclared identifier 'stderr'