# 从源码构建 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 字节码输出),其余全关。