6.22. llvm/clang pass 2 22.1.3

The second llvm/clang pass installs the final compiler toolchain, then refreshes the LLVM runtimes with standalone cross builds and fixes Clang's default search paths for the book's custom filesystem layout.

Input assumption: llvm-project-22.1.3.src.tar.xz is already present in LBI_SOURCES, and sections 5.4 and 5.5 completed successfully.

Licenses

Dependencies

llvm is a modular compiler infrastructure project. we need it to provide the final compiler backend, linker integration, and toolchain libraries for the target system.

clang is a C and C++ frontend for LLVM. we need it to provide the final clang and clang++ compilers for the target system.

compiler-rt is the LLVM runtime support library project. we need it to provide Clang builtins and startup objects.

libunwind is a platform-independent stack unwinding library. we need it to provide unwind support used by C++ exception handling.

libcxxabi is the LLVM C++ ABI support library. we need it to provide ABI and exception runtime support for libcxx.

libcxx is the LLVM C++ standard library implementation. we need it to provide the C++ standard library used by Clang in later stages.

Extract Sources and Enter the LLVM Build Root

cd "$LBI_SOURCES"
tar -xf llvm-project-22.1.3.src.tar.xz
cd llvm-project-22.1.3.src/llvm

Configure llvm/clang Pass 2

Cross-build note: this pass follows LLVM's cross-compilation guidance for the compiler build itself. The top-level LLVM_ENABLE_RUNTIMES flow is intentionally not used here, because it tries to configure compiler-rt builtins with the just-built target compiler, which is not host-runnable in this setup.
lbi_cmake build-llvm-pass2 \
    -G Ninja \
    -DCMAKE_C_COMPILER="$LBI_ROOT/system/tools/bin/$LBI_TARGET-clang" \
    -DCMAKE_CXX_COMPILER="$LBI_ROOT/system/tools/bin/$LBI_TARGET-clang++" \
    -DCMAKE_AR="$LBI_ROOT/system/tools/bin/$LBI_TARGET-ar" \
    -DCMAKE_RANLIB="$LBI_ROOT/system/tools/bin/$LBI_TARGET-ranlib" \
    -DCMAKE_NM="$LBI_ROOT/system/tools/bin/$LBI_TARGET-nm" \
    -DCMAKE_OBJCOPY="$LBI_ROOT/system/tools/bin/$LBI_TARGET-objcopy" \
    -DCMAKE_OBJDUMP="$LBI_ROOT/system/tools/bin/$LBI_TARGET-objdump" \
    -DCMAKE_STRIP="$LBI_ROOT/system/tools/bin/$LBI_TARGET-strip" \
    -DCMAKE_SYSROOT="$LBI_ROOT" \
    -DCMAKE_C_COMPILER_LAUNCHER="ccache" \
    -DCMAKE_CXX_COMPILER_LAUNCHER="ccache" \
    -DCMAKE_FIND_ROOT_PATH="$LBI_ROOT;$LBI_ROOT/system" \
    -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
    -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
    -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
    -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY \
    -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
    -DCMAKE_C_COMPILER_TARGET="$LBI_TARGET" \
    -DCMAKE_CXX_COMPILER_TARGET="$LBI_TARGET" \
    -DCMAKE_ASM_COMPILER_TARGET="$LBI_TARGET" \
    -DCMAKE_C_FLAGS="--target=$LBI_TARGET --sysroot=$LBI_ROOT -isystem /system/headers $LWI_CFLAGS" \
    -DCMAKE_CXX_FLAGS="--target=$LBI_TARGET --sysroot=$LBI_ROOT -isystem /system/headers $LWI_CXXFLAGS" \
    -DCMAKE_SHARED_LINKER_FLAGS="--target=$LBI_TARGET --sysroot=$LBI_ROOT -B/system/libraries -B/system/libraries/clang/22/lib/linux -L/system/libraries $LBI_CUSTOM_LDFLAGS" \
    -DCMAKE_EXE_LINKER_FLAGS="--target=$LBI_TARGET --sysroot=$LBI_ROOT -B/system/libraries -B/system/libraries/clang/22/lib/linux -L/system/libraries $LBI_CUSTOM_LDFLAGS" \
    -DLLVM_NATIVE_TOOL_DIR="$LBI_ROOT/system/tools/bin" \
    -DLLVM_TABLEGEN="$LBI_ROOT/system/tools/bin/llvm-tblgen" \
    -DCLANG_TABLEGEN="$LBI_ROOT/system/tools/bin/clang-tblgen" \
    -DLLVM_ENABLE_PROJECTS="clang;lld" \
    -DLLVM_INSTALL_BINUTILS_SYMLINKS=ON \
    -DLLVM_HOST_TRIPLE="$LBI_TARGET" \
    -DLLVM_TARGETS_TO_BUILD="X86" \
    -DLLVM_DEFAULT_TARGET_TRIPLE="$LBI_TARGET" \
    -DDEFAULT_SYSROOT="/" \
    -DCLANG_DEFAULT_CXX_STDLIB=libc++ \
    -DCLANG_DEFAULT_LINKER=lld \
    -DCLANG_DEFAULT_RTLIB=compiler-rt \
    -DCLANG_DEFAULT_UNWINDLIB=libunwind \
    -DLLVM_ENABLE_ZLIB=ON \
    -DLLVM_ENABLE_ZSTD=OFF \
    -DLLVM_ENABLE_LIBXML2=OFF \
    -DLLVM_INCLUDE_TESTS=OFF \
    -DLLVM_BUILD_TESTS=OFF \
    -DCMAKE_BUILD_TYPE=Release

