blob: 4fdd2d4b2f7f75c3f1396aa80d17be31f3dd2155 [file] [log] [blame] [edit]
.. _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:
``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``:
.. code-block:: 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:
.. code-block:: sh
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 -C build libc.test.src.<HEADER>.<FUNCTION>_test.__unit__
For example, to run the test for ``isalpha`` in ``ctype.h``:
.. code-block:: 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:
.. code-block:: 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.
.. 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::
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 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.
.. code-block:: 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:
.. code-block:: 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:
.. code-block:: sh
CLANG_DIR=$(dirname $(readlink -f /usr/bin/clang))
2. Create a symlink to ``clang`` named ``llvm-libc-clang`` in that directory:
.. code-block:: 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:
.. code-block:: 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.
.. code-block:: C
// hello.c
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
Compile and run the example:
.. code-block:: sh
llvm-libc-clang hello.c
./a.out