Files
note_AI_compiler/iree/10-build-from-source.md
T
2026-08-20 17:20:09 +08:00

120 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 从源码构建 IREE(写 pass 的前置)
> 2026-08-15。为了写自定义 pass,需要从源码构建 IREE 编译器(pip 包只有二进制,没有头文件和构建系统)。
> 记录完整步骤,方便复现。
## 1. 为什么要源码构建
pip 安装的 `iree-base-compiler` 是预编译二进制,**没有头文件、没有 CMake 构建系统**,无法编写和编译自定义 pass。
写 pass 需要:源码 + LLVM/MLIR 头文件 + 构建系统。
## 2. 前提(工具链)
```bash
sudo apt install clang-15 lld-15 # 编译器 + 链接器(Ubuntu 22.04 最新可用 clang)
.venv/bin/pip install ninja # ninja 也可用 pip 装(免 sudo)
```
- clang-15(不能用默认 clang=14,可能太老,IREE 3.11 用 LLVM 23)
- lld-15(快速链接,可选但推荐)
- ninja(构建生成器)
- cmake(系统已有)
## 3. 子模块
```bash
# 关键子模块:llvm-project(IREE fork,~1.5GB,最耗时)、flatcc(VM 字节码)
git submodule update --init --depth 1 third_party/llvm-project third_party/flatcc
```
> 只初始化编译所需的最小集合。写 pass 测试用 linalg 输入,不需要 stablehlo/torch-mlir 等子模块。
## 4. 配置(cmake)
```bash
cmake -G Ninja -B build/ -S . \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15 \
-DIREE_ENABLE_LLD=ON \
-DIREE_BUILD_TESTS=OFF -DIREE_BUILD_SAMPLES=OFF -DIREE_BUILD_PYTHON_BINDINGS=OFF \
-DIREE_TARGET_BACKEND_DEFAULTS=OFF -DIREE_TARGET_BACKEND_LLVM_CPU=ON \
-DIREE_HAL_DRIVER_DEFAULTS=OFF -DIREE_HAL_DRIVER_LOCAL_SYNC=ON -DIREE_HAL_DRIVER_LOCAL_TASK=ON
```
关键选项:
- `-DIREE_BUILD_TESTS/SAMPLES/PYTHON_BINDINGS=OFF` —— 大幅缩减构建(只建编译器)
- `-DIREE_TARGET_BACKEND_DEFAULTS=OFF + LLVM_CPU=ON` —— 只保留 CPU 后端
- `-DIREE_HAL_DRIVER_DEFAULTS=OFF + LOCAL_SYNC/TASK=ON` —— 只保留 CPU 运行时驱动
- `-DCMAKE_BUILD_TYPE=RelWithDebInfo` —— 有调试信息 + 优化(写 pass 推荐)
## 5. 构建
```bash
# 只构建编译器工具(iree-compile + iree-opt),比全量快很多
cmake --build build/ --target iree-compile iree-opt -j 16
```
- 结果在 `build/tools/iree-compile`、`build/tools/iree-opt`
- `iree-opt` 是测试 pass 的关键工具(单 pass 运行,无需完整编译管线)
- 首次全量构建 ~30-60 分钟(16 核)
## 6. 验证
```bash
build/tools/iree-compile --version
build/tools/iree-opt --help
```
## 7. 写 pass 的流程(后续)
1. 在某个 dialect 的 `Transforms/` 下写 pass 的 `.cpp`
2. 在对应 `Passes.td` 里注册 pass(TableGen)
3. 在 `CMakeLists.txt` 里加入源文件
4. 重新构建(增量构建,快)
5. 用 `iree-opt --pass-name` 单测 pass
## 8. 备选:gcc 构建(不用 sudo)
如果没有 sudo 装 clang,可以用系统 gcc 11.4(支持 C++17):
```bash
cmake -G Ninja -B build/ -S . -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DIREE_BUILD_TESTS=OFF -DIREE_BUILD_SAMPLES=OFF -DIREE_BUILD_PYTHON_BINDINGS=OFF \
-DIREE_TARGET_BACKEND_DEFAULTS=OFF -DIREE_TARGET_BACKEND_LLVM_CPU=ON \
-DIREE_HAL_DRIVER_DEFAULTS=OFF -DIREE_HAL_DRIVER_LOCAL_SYNC=ON -DIREE_HAL_DRIVER_LOCAL_TASK=ON
```
(gcc 是 IREE 官方"best effort"支持,能用但稍慢。)
## 9. 实际踩坑记录(本次构建的关键修复)
### 9.1 工具链版本
- **cmake 3.22 太旧**(需 3.26+)→ `pip install cmake`(4.4.2)
- **clang-15 需要 g++-12**:系统只有 `gcc-12`(无 `g++-12`)和 `libstdc++-11-dev`,导致
clang-15 自动选 GCC 12 却找不到 C++ 头文件/`libstdc++.so`。
修复:`sudo apt install g++-12`(带 `libstdc++-12-dev`)
- **lld**:装了 `lld-15` 但没有无版本号 `ld.lld`。修复:软链接
`ln -sf /usr/bin/ld.lld-15 .venv/bin/ld.lld`,并把 `.venv/bin` 加入 PATH
### 9.2 llvm-project 子模块用 tarball 而非 git
git 方式下载 llvm-project(1.5GB)在 VPN 下被 GitHub 限速(~30KB/s),改用 **codeload tarball**(280MB 压缩)+ 断点续传,快很多。但 git 不认 tarball 解压出的目录为子模块,导致 IREE 的子模块检查失败。
修复:把 `build_tools/scripts/git/check_submodule_init.py` 改成 no-op(本地构建,手动提供源码)。
### 9.3 只保留必要组件(大幅缩减构建)
最终配置命令:
```bash
cmake -G Ninja -B build/ -S . \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15 \
-DIREE_ENABLE_LLD=ON \
-DIREE_BUILD_TESTS=OFF -DIREE_BUILD_SAMPLES=OFF -DIREE_BUILD_PYTHON_BINDINGS=OFF -DIREE_BUILD_BENCHMARKS=OFF \
-DIREE_TARGET_BACKEND_DEFAULTS=OFF -DIREE_TARGET_BACKEND_LLVM_CPU=ON \
-DIREE_HAL_DRIVER_DEFAULTS=OFF -DIREE_HAL_DRIVER_LOCAL_SYNC=ON -DIREE_HAL_DRIVER_LOCAL_TASK=ON \
-DIREE_INPUT_STABLEHLO=OFF -DIREE_INPUT_TORCH=OFF -DIREE_INPUT_TOSA=OFF
```
关键:`-DIREE_BUILD_BENCHMARKS=OFF`(否则要 benchmark 子模块)、
`-DIREE_INPUT_*=OFF`(否则要 stablehlo/torch-mlir 子模块)。
### 9.4 写 pass 最小依赖子模块
只用 **llvm-project + flatcc** 两个子模块(linalg 输入 + VM 字节码输出),其余全关。