强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

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 系统要求

资源最低要求推荐配置
CPU2 核8 核以上
内存4 GB16 GB 以上
磁盘20 GB100 GB(含 Debug 构建)
编译器GCC 7+ / Clang 5+GCC 12+ / Clang 15+
CMake3.20+3.25+
Python3.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_TYPEDebugRelease/Debug/RelWithDebInfo/MinSizeRel
CMAKE_INSTALL_PREFIX/usr/local安装路径
LLVM_ENABLE_PROJECTS""要构建的子项目
LLVM_TARGETS_TO_BUILDall目标架构
LLVM_ENABLE_ASSERTIONSOFF启用断言(开发推荐 ON)
LLVM_BUILD_LLVM_DYLIBOFF构建 libLLVM.so 共享库
LLVM_LINK_LLVM_DYLIBOFF工具链接共享库
LLVM_ENABLE_RTTIOFF启用 C++ RTTI
LLVM_ENABLE_EHOFF启用 C++ 异常处理
LLVM_PARALLEL_LINK_JOBS2并行链接数(控制内存)
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 LLVMLLVM_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 APTapt install llvm-18-dev clang-18快速上手
Homebrewbrew install llvmmacOS 开发
预编译二进制下载 tar.xz 解压特定版本需求
源码编译cmake + ninja自定义构建
Dockerdocker run团队环境、CI/CD

扩展阅读

  1. LLVM Getting Started — 官方入门指南
  2. LLVM CMake Build System — CMake 构建选项完整参考
  3. LLVM Docker Images — 官方 Docker 镜像
  4. apt.llvm.org — LLVM 官方 APT 源

下一章: 第 3 章:LLVM 整体架构 — 深入理解 LLVM 的 IR 层次、Pass 框架和模块化设计。