Build llvm/clang Pass 2

cmake --build build-llvm-pass2 $LWI_MAKE_FLAGS

Install llvm/clang Pass 2

DESTDIR="$LBI_ROOT" cmake --install build-llvm-pass2

Refresh LLVM C++ Runtimes

cd "$LBI_SOURCES/llvm-project-22.1.3.src/runtimes"

lbi_cmake build-runtimes-pass2 \
    -G Ninja \
    -DCMAKE_C_COMPILER="$LBI_ROOT/system/tools/bin/$LBI_TARGET-clang" \
    -DCMAKE_CXX_COMPILER="$LBI_ROOT/system/tools/bin/$LBI_TARGET-clang++" \
    -DLLVM_CMAKE_DIR="$LBI_SOURCES/llvm-project-22.1.3.src/llvm/build-llvm-pass2/lib/cmake/llvm" \
    -DCMAKE_SYSROOT="$LBI_ROOT" \
    -DCMAKE_C_COMPILER_LAUNCHER="ccache" \
    -DCMAKE_CXX_COMPILER_LAUNCHER="ccache" \
    -DCMAKE_FIND_ROOT_PATH="$LBI_ROOT;$LBI_ROOT/system" \
    -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER \
    -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
    -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY \
    -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
    -DCMAKE_C_FLAGS="--target=$LBI_TARGET --sysroot=$LBI_ROOT -isystem /system/headers $LWI_CFLAGS" \
    -DCMAKE_CXX_FLAGS="--target=$LBI_TARGET --sysroot=$LBI_ROOT -isystem /system/headers $LWI_CXXFLAGS" \
    -DCMAKE_EXE_LINKER_FLAGS="--target=$LBI_TARGET --sysroot=$LBI_ROOT -B/system/libraries -B/system/libraries/clang/22/lib/linux -L/system/libraries $LBI_CUSTOM_LDFLAGS" \
    -DLLVM_ENABLE_RUNTIMES="libunwind;libcxxabi;libcxx" \
    -DLLVM_ENABLE_LIBXML2=OFF \
    -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF \
    -DLLVM_INCLUDE_TESTS=OFF \
    -DLLVM_INCLUDE_DOCS=OFF \
    -DLIBUNWIND_INSTALL_LIBRARY_DIR=/system/libraries \
    -DLIBUNWIND_INCLUDE_TESTS=OFF \
    -DLIBUNWIND_INCLUDE_DOCS=OFF \
    -DLIBCXXABI_INSTALL_LIBRARY_DIR=/system/libraries \
    -DLIBCXXABI_INCLUDE_TESTS=OFF \
    -DLIBCXX_INSTALL_LIBRARY_DIR=/system/libraries \
    -DLIBCXX_INCLUDE_TESTS=OFF \
    -DLIBCXX_INCLUDE_BENCHMARKS=OFF \
    -DLIBCXX_INCLUDE_DOCS=OFF \
    -DLIBCXX_HAS_MUSL_LIBC=ON \
    -DLIBCXX_HAS_ATOMIC_LIB=OFF \
    -DLIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL=OFF \
    -DLIBCXXABI_USE_LLVM_UNWINDER=ON \
    -DLIBCXX_USE_COMPILER_RT=ON \
    -DLIBCXXABI_USE_COMPILER_RT=ON \
    -DLIBUNWIND_USE_COMPILER_RT=ON \
    -DCMAKE_BUILD_TYPE=Release

