news 2026/10/3 2:40:44

LLVMCon EU 2025 笔记(四)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LLVMCon EU 2025 笔记(四)

#embed指令在 Clang 中的状态如下:

  • 自Clang 19起可用。

  • 在C23标准中受支持。

  • 在旧模式中作为Clang 扩展提供。

  • 该指令有望被纳入C++26标准,目前作为 Clang 扩展提供。

实现中仍有一些问题需要解决。开发者 Maria 已创建相关标签来跟踪这些问题。如果你希望跟进开发或参与贡献,可以关注这些进展。

总结

本节课我们一起学习了 Clang 中的#embed指令。我们了解了它作为一种可移植数据嵌入方式的基本概念,通过性能对比看到了其相对于传统“朴素”方法的巨大优势。我们深入探讨了其实现机制,包括在unsigned char数组下的字符串字面量优化,以及在通用情况下使用的EmbedExprAST 节点。最后,我们回顾了该指令在 Clang 和 C/C++ 标准中的当前状态与未来展望。#embed指令为在代码中嵌入资源提供了一种高效、标准化的解决方案。

https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/llvmcon-eu-2025/img/d2edd3ff34534151022445c701563bbd_2.png

https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/llvmcon-eu-2025/img/d2edd3ff34534151022445c701563bbd_2.png

https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/llvmcon-eu-2025/img/d2edd3ff34534151022445c701563bbd_3.png

https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/llvmcon-eu-2025/img/d2edd3ff34534151022445c701563bbd_3.png

055:理解LLVM_ENABLE_PROJECTS与LLVM_ENABLE_RUNTIMES🏗️

https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/llvmcon-eu-2025/img/9ad5d6c7edc4e953486b0f7c60db432c_0.png

在本节课中,我们将要学习LLVM构建系统中两个核心配置选项的区别:LLVM_ENABLE_PROJECTS和LLVM_ENABLE_RUNTIMES。理解它们的差异是正确构建编译器及其运行时库的基础。

LLVM_ENABLE_PROJECTS的工作方式

LLVM_ENABLE_PROJECTS使用CMake在配置阶段检测到的编译器。这个编译器通常是系统默认的GCC。它主要用于为主机架构构建编译器本身(如Clang)。理论上,你也可以指定一个交叉编译器来构建编译器。

公式:-DLLVM_ENABLE_PROJECTS="clang"

它的工作流程是标准的CMake递归构建,会进入源码的子目录进行构建。

LLVM_ENABLE_RUNTIMES的工作方式

与LLVM_ENABLE_PROJECTS不同,LLVM_ENABLE_RUNTIMES使用之前通过LLVM_ENABLE_PROJECTS构建好的Clang编译器,来构建运行时库本身。这些运行时库是供编译出的代码(例如由你构建的Clang编译的程序)使用的,目标平台可能与构建Clang的主机平台不同。

公式:-DLLVM_ENABLE_RUNTIMES="compiler-rt" -DLLVM_ENABLE_PROJECTS="clang"

它的实现机制更特殊:CMake会创建一些“虚拟”目标,并为每个目标调用LLVMExternalProject_Add。这会在你的构建目录(通常是build/runtimes/runtimes-bins)内部启动一个全新的CMake构建过程。这意味着运行时库的构建发生在CMake的“构建”步骤,而非“配置”步骤,并且会确保所有依赖(如Clang、FileCheck等工具)先被构建完成。


上一节我们介绍了两个核心构建选项的基本概念,本节中我们来看看在使用LLVM_ENABLE_RUNTIMES时的一些高级配置选项。

运行时构建的配置选项

有一些不太被宣传的选项可以传递给运行时库的构建过程。这通过-DCMAKE_C_FLAGS_FOR_RUNTIMES等变量实现。

以下是几个关键选项:

  • 传递编译器标志:例如,使用-DCMAKE_CXX_FLAGS_FOR_RUNTIMES="-ferror-limit=5"。注意,用于构建运行时的Clang可能不接受与构建编译器时完全相同的标志(例如,-fmax-errors对应-ferror-limit)。

  • 指定交叉编译目标:使用-DRUNTIMES_TARGETS="aarch64-unknown-linux-gnu"。你还可以通过-DCMAKE_C_FLAGS_TARGET等为特定目标指定优化选项。

  • 独立构建:你可以进行独立构建,此时可以使用任何编译器(如GCC)来编译运行时库。这需要你将源码顶层目录指定为runtimes,并设置-DCMAKE_C_COMPILER=gcc。


理解了通用运行时构建机制后,本节我们来看看Flang运行时(flang-rt)原有的构建方式及其存在的问题。

Flang运行时的原有构建方式与挑战

Flang运行时之前有两种构建方式:

  1. “内联”构建:进入源码子目录,使用与构建Flang编译器相同的编译器进行构建。

  2. 独立构建:使用不同的顶层目录,并指定已构建好的LLVM/Clang路径和所需的编译器。

