LLVM 学习记录:编译器最佳实践 - 构建,Cmake 和 test

Posted by 叉叉敌 on May 31, 2024

学习内容来自网络课程,这个基本上是针对有点经验的 llvm 开发者,前面的就是过一遍。

https://github.com/PacktPublishing/LLVM-Techniques-Tips-and-Best-Practices-Clang-and-Middle-End-Libraries

https://books.google.com.tw/books?id=g_wqEAAAQBAJ&printsec=copyright&redir_esc=y#v=onepage&q&f=false

1. 构建技巧

  • 用 ninja 构建
  • 指定 lld 或者是 gold 的链接器
  • 用特定的 cmake 参数来构建
  • 构建不同的类型;debug,release,RelWithDebInfo

这个我试了,RelWithDebInfo 又慢又大 release,又快又小,如果不 debug 的话,用这个不错; debug 编译慢,空间占用的也非常的大。

  • 构建指定的目标 target, -DLLVM_TARGETS_TO_BUILD="X86;AMDGPU" … ,有针对性的编译,速度会快很多;

  • 构建动态库: -DBUILD_SHARED_LIBS=ON 链接静态库通常比链接动态库花费更多的时间

  • 使用 gn 来编译,我没有成功;LLVM 的 GN 支持位于 llvm/utils/gn 文件夹中。

2. llvm 里面 Cmake 用法

lib 是 LLVM 框架的基本构建块。

CMake 添加新的库

不要用 add_library,要用add_llvm_component_library

# In an in-tree CMakeLists.txt file…
add_library(MyLLVMPass SHARED
MyPass.cpp) # Do NOT do this to add a new LLVM library

为什么不要用这个?主要就是慢,而且不好扩展和控制。

LLVM 更喜欢使用全局 CMake 参数 (即 BUILD_SHARED_LIBS) 来控制所有的组件库是静态构建还是动态构建。使用内置指令很难做到这一点的

  • LLVM 更喜欢使用一个全局的 CMake 参数来控制一些编译标志
# In a CMakeLists.txt
add_llvm_component_library(LLVMFancyOpt
FancyOpt.cpp)

这里,LLVMFancyOpt 是库名,FancyOpt.cpp 是源文件。

注意下面 2 个用法是一样的:

写到一个里面

add_llvm_component_library(LLVMFancyOpt
FancyOpt.cpp
LINK_COMPONENTS
Analysis ScalarOpts)

分开写,先 link 组件:

set(LLVM_LINK_COMPONENTS
Analysis ScalarOpts)
add_llvm_component_library(LLVMFancyOpt
FancyOpt.cpp)

CMake 函数添加可执行文件和工具

可以使用 add_llvm_executableadd_llvm_tool:

add_llvm_tool(myLittleTool
MyLittleTool.cpp)


还有一个全局的 CMake 变量 LLVM_BUILD_TOOLS,用来启用/禁用 LLVM 工具。

CMake 函数添加 Pass 插件

add_llvm_pass_plugin(MyPass
HelloWorldPass.cpp)

LINK_COMPONENTS、LINK_LIBS 和 DEPENDS 参数也可以在这里使用,其用法和功能与 add_llvm_component_library 相同。

3. lit 测试

LIT 是一个测试基础设施,最初是为运行 LLVM 的回归测试而开发的。主要配合 Filecheck 来用。

书里面,没有提到的,我这里补充一个,就是最好用 llvm-lit 工具,而不是 lit(python 的 lib)。

如果还有就是可以自动更新 lit 测试的检查点;工具位于llvm/util/update_xxxx.py

用法python update_xxx.py under_test_file.xx.