cmake --build build-runtimes-pass2 $LWI_MAKE_FLAGS
DESTDIR="$LBI_ROOT" cmake --install build-runtimes-pass2

Build compiler-rt Builtins and CRT Objects

Compiler-rt note: this follows upstream compiler-rt cross-build guidance for standalone builtins and CRT builds instead of the failing top-level LLVM runtimes wrapper.
cd "$LBI_SOURCES/llvm-project-22.1.3.src/compiler-rt"

lbi_cmake build-compiler-rt-pass2 \
    -G Ninja \
    -DCMAKE_C_COMPILER="$LBI_ROOT/system/tools/bin/$LBI_TARGET-clang" \
    -DCMAKE_CXX_COMPILER="$LBI_ROOT/system/tools/bin/$LBI_TARGET-clang++" \
    -DCMAKE_ASM_COMPILER="$LBI_ROOT/system/tools/bin/$LBI_TARGET-clang" \
    -DCMAKE_AR="$LBI_ROOT/system/tools/bin/$LBI_TARGET-ar" \
    -DCMAKE_NM="$LBI_ROOT/system/tools/bin/$LBI_TARGET-nm" \
    -DCMAKE_RANLIB="$LBI_ROOT/system/tools/bin/$LBI_TARGET-ranlib" \
    -DLLVM_CMAKE_DIR="$LBI_SOURCES/llvm-project-22.1.3.src/llvm/build-llvm-pass2/lib/cmake/llvm" \
    -DCMAKE_SYSROOT="$LBI_ROOT" \
    -DCMAKE_C_COMPILER_LAUNCHER="ccache" \
    -DCMAKE_CXX_COMPILER_LAUNCHER="ccache" \
    -DCMAKE_C_COMPILER_TARGET="$LBI_TARGET" \
    -DCMAKE_CXX_COMPILER_TARGET="$LBI_TARGET" \
    -DCMAKE_ASM_COMPILER_TARGET="$LBI_TARGET" \
    -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
    -DCMAKE_C_FLAGS="--target=$LBI_TARGET --sysroot=$LBI_ROOT -isystem /system/headers $LWI_CFLAGS" \
    -DCMAKE_CXX_FLAGS="--target=$LBI_TARGET --sysroot=$LBI_ROOT -isystem /system/headers $LWI_CXXFLAGS" \
    -DCMAKE_ASM_FLAGS="--target=$LBI_TARGET --sysroot=$LBI_ROOT $LWI_CFLAGS" \
    -DCMAKE_EXE_LINKER_FLAGS="--target=$LBI_TARGET --sysroot=$LBI_ROOT -B/system/libraries -B/system/libraries/clang/22/lib/linux -L/system/libraries $LBI_CUSTOM_LDFLAGS" \
    -DCOMPILER_RT_INSTALL_PATH=/system/lib/clang/22 \
    -DCOMPILER_RT_BUILD_BUILTINS=ON \
    -DCOMPILER_RT_BUILD_CRT=ON \
    -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
    -DCOMPILER_RT_BUILD_MEMPROF=OFF \
    -DCOMPILER_RT_BUILD_ORC=OFF \
    -DCOMPILER_RT_BUILD_PROFILE=OFF \
    -DCOMPILER_RT_BUILD_CTX_PROFILE=OFF \
    -DCOMPILER_RT_BUILD_SANITIZERS=OFF \
    -DCOMPILER_RT_BUILD_XRAY=OFF \
    -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
    -DCOMPILER_RT_INCLUDE_TESTS=OFF \
    -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF \
    -DCMAKE_BUILD_TYPE=Release

