How to Build LLVM with Cross-Compilation Support for Multiple Target Architectures
To build LLVM with cross-compilation support for multiple target architectures, you create a CMake toolchain file describing the target system, configure native host tools using the build_native_tool function, and invoke CMake with the llvm_create_cross_target orchestration logic provided by the CrossCompile.cmake module.
The llvm/llvm-project repository uses a sophisticated CMake-based build system that supports cross-compiling for heterogeneous architectures from a single build environment. The build process leverages the CrossCompile.cmake module to manage the complexity of generating host utilities while simultaneously targeting foreign instruction sets like AArch64 or RISCV.
Understanding the Cross-Compilation Architecture
LLVM's cross-compilation workflow centers on the CrossCompile.cmake module located at llvm/cmake/modules/CrossCompile.cmake. This module defines llvm_create_cross_target, which establishes build directories and stamp files (lines 7-22), and build_native_tool, which compiles essential host utilities like llvm-tblgen required during the cross-compilation process (lines 35-64).
The main llvm/CMakeLists.txt includes this module at line 1392, ensuring cross-compilation capabilities are available during configuration. According to the source code, the module transforms the LLVM_TARGETS_TO_BUILD list into a semicolon-escaped string for recursive CMake calls (lines 62-66) and constructs the custom command invoking CMake for the target with proper variable forwarding (lines 95-100).
Prerequisites for Cross-Compiling LLVM
Before configuring the build, ensure your environment includes:
- A sysroot directory containing the target platform's libc, headers, and libraries
- Clang/LLVM or the target-specific toolchain installed on the host
- CMake 3.20 or newer
- Ninja or Make build system generator
Step-by-Step Cross-Compilation Process
Create a CMake Toolchain File
Create a toolchain file that describes the target system properties. This file is read by the CrossCompile.cmake module to configure the recursive target build.
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSROOT "$ENV{SYSROOT}")
set(CMAKE_C_COMPILER_TARGET aarch64-linux-gnu)
set(CMAKE_CXX_COMPILER_TARGET aarch64-linux-gnu)
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_LINKER_TYPE LLD)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
Configure Native Host Tools
The build_native_tool function automatically handles native compilation, but you can also build these tools manually to cache them for repeated cross-compilation runs.
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -S llvm -B build/native
cmake --build build/native --target llvm-tblgen
Configure the Cross-Target Build
Invoke CMake for the target architecture, passing the toolchain file and the list of targets to support.
cmake -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_PROJECTS="lld;clang" \
-DCMAKE_TOOLCHAIN_FILE=$(pwd)/aarch64-linux-gnu-clang.cmake \
-DLLVM_HOST_TRIPLE=aarch64-linux-gnu \
-DLLVM_TARGETS_TO_BUILD="X86;AArch64;RISCV" \
-DCMAKE_INSTALL_PREFIX=$HOME/llvm-aarch64-linux-gnu \
-S llvm \
-B build/aarch64-linux-gnu
cmake --build build/aarch64-linux-gnu
Essential CMake Variables
Three critical variables control the cross-compilation output when building for multiple architectures:
- LLVM_TARGETS_TO_BUILD: Semicolon-separated list of backend targets (e.g.,
X86;AArch64;RISCV) that the resulting binaries can generate code for. - LLVM_HOST_TRIPLE: The target triple for the produced executables (e.g.,
aarch64-linux-gnu), telling LLVM where the final binaries will run. - CMAKE_SYSROOT: Absolute path to the target sysroot containing the C library and system headers.
These variables are parsed by the CrossCompile.cmake module and forwarded to the recursive CMake invocation via the custom command defined at lines 95-100.
Practical Build Examples
Building for AArch64 and RISCV Simultaneously
To compile LLVM that runs on AArch64 hardware and supports both AArch64 and RISCV code generation:
export SYSROOT=$HOME/sysroot-deb-arm64-stable
export TARGET=aarch64-linux-gnu
export LLVM_TARGETS="AArch64;RISCV"
cat > $TARGET-clang.cmake <<EOF
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSROOT "$SYSROOT")
set(CMAKE_C_COMPILER_TARGET $TARGET)
set(CMAKE_CXX_COMPILER_TARGET $TARGET)
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_LINKER_TYPE LLD)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
EOF
cmake -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_PROJECTS="clang;lld" \
-DCMAKE_TOOLCHAIN_FILE=$(pwd)/$TARGET-clang.cmake \
-DLLVM_HOST_TRIPLE=$TARGET \
-DLLVM_TARGETS_TO_BUILD="$LLVM_TARGETS" \
-S llvm \
-B build/$TARGET
cmake --build build/$TARGET
Reusing Pre-Built Native Tools
If you have already compiled native utilities, the CrossCompile.cmake module automatically discovers and reuses them, avoiding redundant compilation.
# Build native tools once (cached)
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -S llvm -B build/native
cmake --build build/native --target llvm-tblgen
# Cross-compile build automatically locates native tools
cmake -G Ninja \
-DCMAKE_TOOLCHAIN_FILE=$TARGET-clang.cmake \
-DLLVM_ENABLE_PROJECTS="clang" \
-DLLVM_HOST_TRIPLE=$TARGET \
-DLLVM_TARGETS_TO_BUILD="X86;ARM" \
-S llvm \
-B build/$TARGET
Summary
- The CrossCompile.cmake module (
llvm/cmake/modules/CrossCompile.cmake) orchestrates cross-compilation through thellvm_create_cross_targetandbuild_native_toolfunctions. - You must provide a CMake toolchain file specifying the sysroot, target triple, and compiler settings for the destination platform.
- LLVM_TARGETS_TO_BUILD controls which backend architectures (X86, AArch64, RISCV, ARM, etc.) the distribution supports.
- The build process first compiles native host tools, then recursively configures the target build using these utilities as referenced in lines 35-64 of the CrossCompile.cmake implementation.
- The main CMakeLists.txt includes the cross-compilation logic at line 1392, integrating these features into the standard LLVM build.
Frequently Asked Questions
What is the purpose of the CrossCompile.cmake module in LLVM?
The CrossCompile.cmake module at llvm/cmake/modules/CrossCompile.cmake provides the llvm_create_cross_target and build_native_tool functions that manage cross-compilation complexity. According to the llvm/llvm-project source, it creates separate build directories for the target architecture (lines 7-22), handles variable forwarding between host and target configurations, and ensures native utilities like llvm-tblgen are available during the cross-build.
How do I specify which target architectures LLVM should support?
Set the LLVM_TARGETS_TO_BUILD CMake variable to a semicolon-separated list of supported backends such as X86, AArch64, RISCV, or ARM. As implemented in CrossCompile.cmake (lines 62-66), this list is transformed and forwarded to the recursive CMake invocation. If omitted, LLVM defaults to building only the host's native architecture.
Can I use GCC instead of Clang for cross-compiling LLVM?
Yes, though the LLVM project recommends using Clang and LLD for consistency. To use GCC, modify your toolchain file to set CMAKE_C_COMPILER and CMAKE_CXX_COMPILER to your target gcc and g++ binaries, and remove or adjust CMAKE_LINKER_TYPE. Ensure your GCC toolchain matches the target triple specified in LLVM_HOST_TRIPLE.
Where can I find the official documentation for cross-compiling LLVM?
The authoritative guide resides in the llvm/llvm-project repository at llvm/docs/HowToCrossCompileLLVM.md. This document provides platform-specific guidance and troubleshooting steps beyond the CMake module implementation in llvm/cmake/modules/CrossCompile.cmake.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →