Zig 主分支 2026 年更新:包管理迁移、后端改进与构建系统重构带来性能提升!

📅 2026/7/6 8:13:37
Zig 主分支 2026 年更新:包管理迁移、后端改进与构建系统重构带来性能提升!
开发日志本页面精心整理了 Zig 主分支的近期更新内容。你还可以通过 RSS 订阅获取相关信息。本页面记录的是 2026 年的更新内容其他年份的更新可查看开发日志存档页面。2026 年 6 月 30 日所有包管理功能从编译器迁移至构建系统作者是 Andrew Kelley。现在用户的 build.zig 脚本和构建系统本身有了独立进程所以将包管理逻辑放在这里是合理的。他把 zig build、zig fetch、zig init、zig libc 这些子命令迁移到了 maker 进程。这意味着过去包含在编译器可执行文件中的大部分内容现在以源代码形式发布像包获取逻辑、HTTP 客户端和网络功能、TLS 及相关加密功能、Git 协议、xz、gzip、zstd、flate、zip 压缩格式处理、build.zig.zon 文件的解析、验证及其他处理等。因此现在无需重新编译编译器就能对这些功能进行修补让用户和贡献者能更轻松地调整。此外Zig 的包管理在进行网络操作时会启用安全检查因为 maker 可执行文件是在 ReleaseSafe 模式下编译的。而且用于网络和文件哈希的所有加密功能现在都能利用主机上的特殊 CPU 指令。他进行此操作的最初动机与公开构建服务器协议有关目的是给 ZLS 扫除障碍。最初进程树结构是 zig build (Zig 编译器 包管理器) 下面是 builder (用户的 build.zig 逻辑 构建系统实现)。进程分离变更集之后变成 zig build (Zig 编译器 包管理器) 下面有 configurer (用户的 build.zig 逻辑) 和 maker (构建系统)。现在进程树结构变为 zig build (Zig 编译器) 下面是 maker (构建系统 包管理器)maker 下面是 configurer (用户的 build.zig 逻辑)。所以当需要重新运行配置时maker 进程可以继续运行。对于即将推出的构建服务器而言能避免服务器必须退出、客户端必须重新连接的尴尬情况只需通知客户端配置发生了更改。这几乎是一个非重大更改但仍有一些可观察到的差异Zig 可执行文件的二进制大小从 14.1 MiB 缩减至 13.5 MiB缩小了 4%无 LLVMReleaseSmall 模式--maker-opt 标志被 ZIG_DEBUG_MAKER 环境变量取代--zig-lib-dir 标志被 ZIG_LIB_DIR 环境变量取代。此变更集的后续问题是发布 Zig 0.17.0 版本前的主要障碍像构建服务器协议 MVP、引入添加构建脚本自身路径依赖的概念、让 zig build --watch 检测构建脚本的修改并自动重新运行、不同的工作目录会导致构建脚本缓存失效等。他 7 月有两场会议要准备演讲内容所以实际来看8 月初之前没时间完成这些工作。当然欢迎大家贡献代码。非常感谢 ZLS 团队的 Techatrix 主动联系他并一起完善构建服务器协议顺便提一下他们正在寻求赞助。2026 年 6 月 26 日SPIR-V 后端进展作者是 Ali Cheraghi。由于最近编译器的更改SPIR-V 后端在很多方面都出现了问题所以他在过去几周里努力让它恢复到更好的状态。SpirvTypeSPIR-V 有一些类型无法用 Zig 的类型系统表示。为了解决编写着色器的长期难题引入了新的内置函数 SpirvType。调用约定中的执行模式执行模式信息现在由调用约定携带而不是通过内联汇编 OpExecutionMode 来实现。旧的 std.gpu.executionMode() 辅助函数已被移除SPIR-V 汇编器现在也会拒绝手动编写的 OpExecutionMode 指令。此外还为网格着色管线添加了两种新的调用约定 spirv_task 和 spirv_mesh。从 CPU 特性获取功能和扩展过去功能和扩展是由代码生成器临时生成或通过内联汇编实现的。现在它们完全由 CPU 特性集驱动就像其他目标平台一样。依赖链从 SPIRV - Headers 中提取汇编器现在会拒绝任何直接生成 OpCapability 或 OpExtension 的尝试。多线程代码生成从一开始SPIR-V 后端就在链接器线程内以单线程方式运行代码生成。现在每个代码生成任务都会像其他自托管后端一样生成一个 Mir 值并在编译器的线程池上进行调度。同样的更改还恢复了在早期重构中被移除的两个 ISel 通道dedup_types 和 prune_unused。对象文件链接现在.spv 文件被识别为对象文件。可以编译多个 .zig 文件或外部 .spv 对象然后使用 SPIR-V 链接器将它们合并成一个模块。在此过程中修复了数十个 bugspirv64 - vulkan 目标的总通过行为测试增加了近 10%现在达到 49%。std.gpu 被重命名为 std.spirv与一个月前相比SPIR-V 后端的实用性有了显著提升但仍有很长的路要走。SPIR-V 上仍有大量行为测试被跳过。不过现在是尝试使用 Zig 编写着色器或计算内核的不错时机。欢迎提交 bug 报告。2026 年 6 月 25 日新的 bitCast 语义和 LLVM 后端改进作者是 Matthew Lugg。几周前他开始在一个分支上工作旨在实现对 LLVM 后端的一项长期改进计划。结果这项工作演变成了一个更大的变更实现了一些可能感兴趣的语言提案。LLVM 后端整数类型转换Zig 一直将任意位宽的整数类型直接转换为 LLVM IR 的位整数类型。然而这种转换方式并非最优因为 LLVM 文档中规定的这些类型在内存中的表示语义对优化器的限制过多。更重要的是由于 Clang 从未生成过这样的 LLVM IRLLVM 中这些代码路径从未经过充分测试因此在实际应用中支持不佳。在过去几年里发现了许多简单优化被忽略甚至编译错误的情况。因此这个 PR 的最初目标是仅在以 SSA 形式操作值时使用这些位整数类型并在将它们存储到内存中时将其零扩展或符号扩展为 ABI 大小的类型。这应该会得到很好的支持因为这与 Clang 对 C 语言 _BitInt(N) 的转换方式一致。但他遇到了一个问题。bitCast 的问题bitCast 过去被定义为等同于获取操作数的指针、将其转换为目标类型的指针、从该指针加载值。然而随着时间的推移偏离了这个定义。现在允许使用 bitCast 将 [3]u8 重新解释为 u24这会导致未定义行为。到目前为止LLVM 后端一直实现的是 bitCast 内置函数的这些未明确规定的语义。改变在内存中存储整数类型的方式最终影响了 bitCast 的实现并引入了未定义行为导致编译器测试套件崩溃。重新定义 bitCast2024 年Jacob Young 撰写了语言提案旨在通过精确指定一组新的语义来解决 bitCast 的问题。该提案提交后不久就被接受了自托管的 x86_64 后端已经实现了它所描述的语义。所以为了解决 LLVM 后端的问题现在是在所有地方实现新语义的好时机。这样做的另一个好处是可以利用编译器的 Legalize 通道该通道可以将难以转换的操作重写为更简单的操作这样编译器后端只需要支持这些简单的操作即可。他开始在整个编译器中实现这些新语义这不仅包括 LLVM 和 C 后端还包括编译时执行。他还必须审查标准库、编译器和支持库中大量使用 bitCast 的地方。经过一些修复后他的 PR 通过了测试并于昨天将其合并到了主分支。新的 bitCast 语义现在bitCast 是根据逻辑上表示类型的位来定义的。每个支持 bitCast 的类型都有一个“逻辑位布局”。新定义是将一种类型的逻辑位重新解释为另一种类型的逻辑位。最简单的例子是将一个无符号整数转换为相同大小的有符号整数位保持不变只是将最高位重新解释为符号位。整数类型与 packed struct/packed union 类型之间的 bitCast 语义也保持不变。新语义与旧语义不同的地方在于涉及聚合类型时。例如将 [2]u8 进行位转换为 u16在旧语义下结果取决于目标平台的字节序在新语义下该操作在每个目标平台上的行为都是相同的数组的第一个元素成为 8 个最低有效位。新语义倾向于与小端字节序平台上的旧语义行为相匹配。这个定义还允许进行一些更奇特的操作例如将 [2]u3 转换为 Vector(3, u2)。这种操作在需要时确实存在。在进行这些工作的同时他还实现了几个已接受的小提案像禁止 bitCast 与指针向量之间的转换、允许在枚举类型上使用 bitCast。所有这些更改的语义将在 0.17.0 版本的发布说明中进行解释并给出建议的迁移步骤。LLVM 后端性能这个分支的最初动机——改变 LLVM 后端对非 ABI 整数类型的转换方式明显成功地恢复了被忽略的优化。事实上Zig 编译器本身由于更好的优化性能提升了约 5%。这意味着在 0.17.0 版本中可能会看到一些轻微的运行时性能提升。2026 年 5 月 30 日ELF 链接器改进作者是 Matthew Lugg。过去几周他一直在致力于 Zig 0.16.0 版本中推出的新 ELF 链接器的开发。在 0.16.0 版本发布时这个链接器的实现还处于早期阶段仅支持链接纯 Zig 代码不支持任何外部库。因此它默认是禁用的。不过自最初发布以来已经取得了很大的进展。新的 ELF 链接器现在能够在启用 LLVM 和 LLD 库的情况下构建自托管的 Zig 编译器。ELF 链接器的主要亮点是它支持快速增量编译。经过最近的改进现在在 x86_64 Linux 系统上链接外部库、C 源文件等时可以进行增量重建而且不会有任何额外的性能开销。对 Andrew 的 Tetris 克隆项目进行一些小改动后每次构建大约只需要 30 毫秒。快速增量重建在 Zig 编译器本身也能很好地工作。目前这个链接器实现最大的缺失功能是它仍然不支持为 Zig 代码生成 DWARF 调试信息这是接下来的首要任务。但即使没有这个支持即时重建的功能也非常有用。如果你正在使用 Zig 的主分支并且使用的是 x86_64 Linux 系统不妨考虑尝试使用新的 ELF 链接器进行增量编译。如果你遇到任何 bug请提交一个 issue。如果你目前仍然使用 Zig 的标记版本不用担心Zig 0.17.0 版本即将发布你很快就可以尝试这个功能了。2026 年 5 月 26 日构建系统重构作者是 Andrew Kelley。一个重要的分支刚刚合并将 maker 进程与 configurer 进程分离。这篇开发日志是即将发布的版本说明的预览同时也提前通知那些想要帮助测试新功能并提供反馈的人这些反馈将为 Zig 项目的未来发展提供指导。以前build.zig 文件和构建系统实现都被编译到一个臃肿的进程中以调试模式运行。现在build.zig 文件被编译成一个小进程“configurer”以调试模式运行。在该逻辑在内存中构建好构建图后它会被序列化为一个二进制配置文件。父进程 zig build 会感知到这个文件并将其缓存起来供下次使用。在此期间它会异步地以发布模式编译构建图执行进程“maker”。一旦配置文件可用且 maker 进程编译完成就会执行 maker 进程并将配置文件传递给它。由于全局缓存的存在maker 进程每个 zig 版本 只需要编译一次。然后maker 进程会执行包含在序列化配置文件中的构建图。这次更改的主要动机是通过三种方式让 zig build 变得更快每次更改时只会编译用户的 build.zig 逻辑而不是整个构建系统当构建系统知道不会有任何变化时它可以完全跳过重新运行 build.zig 逻辑实际执行构建图的进程是在启用优化的情况下编译的。运行 zig build --help 在更改前后的差异非常显著以前每次执行 zig build 命令时都会执行 build.zig 逻辑而现在构建系统会使用缓存的序列化配置。除了性能提升预计像 ZLS 这样的第三方工具将受益于使用序列化配置文件而不是维护一个构建运行器的分支。这个变更集对 Zig 构建系统的内部机制进行了重大重构但从 API 角度来看大部分是非破坏性的。对于大多数人来说会遇到的主要破坏性变更如下将 if (b.args) |args| { run_cmd.addArgs(args); } 改为 run_cmd.addPassthruArgs();。这一更改从构建脚本中移除了一项功能但意味着在更改这些参数时构建脚本不再需要从源代码重新构建。如果你想影响 Zig 的发展方向现在是将你的项目升级到开发版本并尝试这些更改的好时机。我们将在几周内发布 0.17.0 版本。不过如果你没有时间并且发现 0.17.0 版本破坏了你的构建不用担心在 0.17.1 版本发布时会有足够的机会进行修复。2026 年 4 月 8 日使用 LLVM 进行增量编译作者是 Matthew Lugg。上个月合并了类型解析更改后他花了一些时间处理个人项目但最近还是抽出时间对 LLVM 代码生成后端进行了一些改进。他成功让 LLVM 后端支持增量编译了。遗憾的是这对解决 LLVM 生成目标文件的时间问题没有帮助因为这个时间完全取决于 LLVM。然而增量编译确实有助于减少在实际 Zig 编译器代码中花费的时间。这意味着如果代码有编译错误通常会很快得到这些错误信息。在成功构建时也会带来轻微的速度提升。这个功能现在在主分支构建中可用并将包含在 0.16.0 版本中。对于还没有尝试过的人特别是正在使用 Zig 的主分支的人请通过在 zig build 命令中传递 -fincremental --watch 来尝试增量编译Zig 核心团队在工作流程中使用增量编译已经有一年了也从用户那里听到了很多积极的反馈。这个功能目前已经比较稳定人们常常惊讶于通过在毫秒级而不是秒级获得最新的编译错误信息能节省多少时间。他个人还没有在 LLVM 后端上使用过增量编译但现在 CI 中的所有增量测试覆盖都已经为 LLVM 后端启用了而且他也收到了用户的积极反馈所以绝对值得一试。一如既往如果你在增量编译中遇到 bug请尽可能报告它们2026 年 3 月 10 日类型解析重新设计附带语言更改作者是 Matthew Lugg。今天经过两可以说是三个月的工作他合并了一个 30000 行的 PR。这个分支的目标是将 Zig 编译器的内部类型解析逻辑重新设计为更合理、更直接的架构。这让他清理了编译器的很多内部代码而且还有一些对用户友好的更改。一方面Zig 编译器现在在分析类型字段时更加懒惰如果一个类型从未被初始化那么 Zig 就不需要关心这个类型“长什么样”。当有一个类型同时用作命名空间时这一点很重要。例如当使用 std.Io.Writer 时不希望编译器同时引入 std.Io 中的一堆代码。以前一段代码会产生编译错误现在可以正常编译因为 Zig 实际上不会查看 compileError 调用。还在“依赖循环”体验方面做了改进。以前遇到依赖循环编译错误时错误信息完全没有帮助现在情况不同了如果遇到一个依赖循环会得到一个详细的错误信息告诉你依赖循环具体来自哪里。此外这个 PR 还对 Zig 编译器的“增量编译”