cmake --build build-compiler-rt-pass2 --target builtins $LWI_MAKE_FLAGS
cmake --build build-compiler-rt-pass2 --target crt $LWI_MAKE_FLAGS
DESTDIR="$LBI_ROOT" cmake --install build-compiler-rt-pass2

Make Clang Resource Files Visible in the Final Tree

mkdir -p "$LBI_ROOT/system/lib/clang/22/lib/$LBI_TARGET"

if [ -f "$LBI_ROOT/system/tools/lib/clang/22/lib/$LBI_TARGET/libclang_rt.builtins.a" ]; then
    ln -sf "/system/tools/lib/clang/22/lib/$LBI_TARGET/libclang_rt.builtins.a" \
        "$LBI_ROOT/system/lib/clang/22/lib/$LBI_TARGET/libclang_rt.builtins.a"
fi

Create Compiler and Linker Compatibility Symlinks

cd "$LBI_ROOT/system/binaries"

ln -sf ld.lld ld
ln -sf clang cc
ln -sf clang++ c++

ln -sf clang "$LBI_TARGET-clang"
ln -sf clang++ "$LBI_TARGET-clang++"
ln -sf clang "$LBI_TARGET-cc"
ln -sf clang++ "$LBI_TARGET-c++"
ln -sf ld.lld "$LBI_TARGET-ld"

Link Clang Startup Objects for musl Compatibility

CRTBEGIN_OBJ=$(find "$LBI_ROOT/system/libraries/clang" \
    -type f \( -name 'crtbeginS.o' -o -name 'clang_rt.crtbegin*.o' \) | head -n1)
CRTEND_OBJ=$(find "$LBI_ROOT/system/libraries/clang" \
    -type f \( -name 'crtendS.o' -o -name 'clang_rt.crtend*.o' \) | head -n1)

CRT_DIR=$(dirname "$CRTBEGIN_OBJ")

if [ -n "$CRTBEGIN_OBJ" ] && [ -n "$CRTEND_OBJ" ]; then
    ln -sf "$(basename "$CRTBEGIN_OBJ")" "$CRT_DIR/crtbeginS.o"
    ln -sf "$(basename "$CRTEND_OBJ")" "$CRT_DIR/crtendS.o"

    ln -sf "${CRTBEGIN_OBJ#$LBI_ROOT/system}" "$LBI_ROOT/system/libraries/crtbeginS.o"
    ln -sf "${CRTEND_OBJ#$LBI_ROOT/system}" "$LBI_ROOT/system/libraries/crtendS.o"
fi

Add Clang Driver Wrapper Defaults

mv "$LBI_ROOT/system/binaries/clang" "$LBI_ROOT/system/binaries/clang.real"
mv "$LBI_ROOT/system/binaries/clang++" "$LBI_ROOT/system/binaries/clang++.real"

cat > "$LBI_ROOT/system/binaries/clang" <<'EOF'
#!/bin/sh
exec /system/binaries/clang.real \
    -isystem /system/headers \
    -B/system/libraries \
    -Wno-unused-command-line-argument \
    -B/system/libraries/clang/22/lib/linux \
    -L/system/libraries \
    "$@"
EOF

cat > "$LBI_ROOT/system/binaries/clang++" <<'EOF'
#!/bin/sh
exec /system/binaries/clang++.real \
    -nostdinc++ \
    -I/system/headers/c++/v1 \
    -isystem /system/libraries/clang/22/include \
    -isystem /system/headers \
    -B/system/libraries \
    -B/system/libraries/clang/22/lib/linux \
    -L/system/libraries \
    -Wl,-rpath,/system/libraries \
    "$@" \
    -Wno-unused-command-line-argument \
    -lc++ \
    -lc++abi \
    -lunwind
EOF

chmod 755 "$LBI_ROOT/system/binaries/clang" "$LBI_ROOT/system/binaries/clang++"

cd "$LBI_ROOT/system/binaries"
ln -sf clang cc
ln -sf clang++ c++
ln -sf clang "$LBI_TARGET-clang"
ln -sf clang++ "$LBI_TARGET-clang++"
ln -sf clang "$LBI_TARGET-cc"
ln -sf clang++ "$LBI_TARGET-c++"

Command Explanations