# LLVM

# 介绍

GCC一样,LLVM也是编译器,GCC是由GNU开发的编程语言编译器,是GNU项目的关键部分,也是自由的类Unix及苹果电脑Mac OS X操作系统的标准编译器。

LLVM本身不是缩略词,项目的名称就叫这个。该项目于2000年由美国伊利诺伊大学University of Illinois厄巴纳-香槟分校的Vikram AdveChris Lattner发起的,他们的目标在于提供一种基于静态单赋值SSA 现代编译策略能够支持任意编程语言的静态和动态编译的工具。LLVM首次发布是在2003年。从那时起,LLVM 已经发展成为一个由许多子项目组成的项目集,其中许多子项目广泛应用于商业软件,开源软件和学术研究中。LLVM的开源协议为:"Apache 2.0 License with LLVM exceptions" (opens new window)

LLVM包含的主要子工程有:

  • LLVM Core Libraries,LLVM核心库提供了现代的独立于源码和目标的优化器,同时支持生成许多流行CPU的代码,这些库围绕一个明确的中间代码表示来构建,因此使用LLVM可以轻松地创建新的语言。

  • ClangClangLLVM原生的,主要用于CC++Objective-C的编译器。Clang Static Analyzerclang-tidyClang前端工具,用于静态代码分析,可以自动的检测定位代码中的bug

  • LLDB,LLDB是一个由ClangLLVM支持的用于调试CC++Objective-CObjective-C++程序的交互式调试器。

  • Polly,Polly是一个优化器插件,它使用数据流分析来提供高级优化。

  • MLIRMLIR是一个用于编译器和运行时系统的中间表示形式。MLIR 旨在解决软件碎片化问题,改进异构硬件的编译,大幅降低构建特定领域编译器的成本,并帮助将现有编译器连接在一起。

  • OpenMP runtime,OpenMP运行时库支持多核和分布式并行计算。

  • libc++libc++abilibc++LLVM的C++标准库的实现,其比GCC更严格的遵守C++标准。

  • LLD是一个新的链接器Linker,它可以直接替代系统链接器,而且运行速度更快。

  • BOLT工程是一个后链接优化器,它根据采样剖析器收集的执行情况优化应用程序的代码布局,从而实现改进。

除了官方的子工程外,还有很多其他的工程使用LLVM来完成各种任务 (opens new window),借助这些工程,可以使用LLVM来编译Ruby/Python/Haskell/Rust/PHP/Lua/Julia等语言。LLVM的优势在于其通用性,灵活性和可重用性,这也是其能够广泛应用于各种不同任务的原因。

# 安装LLVM

参考手册https://llvm.org/docs/GettingStarted.html#hardware (opens new window)

  • 获取源码
git clone https://github.com/llvm/llvm-project.git
# 查看tag信息
git tag
# 切到对应版本的分支上
git checkout tag-name
  • 构建配置
cmake -S llvm -B build -G <generator> [options]

命令中-S用于指定源代码目录,-B用于指定构建目录,-G用于指定生成器,不同平台使用的生成器分别为:

  • Ninja,生成Ninja构建文件
  • Unix Makefiles生成makefile
  • Visual Studio生成Visual Stuio工程需要的文件
  • Xcode生成Xcode工程

常用的cmake构建选项参数[options]:

  • -DLLVM_ENABLE_PROJECTS想要构建的LLVM子项目列表,多个项目名称间使用逗号分割。譬如-DLLVM_ENABLE_PROJECTS="clang;lld;clang-tools-extra;lldb;polly"
  • -DCMAKE_INSTALL_PREFIX=directory安装路径
  • -DCMAKE_BUILD_TYPE=type构建类型,可选值有DebugReleaseRelWithDebInfoMinSizeRel
  • -DLLVM_ENABLE_ASSERTIONS=ON在启用断言检查的情况下进行编译(对于调试构建,默认为打开,对于所有其他构建类型,默认为关闭)。
  • -DLLVM_TARGETS_TO_BUILD=targets指定要构建的目标平台,多个目标名称用分号分隔。譬如-DLLVM_TARGETS_TO_BUILD="X86;ARM;AArch64"
  • -DLLVM_USE_LINKER=lld使用LDD作为链接器,

一个构建命令示例:

cmake -S llvm -B build -G "Unix Makefiles" -DLLVM_ENABLE_PROJECTS="clang;lld;clang-tools-extra;lldb;polly" -DCMAKE_INSTALL_PREFIX=/home/lx/data/sw/llvm-project-main/install -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_USE_LINKER=lld
  • 构建安装
make -jN && make install

# 使用LLVM

install_dir/bin添加到环境变量PATH中,就可以使用LLVM了。

  • 使用LLVM编译C/C++程序
clang++ -c hello.cpp -o hello.o
  • 使用LLVM链接程序
lld -flavor gnu -o hello hello.o
  • 使用LLVMlldb调试程序
lldb ./hello
  • cmake中使用clang
    • 设置环境变量
    export CC=/usr/bin/clang
    export CXX=/usr/bin/clang++
    cmake ..
    make
    
    • 使用cmake参数
    cmake .. -DCMAKE_C_COMPILER=/sw/llvm-project-main/install/bin/clang -DCMAKE_CXX_COMPILER=/sw/llvm-project-main/install/bin/clang
    

# reference

1.https://llvm.org/ (opens new window)
2.https://llvm.org/docs/GettingStarted.html#hardware (opens new window)