LLVM 22.x tile for building compilers, language runtimes, and out-of-tree tooling
88
83%
Does it follow best practices?
Impact
96%
1.23xAverage score across 5 eval scenarios
Passed
No known issues
Reference: Building LLVM with CMake | llvm-config
Build out-of-tree (against an installed LLVM) when you are:
opt --load-pass-pluginBuild in-tree (inside the LLVM source tree) when you are:
# macOS (Homebrew)
brew install llvm@22
# Headers: /opt/homebrew/opt/llvm@22/include
# CMake: /opt/homebrew/opt/llvm@22/lib/cmake/llvm
# Ubuntu / Debian
apt install llvm-22-dev libclang-22-dev
# Headers: /usr/lib/llvm-22/include
# CMake: /usr/lib/llvm-22/lib/cmake/llvm
# Build from source
cmake -S llvm -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local/llvm-22 \
-DLLVM_TARGETS_TO_BUILD="X86;AArch64;RISCV" \
-DLLVM_ENABLE_PROJECTS="clang" \
-G Ninja
ninja -C build installLocate the cmake config directory:
llvm-config-22 --cmakedir
# /usr/lib/llvm-22/lib/cmake/llvmcmake_minimum_required(VERSION 3.20)
project(MyCompiler CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# ── Locate LLVM 22 ────────────────────────────────────────────────────────────
find_package(LLVM 22 REQUIRED CONFIG)
message(STATUS "LLVM version: ${LLVM_PACKAGE_VERSION}")
message(STATUS "LLVM CMake dir: ${LLVM_DIR}")
include_directories(${LLVM_INCLUDE_DIRS})
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS_LIST})
# ── Map LLVM components to link targets ───────────────────────────────────────
llvm_map_components_to_libnames(LLVM_LIBS
Core # LLVMContext, Module, IRBuilder, basic types
Support # raw_ostream, StringRef, Error, CommandLine
Analysis # DominatorTree, ScalarEvolution, AliasAnalysis
Passes # PassBuilder, NPM infrastructure
IRReader # parseIRFile, parseAssemblyString
BitWriter # WriteBitcodeToFile
Target # TargetMachine, TargetRegistry
X86CodeGen # X86 backend (replace with your target)
X86AsmParser
X86Desc
X86Info
)
# ── Targets ───────────────────────────────────────────────────────────────────
add_executable(mycompiler
src/main.cpp
src/Frontend.cpp
src/CodeGen.cpp
)
target_include_directories(mycompiler PRIVATE include)
target_link_libraries(mycompiler PRIVATE ${LLVM_LIBS})List all available components:
llvm-config-22 --components| Component | What it provides |
|---|---|
Core | LLVMContext, Module, Function, IRBuilder, all IR types |
Support | raw_ostream, StringRef, Error, Expected, CommandLine, MemoryBuffer |
Analysis | DominatorTree, LoopInfo, ScalarEvolution, AAResults, CallGraph |
Passes | PassBuilder, ModulePassManager, all standard analyses |
IRReader | parseIRFile(), parseAssemblyString() |
BitReader | parseBitcodeFile() |
BitWriter | WriteBitcodeToFile() |
Linker | Linker::linkModules() |
TransformUtils | CloneFunction, InlineFunction, utility transforms |
Scalar | Scalar optimization passes (instcombine, simplifycfg, etc.) |
IPO | Interprocedural passes (inliner, argument promotion, etc.) |
Vectorize | Loop and SLP vectorizers |
Target | TargetMachine, TargetRegistry, TargetOptions |
MC | MCContext, MCInstrInfo, MCRegisterInfo — needed for MC layer |
ExecutionEngine | LLVM interpreter / JIT infrastructure |
MCJIT | MCJIT execution engine |
OrcJIT | ORC JIT v2 (preferred JIT in LLVM 22) |
X86CodeGen | X86 target code generation |
AArch64CodeGen | AArch64 target code generation |
RISCVCodeGen | RISC-V target code generation |
# Using LLVM_DIR explicitly
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_DIR=$(llvm-config-22 --cmakedir)
# Or via CMAKE_PREFIX_PATH
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH=/usr/local/llvm-22
cmake --build build -j$(nproc)To build a pass loadable by opt --load-pass-plugin:
add_library(MyPassPlugin MODULE
src/MyPass.cpp
)
target_include_directories(MyPassPlugin PRIVATE
${LLVM_INCLUDE_DIRS}
include
)
target_compile_definitions(MyPassPlugin PRIVATE ${LLVM_DEFINITIONS})
set_target_properties(MyPassPlugin PROPERTIES
CXX_STANDARD 17
POSITION_INDEPENDENT_CODE ON
# No default lib prefix on macOS/Linux
PREFIX ""
)
# Do NOT link LLVM libs into the plugin — use symbols from the host (opt)
# target_link_libraries(MyPassPlugin PRIVATE ${LLVM_LIBS}) ← DON'T DO THISTest the plugin:
opt --load-pass-plugin=./MyPassPlugin.so \
-passes=my-pass -S input.ll# Debug build with assertions (slow, catches bugs early)
cmake -DCMAKE_BUILD_TYPE=Debug \
-DLLVM_ENABLE_ASSERTIONS=ON ...
# Release with assertions (recommended for development)
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DLLVM_ENABLE_ASSERTIONS=ON ...
# Release (production / benchmarking)
cmake -DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_ASSERTIONS=OFF ...Match LLVM_ENABLE_ASSERTIONS to what your LLVM install was built with to avoid ABI mismatches.
If you have multiple LLVM versions installed, avoid mixing them:
# Ensure cmake finds LLVM 22, not LLVM 21:
export PATH=/usr/local/llvm-22/bin:$PATH
cmake -DLLVM_DIR=/usr/local/llvm-22/lib/cmake/llvm ...
# Check version after configure:
# The cmake output should show: "LLVM version: 22.x.x"| Variable | Description |
|---|---|
LLVM_PACKAGE_VERSION | Full version string, e.g. 22.1.2 |
LLVM_VERSION_MAJOR | Major version integer, e.g. 22 |
LLVM_INCLUDE_DIRS | Header search paths |
LLVM_LIBRARY_DIRS | Library search paths |
LLVM_DEFINITIONS | Compiler definitions (e.g. -D_GNU_SOURCE) |
LLVM_TOOLS_BINARY_DIR | Path to opt, llc, llvm-lit, etc. |
LLVM_BUILD_MAIN_SRC_DIR | Source tree (only set for build-tree installs) |
LLVM_ENABLE_ASSERTIONS | Whether assertions were enabled |
LLVM_ENABLE_EH | Whether exceptions are enabled in LLVM |
LLVM_ENABLE_RTTI | Whether RTTI is enabled in LLVM |
Important: If
LLVM_ENABLE_RTTI=OFF(the default), your project must also disable RTTI:if(NOT LLVM_ENABLE_RTTI) target_compile_options(mycompiler PRIVATE -fno-rtti) endif()
-lLLVMCore etc. — use llvm_map_components_to_libnames so CMake handles ordering and transitive deps.opt which already has them; double-linking causes symbol conflicts.LLVM_PACKAGE_VERSION in the cmake output.InitializeAll*() target init functions before using TargetRegistry or creating TargetMachine.docs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
skills
add-alias-analysis
add-attributes-metadata
add-calling-convention
add-debug-info
add-exception-handling
add-gc-statepoints
add-intrinsic
add-lto
add-sanitizer
add-vectorization-hint
frontend-to-ir
jit-setup
lit-filecheck
lower-struct-types
new-target
out-of-tree-setup
tessl-llvm
version-sync