How to Build LLVM with Link Time Optimization (LTO)

Enable LTO when building LLVM by setting the LLVM_ENABLE_LTO CMake option to Thin or Full, and ensure you use an LTO-capable linker such as LLD or Gold.

Building the LLVM project with Link Time Optimization (LTO) produces faster, more optimized compiler binaries by enabling whole-program analysis across translation units. The llvm/llvm-project repository uses CMake to control this through the LLVM_ENABLE_LTO option, which configures the build to leverage the libLTO plugin and compatible linkers. This guide walks through the exact configuration steps, source files, and verification methods used in the official LLVM codebase.

Understanding LLVM's LTO Implementation

LLVM supports two distinct LTO modes that integrate with the build system at different stages of the pipeline.

CMake Option Configuration

The LLVM_ENABLE_LTO option is defined in llvm/cmake/modules/HandleLLVMOptions.cmake, where it defaults to OFF but accepts Thin or Full as valid values. When enabled, this variable propagates to the compiler flag generation logic, injecting -flto and linker-specific options during the configuration phase. The module validates that the selected linker supports LTO before generating the build targets.

The LTO Plugin Architecture

Link-time optimization relies on libLTO, implemented in llvm/lib/Linker, which provides the C API used by linkers to process LLVM bitcode at link time. The AddLLVM.cmake module (located at llvm/cmake/modules/AddLLVM.cmake) coordinates between the build system and libLTO by adding the necessary -Wl,-plugin-opt flags and ensuring the chosen linker (LLD or Gold) loads the appropriate plugin.

Prerequisites for Building LLVM with LTO

Before configuring the build, ensure your system meets the following requirements:

  • LTO-capable linker: On Linux, install lld (recommended) or ld.gold. On Windows, LLD-link is mandatory.
  • Clang compiler: While GCC can work, LLVM officially recommends building with Clang (clang and clang++) to ensure optimal LTO compatibility.
  • Sufficient memory: Full-LTO requires significantly more RAM during linking than Thin-LTO or standard builds.
  • CMake and Ninja: Version 3.20+ of CMake and a recent Ninja build system for efficient parallel compilation.

Configuring and Building LLVM with LTO

Follow these steps to configure and compile LLVM with LTO enabled, using the exact CMake variables referenced in the source tree.

Step 1: Select an LTO-Capable Linker

On Linux systems, install LLD via your package manager, or ensure ld.gold is available. On Windows, the LLVM build system will emit an error if LLD-link is not detected when LLVM_ENABLE_LTO is active.

Step 2: Configure CMake with LLVM_ENABLE_LTO

Create a build directory and run CMake with the appropriate LTO setting. The LLVM_ENABLE_LTO flag propagates to HandleLLVMOptions.cmake, which switches the build mode to Thin-LTO or Full-LTO.

git clone https://github.com/llvm/llvm-project.git
cd llvm-project
mkdir build && cd build

cmake -G Ninja \
      -DCMAKE_BUILD_TYPE=Release \
      -DLLVM_ENABLE_PROJECTS="clang;lld;mlir" \
      -DLLVM_ENABLE_LTO=Thin \
      -DLLVM_USE_LINKER=lld \
      -DLLVM_ENABLE_ASSERTIONS=ON \
      -DCMAKE_C_COMPILER=clang \
      -DCMAKE_CXX_COMPILER=clang++ \
      ../llvm

For Full-LTO (classic LTO with whole-program optimization), change -DLLVM_ENABLE_LTO=Full and ensure you have sufficient memory available.

Step 3: Build the Project

Invoke your build tool to compile with LTO flags active. During this process, CMake adds -flto to compilation commands, and the final link step invokes the LTO plugin through AddLLVM.cmake.

ninja

Step 4: Verify LTO Sections in Binaries

After building, verify that LTO was applied by inspecting the binary for SHT_LLVM_LTO sections using llvm-readelf.

llvm-readelf -S bin/clang | grep LTO

The presence of .llvm.lto or SHT_LLVM_LTO sections confirms the binary was built with Link Time Optimization.

CMake Configuration Examples

Choose the configuration that matches your optimization needs and hardware constraints.

Thin-LTO performs fast, scalable summary analysis and requires less memory than Full-LTO.

cmake -G Ninja \
      -DCMAKE_BUILD_TYPE=Release \
      -DLLVM_ENABLE_PROJECTS="clang;lld" \
      -DLLVM_ENABLE_LTO=Thin \
      -DLLVM_USE_LINKER=lld \
      -DCMAKE_C_COMPILER=clang \
      -DCMAKE_CXX_COMPILER=clang++ \
      ../llvm

Full-LTO Configuration

Full-LTO performs whole-program optimization but requires substantial memory during the final link step.

cmake -G "Unix Makefiles" \
      -DCMAKE_BUILD_TYPE=Release \
      -DLLVM_ENABLE_PROJECTS="clang;lld;polly" \
      -DLLVM_ENABLE_LTO=Full \
      -DLLVM_USE_LINKER=gold \
      -DCMAKE_C_COMPILER=clang \
      -DCMAKE_CXX_COMPILER=clang++ \
      ../llvm

Summary

  • Set LLVM_ENABLE_LTO=Thin or LLVM_ENABLE_LTO=Full in your CMake configuration to build LLVM with Link Time Optimization.
  • Use an LTO-capable linker such as LLD or Gold via the LLVM_USE_LINKER variable.
  • The HandleLLVMOptions.cmake module processes LTO settings, while AddLLVM.cmake injects the necessary compiler and linker flags.
  • Verify LTO application by checking for SHT_LLVM_LTO sections in built binaries using llvm-readelf.
  • Thin-LTO offers a balance of performance and resource usage, while Full-LTO provides maximum optimization at the cost of higher memory requirements.

Frequently Asked Questions

What is the difference between Thin-LTO and Full-LTO when building LLVM?

Thin-LTO performs a fast, scalable analysis using summary information, allowing parallel backend compilation and reduced memory usage. Full-LTO performs whole-program optimization by merging all bitcode into a single module at link time, resulting in potentially better optimization but requiring significantly more memory and time during linking. The choice is controlled by setting LLVM_ENABLE_LTO to the corresponding value in your CMake configuration.

Which linker should I use for building LLVM with LTO on Linux?

LLVM recommends using LLD (lld) when building with LTO, specified via -DLLVM_USE_LINKER=lld. Alternatively, the Gold linker (ld.gold) with the LLVM plugin is supported. The build system in AddLLVM.cmake validates linker compatibility and emits errors if the selected linker cannot support LTO.

How can I verify that LLVM was built with LTO enabled?

After building, run llvm-readelf -S on any generated binary (such as bin/clang) and search for LTO-related sections. The presence of sections named .llvm.lto or entries with SHT_LLVM_LTO type confirms that Link Time Optimization was active during the build process.

Does building LLVM with LTO require more memory than a standard build?

Yes, particularly when using Full-LTO. Full-LTO consolidates all translation units during the link step, which can consume substantial RAM on large projects like LLVM. Thin-LTO mitigates this by processing modules in parallel, making it the recommended approach for systems with limited memory.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →