[libc-commits] [libc] b2f5992 - [libc][docs][NFC] Document cross-compilation testing with QEMU (#188838)
via libc-commits
libc-commits at lists.llvm.org
Fri Mar 27 08:14:43 PDT 2026
Author: Jeff Bailey
Date: 2026-03-27T15:14:38Z
New Revision: b2f59924124c636f948a2a0943bb733678d18647
URL: https://github.com/llvm/llvm-project/commit/b2f59924124c636f948a2a0943bb733678d18647
DIFF: https://github.com/llvm/llvm-project/commit/b2f59924124c636f948a2a0943bb733678d18647.diff
LOG: [libc][docs][NFC] Document cross-compilation testing with QEMU (#188838)
Added a "Building and Testing with an Emulator" section to
full_cross_build.rst using riscv64 and qemu-riscv64 as the example.
Outlined necessary CMake flags for cross-compiling with Clang, including
CMAKE_C_COMPILER_TARGET, CMAKE_CXX_COMPILER_TARGET, and
LLVM_ENABLE_LLD=ON. Switched from CMAKE_SYSROOT to LIBC_KERNEL_HEADERS
and added the gcc-riscv64-linux-gnu package dependency to ensure sysroot
issues on Debian-based systems are avoided while retaining access to
cross-compiler runtime objects.
Explained the self-hosted libc-hermetic-tests target as the required
target for executing tests during a standalone cross build, since the
standard check-libc tests are not hermetic.
Refactored existing CMake examples in full_cross_build.rst to use -S and
-B flags instead of cd and mkdir.
Removed prompt characters from code blocks and separated host
environment setup into explicit code blocks for easier copy-pasting.
Also removed the initial 'cd llvm-project' directory changes to reduce
boilerplate.
Added a cross-reference to the new emulator section in
build_and_test.rst.
Added:
Modified:
libc/docs/build_and_test.rst
libc/docs/full_cross_build.rst
Removed:
################################################################################
diff --git a/libc/docs/build_and_test.rst b/libc/docs/build_and_test.rst
index d608591288cf1..ddbbe1a8897fb 100644
--- a/libc/docs/build_and_test.rst
+++ b/libc/docs/build_and_test.rst
@@ -108,3 +108,10 @@ As an example, to build and test in a container for 32-bit Arm:
--arch arm docker.io/ubuntu:jammy bash
#. Install necessary packages, invoke CMake, build, and run tests.
+
+Building and Testing with an Emulator
+=====================================
+
+If you are cross-compiling the libc for a
diff erent architecture, you can use an emulator
+such as QEMU to run the tests directly on your host without a container. See
+:ref:`full_cross_build` for detailed instructions on configuring CMake to use an emulator.
diff --git a/libc/docs/full_cross_build.rst b/libc/docs/full_cross_build.rst
index 436396d7acf46..e452910fc5780 100644
--- a/libc/docs/full_cross_build.rst
+++ b/libc/docs/full_cross_build.rst
@@ -43,25 +43,43 @@ to explicitly build the build tools first and then build the libc. A point to
keep in mind is that the compiler used should be capable of building for the
host as well as the target.
+.. note::
+ Even though the LLVM libc provides its own complete C library implementation,
+ compiling it for a Linux target still requires the Linux kernel API headers for
+ that architecture. On Debian-based systems, these and other standard cross-compilation
+ runtimes (like ``libgcc``) can be installed via packages like
+ ``gcc-riscv64-linux-gnu`` and ``linux-libc-dev-riscv64-cross`` (or similar for
+ other architectures). You will need to point CMake to the kernel headers using
+ ``-DLIBC_KERNEL_HEADERS`` (e.g.,
+ ``-DLIBC_KERNEL_HEADERS=/usr/riscv64-linux-gnu/include``) so the libc build
+ can find headers like ``asm/unistd.h``.
+
CMake configure step
--------------------
+First, set up the environment variables for your compiler and target:
+
+.. code-block:: sh
+
+ C_COMPILER=clang
+ CXX_COMPILER=clang++
+ TARGET_TRIPLE=aarch64-linux-gnu
+
Below is the CMake command to configure the standalone crossbuild of the libc.
.. code-block:: sh
- $> cd llvm-project # The llvm-project checkout
- $> mkdir build
- $> cd build
- $> C_COMPILER=<C compiler> # For example "clang"
- $> CXX_COMPILER=<C++ compiler> # For example "clang++"
- $> cmake ../runtimes \
+ cmake \
+ -B build \
+ -S runtimes \
-G Ninja \
-DLLVM_ENABLE_RUNTIMES=libc \
-DCMAKE_C_COMPILER=$C_COMPILER \
-DCMAKE_CXX_COMPILER=$CXX_COMPILER \
+ -DCMAKE_C_COMPILER_TARGET=$TARGET_TRIPLE \
+ -DCMAKE_CXX_COMPILER_TARGET=$TARGET_TRIPLE \
-DLLVM_LIBC_FULL_BUILD=ON \
- -DLIBC_TARGET_TRIPLE=<Your target triple> \
+ -DLIBC_TARGET_TRIPLE=$TARGET_TRIPLE \
-DCMAKE_BUILD_TYPE=<Release|Debug>
We will go over the special options passed to the ``cmake`` command above.
@@ -82,7 +100,7 @@ the libc for the target with the following command:
.. code-block:: sh
- $> ninja libc libm
+ ninja -C build libc libm
The above ``ninja`` command will build the libc static archives ``libc.a`` and
``libm.a`` for the target specified with ``-DLIBC_TARGET_TRIPLE`` in the CMake
@@ -97,15 +115,21 @@ the libc for the target.
CMake configure step
--------------------
+First, set up the environment variables for your compiler and target:
+
.. code-block:: sh
- $> cd llvm-project # The llvm-project checkout
- $> mkdir build
- $> cd build
- $> C_COMPILER=<C compiler> # For example "clang"
- $> CXX_COMPILER=<C++ compiler> # For example "clang++"
- $> TARGET_TRIPLE=<Your target triple>
- $> cmake ../llvm \
+ C_COMPILER=clang
+ CXX_COMPILER=clang++
+ TARGET_TRIPLE=aarch64-linux-gnu
+
+Then, configure the CMake build for the bootstrap build:
+
+.. code-block:: sh
+
+ cmake \
+ -B build \
+ -S llvm \
-G Ninja \
-DCMAKE_C_COMPILER=$C_COMPILER \
-DCMAKE_CXX_COMPILER=$CXX_COMPILER \
@@ -129,7 +153,7 @@ The build step is similar to the other recipe:
.. code-block:: sh
- $> ninja libc
+ ninja -C build libc
The above ninja command should build the libc static archives for the target
specified with ``-DLLVM_RUNTIME_TARGETS``.
@@ -152,3 +176,66 @@ target triple as one of the supported GPU targets. Currently, this is either
``nvptx64-nvidia-cuda`` for NVIDIA GPUs or ``amdgcn-amd-amdhsa`` for AMD GPUs.
More detailed information is provided in the :ref:`GPU
documentation<libc_gpu_building>`.
+
+Building and Testing with an Emulator
+=====================================
+
+If you are cross-compiling the libc for a
diff erent architecture, you can use an emulator
+such as QEMU to run the tests. For instance, to cross-compile for ``riscv64`` and run tests
+using ``qemu-riscv64``, you can use the standalone cross build recipe with a few additional CMake flags.
+
+CMake configure step
+--------------------
+
+Assuming your system compiler (e.g., ``clang++``) supports the RISC-V target,
+you can configure the build as follows:
+
+.. code-block:: sh
+
+ cmake \
+ -B build \
+ -S runtimes \
+ -G Ninja \
+ -DLLVM_ENABLE_RUNTIMES=libc \
+ -DCMAKE_C_COMPILER=clang \
+ -DCMAKE_CXX_COMPILER=clang++ \
+ -DCMAKE_C_COMPILER_TARGET=riscv64-linux-gnu \
+ -DCMAKE_CXX_COMPILER_TARGET=riscv64-linux-gnu \
+ -DLLVM_LIBC_FULL_BUILD=ON \
+ -DLIBC_TARGET_TRIPLE=riscv64-linux-gnu \
+ -DLIBC_KERNEL_HEADERS=/usr/riscv64-linux-gnu/include \
+ -DCMAKE_CROSSCOMPILING_EMULATOR=qemu-riscv64 \
+ -DLLVM_ENABLE_LLD=ON \
+ -DCMAKE_BUILD_TYPE=Debug
+
+The notable additions are:
+
+* **The compiler target** - We set ``-DCMAKE_C_COMPILER_TARGET=riscv64-linux-gnu`` and ``-DCMAKE_CXX_COMPILER_TARGET=riscv64-linux-gnu`` to tell CMake to pass the correct ``--target`` flags to ``clang`` so that it cross-compiles rather than building for the host.
+* **The target triple** - We set ``-DLIBC_TARGET_TRIPLE=riscv64-linux-gnu``
+* **The kernel headers** - We set ``-DLIBC_KERNEL_HEADERS=/usr/riscv64-linux-gnu/include``
+ to point to the target's Linux API headers (e.g. for ``asm/unistd.h``).
+* **The cross-compiling emulator** - We set ``-DCMAKE_CROSSCOMPILING_EMULATOR=qemu-riscv64``
+ to tell CMake how to execute the compiled unittests. Note that this requires that
+ ``qemu-riscv64`` is installed and available in your ``$PATH``.
+* **LLD Linker** - We set ``-DLLVM_ENABLE_LLD=ON`` to ensure the test suite is linked using ``lld``, which is necessary for cross-compilation.
+
+Build and Test step
+-------------------
+
+You can then build the libc using:
+
+.. code-block:: sh
+
+ ninja -C build libc
+
+To run the tests for the cross-compiled libc, you must use the hermetic test
+suite, which is entirely self-hosted.
+
+.. code-block:: sh
+
+ ninja -C build libc-hermetic-tests
+
+.. note::
+ The standard ``check-libc`` target relies on the target's system C++ and C library
+ headers. Because these tests aren't hermetic, they are not expected to work for
+ a standalone cross-compilation build.
More information about the libc-commits
mailing list