| (full_host_build)= | |
| # 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. | |
| ::: | |
| ## Standard Building and Testing | |
| :::{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: | |
| ```sh | |
| 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`: | |
| ```sh | |
| 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: | |
| ```sh | |
| ninja -C build libc libm check-libc | |
| ``` | |
| To build just the generated headers (useful for troubleshooting): | |
| ```sh | |
| ninja -C build generate-libc-headers | |
| ``` | |
| To run a specific unit test for a function, you can target it directly using its | |
| full name: | |
| ```sh | |
| ninja -C build libc.test.src.<HEADER>.<FUNCTION>_test.__unit__ | |
| ``` | |
| For example, to run the test for `isalpha` in `ctype.h`: | |
| ```sh | |
| ninja -C build libc.test.src.ctype.isalpha_test.__unit__ | |
| ``` | |
| ## Building Documentation | |
| 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: | |
| ```sh | |
| ninja -C build docs-libc-html | |
| ``` | |
| The generated documentation will be available in the `docs/libc/html` directory | |
| within your build folder. | |
| ## Building a Simple Sysroot | |
| :::{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: | |
| - The host and target are the same architecture and OS. For example, building | |
| a Linux x86-64 libc on a Linux x86-64 host. | |
| - The host has a working and recent Clang toolchain. Clang 21 has been tested. | |
| - Your container is using Debian Testing or a derived distribution. Other | |
| distributions likely work but the package names and paths may differ. | |
| - You have root access to your machine to set up the compiler wrapper. | |
| For more comprehensive instructions on setting up a sysroot, see the [official LLVM | |
| guide](https://llvm.org/docs/HowToCrossCompileLLVM.html#setting-up-a-sysroot). | |
| ### Step 1: Preparation | |
| First, set up the environment variables for your sysroot path and the major | |
| version of your host Clang. | |
| ```sh | |
| SYSROOT=$(readlink -f ~/sysroot) | |
| ``` | |
| ### Step 2: Linux Headers | |
| 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. | |
| ```sh | |
| # 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: | |
| ```sh | |
| # 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. | |
| ::: | |
| ### Step 3: Build and Install Runtimes | |
| 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. | |
| ```sh | |
| 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: | |
| ```sh | |
| ninja -C build-runtimes install-clang-resource-headers install-libc install-compiler-rt install-builtins | |
| ``` | |
| ### Step 4: Configure the Compiler Wrapper | |
| 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. | |
| 1. Identify the directory where your Clang binary is located: | |
| ```sh | |
| CLANG_DIR=$(dirname $(readlink -f /usr/bin/clang)) | |
| ``` | |
| 2. Create a symlink to `clang` named `llvm-libc-clang` in that directory: | |
| ```sh | |
| sudo ln -sf $CLANG_DIR/clang /usr/bin/llvm-libc-clang | |
| ``` | |
| 3. Create the configuration file in the same directory. Clang automatically looks | |
| for a file named `<executable-name>.cfg` in the same directory as the | |
| executable. Use the following command to generate it with your environment | |
| variables: | |
| ```sh | |
| 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 | |
| ``` | |
| ### Step 5: Verification | |
| You can now use your newly built toolchain by running your wrapper. | |
| ```c | |
| // hello.c | |
| #include <stdio.h> | |
| int main() { | |
| printf("Hello, World!\n"); | |
| return 0; | |
| } | |
| ``` | |
| Compile and run the example: | |
| ```sh | |
| llvm-libc-clang hello.c | |
| ./a.out | |
| ``` |