# How to Build LLVM with Cross-Compilation Support for Multiple Target Architectures

> Learn to build LLVM with cross-compilation for multiple targets. Use a CMake toolchain file and the CrossCompile.cmake module to configure native host tools and orchestrate your build.

- Repository: [LLVM/llvm-project](https://github.com/llvm/llvm-project)
- Tags: how-to-guide
- Published: 2026-09-11

---

**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`](https://github.com/llvm/llvm-project/blob/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.

```cmake
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.

```bash
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.

```bash
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:

```bash
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.

```bash

# 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 the `llvm_create_cross_target` and `build_native_tool` functions.
- 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`](https://github.com/llvm/llvm-project/blob/main/llvm/docs/HowToCrossCompileLLVM.md). This document provides platform-specific guidance and troubleshooting steps beyond the CMake module implementation in `llvm/cmake/modules/CrossCompile.cmake`.