原有方式存在一个显著问题:十进制库(decimal library)同时被Flang运行时和编译器本身共享使用。这导致如果运行时为了支持CUDA而用NVCC编译,那么Flang编译器可执行文件也会依赖CUDA库。这是需要改变的一个原因,以使Flang运行时与其他LLVM运行时保持一致。

此外,还有以下挑战:

  • 多目标支持:例如为AMD GPU编译时,需要为每个主机架构(x86, AArch64等)分别构建运行时,过程繁琐。

  • 共享代码的依赖:共享的libdecimal代码带来了问题,因为编译运行时和编译编译器本身可能对编译环境有不同要求(例如,LTO支持)。

  • 环境依赖:某些功能(如128位浮点支持)的测试依赖于构建Flang的主机平台环境,而非最终运行代码的目标平台,这可能导致可移植性问题。


上一节我们分析了原有构建方式的问题,本节中我们来看看如何将Flang运行时集成到统一的LLVM_ENABLE_RUNTIMES框架中。

集成到LLVM_ENABLE_RUNTIMES的改动

核心改动是让Flang运行时能够使用LLVM现有的运行时构建系统。

主要构建方式:

使用-DLLVM_ENABLE_RUNTIMES="flang-rt"。这种方式会使用已构建的Clang来编译Flang运行时。

代码示例:

cmake-DLLVM_ENABLE_PROJECTS="clang;flang"-DLLVM_ENABLE_RUNTIMES="flang-rt"...

独立构建的支持:

独立构建仍然被支持。你需要将顶层目录设为runtimes,并指定LLVM的路径。一个特殊之处在于,由于此时还没有运行时库,CMake检测编译器能力时会失败。因此,我们需要像Clang自举构建一样,告诉CMake忽略链接检查,假设编译器可以工作。


在集成过程中,需要进行一系列重构来解决问题并保持一致性。本节我们将介绍这些具体的重构工作。

重构与待解决的问题

为了成功集成,我们进行了以下关键重构:

  1. 库重命名:遵循LLVM运行时库的命名约定(如libclang_rt.component),将Flang运行时库进行了重命名。十进制库(libdecimal)被集成到运行时中,用户无需关心编译器与运行时的内部代码结构。

  2. 源码与头文件分离:我们清晰地分离了仅用于运行时的代码和仅用于编译器的代码,特别是处理了那些混合两者的头文件。

  3. 共享库支持:使Flang运行时的共享库构建方式与其他LLVM运行时保持一致。

尽管取得了进展,仍有一些复杂问题待解决:

  • Fortran模块支持:让Fortran模块也能使用运行时构建系统。

  • 多目标构建的复杂性:同时为多个目标环境构建运行时非常复杂,目前尚未实现。

  • Windows支持:Windows平台总有特殊之处需要处理。

  • 实验性CUDA支持:使用NVCC编译运行时的实验性功能。


https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/llvmcon-eu-2025/img/9ad5d6c7edc4e953486b0f7c60db432c_2.png

https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/llvmcon-eu-2025/img/9ad5d6c7edc4e953486b0f7c60db432c_3.png

本节课中我们一起学习了LLVM构建系统中LLVM_ENABLE_PROJECTS与LLVM_ENABLE_RUNTIMES的核心区别,深入探讨了Flang运行时从原有特殊构建方式集成到统一运行时构建框架的过程、所做的重构以及面临的剩余挑战。掌握这些知识有助于你更灵活、正确地构建LLVM工具链及其组件。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 2:39:21

工业曲线图:设计与实现

一、工业曲线图:设计与实现 1. 先认清原生 Chart 的边界 原生 .NET Framework 的 Chart 控件支持 Line、Spline、FastLine 等多种类型,具备数据绑定、X/Y 轴自动缩放、滚动视图、实时添加数据点、触发重绘等基础能力。但默认性能在高频率(>…

作者头像 李华
网站建设 2026/10/3 2:36:56

0基础深入理解DeepSeek Harness 架构【5】系统提示词是怎么拼出来的

第 5 章 系统提示词是怎么拼出来的摘要:本章深入解析 DeepSeek Harness 中系统提示词的组装机制。系统提示词并非硬编码,而是由插件通过段落(PromptSection)、动态上下文(PromptContext)和工具 schema 提供…

作者头像 李华
网站建设 2026/10/3 2:36:54

Gitee+Linux+ROS+OpenCV视觉工程交付全链路指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/3 2:36:51

PDF浏览器(阅读、编辑、新建)

PdfViewer 功能总览 可编辑PDF文字内容,插入文字、插入图片、表格。也可新建空白PDF文件。 哔哩哔哩视频地址:https://www.bilibili.com/video/BV1ZBaZ65EZ3 (PDF阅读) (PDF编辑) Pd fViewer 是一款面向…

作者头像 李华