编译 LLVM 源码,使用 Clion 调试 clang

版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/

1. LLVM 简介

LLVM 是一个开源的编译器基础架构,最初由 Chris Lattner 于 2000 年在伊利诺伊大学开发,后来成为一个广泛应用于编译器和程序分析的项目。

LLVM 的核心组件:

  • LLVM Core Libraries:提供用于编译器开发的核心工具集,包括代码生成、优化、目标机器描述等。

  • Clang:一个基于 LLVM 的 C、C++、Objective-C 编译器前端。

  • LLVM IR(Intermediate Representation):一种类似汇编的中间表示语言,是 LLVM 的核心抽象。代码在编译过程中先被转换为 LLVM IR,随后进行各种优化,再生成目标机器码。

  • LLVM Optimizer:对 LLVM IR 进行各种优化,如循环优化、内联展开等,以提升性能。

  • LLVM Code Generator:将优化后的 LLVM IR 转换为特定平台的机器码。

  • Linker:LLVM 也包含了一些链接器工具(如 LLD),用于将编译好的目标文件链接成可执行文件或库。

LLVM 的优势:

  • 模块化设计:可用于多种语言的编译器开发(如 Rust、Swift)。

  • 跨平台支持:支持多种处理器架构(如 x86、ARM、RISC-V)。

  • 高度优化:提供丰富的优化技术,帮助生成更高效的机器码。

  • 动态编译支持:适用于 JIT(即时编译),如 WebAssembly 和 Swift 的 REPL 环境。

LLVM 官网:https://llvm.org/

Getting Started with LLVM Core Libraries(中文版)

2. 下载 LLVM

在 Android NDK 中,LLVM/Clang 是默认的编译器。自 Android NDK r18 开始,Google 弃用了 GCC,全面转向使用 LLVM/Clang 作为 NDK 的编译工具链。

这意味着:

  • Clang 作为 C/C++ 的编译前端:替代了 GCC,负责将 C/C++ 代码编译为 LLVM IR。

  • LLVM IR 优化和代码生成:LLVM 对中间表示进行优化,并生成适合 Android 设备(如 ARM、ARM64、x86、x86_64)的机器码。

  • LLD 链接器:NDK 还默认使用了 LLD 作为链接器,提高了链接速度。

NDK 中 LLVM 所在路径
截图.png

查看 clang 版本,这里版本是 18.0.2

(base) PS D:\App\android\sdk\ndk\27.1.12297006\toolchains\llvm\prebuilt\windows-x86_64\bin> ./clang --version

