LLVM 开发指南 / 第 2 章:安装与环境搭建
第 2 章:安装与环境搭建
工欲善其事,必先利其器。
2.1 安装方式概览
LLVM 提供多种安装方式,各有优缺点:
| 方式 | 耗时 | 灵活性 | 适用场景 |
|---|---|---|---|
| 包管理器安装 | ⏱ 1-5 分钟 | ⭐ 低 | 快速上手、学习 LLVM IR |
| 预编译二进制 | ⏱ 5-15 分钟 | ⭐⭐ 中 | 需要特定版本 |
| 源码编译 | ⏱ 1-4 小时 | ⭐⭐⭐ 高 | 开发 LLVM 本身、自定义构建 |
| Docker | ⏱ 2-10 分钟 | ⭐⭐ 中 | 团队统一环境、CI/CD |
2.2 包管理器安装
2.2.1 Ubuntu / Debian
# 方式一:安装 LLVM 官方 APT 源(推荐,可获得最新版本)
# 添加 LLVM 官方 GPG 密钥
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
# 添加 APT 源(以 Ubuntu 22.04 为例,LLVM 18)
echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main" | \
sudo tee /etc/apt/sources.list.d/llvm-18.list
# 更新并安装
sudo apt update
sudo apt install -y llvm-18-dev clang-18 lld-18 lldb-18 \
clang-tools-18 libclang-18-dev libclang-cpp18-dev \
libc++-18-dev libc++abi-18-dev
# 设置版本别名(可选)
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-18 100
sudo update-alternatives --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-18 100
# 方式二:使用发行版自带版本(版本较老,仅适合学习基础)
sudo apt update
sudo apt install -y llvm-dev clang lld
2.2.2 macOS (Homebrew)
# 安装 LLVM
brew install llvm
# Homebrew 的 LLVM 不会覆盖系统 clang,需要显式指定路径
# 查看安装路径
brew --prefix llvm
# 输出: /opt/homebrew/opt/llvm (Apple Silicon)
# /usr/local/opt/llvm (Intel)
# 配置环境变量(添加到 ~/.zshrc 或 ~/.bash_profile)
export PATH="$(brew --prefix llvm)/bin:$PATH"
export LDFLAGS="-L$(brew --prefix llvm)/lib"
export CPPFLAGS="-I$(brew --prefix llvm)/include"
# 验证安装
source ~/.zshrc
clang --version
llvm-config --version
2.2.3 Fedora / RHEL / CentOS
# Fedora
sudo dnf install -y llvm-devel clang-devel lld lldb
# RHEL / CentOS Stream
sudo dnf install -y llvm-devel clang-devel
# 验证
llvm-config --version
2.2.4 Arch Linux
# Arch 提供最新版本的 LLVM
sudo pacman -S llvm clang lld lldb compiler-rt libc++
# 验证
llvm-config --version
2.2.5 Windows
# 方式一:使用 winget
winget install LLVM.LLVM
# 方式二:使用 Chocolatey
choco install llvm
# 方式三:使用 vcpkg
vcpkg install llvm
# 验证(需要重启终端或刷新 PATH)
clang --version
2.3 预编译二进制安装
从 LLVM GitHub Releases 下载预编译二进制:
# 下载 LLVM 18 预编译包
LLVM_VERSION=18.1.8
# Linux x86_64
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/clang+llvm-${LLVM_VERSION}-x86_64-linux-gnu-ubuntu-22.04.tar.xz
# 解压到 /opt/llvm
sudo tar -xJf clang+llvm-${LLVM_VERSION}-x86_64-linux-gnu-ubuntu-22.04.tar.xz -C /opt/
sudo ln -sf /opt/clang+llvm-${LLVM_VERSION}-x86_64-linux-gnu-ubuntu-22.04 /opt/llvm
# 配置环境变量
cat >> ~/.bashrc << 'EOF'
export PATH="/opt/llvm/bin:$PATH"
export LD_LIBRARY_PATH="/opt/llvm/lib:$LD_LIBRARY_PATH"
export LLVM_DIR="/opt/llvm/lib/cmake/llvm"
export Clang_DIR="/opt/llvm/lib/cmake/clang"
EOF
source ~/.bashrc
# 验证
clang --version
llvm-config --version
注意: 预编译二进制包的 CMake 配置文件路径可能与源码编译不同。如果在 CMake 项目中使用
find_package(LLVM),需要确保设置了正确的LLVM_DIR。
2.4 源码编译
源码编译是获得最大灵活性的方式,但需要较长的编译时间和较多的磁盘空间。
2.4.1 系统要求
| 资源 | 最低要求 | 推荐配置 |
|---|---|---|
| CPU | 2 核 | 8 核以上 |
| 内存 | 4 GB | 16 GB 以上 |
| 磁盘 | 20 GB | 100 GB(含 Debug 构建) |
| 编译器 | GCC 7+ / Clang 5+ | GCC 12+ / Clang 15+ |
| CMake | 3.20+ | 3.25+ |
| Python | 3.8+ | 3.10+ |
2.4.2 安装构建依赖
# Ubuntu / Debian
sudo apt update
sudo apt install -y \
build-essential cmake ninja-build python3 python3-pip \
git curl wget xz-utils \
gcc g++ \
libffi-dev libxml2-dev zlib1g-dev \
swig
# 验证构建工具
cmake --version # >= 3.20
ninja --version # >= 1.10
python3 --version # >= 3.8
2.4.3 获取源码
# 方式一:使用 git clone(完整历史,推荐开发者)
git clone https://github.com/llvm/llvm-project.git
cd llvm-project
git checkout llvmorg-18.1.8 # 切换到特定版本
# 方式二:浅克隆(节省空间和时间)
git clone --depth 1 --branch llvmorg-18.1.8 https://github.com/llvm/llvm-project.git
# 方式三:下载源码包
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-18.1.8/llvm-project-18.1.8.src.tar.xz
tar -xJf llvm-project-18.1.8.src.tar.xz
2.4.4 CMake 配置
cd llvm-project
# 基础 Release 构建(推荐日常使用)
cmake -G Ninja -S llvm -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/opt/llvm \
-DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;lldb" \
-DLLVM_TARGETS_TO_BUILD="X86;ARM;AArch64;RISCV" \
-DLLVM_ENABLE_ASSERTIONS=ON
CMake 常用选项说明:
| 选项 | 默认值 | 说明 |
|---|---|---|
CMAKE_BUILD_TYPE | Debug | Release/Debug/RelWithDebInfo/MinSizeRel |
CMAKE_INSTALL_PREFIX | /usr/local | 安装路径 |
LLVM_ENABLE_PROJECTS | "" | 要构建的子项目 |
LLVM_TARGETS_TO_BUILD | all | 目标架构 |
LLVM_ENABLE_ASSERTIONS | OFF | 启用断言(开发推荐 ON) |
LLVM_BUILD_LLVM_DYLIB | OFF | 构建 libLLVM.so 共享库 |
LLVM_LINK_LLVM_DYLIB | OFF | 工具链接共享库 |
LLVM_ENABLE_RTTI | OFF | 启用 C++ RTTI |
LLVM_ENABLE_EH | OFF | 启用 C++ 异常处理 |
LLVM_PARALLEL_LINK_JOBS | 2 | 并行链接数(控制内存) |
CMAKE_C_COMPILER | 系统默认 | C 编译器路径 |
CMAKE_CXX_COMPILER | 系统默认 | C++ 编译器路径 |
2.4.5 不同构建配置
# Debug 构建(适合 LLVM 开发调试,非常大 ~80GB)
cmake -G Ninja -S llvm -B build-debug \
-DCMAKE_BUILD_TYPE=Debug \
-DLLVM_ENABLE_PROJECTS="clang;lld" \
-DLLVM_ENABLE_ASSERTIONS=ON
# Release + 调试信息(推荐开发)
cmake -G Ninja -S llvm -B build-relwithdebinfo \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DLLVM_ENABLE_PROJECTS="clang;lld" \
-DLLVM_ENABLE_ASSERTIONS=ON
# 最小化构建(仅 LLVM 核心库,不含 Clang)
cmake -G Ninja -S llvm -B build-minimal \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_TARGETS_TO_BUILD="X86" \
-DLLVM_ENABLE_PROJECTS=""
# 构建共享库(适合插件开发)
cmake -G Ninja -S llvm -B build-shared \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_PROJECTS="clang" \
-DLLVM_BUILD_LLVM_DYLIB=ON \
-DLLVM_LINK_LLVM_DYLIB=ON \
-DLLVM_ENABLE_RTTI=ON
2.4.6 编译与安装
# 编译(-j 指定并行数,建议为 CPU 核心数)
ninja -C build -j$(nproc)
# 运行 LLVM 测试套件(可选)
ninja -C build check-llvm
ninja -C build check-clang
# 安装
sudo ninja -C build install
# 验证
/opt/llvm/bin/llvm-config --version
/opt/llvm/bin/clang --version
注意: 完整的 LLVM + Clang 编译在 8 核机器上大约需要 1-2 小时(Release 模式),Debug 模式可能需要 3-4 小时。
2.4.7 交叉编译 LLVM
# 为 ARM64 交叉编译 LLVM
cmake -G Ninja -S llvm -B build-aarch64 \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc \
-DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ \
-DCMAKE_SYSTEM_PROCESSOR=aarch64 \
-DLLVM_TARGETS_TO_BUILD="AArch64" \
-DLLVM_ENABLE_PROJECTS="clang;lld" \
-DLLVM_DEFAULT_TARGET_TRIPLE=aarch64-linux-gnu
2.5 Docker 环境
2.5.1 使用官方 LLVM Docker 镜像
# 拉取 LLVM 18 开发镜像
docker pull ghcr.io/llvm/llvm-project-ubuntu-22.04:latest
# 启动容器
docker run -it --name llvm-dev \
-v $(pwd):/workspace \
ghcr.io/llvm/llvm-project-ubuntu-22.04:latest \
/bin/bash
2.5.2 自定义 Dockerfile
# Dockerfile
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
ENV LLVM_VERSION=18
# 安装基础依赖
RUN apt-get update && apt-get install -y \
wget gnupg2 software-properties-common \
build-essential cmake ninja-build python3 \
git curl ca-certificates
# 添加 LLVM APT 源
RUN wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | \
tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc && \
echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-${LLVM_VERSION} main" | \
tee /etc/apt/sources.list.d/llvm.list
# 安装 LLVM 工具链
RUN apt-get update && apt-get install -y \
llvm-${LLVM_VERSION}-dev \
clang-${LLVM_VERSION} \
lld-${LLVM_VERSION} \
lldb-${LLVM_VERSION} \
clang-tools-${LLVM_VERSION} \
libclang-${LLVM_VERSION}-dev \
libc++-${LLVM_VERSION}-dev \
libc++abi-${LLVM_VERSION}-dev \
&& rm -rf /var/lib/apt/lists/*
# 设置环境变量
ENV PATH="/usr/lib/llvm-${LLVM_VERSION}/bin:${PATH}"
ENV LLVM_DIR="/usr/lib/llvm-${LLVM_VERSION}/lib/cmake/llvm"
WORKDIR /workspace
CMD ["/bin/bash"]
# 构建并运行
docker build -t llvm-dev .
docker run -it -v $(pwd):/workspace llvm-dev
2.5.3 从源码编译的 Dockerfile
# Dockerfile.build — 从源码编译完整 LLVM
FROM ubuntu:22.04 AS builder
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
build-essential cmake ninja-build python3 python3-pip \
git curl wget xz-utils libffi-dev libxml2-dev zlib1g-dev
# 获取源码
WORKDIR /src
RUN git clone --depth 1 --branch llvmorg-18.1.8 \
https://github.com/llvm/llvm-project.git
# 编译
WORKDIR /src/llvm-project
RUN cmake -G Ninja -S llvm -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/opt/llvm \
-DLLVM_ENABLE_PROJECTS="clang;lld" \
-DLLVM_TARGETS_TO_BUILD="X86;AArch64" \
-DLLVM_ENABLE_ASSERTIONS=ON \
-DLLVM_BUILD_LLVM_DYLIB=ON \
&& ninja -C build -j$(nproc) \
&& ninja -C build install
# 最终镜像(多阶段构建,减小体积)
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
libstdc++6 libgcc-s1 zlib1g libffi8 \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /opt/llvm /opt/llvm
ENV PATH="/opt/llvm/bin:${PATH}"
ENV LD_LIBRARY_PATH="/opt/llvm/lib:${LD_LIBRARY_PATH}"
WORKDIR /workspace
CMD ["/bin/bash"]
2.6 验证安装
2.6.1 基础验证
# 检查 LLVM 版本
llvm-config --version
# 检查可用的目标架构
llvm-config --targets-built
# 检查 LLVM 组件
llvm-config --components
# 检查 Clang
clang --version
# 检查 LLD(链接器)
lld --version
# 检查 LLDB(调试器)
lldb --version
2.6.2 编译测试
// hello.c
#include <stdio.h>
int main() {
printf("Hello, LLVM!\n");
return 0;
}
# 使用 Clang 编译
clang hello.c -o hello
./hello
# 生成 LLVM IR
clang -S -emit-llvm hello.c -o hello.ll
# 查看 IR
cat hello.ll
# 使用 opt 优化
opt -O2 hello.ll -o hello_opt.bc
# 生成汇编
llc hello_opt.bc -o hello.s
# 汇编并链接
clang hello.s -o hello_optimized
./hello_optimized
2.6.3 CMake 集成测试
# CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(LLVMTest)
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
# 添加 LLVM 头文件和定义
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
# 构建一个使用 LLVM API 的程序
add_executable(llvm-test main.cpp)
llvm_map_components_to_libnames(llvm_libs core support)
target_link_libraries(llvm-test ${llvm_libs})
// main.cpp
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
int main() {
LLVMContext Context;
Module *Module = new Module("test", Context);
IRBuilder<> Builder(Context);
// 创建函数: int add(int a, int b)
FunctionType *FuncType = FunctionType::get(
Builder.getInt32Ty(),
{Builder.getInt32Ty(), Builder.getInt32Ty()},
false
);
Function *Func = Function::Create(
FuncType, Function::ExternalLinkage, "add", Module
);
BasicBlock *Entry = BasicBlock::Create(Context, "entry", Func);
Builder.SetInsertPoint(Entry);
Value *Sum = Builder.CreateAdd(Func->getArg(0), Func->getArg(1), "sum");
Builder.CreateRet(Sum);
// 打印生成的 IR
Module->print(outs(), nullptr);
return 0;
}
# 构建测试
mkdir build && cd build
cmake -DLLVM_DIR=/opt/llvm/lib/cmake/llvm ..
make
./llvm-test
预期输出:
; ModuleID = 'test'
source_filename = "test"
define i32 @add(i32 %0, i32 %1) {
entry:
%sum = add i32 %0, %1
ret i32 %sum
}
2.7 多版本管理
2.7.1 使用 update-alternatives(Linux)
# 注册多个 LLVM 版本
sudo update-alternatives --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-17 10
sudo update-alternatives --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-18 20
# 交互式选择
sudo update-alternatives --config llvm-config
2.7.2 使用环境变量
# 在 .bashrc 中设置版本切换函数
switch_llvm() {
local version=$1
export PATH="/usr/lib/llvm-${version}/bin:${PATH}"
export LLVM_DIR="/usr/lib/llvm-${version}/lib/cmake/llvm"
export CC="clang-${version}"
export CXX="clang++-${version}"
echo "Switched to LLVM ${version}"
}
# 使用
switch_llvm 17
switch_llvm 18
2.8 IDE 配置
2.8.1 VS Code
// .vscode/settings.json
{
"cmake.configureArgs": [
"-DLLVM_DIR=/opt/llvm/lib/cmake/llvm"
],
"clangd.path": "/opt/llvm/bin/clangd",
"C_Cpp.intelliSenseEngine": "disabled",
"clangd.arguments": [
"--compile-commands-dir=${workspaceFolder}/build",
"--header-insertion=never"
]
}
2.8.2 生成 compile_commands.json
# CMake 项目自动生成
cmake -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -S . -B build
# 对于 LLVM 自身的源码
cmake -G Ninja -S llvm -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
ln -s build/compile_commands.json .
2.9 常见安装问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
CMake Error: Could not find LLVM | LLVM_DIR 未设置 | export LLVM_DIR=/path/to/llvm/lib/cmake/llvm |
fatal error: 'llvm/IR/Module.h' file not found | 缺少 LLVM 开发包 | sudo apt install llvm-dev |
undefined reference to LLVM... | 链接库缺失 | 检查 llvm-config --libs |
ld.lld: error: unable to find library -lstdc++ | C++ 标准库缺失 | sudo apt install libstdc++-dev |
| 编译 LLVM 时 OOM | 内存不足 | 减少并行数: ninja -C build -j2 |
| 编译 LLVM 时磁盘满 | 磁盘空间不足 | Release 构建约 15GB,Debug 约 80GB |
2.10 本章小结
| 安装方式 | 命令 | 适用场景 |
|---|---|---|
| Ubuntu APT | apt install llvm-18-dev clang-18 | 快速上手 |
| Homebrew | brew install llvm | macOS 开发 |
| 预编译二进制 | 下载 tar.xz 解压 | 特定版本需求 |
| 源码编译 | cmake + ninja | 自定义构建 |
| Docker | docker run | 团队环境、CI/CD |
扩展阅读
- LLVM Getting Started — 官方入门指南
- LLVM CMake Build System — CMake 构建选项完整参考
- LLVM Docker Images — 官方 Docker 镜像
- apt.llvm.org — LLVM 官方 APT 源
下一章: 第 3 章:LLVM 整体架构 — 深入理解 LLVM 的 IR 层次、Pass 框架和模块化设计。