(full_host_build)=
:::{note} Fullbuild requires running headergen, which is a python program that depends on pyyaml. The minimum versions are listed on the {ref}header_generation page, as well as additional information. :::
:::{note} If your build fails with an error saying the compiler can‘t find <asm/unistd.h> or similar then you’re probably missing the symlink from /usr/include/asm to /usr/include/<HOST TRIPLE>/asm. Installing the gcc-multilib package creates this symlink, or you can do it manually with this command:
sudo ln -s /usr/include/<HOST TRIPLE>/asm /usr/include/asm
(your host triple will probably be similar to x86_64-linux-gnu) :::
For basic development, such as adding new functions or fixing bugs, you can build and test the libc directly without setting up a full sysroot. This approach is using the runtimes build (see {ref}build_concepts for more information) and is faster and sufficient for most contributors.
To configure the build, create a build directory and run cmake:
cmake \ -B build \ -S runtimes \ -G Ninja \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DLLVM_ENABLE_RUNTIMES="libc;compiler-rt" \ -DLLVM_LIBC_FULL_BUILD=ON \ -DCMAKE_BUILD_TYPE=Debug \ -DLLVM_LIBC_INCLUDE_SCUDO=ON \ -DCOMPILER_RT_BUILD_SCUDO_STANDALONE_WITH_LLVM_LIBC=ON \ -DCOMPILER_RT_BUILD_GWP_ASAN=OFF \ -DCOMPILER_RT_SCUDO_STANDALONE_BUILD_SHARED=OFF \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DLLVM_ENABLE_SPHINX=ON -DLIBC_INCLUDE_DOCS=ON \ -DLIBC_CMAKE_VERBOSE_LOGGING=ON
After configuring the build, you can build the libc, math library, and run the tests with the following command:
ninja -C build libc libm check-libc
To build just the generated headers (useful for troubleshooting):
ninja -C build generate-libc-headers
To run a specific unit test for a function, you can target it directly using its full name:
ninja -C build libc.test.src.<HEADER>.<FUNCTION>_test.__unit__
For example, to run the test for isalpha in ctype.h:
ninja -C build libc.test.src.ctype.isalpha_test.__unit__
If you have Sphinx installed, you can build the libc documentation locally. The build configuration above already includes the necessary flags (-DLLVM_ENABLE_SPHINX=ON -DLIBC_INCLUDE_DOCS=ON).
To generate the HTML documentation:
ninja -C build docs-libc-html
The generated documentation will be available in the docs/libc/html directory within your build folder.
:::{warning} The LLVM libc is missing many critical functions needed to build non-trivial applications. If you are not currently working on porting the libc, we recommend sticking with your system libc. However, ignoring warnings like this are how most of us got into this business. So: Speak friend and enter. :::
This document describes how to set up a simple sysroot and a compiler that uses it from scratch. These are not full cross-compilation instructions. We make a few assumptions:
For more comprehensive instructions on setting up a sysroot, see the official LLVM guide.
First, set up the environment variables for your sysroot path and the major version of your host Clang.
SYSROOT=$(readlink -f ~/sysroot)
Next, install the Linux kernel headers into your sysroot. For this guide, we‘ll copy the headers from the host system’s /usr/include directory. This includes linux, asm-generic, and the architecture-specific asm headers.
# Create the include directory mkdir -p $SYSROOT/usr/include # Copy the header directories cp -R /usr/include/linux $SYSROOT/usr/include/ cp -R /usr/include/asm-generic $SYSROOT/usr/include/ # Use -L to dereference the asm symlink and copy the actual files cp -R -L /usr/include/asm $SYSROOT/usr/include/
If you instead want to build the headers from the kernel sources, you can run the following commands:
# Create the include directory mkdir -p $SYSROOT/usr/include git clone --depth=1 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git /tmp/linux make LLVM=1 INSTALL_HDR_PATH=$SYSROOT/usr -C /tmp/linux headers_install
The headers can be built to target non-host architectures by adding the ARCH={arm|arm64|i386} to the above invocation of make.
:::{note} For a more production-ready sysroot, you would typically download a specific kernel version and install the headers using make headers_install configured for the target architecture and installation path using the above instructions. :::
Now, configure the build for LLVM libc and compiler-rt. We're using the bootstrap build (see {ref}build_concepts) because we need to build the full clang and then install the clang-resource-headers that provide stdarg.h, stddef.h and others.
cmake \ -S llvm \ -B build-runtimes \ -G Ninja \ -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF \ -DCMAKE_INSTALL_PREFIX=$SYSROOT/usr \ -DLLVM_ENABLE_PROJECTS="clang" \ -DLLVM_ENABLE_RUNTIMES="libc;compiler-rt" \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_LIBC_FULL_BUILD=ON \ -DLIBC_INCLUDE_DOCS=OFF \ -DLLVM_LIBC_INCLUDE_SCUDO=ON \ -DCOMPILER_RT_BUILD_SCUDO_STANDALONE_WITH_LLVM_LIBC=ON \ -DCOMPILER_RT_BUILD_GWP_ASAN=OFF \ -DCOMPILER_RT_SCUDO_STANDALONE_BUILD_SHARED=OFF \ -DCOMPILER_RT_BUILD_BUILTINS:BOOL=TRUE \ -DCOMPILER_RT_BUILD_CRT:BOOL=TRUE
After configuring, build and install the necessary components:
ninja -C build-runtimes install-clang-resource-headers install-libc install-compiler-rt install-builtins
To make using the new toolchain easier, you can create a Clang configuration file. This allows you to avoid passing long command line arguments every time you compile a program.
CLANG_DIR=$(dirname $(readlink -f /usr/bin/clang))
clang named llvm-libc-clang in that directory:sudo ln -sf $CLANG_DIR/clang /usr/bin/llvm-libc-clang
<executable-name>.cfg in the same directory as the executable. Use the following command to generate it with your environment variables:CLANG_VERSION=$(build-runtimes/bin/clang -dumpversion | cut -d. -f1) cat <<EOF | sudo tee $CLANG_DIR/llvm-libc-clang.cfg --target=x86_64-unknown-linux-llvm --sysroot=$SYSROOT -resource-dir=$SYSROOT/usr/lib/clang/$CLANG_VERSION --rtlib=compiler-rt --unwindlib=none -static EOF
You can now use your newly built toolchain by running your wrapper.
// hello.c #include <stdio.h> int main() { printf("Hello, World!\n"); return 0; }
Compile and run the example:
llvm-libc-clang hello.c ./a.out