[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
This commit is contained in:
parent
664663cbbf
commit
aa0e429576
@ -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
|
||||
``<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
|
||||
@ -37,12 +25,17 @@ documentation and verbose cmake logging, which are useful development features.
|
||||
``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 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.<HEADER>.<FUNCTION>_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.<HEADER>.<FUNCTION>_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:
|
||||
`<https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html>`_) which includes
|
||||
not only the components of LLVM's libc, but also a full LLVM only toolchain
|
||||
consisting of the `clang <https://clang.llvm.org/>`_ compiler, the
|
||||
`lld <https://lld.llvm.org/>`_ linker and the
|
||||
`compiler-rt <https://compiler-rt.llvm.org/>`_ 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++ <https://libcxx.llvm.org/>`_ 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++ <https://libcxx.llvm.org/>`_, 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 <https://llvm.org/docs/ScudoHardenedAllocator.html>`_ 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 <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::
|
||||
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/<TARGET TRIPLE>/asm``. Installing the
|
||||
``gcc-multilib`` package creates this symlink, or you can do it manually with
|
||||
this command:
|
||||
``sudo ln -s /usr/include/<TARGET TRIPLE>/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
|
||||
`<https://github.com/llvm/llvm-project/tree/main/libc/examples>`_ 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 ``<executable-name>.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 <<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 make sure you're using the newly built toolchain by trying out features
|
||||
that aren't yet supported by the system toolchain, such as fixed point. The
|
||||
following is an example program that demonstrates the difference:
|
||||
You can now use your newly built toolchain by running your wrapper.
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
// $ $SYSROOT/bin/clang example.c -static -ffixed-point --sysroot=$SYSROOT
|
||||
|
||||
// hello.c
|
||||
#include <stdio.h>
|
||||
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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user