预编译包适合开箱即用场景,如仅用clang编译/链接或CI中不涉及IR分析;源码安装则必须用于编译器开发、定制优化或调试IR,因其提供可读、可断点、可修改的完整工具链。

日常开发用预编译包,编译器开发/定制优化/调试IR必须源码安装。预编译包开箱即用,但所有内部结构、Pass行为、IR生成细节都对你黑盒;源码安装不是“更高级”,而是把整个工具链变成你可读、可断点、可修改的代码实体——这是做真实编译器工作的起点。
什么时候该用 apt install llvm clang 或 brew install llvm
满足以下任意一条,就别折腾源码:
- 只写 C/C++ 代码,用
clang编译、clang++链接,偶尔跑clang-tidy检查风格 - 项目 CI 中需要 LLVM 工具链,但不涉及 IR 分析或 Pass 开发
- 机器磁盘空间紧张(预编译包通常
- 系统是 CentOS/RHEL 且无 root 权限,又不需要定制功能(这时
llvm-project的 CMake 构建会卡在libunwind或compiler-rt依赖上)
为什么 git clone https://github.com/llvm/llvm-project.git 是刚需
当你遇到这些情况时,预编译包完全失效:
- 想在
llvm::FunctionPass里加一行errs() 并单步进去看它在哪被调用 - 需要启用
-DLLVM_ENABLE_ASSERTIONS=ON+-DCMAKE_BUILD_TYPE=Debug跑出带完整符号的clang,然后用gdb追ParseDeclaration怎么把auto x = f();变成 IR - 要给
llvm/lib/Transforms/Scalar新增一个LoopFusionPass,并让它出现在opt -loop-fusion命令里 - 目标平台是 RISC-V 或 ARM64,但发行版预编译包只打了 x86_64 支持(
-DLLVM_TARGETS_TO_BUILD="RISCV;ARM"这种控制粒度,二进制包根本不提供)
cmake -S llvm -B build 构建时最常踩的三个坑
不是配置错,而是默认行为反直觉:
-
-DLLVM_ENABLE_PROJECTS必须显式声明,比如只想要 Clang 和 LLD,就得写-DLLVM_ENABLE_PROJECTS="clang;lld";漏掉clang就连build/bin/clang都不会生成 -
build目录不能和llvm源码目录混在一起,否则 CMake 会反复报Source directory ... contains a CMakeLists.txt but is not the build directory -
-DCMAKE_INSTALL_PREFIX如果设成/usr/local,后续sudo make install会覆盖系统原有llvm-config,导致其他依赖 LLVM 的工具(如 Rust 的rustc)突然报错找不到LLVMConfig.cmake
真正难的不是编译成功,而是第一次用 clang -emit-llvm -S test.c 看到 IR 后,意识到 %1 = alloca i32, align 4 这行背后有整整七个 Pass 在 lib/CodeGen/ 里接力改写它——这时候你才明白,为什么非得从源码开始。

