Android (12285214, based on r522817b) clang version 18.0.2 (https://android.googlesource.com/toolchain/llvm-project d8003a456d14a3deb8054cdaa529ffbf02d9b262)
Target: x86_64-w64-windows-gnu
Thread model: posix
InstalledDir: D:/App/android/sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/windows-x86_64/bin

LLVM 下载:https://releases.llvm.org/
image.png

通过下面命令,把 llvm 18.1.8 版本源码下载到本地

git clone --depth 1 --branch llvmorg-18.1.8 https://github.com/llvm/llvm-project.git

3. LLVM 项目介绍

llvm-project/
├── .clang-tidy                 # Clang-Tidy 配置文件,用于代码静态分析和代码质量检查
├── .gitattributes              # Git 属性配置文件,控制文件的检查、合并和不同平台的换行符设置
├── .git-blame-ignore-revs      # Git blame 忽略特定提交,用于排除格式化提交的影响
├── .gitignore                  # Git 忽略文件配置,定义哪些文件和目录不应纳入版本控制
├── .mailmap                    # Git 邮件映射文件,用于规范化提交者的邮箱地址
├── CODE_OF_CONDUCT.md          # 社区行为规范,规定贡献者的行为守则
├── CONTRIBUTING.md             # 贡献指南,介绍如何为项目做贡献
├── LICENSE.TXT                 # 项目开源许可证,通常为 Apache License 2.0
├── README.md                   # 项目简介和快速入门指南
├── SECURITY.md                 # 安全报告流程,说明如何报告安全漏洞
├── .ci                         # 持续集成相关配置文件
├── .github                     # GitHub 特定文件(如 issue 模板、pull request 模板、CI 配置等)

├── bolt                        # BOLT (Binary Optimization and Layout Tool),用于对二进制文件进行优化和布局调整
├── clang                       # Clang 编译器前端,支持 C、C++、Objective-C 等语言
├── clang-tools-extra           # Clang 相关的额外工具,如 clang-tidy、clangd、include-fixer 等
├── cmake                       # CMake 模块和工具,辅助构建 LLVM 项目
├── compiler-rt                 # 运行时库,包括 AddressSanitizer、ThreadSanitizer、UBSan 等
├── cross-project-tests         # 跨项目测试,确保各个子项目在一起工作时的兼容性
├── flang                       # Fortran 编译器前端,将 Fortran 代码编译为 LLVM IR
├── libc                        # LLVM 实现的标准 C 库 (libc),专为高性能场景设计
├── libclc                      # OpenCL C 标准库实现,主要用于 GPU 计算
├── libcxx                      # LLVM 的 C++ 标准库实现(如 `<iostream>`、`<vector>`)
├── libcxxabi                   # C++ ABI 支持库,用于异常处理和 RTTI(运行时类型识别)
├── libunwind                   # 轻量级栈展开库,用于实现异常处理时的栈展开功能
├── lld                         # LLVM 项目的高效链接器,替代 GNU ld
├── lldb                        # LLVM 调试器,类似于 GDB,支持调试 C、C++、Swift 等语言
├── llvm                        # LLVM 核心库,包括 IR 生成、优化和代码生成
├── llvm-libgcc                 # 提供 GCC 兼容的库(如 `__builtin` 函数的实现)
├── mlir                        # 多层次中间表示(MLIR),用于 DSL 和机器学习编译器开发
├── openmp                      # OpenMP 运行时库,支持并行编程
├── polly                       # LLVM 的循环优化器,用于自动并行化和矢量化
├── pstl                        # 并行 STL(C++ 标准模板库)实现,提升算法性能
├── runtimes                    # 各种运行时库的集合(如 libc、libc++、compiler-rt)
├── third-party                 # 第三方依赖库,如 googletest(用于单元测试)
├── utils                       # 辅助工具和脚本(如更新文档、构建脚本等)

├── .arcconfig                  # Phabricator 配置文件,用于项目代码审查
├── .arclint                    # Phabricator Lint 配置文件,用于代码风格检查
├── .clang-format              # Clang-Format 配置文件,用于统一代码风格

4. 编译 LLVM

Getting Started with the LLVM System:https://llvm.org/docs/GettingStarted.html

下载并安装必需的软件
image.png
比如,我这里是 Windows 11,先安装 Visual Studio

安装 Python 依赖项

pip install pygments pyyaml

搜索 “x64 Native Tools Command Prompt for VS”(这个工具默认配置 64 位环境)
截图.png

创建构建目录

cd D:\Projects\llvm-project

mkdir build

进入 build 目录,并检测 cmake 和 ninja 是否能正常运行

**********************************************************************
** Visual Studio 2022 Developer Command Prompt v17.12.0
** Copyright (c) 2022 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'

D:\App\VisualStudio\IDE>cd D:\Projects\llvm-project\build

D:\Projects\llvm-project\build>cmake --version
cmake version 3.29.5-msvc4

CMake suite maintained and supported by Kitware (kitware.com/cmake).

D:\Projects\llvm-project\build>ninja --version
1.12.1

运行 CMake 配置

cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="/utf-8" -DLLVM_ENABLE_PROJECTS="clang" ../llvm

可选的构建类型说明:

  • Release: 生成优化后的构建,无断言和调试信息。适合用于发布。

  • Debug: 生成未优化的构建,包含断言和调试信息。适合用于调试。

  • RelWithDebInfo: 生成优化后的构建,无断言,但包含调试信息。适合需要调试符号但仍然希望性能接近 Release 的情况。

  • MinSizeRel: 生成针对最小尺寸优化的构建,而非速度优化。适合用于空间受限的环境。

03-09
### 关于 LLVM 编译器基础设施项目介绍 #### 什么是 LLVMLLVM(Low Level Virtual Machine)是一套高度优化的编译器基础设施,它不仅限于虚拟机的功能。这套工具集提供了现代化的静态编译器框架,支持开发高效、灵活的编译器、优化器以及运行时环境[^3]。 #### 开源性质与许可协议 作为一个开源项目,LLVM 遵循特定的许可协议,这使得开发者能够自由地分发并修改其源代码。这种开放性促进了社区贡献和技术进步,同时也保障了项目的透明度和发展活力。 #### 主要组成部分及其功能 - **Clang**: C/C++/Objective-C 前端解析器,负责处理这些语言的标准语法分析。 - **LLVM Core Libraries (IR)**: 中间表示层,即 Intermediate Representation, 定义了一种低级别的中间形式来表达程序逻辑,在此之上可以实施多种类型的转换和优化操作。 - **MC Layer & Assembler**: 处理汇编语言层面的任务,包括但不限于目标文件生成和支持多平台架构的能力。 - **Optimization Passes**: 实现了一系列针对性能提升而设计的数据流分析算法和其他高级变换技术。 - **Code Generation Backends**: 支持多个硬件平台的目标码生产模块,确保跨平台兼容性和执行效率。 #### 应用场景多样性 除了官方维护的核心子项目之外,还有众多第三方利用 LLVM 组件完成各自领域内的特殊需求。例如,借助 LLVM 可以为 Ruby、Python、Haskell 等动态脚本语言创建高效的 JIT 解释器;也可以服务于 Fortran 这样传统科学计算领域的 heavyweight applications【^4】. ```cpp // 示例:简单的 Clang 调用方式展示如何编译 C 文件至 IR 形式 clang -emit-llvm -c hello.c -o hello.bc ``` #### 学习资源推荐 对于那些希望深入了解 LLVM 或者从事相关研究工作的人员来说,《探索 LLVM 编译器基础设施》这份由 HunterZju 创建的教学材料将会是非常有价值的参考资料之一。该指南覆盖广泛的主题,并且包含了大量实用的例子帮助读者更好地掌握这一强大工具链的工作机制[^2].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值