How to Integrate LLVM into Your Own Project Using CMake
To integrate LLVM into a CMake-based project, use find_package(LLVM REQUIRED CONFIG) to locate the installed LLVM build, include ${LLVM_INCLUDE_DIRS}, and link against specific components using llvm_map_components_to_libnames and target_link_libraries.
LLVM's build system is fully CMake-based and, starting with LLVM 3.5, exports libraries as CMake import targets through the llvm/llvm-project repository. This allows downstream projects to locate an installed LLVM build and link against specific components without manual path configuration. The integration relies on the LLVMConfig.cmake file generated during LLVM's build process, which defines essential variables and helper macros for consuming LLVM libraries.
Understanding LLVM's CMake Export System
The LLVMConfig.cmake Installation Layout
When LLVM is built with CMake, it generates LLVMConfig.cmake in <install-prefix>/lib/cmake/llvm/LLVMConfig.cmake (or llvm/build/lib/cmake/llvm for in-tree builds). This file is the entry point for find_package and defines variables such as LLVM_INCLUDE_DIRS, LLVM_DEFINITIONS, LLVM_CMAKE_DIR, and LLVM_PACKAGE_VERSION. According to the source in llvm/CMakeLists.txt, this configuration script also provides the llvm_map_components_to_libnames macro for translating component names into actual library targets.
Key Variables and Helper Macros
The configuration exposes several critical variables for downstream consumption:
LLVM_INCLUDE_DIRS– Headers needed to compile against LLVMLLVM_DEFINITIONS– Preprocessor definitions required by LLVM headersLLVM_DIR– Cache entry set to the directory containingLLVMConfig.cmake
Locating and Configuring LLVM in Your Project
Finding the LLVM Installation
In your project's CMakeLists.txt, invoke:
find_package(LLVM REQUIRED CONFIG)
CMake searches for LLVMConfig.cmake and sets LLVM_DIR automatically for system prefixes like /usr/. For custom locations, specify the path explicitly when running CMake:
cmake -DLLVM_DIR=/path/to/llvm/lib/cmake/llvm ..
Configuring Compile Flags
After finding LLVM, configure your build to use its headers and definitions:
include_directories(${LLVM_INCLUDE_DIRS})
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS_LIST})
This pattern ensures your compiler receives the same preprocessor settings used to build LLVM itself, as documented in llvm/docs/CMake.md.
Selecting and Linking LLVM Components
Mapping Components to Libraries
LLVM consists of granular libraries (e.g., core, support, irreader). Use the provided macro to resolve component names to library targets:
llvm_map_components_to_libnames(llvm_libs core support irreader)
Linking Against Imported Targets
Link your executable or library against the resolved components:
target_link_libraries(my_tool ${llvm_libs})
Because these are imported targets defined in llvm/cmake/modules/LLVMConfig.cmake, CMake automatically handles library search paths, RPATH settings, and transitive dependencies.
Complete Minimal Example
Below is a working CMakeLists.txt for a tool named simple-tool that parses LLVM IR, referencing the exact patterns found in the llvm/llvm-project source tree:
cmake_minimum_required(VERSION 3.20.0)
project(SimpleTool)
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
include_directories(${LLVM_INCLUDE_DIRS})
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS_LIST})
add_executable(simple-tool tool.cpp)
llvm_map_components_to_libnames(llvm_libs core support irreader)
target_link_libraries(simple-tool ${llvm_libs})
The corresponding tool.cpp demonstrates basic LLVM API usage:
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Support/SourceMgr.h"
#include <iostream>
int main(int argc, char **argv) {
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " <IR file>\n";
return 1;
}
llvm::LLVMContext ctx;
llvm::SMDiagnostic err;
std::unique_ptr<llvm::Module> mod = llvm::parseIRFile(argv[1], err, ctx);
if (!mod) {
err.print(argv[0], llvm::errs());
return 1;
}
std::cout << "Module name: " << mod->getName().str() << "\n";
return 0;
}
Build the project:
mkdir build && cd build
cmake -DLLVM_DIR=/path/to/llvm/lib/cmake/llvm ..
cmake --build .
The resulting binary links against static or shared LLVM libraries depending on how LLVM was built (controlled by BUILD_SHARED_LIBS and LLVM_LINK_LLVM_DYLIB in llvm/CMakeLists.txt).
Summary
- Use
find_package(LLVM REQUIRED CONFIG)to locate theLLVMConfig.cmakefile generated during LLVM's build process in<install-prefix>/lib/cmake/llvm/. - Include
${LLVM_INCLUDE_DIRS}and${LLVM_DEFINITIONS}to ensure your compiler can find LLVM headers with the correct preprocessor settings defined in the LLVM build. - Leverage
llvm_map_components_to_libnamesto translate high-level component names (likecore,support, orirreader) into actual library target names for linking. - Link using
target_link_librariesagainst the imported targets to automatically handle transitive dependencies and RPATH configuration. - Reference
llvm/docs/CMake.mdin thellvm/llvm-projectrepository for the official embedding guide and advanced options likeLLVM_INSTALL_BINUTILS_SYMLINKS.
Frequently Asked Questions
How do I specify a custom LLVM installation path?
Pass the directory containing LLVMConfig.cmake to CMake when configuring your project:
cmake -DLLVM_DIR=/custom/path/to/llvm/lib/cmake/llvm ..
CMake will use this path instead of searching system directories like /usr/lib/cmake/llvm.
What is the difference between LLVM_DEFINITIONS and LLVM_INCLUDE_DIRS?
LLVM_INCLUDE_DIRS provides the header search paths required to find LLVM API headers like llvm/IR/Module.h, while LLVM_DEFINITIONS contains compiler flags and preprocessor macros (such as -DNDEBUG or -DLLVM_BUILD_* flags) that must be set when compiling code that includes LLVM headers to avoid compilation errors.
Can I link against all LLVM libraries at once instead of specific components?
While possible, it is not recommended. The llvm_map_components_to_libnames macro exists precisely to help you link only the libraries your tool actually needs (e.g., core, support, irreader), reducing binary size and link time. Linking everything would unnecessarily bloat your executable and increase build times.
Where can I learn more about LLVM's CMake系统的内部工作原理?
For newcomers to CMake, the LLVM project provides llvm/docs/CMakePrimer.md, which explains CMake basics in the context of LLVM. For advanced integration details, consult llvm/docs/CMake.md and examine the master build script at llvm/CMakeLists.txt to see how the LLVMConfig.cmake file is generated and which build-time options (like LLVM_LINK_LLVM_DYLIB) affect the installed package layout.
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 →