编译 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 所在路径 +
+查看 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/ +
+通过下面命令,把 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
+下载并安装必需的软件 + +比如,我这里是 Windows 11,先安装 Visual Studio
+安装 Python 依赖项
+pip install pygments pyyaml
+
搜索 “x64 Native Tools Command Prompt for VS”(这个工具默认配置 64 位环境) +
+创建构建目录
+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: 生成针对最小尺寸优化的构建,而非速度优化。适合用于空间受限的环境。
+
+
编译项目
+ninja
+
编译完成后大概 104GB +
+编译成功后,你可以验证 clang 或其他工具是否已正确生成
+D:\Projects\llvm-project\build\bin\clang --version
+
+5. 解决编译报错
+5.1 编码警告 (warning C4819)
+[94/3656] Building CXX object lib\Support\CMakeFiles\LLVMSupport.dir\Parallel.cpp.obj
+D:\Projects\llvm-project\llvm\lib\Support\Parallel.cpp(1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[300/3656] Building CXX object lib\BinaryFormat\CMakeFiles\LLVMBinaryFormat.dir\ELF.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[306/3656] Building CXX object lib\BinaryFormat\CMakeFiles\LLVMBinaryFormat.dir\DXContainer.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm/BinaryFormat/DXContainer.h(1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符 。请将该文件保存为 Unicode 格式以防止数据丢失
+[347/3656] Building CXX object lib\IR\CMakeFiles\LLVMCore.dir\DebugInfo.cpp.obj
+D:\Projects\llvm-project\llvm\lib\IR\DebugInfo.cpp(1504): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存 为 Unicode 格式以防止数据丢失
+[396/3656] Building CXX object lib\MC\CMakeFiles\LLVMMC.dir\DXContainerPSVInfo.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm/BinaryFormat/DXContainer.h(1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符 。请将该文件保存为 Unicode 格式以防止数据丢失
+[404/3656] Building CXX object lib\MC\CMakeFiles\LLVMMC.dir\MCAsmBackend.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[411/3656] Building CXX object lib\MC\CMakeFiles\LLVMMC.dir\ELFObjectWriter.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[415/3656] Building CXX object lib\MC\CMakeFiles\LLVMMC.dir\MCAsmInfoELF.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[418/3656] Building CXX object lib\MC\CMakeFiles\LLVMMC.dir\MCELFObjectTargetWriter.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[424/3656] Building CXX object lib\MC\CMakeFiles\LLVMMC.dir\MCDXContainerWriter.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm/BinaryFormat/DXContainer.h(1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符 。请将该文件保存为 Unicode 格式以防止数据丢失
+[427/3656] Building CXX object lib\MC\CMakeFiles\LLVMMC.dir\MCContext.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[428/3656] Building CXX object lib\MC\CMakeFiles\LLVMMC.dir\MCELFStreamer.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[445/3656] Building CXX object lib\MC\CMakeFiles\LLVMMC.dir\MCSectionELF.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[447/3656] Building CXX object lib\MC\CMakeFiles\LLVMMC.dir\MCObjectFileInfo.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[454/3656] Building CXX object lib\MC\CMakeFiles\LLVMMC.dir\MCSymbolELF.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[488/3656] Building CXX object lib\MC\MCParser\CMakeFiles\LLVMMCParser.dir\ELFAsmParser.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[519/3656] Building CXX object lib\Object\CMakeFiles\LLVMObject.dir\Decompressor.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[522/3656] Building CXX object lib\Object\CMakeFiles\LLVMObject.dir\DXContainer.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm/BinaryFormat/DXContainer.h(1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符 。请将该文件保存为 Unicode 格式以防止数据丢失
+D:\Projects\llvm-project\llvm\lib\Object\DXContainer.cpp(344): warning C4018: “<”: 有符号/无符号不匹配
+[526/3656] Building CXX object lib\Object\CMakeFiles\LLVMObject.dir\BuildID.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[533/3656] Building CXX object lib\Object\CMakeFiles\LLVMObject.dir\ELF.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+D:\Projects\llvm-project\llvm\include\llvm/BinaryFormat/ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[535/3656] Building CXX object lib\Object\CMakeFiles\LLVMObject.dir\ELFObjectFile.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[543/3656] Building CXX object lib\Object\CMakeFiles\LLVMObject.dir\RelocationResolver.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[546/3656] Building CXX object lib\Object\CMakeFiles\LLVMObject.dir\SymbolSize.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[548/3656] Building CXX object lib\Object\CMakeFiles\LLVMObject.dir\OffloadBinary.cpp.obj
+D:\Projects\llvm-project\llvm\include\llvm\BinaryFormat\ELFRelocs/LoongArch.def(1): warning C4819: 该文件包含不能在当前代码页(936)中 表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+[579/3656] Building CXX object lib\DebugInfo\PDB\CMakeFiles\LLVMDebugInfoPDB.dir\PDB.cpp.obj
+FAILED: lib/DebugInfo/PDB/CMakeFiles/LLVMDebugInfoPDB.dir/PDB.cpp.obj
+D:\App\VisualStudio\IDE\VC\Tools\MSVC\14.42.34433\bin\Hostx86\x86\cl.exe /nologo /TP -DGTEST_HAS_RTTI=0 -DUNICODE -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_FILE_OFFSET_BITS=64 -D_HAS_EXCEPTIONS=0 -D_LARGEFILE_SOURCE -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -ID:\Projects\llvm-project\build\lib\DebugInfo\PDB -ID:\Projects\llvm-project\llvm\lib\DebugInfo\PDB -ID:\Projects\llvm-project\build\include -ID:\Projects\llvm-project\llvm\include -external:I"D:\App\VisualStudio\IDE\DIA SDK\include" -external:W0 /Zc:inline /Zc:preprocessor /Zc:__cplusplus /Oi /bigobj /permissive- /W4 -wd4141 -wd4146 -wd4244 -wd4267 -wd4291 -wd4351 -wd4456 -wd4457 -wd4458 -wd4459 -wd4503 -wd4624 -wd4722 -wd4100 -wd4127 -wd4512 -wd4505 -wd4610 -wd4510 -wd4702 -wd4245 -wd4706 -wd4310 -wd4701 -wd4703 -wd4389 -wd4611 -wd4805 -wd4204 -wd4577 -wd4091 -wd4592 -wd4319 -wd4709 -wd5105 -wd4324 -w14062 -we4238 -std:c++17 -MDd /EHs-c- /GR- /showIncludes /Folib\DebugInfo\PDB\CMakeFiles\LLVMDebugInfoPDB.dir\PDB.cpp.obj /Fdlib\DebugInfo\PDB\CMakeFiles\LLVMDebugInfoPDB.dir\LLVMDebugInfoPDB.pdb /FS -c D:\Projects\llvm-project\llvm\lib\DebugInfo\PDB\PDB.cpp
+
这些警告表明某些源文件包含在当前代码页(936,即简体中文 GBK 编码)中无法表示的字符。
+可以通过设置编译器选项 -DCMAKE_CXX_FLAGS="/utf-8" 来避免这些编码问题。
+cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="/utf-8" ../llvm
+
这将告诉 MSVC 编译器以 UTF-8 编码处理所有源文件。
+5. 2 缺少 atlbase.h 头文件 (fatal error C1083)
+D:\Projects\llvm-project\llvm\include\llvm\DebugInfo\PDB\DIA\DIASupport.h(25): fatal error C1083: 无法打开包括文件: “atlbase.h”: No such file or directory
+[592/3656] Building CXX object lib\DebugInfo\DWARF\CMakeFiles\LLVMDebugInfoDWARF.dir\DWARFVerifier.cpp.obj
+D:\Projects\llvm-project\llvm\lib\DebugInfo\DWARF\DWARFVerifier.cpp(1513): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
+ninja: build stopped: subcommand failed.
+
错误信息提示 atlbase.h 头文件无法找到,这通常是因为未安装 ATL/MFC 支持。这是 Visual Studio 的可选组件,默认情况下可能未安装。
+解决方法:
+-
+
-
+
打开 Visual Studio Installer
+
+ -
+
修改 Visual Studio 安装
+
+ -
+
添加 ATL/MFC 支持
+
+
安装完成后,再次运行 ninja 重新编译
+5.3 LLVM ERROR: out of memory
+[1/281] Building RISCVGenDAGISel.inc...
+FAILED: lib/Target/RISCV/RISCVGenDAGISel.inc D:/Projects/llvm-project/build/lib/Target/RISCV/RISCVGenDAGISel.inc
+C:\Windows\system32\cmd.exe /C "cd /D D:\Projects\llvm-project\build && D:\Projects\llvm-project\build\bin\llvm-tblgen.exe -gen-dag-isel -I D:/Projects/llvm-project/llvm/lib/Target/RISCV -ID:/Projects/llvm-project/build/include -ID:/Projects/llvm-project/llvm/include -I D:/Projects/llvm-project/llvm/lib/Target --long-string-literals=0 D:/Projects/llvm-project/llvm/lib/Target/RISCV/RISCV.td --write-if-changed -o lib/Target/RISCV/RISCVGenDAGISel.inc -d lib/Target/RISCV/RISCVGenDAGISel.inc.d"
+LLVM ERROR: out of memory
+Allocation failed
+PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
+Stack dump:
+0\. Program arguments: D:\\Projects\\llvm-project\\build\\bin\\llvm-tblgen.exe -gen-dag-isel -I D:/Projects/llvm-project/llvm/lib/Target/RISCV -ID:/Projects/llvm-project/build/include -ID:/Projects/llvm-project/llvm/include -I D:/Projects/llvm-project/llvm/lib/Target --long-string-literals=0 D:/Projects/llvm-project/llvm/lib/Target/RISCV/RISCV.td --write-if-changed -o lib/Target/RISCV/RISCVGenDAGISel.inc -d lib/Target/RISCV/RISCVGenDAGISel.inc.d
+Exception Code: 0x80000003
+ #0 0x0104f4e9 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x2af4e9)
+ #1 0x6a4528b4 (C:\Windows\SYSTEM32\ucrtbased.dll+0xc28b4)
+ #2 0x6a453ed2 (C:\Windows\SYSTEM32\ucrtbased.dll+0xc3ed2)
+ #3 0x010075ca (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x2675ca)
+ #4 0x01007e3f (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x267e3f)
+ #5 0x6a566608 (C:\Windows\SYSTEM32\MSVCP140D.dll+0x26608)
+ #6 0x6a43fb72 (C:\Windows\SYSTEM32\ucrtbased.dll+0xafb72)
+ #7 0x01112357 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x372357)
+ #8 0x00db004c (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x1004c)
+ #9 0x00daa176 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0xa176)
+#10 0x00daa06f (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0xa06f)
+#11 0x00db0e69 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x10e69)
+#12 0x00daa0a1 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0xa0a1)
+#13 0x00daa135 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0xa135)
+#14 0x00dac0c7 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0xc0c7)
+#15 0x00db103b (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x1103b)
+#16 0x0102c922 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x28c922)
+#17 0x01009a87 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x269a87)
+#18 0x01008d00 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x268d00)
+#19 0x00da66da (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x66da)
+#20 0x00da6694 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x6694)
+#21 0x00eba51f (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x11a51f)
+#22 0x00eb90b8 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x1190b8)
+#23 0x00ebb1d4 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x11b1d4)
+#24 0x00eb90b8 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x1190b8)
+#25 0x00eba414 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x11a414)
+#26 0x00eb90b8 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x1190b8)
+#27 0x00ebb1d4 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x11b1d4)
+#28 0x00eb90b8 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x1190b8)
+#29 0x00eb87ca (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x1187ca)
+#30 0x00eb65a0 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x1165a0)
+#31 0x00eb6a07 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x116a07)
+#32 0x010e06a8 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x3406a8)
+#33 0x00fe7d1a (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x247d1a)
+#34 0x01113143 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x373143)
+#35 0x0111304a (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x37304a)
+#36 0x01112eed (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x372eed)
+#37 0x011131a8 (D:\Projects\llvm-project\build\bin\llvm-tblgen.exe+0x3731a8)
+#38 0x77507ba9 (C:\Windows\System32\KERNEL32.DLL+0x17ba9)
+#39 0x77dac0cb (C:\Windows\SYSTEM32\ntdll.dll+0x6c0cb)
+#40 0x77dac04f (C:\Windows\SYSTEM32\ntdll.dll+0x6c04f)
+ninja: build stopped: subcommand failed.
+
如果你使用的是 32 位编译环境(工具链或 llvm-tblgen.exe),它可能受到 2GB 内存使用限制。
+通过下面命令验证是否生成 64 位可执行文件
+D:\Projects\llvm-project\build>dumpbin /headers D:\Projects\llvm-project\build\bin\llvm-tblgen.exe | findstr machine
+ 14C machine (x86)
+ 32 bit word machine
+
如果不是,搜索 “x64 Native Tools Command Prompt for VS”(这个工具默认配置 64 位环境) +
+验证当前编译器配置,输出中应包含 x64,表示 64 位环境已成功配置。
+**********************************************************************
+** Visual Studio 2022 Developer Command Prompt v17.12.0
+** Copyright (c) 2022 Microsoft Corporation
+**********************************************************************
+[vcvarsall.bat] Environment initialized for: 'x64'
+
+D:\App\VisualStudio\IDE>cl
+用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.42.34433 版
+版权所有(C) Microsoft Corporation。保留所有权利。
+
+用法: cl [ 选项... ] 文件名... [ /link 链接选项... ]
+
+D:\Projects\llvm-project\build>where cl.exe
+D:\App\VisualStudio\IDE\VC\Tools\MSVC\14.42.34433\bin\Hostx64\x64\cl.exe
+
清理之前的缓存,重新生成构建目录
+rmdir /s /q build
+
+mkdir build
+
+cd build
+
最后,重新生成配置和编译。
+5.4 LNK1104: 无法打开文件“tools\llvm-nm\CMakeFiles\llvm-nm.dir/intermediate.manifest”
+[3117/3660] Linking CXX executable bin\llvm-nm.exe
+FAILED: bin/llvm-nm.exe
+C:\Windows\system32\cmd.exe /C "cd . && D:\App\VisualStudio\IDE\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe -E vs_link_exe --intdir=tools\llvm-nm\CMakeFiles\llvm-nm.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100226~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100226~1.0\x64\mt.exe --manifests -- D:\App\VisualStudio\IDE\VC\Tools\MSVC\14.42.34433\bin\Hostx64\x64\link.exe /nologo @CMakeFiles\llvm-nm.rsp /out:bin\llvm-nm.exe /implib:lib\llvm-nm.lib /pdb:bin\llvm-nm.pdb /version:0.0 /machine:x64 /STACK:10000000 /debug /INCREMENTAL /subsystem:console && cd ."
+FINAL LINK: command "D:\App\VisualStudio\IDE\VC\Tools\MSVC\14.42.34433\bin\Hostx64\x64\link.exe /nologo @CMakeFiles\llvm-nm.rsp /out:bin\llvm-nm.exe /implib:lib\llvm-nm.lib /pdb:bin\llvm-nm.pdb /version:0.0 /machine:x64 /STACK:10000000 /debug /INCREMENTAL /subsystem:console /MANIFEST /MANIFESTFILE:tools\llvm-nm\CMakeFiles\llvm-nm.dir/intermediate.manifest tools\llvm-nm\CMakeFiles\llvm-nm.dir/manifest.res" failed (exit code 1104) with the following output:
+LINK : fatal error LNK1104: 无法打开文件“tools\llvm-nm\CMakeFiles\llvm-nm.dir/intermediate.manifest”
+[3130/3660] Building CXX object tools\llvm-exegesis\lib\CMakeFiles\LLVMExegesis.dir\UopsBenchmarkRunner.cpp.obj
+ninja: build stopped: subcommand failed.
+
查看 tools\llvm-nm\CMakeFiles\llvm-nm.dir/intermediate.manifest 文件是存在的而且也能正常打开,重新执行 ninja 命令再编译一遍试试。 +
+接下来报错 LNK1104: 无法打开文件“bin\llvm-rc.exe”
+[297/531] Linking CXX executable bin\llvm-rc.exe
+FAILED: bin/llvm-rc.exe
+C:\Windows\system32\cmd.exe /C "cd . && D:\App\VisualStudio\IDE\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe -E vs_link_exe --intdir=tools\llvm-rc\CMakeFiles\llvm-rc.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100226~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100226~1.0\x64\mt.exe --manifests -- D:\App\VisualStudio\IDE\VC\Tools\MSVC\14.42.34433\bin\Hostx64\x64\link.exe /nologo tools\llvm-rc\CMakeFiles\llvm-rc.dir\llvm-rc.cpp.obj tools\llvm-rc\CMakeFiles\llvm-rc.dir\ResourceFileWriter.cpp.obj tools\llvm-rc\CMakeFiles\llvm-rc.dir\ResourceScriptCppFilter.cpp.obj tools\llvm-rc\CMakeFiles\llvm-rc.dir\ResourceScriptParser.cpp.obj tools\llvm-rc\CMakeFiles\llvm-rc.dir\ResourceScriptStmt.cpp.obj tools\llvm-rc\CMakeFiles\llvm-rc.dir\ResourceScriptToken.cpp.obj tools\llvm-rc\CMakeFiles\llvm-rc.dir\llvm-rc-driver.cpp.obj tools\llvm-rc\CMakeFiles\llvm-rc.dir\__\__\resources\windows_version_resource.rc.res /out:bin\llvm-rc.exe /implib:lib\llvm-rc.lib /pdb:bin\llvm-rc.pdb /version:0.0 /machine:x64 /STACK:10000000 /debug /INCREMENTAL /subsystem:console lib\LLVMObject.lib lib\LLVMOption.lib lib\LLVMSupport.lib lib\LLVMTargetParser.lib lib\LLVMIRReader.lib lib\LLVMBitReader.lib lib\LLVMAsmParser.lib lib\LLVMCore.lib lib\LLVMRemarks.lib lib\LLVMBitstreamReader.lib lib\LLVMMCParser.lib lib\LLVMMC.lib lib\LLVMDebugInfoCodeView.lib lib\LLVMTextAPI.lib lib\LLVMBinaryFormat.lib lib\LLVMTargetParser.lib lib\LLVMSupport.lib psapi.lib shell32.lib ole32.lib uuid.lib advapi32.lib ws2_32.lib delayimp.lib -delayload:shell32.dll -delayload:ole32.dll lib\LLVMDemangle.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
+FINAL LINK: command "D:\App\VisualStudio\IDE\VC\Tools\MSVC\14.42.34433\bin\Hostx64\x64\link.exe /nologo tools\llvm-rc\CMakeFiles\llvm-rc.dir\llvm-rc.cpp.obj tools\llvm-rc\CMakeFiles\llvm-rc.dir\ResourceFileWriter.cpp.obj tools\llvm-rc\CMakeFiles\llvm-rc.dir\ResourceScriptCppFilter.cpp.obj tools\llvm-rc\CMakeFiles\llvm-rc.dir\ResourceScriptParser.cpp.obj tools\llvm-rc\CMakeFiles\llvm-rc.dir\ResourceScriptStmt.cpp.obj tools\llvm-rc\CMakeFiles\llvm-rc.dir\ResourceScriptToken.cpp.obj tools\llvm-rc\CMakeFiles\llvm-rc.dir\llvm-rc-driver.cpp.obj tools\llvm-rc\CMakeFiles\llvm-rc.dir\__\__\resources\windows_version_resource.rc.res /out:bin\llvm-rc.exe /implib:lib\llvm-rc.lib /pdb:bin\llvm-rc.pdb /version:0.0 /machine:x64 /STACK:10000000 /debug /INCREMENTAL /subsystem:console lib\LLVMObject.lib lib\LLVMOption.lib lib\LLVMSupport.lib lib\LLVMTargetParser.lib lib\LLVMIRReader.lib lib\LLVMBitReader.lib lib\LLVMAsmParser.lib lib\LLVMCore.lib lib\LLVMRemarks.lib lib\LLVMBitstreamReader.lib lib\LLVMMCParser.lib lib\LLVMMC.lib lib\LLVMDebugInfoCodeView.lib lib\LLVMTextAPI.lib lib\LLVMBinaryFormat.lib lib\LLVMTargetParser.lib lib\LLVMSupport.lib psapi.lib shell32.lib ole32.lib uuid.lib advapi32.lib ws2_32.lib delayimp.lib -delayload:shell32.dll -delayload:ole32.dll lib\LLVMDemangle.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:tools\llvm-rc\CMakeFiles\llvm-rc.dir/intermediate.manifest tools\llvm-rc\CMakeFiles\llvm-rc.dir/manifest.res" failed (exit code 1104) with the following output:
+LINK : fatal error LNK1104: 无法打开文件“bin\llvm-rc.exe”
+[310/531] Generating export list for LLVM-C
+ninja: build stopped: subcommand failed.
+
再次执行 ninja 命令编译,接下来的 LNK1104 报错同理。 +
+6. clang 编译 hello world
+执行下面命令把 bin 目录配置到环境变量
+set PATH=%PATH%;D:\Projects\llvm-project\build\bin
+
编写 hello.c 源码
+#include <stdio.h>
+
+int main() {
+ printf("Hello, World!\n");
+ return 0;
+}
+
执行下面命令把 hello.c 编译成可执行程序
+clang hello.c -o hello.exe
+
执行 hello.exe +
+7. 使用 CLion 调试 clang
+7.1 导入项目
+使用 CLion 打开 llvm-project\clang\CMakeLists.txt +
+作为项目打开 +
+7.2 设置 LLVM_DIR
+执行 CMake 报错如下
+CMake Error at CMakeLists.txt:31 (find_package):
+ Could not find a package configuration file provided by "LLVM" with any of
+ the following names:
+
+ LLVMConfig.cmake
+ llvm-config.cmake
+
+ Add the installation prefix of "LLVM" to CMAKE_PREFIX_PATH or set
+ "LLVM_DIR" to a directory containing one of the above files. If "LLVM"
+ provides a separate development package or SDK, be sure it has been
+ installed.
+
+
+-- Configuring incomplete, errors occurred!
+
这因为 Clang 依赖于已构建的 LLVM 库。如果你之前已经成功构建了 LLVM,你需要告知 CMake 该文件的位置。
+打开 CMake 设置,在 CMake Options 字段中,添加以下配置
+-DLLVM_DIR="D:/Projects/llvm-project/build/lib/cmake/llvm"
+
或者
+-DCMAKE_PREFIX_PATH="D:/Projects/llvm-project/build"
+
这会告知 CMake 在构建项目时去哪里寻找 LLVM 库。
+点击应用,重新执行 cmake +
+7.3 禁用 llvm-gtest
+接着报错如下
+CMake Error at CMakeLists.txt:117 (message):
+ llvm-gtest not found. Please install llvm-gtest or disable tests with
+ -DLLVM_INCLUDE_TESTS=OFF
+
+
+-- Configuring incomplete, errors occurred!
+
这个错误表明 CMake 在配置 LLVM 项目时找不到 llvm-gtest,因此无法继续。
+不需要运行测试,可以通过设置 LLVM_INCLUDE_TESTS=OFF 来跳过测试模块。
+-DLLVM_INCLUDE_TESTS=OFF
+
在 CMake Options 字段中,添加禁用测试选项 +
+cmake 执行成功后,可以看到 clang 项目所有的运行/调试配置 +
+7.4 配置调试信息
+编辑 clang 调试配置 +
+添加 Program arguments,比如
+"D:\Projects\llvm-project\build\hello.c" -o "D:\Projects\llvm-project\build\hello.exe"
+
找到 main 函数(clang/tools/driver/driver.cpp),并下断点 +
+7.5 切换 Visual Studio 工具链
+运行调试 clang,但是报错如下
+D:/Projects/llvm-project/llvm/include/llvm/ADT/SmallVector.h:304: undefined reference to `llvm::SmallVectorBase<unsigned int>::size() const'
+
+D:/Projects/llvm-project/llvm/include/llvm/Support/CommandLine.h:783: undefined reference to `llvm::cl::generic_parser_base::printGenericOptionDiff(llvm::cl::Option const&, llvm::cl::GenericOptionValue const&, llvm::cl::GenericOptionValue const&, unsigned long long) const'
+
+D:\App\CLion 2024.2.3\bin\mingw\bin/ld.exe: utils/TableGen/CMakeFiles/clang-tblgen.dir/TableGen.cpp.obj:TableGen.cpp:(.rdata$.refptr._ZTVN4llvm2cl11OptionValueINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE[.refptr._ZTVN4llvm2cl11OptionValueINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE]+0x0): undefined reference to `vtable for llvm::cl::OptionValue<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >'
+D:\App\CLion 2024.2.3\bin\mingw\bin/ld.exe: utils/TableGen/CMakeFiles/clang-tblgen.dir/TableGen.cpp.obj:TableGen.cpp:(.rdata$.refptr._ZTVN4llvm23PrettyStackTraceProgramE[.refptr._ZTVN4llvm23PrettyStackTraceProgramE]+0x0): undefined reference to `vtable for llvm::PrettyStackTraceProgram'
+D:\App\CLion 2024.2.3\bin\mingw\bin/ld.exe: utils/TableGen/CMakeFiles/clang-tblgen.dir/TableGen.cpp.obj:TableGen.cpp:(.rdata$.refptr._ZTVN4llvm2cl6parserINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE[.refptr._ZTVN4llvm2cl6parserINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE]+0x0): undefined reference to `vtable for llvm::cl::parser<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >'
+D:\App\CLion 2024.2.3\bin\mingw\bin/ld.exe: utils/TableGen/CMakeFiles/clang-tblgen.dir/TableGen.cpp.obj:TableGen.cpp:(.rdata$.refptr._ZTVN4llvm2cl12basic_parserINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE[.refptr._ZTVN4llvm2cl12basic_parserINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE]+0x0): undefined reference to `vtable for llvm::cl::basic_parser<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >'
+D:\App\CLion 2024.2.3\bin\mingw\bin/ld.exe: utils/TableGen/CMakeFiles/clang-tblgen.dir/TableGen.cpp.obj:TableGen.cpp:(.rdata$.refptr._ZTVN4llvm2cl17basic_parser_implE[.refptr._ZTVN4llvm2cl17basic_parser_implE]+0x0): undefined reference to `vtable for llvm::cl::basic_parser_impl'
+D:\App\CLion 2024.2.3\bin\mingw\bin/ld.exe: utils/TableGen/CMakeFiles/clang-tblgen.dir/TableGen.cpp.obj:TableGen.cpp:(.rdata$.refptr._ZTVN4llvm2cl19generic_parser_baseE[.refptr._ZTVN4llvm2cl19generic_parser_baseE]+0x0): undefined reference to `vtable for llvm::cl::generic_parser_base'
+D:\App\CLion 2024.2.3\bin\mingw\bin/ld.exe: utils/TableGen/CMakeFiles/clang-tblgen.dir/TableGen.cpp.obj:TableGen.cpp:(.rdata$.refptr._ZTVN4llvm2cl18GenericOptionValueE[.refptr._ZTVN4llvm2cl18GenericOptionValueE]+0x0): undefined reference to `vtable for llvm::cl::GenericOptionValue'
+D:\App\CLion 2024.2.3\bin\mingw\bin/ld.exe: utils/TableGen/CMakeFiles/clang-tblgen.dir/TableGen.cpp.obj:TableGen.cpp:(.rdata$.refptr._ZTVN4llvm2cl6OptionE[.refptr._ZTVN4llvm2cl6OptionE]+0x0): undefined reference to `vtable for llvm::cl::Option'
+collect2.exe: error: ld returned 1 exit status
+ninja: build stopped: subcommand failed.
+
这个错误信息表明在使用 MinGW 编译 LLVM 时,链接器找不到某些 LLVM 函数和虚表(vtable)的定义。
+默认是使用 MinGW 编译器来编译 LLVM。LLVM 通常更适合使用 MSVC(Microsoft Visual C++)编译器在 Windows 上进行编译。
+切换到 MSVC 编译器,应该能解决 undefined reference 的链接错误。
+打开 Visual Studio Installer,确认已经安装 MSVC +
+在设置窗口中,导航到 Build, Execution, Deployment > Toolchains。添加新的 toolchain,选择 Visual Studio,工具集选择 VisualStudio\IDE 目录,等待工具检测完毕点击应用。 + +参考:https://www.jetbrains.com/help/clion/quick-tutorial-on-configuring-clion-on-windows.html#MSVC
+修改 Cmake 配置,工具链选择 Visual Studio +
+重新运行调试 clang +
+ +