A guide on setting up the development environment for working with MLIR, including prerequisites and installation steps.
在开始之前, 首先有以下的建议:
熟悉 CMake 的基本语法和使用
熟练使用 Linux 进行 C/C++ 开发, 熟悉 Linux 的常用命令
非常熟悉 C/C++ 的编译和链接过程, 能够定位常见的编译和链接错误(比如
Undefined Reference )
熟悉 Git 的基本使用
最好了解过 LLVM 的基本使用和开发
你应该或多或少了解过这些但不限于这些的概念: 符号表, ABI, 链接器, 动态库/静态库, RTTI, 智能指针, 模板编程, C++名称修饰(Mangling)及其导致的问题.
首先安装一些前置依赖:
apt install build-essential cmake git python3 python3-pip ninja-build clang lld ccache libc++-dev然后从源码克隆 LLVM 仓库:
git clone https://github.com/llvm/llvm-project.git # 项目较大 若拉取失败可以尝试SSH克隆
cd llvm-project
git checkout llvmorg-21.1.2 # choose the version you want
mkdir build && cd build
cmake -G Ninja ../llvm \
-DLLVM_ENABLE_PROJECTS="mlir" \
-DLLVM_TARGETS_TO_BUILD="host" \
-DCMAKE_BUILD_TYPE=DEBUG \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DLLVM_ENABLE_ASSERTIONS=ON \
-DLLVM_USE_LINKER=lld \ # Use lld as the linker to speed up linking
-DLLVM_CCACHE_BUILD=ON \ # Use ccache to speed up compilation
-DLLVM_ENABLE_LIBCXX=ON \ # Use libc++ as the standard library
cmake --build . --target check-mlir这里是一些提示:
建议开启 lld 链接器, 它会比 Linux 上默认的 ld 链接器快很多.
建议开启 ccache, 它会缓存编译结果, 提高二次编译的速度.
libc++ 标准库看需求. 如果不使用 libc++, 在 Regression Test
中可能会有一些地方爆出内存泄漏之类的问题. 这是因为 libc++ 和
libstdc++ 的实现细节有差异. 但注意, 这两家标准库是ABI不兼容的,
如果你的项目中需要链接 LLVM 以外的库, 这些库大概率是基于 libstdc++
编译的, 此时建议使用 libstdc++ 以避免不必要的问题.
另外, 由于 MLIR 仍然在快速发展, 每个大版本都可能有Breaking Changes, 因此关于一些API的使用, 建议阅读Doxygen文档, 或者干脆直接参考源码. 一些曾经可以使用的API, 可能在新版本中已经被移除或者修改.
接着可以将 LLVM 和 MLIR 的可执行文件路径添加到环境变量中:
export PATH=/path/to/llvm-project/build/bin:$PATH
export LD_LIBRARY_PATH=/path/to/llvm-project/build/lib:$LD_LIBRARY_PATH这样可以让系统识别 LLVM 和 MLIR 的工具和库.
很多时候如果你想去使用别人的 MLIR 工程, 但各种工程依赖的 MLIR 版本千奇百怪(至少在学术界用 MLIR 做工作的情况是这样的), 然后每个工程都会自带一个 LLVM 子模块, 每次都要克隆很长时间.
这个时候你可以在本地先完整克隆一个 LLVM 仓库, 然后在你想要使用的工程中执行以下命令:
git submodule init
git submodule sync
rm -rf /path/to/submodule-llvm-project
cp -r /path/to/local/llvm-project /path/to/submodule-llvm-project
git submodule update # automatically checkout the right version直接将本地的 LLVM 仓库复制到子模块目录下, 这样就避免了重复下载.
另外如果在本地 LLVM 仓库中已经有一个 build 目录, 直接复制整个顶层
llvm-project 会浪费很多空间和时间(开调试构建出来的 LLVM
的符号表是非常大的, 总文件大小随便达到几十GB), 你可以使用 rsync
排除其中某些目录, 例如:
rsync -av --progress --exclude 'build' /path/to/local/llvm-project/ /path/to/submodule-llvm-project/这样节省很多时间. 注意 exclude 后面的路径是相对源路径的, 不是相对
$SHELL(pwd) 的.
或者干脆在克隆子模块的时候加上 --depth 1 选项, 只克隆最新的提交.
git submodule update --init --depth 1开发的过程中建议使用CLion作为IDE, 因为VSCode上的 clangd 插件在重度模版和代码量很大的情况下索引会比较慢, 甚至可能莫名崩溃. 例如类似这样的常见模板变参:
template<class Ty, typename... Args>
void builder(Location loc, Args&& ... args) {
return Ty::build(builder, loc, std::forward<Args>(args)...);
}VSCode上的 clangd 插件在无法在参数不符合 Ty::build 签名的时候报错, 一定要到编译器开始编译时才能发现问题.
并且VSCode上的CMake插件实在是太简陋了, 对CMake代码的补全/索引/跳转几乎等于没有, 切换CMake Target也很麻烦, 甚至不如直接在终端手动指定来的方便. CLion同样支持WSL, 所以无需担心这一点(还是建议纯血Linux开发舒服). 至于在Windows上开发, 我觉得纯粹是自讨苦吃, 别折磨自己.