Complete Runtimes Build for Linux#
The first two steps are the same as a full host build.
Building a Simple Sysroot#
Step 1: Preparation#
First, check out the demo branch in your llvm-project, then set up the environment variables for your sysroot path.
cd llvm-project
gh pr checkout 234353
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.
# 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:
# 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#
For simplicity I’m going to assume you’ve already got a recent version of clang. These instructions hard-code the clang version being 24 in a couple places.
# If your system clang isn't at least clang 22
CLANG_BIN=<path_to>/latest_clang/bin
cmake -G Ninja \
-S runtimes \
-B build-runtimes \
-C libcxx/cmake/caches/Generic-llvm-libc.cmake \
-DCMAKE_C_COMPILER=$CLANG_BIN/clang \
-DCMAKE_CXX_COMPILER=$CLANG_BIN/clang++ \
-DCMAKE_INSTALL_PREFIX=$SYSROOT/usr \
-DLIBC_KERNEL_HEADERS=$SYSROOT/usr/include \
-DCOMPILER_RT_INSTALL_PATH=$SYSROOT/usr/lib/clang/24
if you want to run the tests add
-DLIBCXX_TEST_CONFIG="llvm-libc++-llvm-libc.cfg.in" \
-DLIBCXXABI_TEST_CONFIG="llvm-libc++abi-llvm-libc.cfg.in" \
After configuring, build and install the necessary components:
ninja -C build-runtimes install
Step 4: Build clang with the installed runtimes#
cmake -G Ninja \
-S llvm \
-B build-clang-stage2 \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=$CLANG_BIN/clang \
-DCMAKE_CXX_COMPILER=$CLANG_BIN/clang++ \
-DCMAKE_SYSROOT=$SYSROOT \
-DCMAKE_INSTALL_PREFIX=$SYSROOT/usr \
-DCMAKE_EXE_LINKER_FLAGS="-resource-dir=$SYSROOT/usr/lib/clang/24 -stdlib=libc++ --rtlib=compiler-rt --unwindlib=libunwind -fuse-ld=lld -static" \
-DLLVM_ENABLE_PROJECTS="clang;lld" \
-DLLVM_TARGETS_TO_BUILD="X86" \
-DLLVM_ENABLE_LIBCXX=ON \
-DLLVM_ENABLE_PIC=OFF
ninja -C build-clang-stage2 \
install-clang install-lld install-clang-resource-headers \
install-llvm-ar install-llvm-ranlib
Step 5: Configure the Compiler#
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.
cat << 'EOF' > $SYSROOT/usr/bin/x86_64-unknown-linux-gnu.cfg
--sysroot=<CFGDIR>/../..
-stdlib=libc++
-rtlib=compiler-rt
--unwindlib=libunwind
-fuse-ld=lld
-static
EOF
Step 6: Verification#
You can now use your newly built toolchain by running your compiler.
// hello.c
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
Compile and run the example:
$SYSROOT/usr/bin/clang hello.c
./a.out
The All-in-One Command#
This is so I can copy/paste the whole thing at once.
SYSROOT=$(readlink -f ~/sysroot)
CLANG_BIN=$(readlink -f ~/latest_clang/bin)
LINUX_HEADERS=$(readlink -f ~/linux_headers/include)
mkdir -p $SYSROOT/usr/include
cp -r $LINUX_HEADERS $SYSROOT/usr/
cmake -G Ninja \
-S runtimes \
-B build-runtimes \
-C libcxx/cmake/caches/Generic-llvm-libc.cmake \
-DCMAKE_C_COMPILER=$CLANG_BIN/clang \
-DCMAKE_CXX_COMPILER=$CLANG_BIN/clang++ \
-DCMAKE_INSTALL_PREFIX=$SYSROOT/usr \
-DLIBC_KERNEL_HEADERS=$SYSROOT/usr/include \
-DCOMPILER_RT_INSTALL_PATH=$SYSROOT/usr/lib/clang/24
ninja -C build-runtimes install
cmake -G Ninja \
-S llvm \
-B build-clang-stage2 \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=$CLANG_BIN/clang \
-DCMAKE_CXX_COMPILER=$CLANG_BIN/clang++ \
-DCMAKE_SYSROOT=$SYSROOT \
-DCMAKE_INSTALL_PREFIX=$SYSROOT/usr \
-DCMAKE_EXE_LINKER_FLAGS="-resource-dir=$SYSROOT/usr/lib/clang/24 -stdlib=libc++ --rtlib=compiler-rt --unwindlib=libunwind -fuse-ld=lld -static" \
-DLLVM_ENABLE_PROJECTS="clang;lld" \
-DLLVM_TARGETS_TO_BUILD="X86" \
-DLLVM_ENABLE_LIBCXX=ON \
-DLLVM_ENABLE_PIC=OFF
ninja -C build-clang-stage2 \
install-clang install-lld install-clang-resource-headers \
install-llvm-ar install-llvm-ranlib
cat << 'EOF' > $SYSROOT/usr/bin/x86_64-unknown-linux-gnu.cfg
--sysroot=<CFGDIR>/../..
-stdlib=libc++
-rtlib=compiler-rt
--unwindlib=libunwind
-fuse-ld=lld
-static
EOF