From aa0e429576cfb496e66f6bbe76df8982aab6b083 Mon Sep 17 00:00:00 2001 From: Jeff Bailey Date: Thu, 12 Feb 2026 07:54:34 +0000 Subject: [PATCH] [libc] Rewrite "Full Host Build" instructions (#180439) This commit restructures the full_host_build.rst documentation to better serve two use cases: 1. Standard Building and Testing: Add a new introductory section with simplified instructions for local development. This covers basic build configuration, building/testing without a full sysroot, and documentation generation. 2. Building a Sysroot: Reorganize the comprehensive sysroot setup instructions into a clear 5-step guide: - Step 1: Preparation (environment variables) - Step 2: Linux Headers (copying headers into sysroot) - Step 3: Build and Install Runtimes (cmake configuration and ninja build) - Step 4: Configure the Compiler Wrapper (creating clang config file) - Step 5: Verification (testing with sample C program) Key improvements: - Restructure content to lead with simpler development workflow - Replace bootstrapping build instructions with clearer sysroot instructions - Fix typo: "non-triivial" -> "non-trivial" - Remove directory changes that can be confusing. All commands are run from the root of the llvm tree - Improve code block formatting and add complete working examples - Make it easy to cut and paste shell commands - Simplify "Hello, World!" example - Simplify and clarify assumptions and requirements - Remove obsolete notes about C++ standard library support Tested: * Built runtimes build and tests * Built sysroot and verified with sample C program * Verified document builds and looks right in VSCode browser --- libc/docs/full_host_build.rst | 265 ++++++++++++++++++---------------- 1 file changed, 141 insertions(+), 124 deletions(-) diff --git a/libc/docs/full_host_build.rst b/libc/docs/full_host_build.rst index 12aacf181695..ab410af9efa2 100644 --- a/libc/docs/full_host_build.rst +++ b/libc/docs/full_host_build.rst @@ -13,23 +13,11 @@ Full Host Build pyyaml. The minimum versions are listed on the :ref:`header_generation` page, as well as additional information. -In this document, we will present a recipe to build the full libc for the host. -When we say *build the libc for the host*, the goal is to build the libc for -the same system on which the libc is being built. First, we will explain how to -build for developing LLVM-libc, then we will explain how to build LLVM-libc as -part of a complete toolchain. - -Configure the build for development -=================================== - - -Below is the list of commands for a simple recipe to build LLVM-libc for -development. In this we've set the Ninja generator, set the build type to -"Debug", and enabled the Scudo allocator. This build also enables generating the -documentation and verbose cmake logging, which are useful development features. +Standard Building and Testing +============================= .. note:: - if your build fails with an error saying the compiler can't find + If your build fails with an error saying the compiler can't find ```` or similar then you're probably missing the symlink from ``/usr/include/asm`` to ``/usr/include//asm``. Installing the ``gcc-multilib`` package creates this symlink, or you can do it manually with @@ -37,12 +25,17 @@ documentation and verbose cmake logging, which are useful development features. ``sudo ln -s /usr/include//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 faster and sufficient for most contributors. + +To configure the build, create a build directory and run ``cmake``: + .. code-block:: sh - $> cd llvm-project # The llvm-project checkout - $> mkdir build - $> cd build - $> cmake ../runtimes \ + cmake \ + -B build \ + -S runtimes \ -G Ninja \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ @@ -57,162 +50,186 @@ documentation and verbose cmake logging, which are useful development features. -DLLVM_ENABLE_SPHINX=ON -DLIBC_INCLUDE_DOCS=ON \ -DLIBC_CMAKE_VERBOSE_LOGGING=ON -Build and test -============== - -After configuring the build with the above ``cmake`` command, one can build test -libc with the following command: +After configuring the build, you can build the libc, math library, and run the +tests with the following command: .. code-block:: sh - $> ninja libc libm check-libc - -To build the docs run this command: + ninja -C build libc libm check-libc +To run a specific unit test for a function, you can target it directly using its +full name: .. code-block:: sh - $> ninja docs-libc-html + ninja -C build libc.test.src.
._test.__unit__ -To run a specific test, use the following: +For example, to run the test for ``isalpha`` in ``ctype.h``: .. code-block:: sh - $> ninja libc.test.src.
._test.__unit__ - $> ninja libc.test.src.ctype.isalpha_test.__unit__ # EXAMPLE + ninja -C build libc.test.src.ctype.isalpha_test.__unit__ -Configure the complete toolchain build -====================================== +Building Documentation +====================== -For a complete toolchain we recommend creating a *sysroot* (see the documentation -of the ``--sysroot`` option here: -``_) which includes -not only the components of LLVM's libc, but also a full LLVM only toolchain -consisting of the `clang `_ compiler, the -`lld `_ linker and the -`compiler-rt `_ runtime libraries. LLVM-libc is -not quite complete enough to allow using and linking a C++ application against -a C++ standard library (like libc++). Hence, we do not include -`libc++ `_ in the sysroot. +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``). -.. note:: When the libc is complete enough, we should be able to include - `libc++ `_, libcxx-abi and libunwind in the - LLVM only toolchain and use them to build and link C++ applications. +To generate the HTML documentation: -Below is the cmake command for a bootstrapping build of LLVM. This will build -clang and lld with the current system's toolchain, then build compiler-rt and -LLVM-libc with that freshly built clang. This ensures that LLVM-libc can take -advantage of the latest clang features and optimizations. +.. code-block:: sh -This build also uses Ninja as cmake's generator, and sets lld and compiler-rt as -the default for the fresh clang. Those settings are recommended, but the build -should still work without them. The compiler-rt options are required for -building `Scudo `_ as the -allocator for LLVM-libc. + 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 `_. + + +Step 1: Preparation +------------------- + +First, set up the environment variables for your sysroot path and the major +version of your host Clang. + +.. code-block:: 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. + +.. code-block:: 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/ .. note:: - if your build fails with an error saying the compiler can't find - ```` or similar then you're probably missing the symlink from - ``/usr/include/asm`` to ``/usr/include//asm``. Installing the - ``gcc-multilib`` package creates this symlink, or you can do it manually with - this command: - ``sudo ln -s /usr/include//asm /usr/include/asm`` + 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. + +Step 3: Build and Install Runtimes +---------------------------------- + +Now, configure the build for LLVM libc and compiler-rt. We're building with +llvm instead of runtimes because we need to install the +``clang-resource-headers`` that provide ``stdarg.h``, ``stddef.h`` and others. .. code-block:: sh - $> cd llvm-project # The llvm-project checkout - $> mkdir build - $> cd build - $> SYSROOT=/path/to/sysroot # Remember to set this! - $> cmake ../llvm \ - -G Ninja \ - -DLLVM_ENABLE_PROJECTS="clang;lld" \ + 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 \ - -DCMAKE_C_COMPILER=clang \ - -DCMAKE_CXX_COMPILER=clang++ \ + -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 \ - -DCLANG_DEFAULT_LINKER=lld \ - -DCLANG_DEFAULT_RTLIB=compiler-rt \ - -DCMAKE_INSTALL_PREFIX=$SYSROOT + -DCOMPILER_RT_BUILD_BUILTINS:BOOL=TRUE \ + -DCOMPILER_RT_BUILD_CRT:BOOL=TRUE \ + -DCOMPILER_RT_BUILD_GWP_ASAN:BOOL=FALSE -Build and install -================= - -.. TODO: add this warning to the cmake -.. warning:: - Running these install commands without setting a ``$SYSROOT`` will install - them into your system include path, which may break your system. If you're - just trying to develop libc, then just run ``ninja check-libc`` to build the - libc and run the tests. If you've already accidentally installed the headers, - you may need to delete them from ``/usr/local/include``. - -After configuring the build with the above ``cmake`` command, one can build and -install the toolchain with +After configuring, build and install the necessary components: .. code-block:: sh - $> ninja install-clang install-builtins install-compiler-rt \ - install-core-resource-headers install-libc install-lld + ninja -C build-runtimes install-clang-resource-headers install-libc install-compiler-rt install-builtins -or +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: .. code-block:: sh - $> ninja install + CLANG_DIR=$(dirname $(readlink -f /usr/bin/clang)) -Once the above command completes successfully, the ``$SYSROOT`` directory you -have specified with the CMake configure step above will contain a full LLVM-only -toolchain with which you can build practical/real-world C applications. See -``_ for examples -of how to start using this new toolchain. - -Linux Headers -============= - -If you are using the full libc on Linux, then you will also need to install -Linux headers in your sysroot. Let's build them from source. +2. Create a symlink to ``clang`` named ``llvm-libc-clang`` in that directory: .. code-block:: sh - $> git clone --depth=1 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git /tmp/linux - $> make LLVM=1 INSTALL_HDR_PATH=/path/to/sysroot -C /tmp/linux headers_install + sudo ln -sf $CLANG_DIR/clang /usr/bin/llvm-libc-clang -The headers can be built to target non-host architectures by adding the -``ARCH={arm|arm64|i386}`` to the above invocation of ``make``. - -Using your newly built libc -=========================== - -You can now use your newly built libc nearly like you would use any compiler -invocation: +3. Create the configuration file in the same directory. Clang automatically looks + for a file named ``.cfg`` in the same directory as the + executable. Use the following command to generate it with your environment + variables: .. code-block:: sh - $> /path/to/sysroot/bin/clang -static main.c + CLANG_VERSION=$(build-runtimes/bin/clang -dumpversion | cut -d. -f1) -.. warning:: - Because the libc does not yet support dynamic linking, the -static parameter - must be added to all clang invocations. + cat < int main() { - printf("Hello, World!\n%.9f\n%.9lK\n", - 4294967295.000000001, - 4294967295.000000001ulK); + printf("Hello, World!\n"); return 0; } +Compile and run the example: + +.. code-block:: sh + + llvm-libc-clang hello.c + ./a.out +