Zig 包管理与构建系统重构

Zig 包管理与构建系统重构

Zig 已将其包管理逻辑从编译器可执行文件中解耦,并将其移入构建系统("maker" 进程)。这种架构转变允许在不重新构建编译器的情况下对包管理任务进行修补,并允许在网络操作中使用 ReleaseSafe 模式,从而提高了整体安全性和性能。

包管理已移至构建系统

Zig 已将包管理的责任从编译器转移到了构建系统。这意味着诸如 zig buildzig fetchzig initzig libc 等子命令现在由 maker 进程处理,而不是由编译器可执行文件处理。

因此,先前捆绑在编译器中的几个组件现在以源码形式发布,包括:

  • 包获取逻辑
  • HTTP 客户端和网络栈
  • TLS (Transport Layer Security) 和相关的密码学
  • Git 协议实现
  • 压缩库 (xz, gzip, zstd, flate, zip)
  • build.zig.zon 解析与验证

这种分离允许构建系统利用宿主特定的 CPU 指令来进行密码学和文件哈希,而这些指令在通用的编译器发行版中可能因过于罕见而无法包含。它还使 Zig 可执行二进制文件的体积减小了约 4%(在 no-LLVM, ReleaseSmall 配置下,从 14.1 MiB 减小到 13.5 MiB)。

进程架构演进

为了支持这一变化,Zig 演进其进程树,以确保构建系统在配置重新运行时保持为父进程。

先前架构:

zig build (the zig compiler + package manager)
└─ builder (the user's build.zig logic + build system implementation)

中间架构:

zig build (the zig compiler + package manager)
├─ configurer (the user's build.zig logic)
└─ maker (build system)

当前架构:

zig build (the zig compiler)
└─ maker (build system + package manager)
   └─ configurer (the user's build.zig logic)

通过使 maker 成为 configurer 的父进程,即使在 configurer 需要重新运行时(例如,在 zig build --watch 会话期间),maker 进程也可以持续存在,从而避免了服务器退出并需要客户端重新连接的需求。这是向为 ZLS (Zig Language Server) 提供构建服务器协议以解除阻塞的关键一步。

构建系统性能与重构

Zig 引入了 "configurer"(执行用户 build.zig 逻辑的进程)与 "maker"(执行构建图的进程)之间的分离。configurer 以 debug 模式编译,而 maker 以 release 模式编译。

这次重构提供了三个主要的性能优势:

  1. 减少编译时间: 只有用户的 build.zig 逻辑在发生变化时会被编译,而不是整个构建系统。
  2. 缓存配置: 如果未检测到变化,构建系统可以完全跳过重新运行 build.zig 逻辑,而是使用序列化的二进制配置文件。
  3. 优化执行: 执行构建图的进程现在已启用优化编译。

基准测试显示,简单命令的实际运行时间大幅减少;例如,zig build -h 从 150ms 降至 14.3ms(约 90% 的改进)。

LLVM 后端与 @bitCast 语义

Zig 已更新 LLVM 后端,以改进非-ABI 整数类型的降级方式。先前,任意位宽的整数被直接降级为 LLVM IR bit-int 类型,这经常导致优化缺失或编译错误。Zig 现在在将这些类型存储在内存中时,会将它们零扩展或符号扩展为 ABI 大小的类型,这与 Clang 对 _BitInt(N) 的行为一致。

重新定义 @bitCast

为了适应这些内存变化,Zig 重新定义了 @bitCast,使其基于类型的逻辑位布局,而不是内存中字节的重新解释。

  • 逻辑位布局: 类型现在被表示为有序的位序列(从最低有效位到最高有效位)。例如, u5 是 5 个逻辑位; [2]u5 是 10 个逻辑位。
  • 字节序无关性: 由于该操作现在是逻辑性的,@bitCast 在所有目标平台上表现一致。将 [2]u8 bitcast 到 u16 始终会使第一个数组元素成为 8 个最低有效位,无论目标平台是 大端序 (big-endian) 还是 小端序 (little-endian)。

这种变化也使得可以使用编译器的 Legalize 阶段来将复杂的 @bitCast 操作重写为更简单的操作,涵盖 LLVM 和 C 后端。

ELF Linker 与增量编译

Zig 引入了一个新的 ELF linker(通过 -fnew-linker 启用),支持在 x86_64 Linux 上进行快速增量量编译。该 linker 实现可以在链接外部库和 C 源码时,在不增加额外性能开销的情况下进行增量重构,使得某些重构构建任务可以在短短 30ms 内完成。

SPIR-V 后端进展

SPIR-V 后端有了重大更新,包括:

  • @SpirvType: 一个新的内置函数,用于表达 Zig 标准类型系统中无法表达的 SPIR-V 类型(例如,采样器和图像)。

  • 调用约定: 执行模式信息(工作组大小等)现在由调用约定携带(例如, callconv(.spirv_kernel)),而不是通过内联汇编实现。

  • 多线程代码生成: 代码生成现在产生 Mir 值,并在编译器的线程池中调度,从而从单线程执行转向了多线程执行。

  • Object File Linking: .spv 文件现在被识别为对象文件,允许将多个 .zig 文件或外部 .spv 对象链接成一个单一模块。

标准库与 OS 集成

Windows Native API 偏好

Zig 正在转向倾向于使用原生 NT API 而不是 Win32 (kernel32.dll) 包装器。这是为了减少不必要的堆分配,避免冗余的失败模式,并消除冗余。例如, Zig 现在在处理熵(随机字节)和文件 I/O (NtReadFile/NtWriteFile) 时绕过了 kernel32.dll,从而实现了与取消操作更好的集成,并实现了更高效的资源管理。

zig libc

Zig 正在逐步地将其 libc 实现中的内置 C 源码文件替换为 Zig 标准库包装器。这减少了对 C 语言的依赖,并提高了编译速度和二进制文件体积。这些 libc 函数现在共享 Zig 编译单元 (ZCU),从而允许进行类似于链接时优化 (LTO) 的跨边界优化。

事件驱动 I/O

实验性的 io_uring (Linux) 和 Grand Central Dispatch (GCD, macOS) 实现已在 std.Io.Evented 中上线。这些实现使用用户空间栈切换(fibers/green threads)来允许 I/O 实现可以在不改变应用逻辑的情况下轻松地进行更换。

社区洞察

虽然架构上的变化通常因其技术合理性而受到称赞,但一些用户对用户体验 (UX) 表现出了担忧。一位贡献者指出,将 @cImport 从编译器中移除并移入构建系统是一个权衡,即 "开发者的开发体验 (UX) 优先于开发者的理智 (sanity) 优先于 UX"。

"Zig, Go, and Python 开发者做这种事,他们宣布说 'We have removed the radiator fluid from the fuel tank,' 并且他们支持者支持说这很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限很限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限限 metaphoric 核心思想是:开发者们宣布说 'We have removed the radiator fluid from the fuel tank,' 并且他们支持者支持说这很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很men 很好很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很很支持者欢呼这对于语言来说是件好事,这让我在这里纳闷,为什么他们当初要把散热器冷却液放在燃料箱里呢?"""

Sources