vault backup: 2026-11-07 16:33:44

This commit is contained in:
cheney
2026-11-07 16:33:55 +08:00
commit 7015312702
1208 changed files with 132432 additions and 0 deletions
@@ -0,0 +1,196 @@
Zig 的“统一编译”理念和内置的跨平台支持,让它在这个领域表现出色。结合 Docker 可以保证环境的一致性和可复现性。
下面我将为你梳理需要了解的核心概念和基础知识,并提供一个完整的 Docker 化工作流。
### 第一部分:核心概念与 Zig 基础知识
#### 1. Zig 的“统一编译”理念
这是 Zig 最核心的竞争力之一。它意味着:
* **单一编译器:** 你只需要安装一个 Zig 编译器和对应的标准库源码,就可以为任何支持的目标平台进行编译。无需安装多个交叉编译工具链。
* **目标三元组:** Zig 使用 `-target` 参数来指定编译目标。格式为:`cpu-arch-vendor-os-abi`。
* 例如:`x86_64-linux-gnu`, `aarch64-macos-none`, `wasm32-freestanding`。
* **内置标准库:** Zig 编译器内置了所有目标平台的 C 标准库(如 glibc, musl, libc++ 等)的源码,并在编译时按需链接。这确保了编译结果的确定性和可复现性。
#### 2. Zig 构建系统的核心:`build.zig`
Zig 使用一个用 Zig 语言编写的 `build.zig` 文件来定义构建规则,而不是 Makefile 或 CMakeLists.txt。
* **运行方式:** `zig build` 命令会读取当前目录的 `build.zig` 文件。
* **核心对象:**
* `std.Build`:构建系统的主要对象,提供了创建编译步骤的方法。
* `*std.Build.Step.Compile`:代表一个可执行文件、静态库或动态库的编译步骤。
* `*std.Build.Step`:代表一个构建步骤(如运行命令、安装文件等)。
* **基本结构:**
```zig
// build.zig
const std = @import("std");
pub fn build(b: *std.Build) void {
// 标准构建选项
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// 定义一个可执行文件
const exe = b.addExecutable(.{
.name = "my_app",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
// 这将创建一个 `zig build install` 步骤,将可执行文件安装到 `zig-out/bin/`
b.installArtifact(exe);
// 定义一个运行测试的步骤
const exe_tests = b.addTest(.{
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
const run_exe_tests = b.addRunArtifact(exe_tests);
// 创建一个 `zig build test` 步骤来运行测试
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_exe_tests.step);
}
```
#### 3. 交叉编译的关键:`std.Build.installArtifact`
在 `build.zig` 中,`b.installArtifact(exe)` 是核心。它告诉构建系统:“我想要生成这个可执行文件,并把它安装到标准输出目录(通常是 `zig-out/bin/`)”。
当你运行 `zig build -Dtarget=<target_triple>` 时,构建系统会自动处理所有交叉编译的细节,并将对应平台的可执行文件安装到 `zig-out/bin/`。
#### 4. WebAssembly 的特殊性
对于 WASM,目标通常是 `wasm32-freestanding`。
* **Freestanding:** 表示没有操作系统。WASM 模块运行在沙箱环境中。
* **导出函数:** 你需要使用 `export` 关键字来导出希望 JavaScript 能够调用的函数。
```zig
// math.zig
export fn add(a: i32, b: i32) i32 {
return a + b;
}
```
* **构建配置:** 在 `build.zig` 中,你需要创建一个**静态库**而不是可执行文件,因为 WASM 模块本质上是库。
```zig
const wasm_lib = b.addStaticLibrary(.{
.name = "math",
.root_source_file = .{ .path = "src/math.zig" },
.target = b.resolveTargetQuery(.{
.cpu_arch = .wasm32,
.os_tag = .freestanding,
}),
.optimize = optimize,
});
// 重要:设置链接模式
wasm_lib.override_libc = null; // 我们不链接 libc
wasm_lib.rdynamic = true; // 确保所有符号都被导出
b.installArtifact(wasm_lib); // 会生成 zig-out/lib/math.wasm
```
---
### 第二部分:Docker 环境下的工作流
使用 Docker 可以固化构建环境,确保任何人、任何机器上都能得到完全相同的编译结果。
#### 1. 创建 Dockerfile
这个 Dockerfile 会安装 Zig 编译器并设置工作目录。
```dockerfile
# Dockerfile
# 选择一个轻量级的基础镜像
FROM alpine:latest AS zig-builder
# 安装依赖(Alpine 使用 musl libc,非常轻量)
RUN apk add --no-cache xz tar
# 设置工作目录
WORKDIR /workspace
# 从官方地址下载并安装 Zig
# 请替换为最新的稳定版本,可从 https://ziglang.org/download/ 获取
ARG ZIG_VERSION=0.12.0
ARG ZIG_ARCH=x86_64-linux
RUN wget https://ziglang.org/builds/zig-${ZIG_ARCH}-${ZIG_VERSION}.tar.xz && \
tar -xf zig-${ZIG_ARCH}-${ZIG_VERSION}.tar.xz && \
rm zig-${ZIG_ARCH}-${ZIG_VERSION}.tar.xz
# 将 Zig 二进制文件路径添加到 PATH
ENV PATH="/workspace/zig-${ZIG_ARCH}-${ZIG_VERSION}:${PATH}"
# 验证安装
RUN zig version
# 设置默认命令
CMD ["/bin/sh"]
```
#### 2. 创建 docker-compose.yml(推荐)
使用 Docker Compose 可以更方便地管理构建命令和卷映射。
```yaml
# docker-compose.yml
version: '3.8'
services:
zig-build:
build:
context: .
dockerfile: Dockerfile
volumes:
# 将宿主机的当前目录挂载到容器的 /workspace
- .:/workspace
working_dir: /workspace
# 默认命令,可以覆盖
command: zig build --help
```
#### 3. 项目目录结构
```
my-zig-project/
├── Dockerfile
├── docker-compose.yml
├── build.zig
├── src/
│ └── main.zig
└── zig-out/ (由 zig build 自动生成)
```
#### 4. 完整的构建命令示例
假设你的 `build.zig` 已经配置好,并且定义了名为 `my_app` 的可执行文件。
1. **构建 Docker 镜像:**
```bash
docker-compose build
```
2. **编译 Linux x86_64 版本:**
```bash
docker-compose run zig-build zig build -Dtarget=x86_64-linux-musl -Doptimize=ReleaseSafe
```
完成后,在宿主机的 `zig-out/bin/` 目录下会找到 `my_app`。
3. **编译 Windows x86_64 版本:**
```bash
docker-compose run zig-build zig build -Dtarget=x86_64-windows-gnu -Doptimize=ReleaseSafe
```
完成后,在宿主机的 `zig-out/bin/` 目录下会找到 `my_app.exe`。
4. **编译 WebAssembly:**
假设你的 `build.zig` 中已经定义了 `wasm_lib`。
```bash
# 这个命令会运行 build.zig 中定义的安装步骤,生成 .wasm 文件
docker-compose run zig-build zig build -Doptimize=ReleaseSmall
# 或者,如果你为 wasm 定义了一个特定的构建步骤(例如 b.step("wasm", "Build WASM")),你可以运行:
# docker-compose run zig-build zig build wasm
```
完成后,在宿主机的 `zig-out/lib/` 目录下会找到 `math.wasm`。
### 总结
1. **核心概念:** 理解 Zig 的**目标三元组**和基于 `build.zig` 的**构建系统**。
2. **WASM 要点:** 使用 `wasm32-freestanding` 目标,创建**静态库**,并使用 `export` 导出函数。
3. **Docker 化:** 使用 Dockerfile 固化 Zig 编译环境,使用 Docker Compose 简化构建命令的执行。
4. **工作流:** 通过 `docker-compose run zig-build zig build -Dtarget=...` 来为不同平台交叉编译。
这个组合(Zig + Docker)为你提供了一个极其强大、一致且可移植的跨平台编译环境,无论是用于本地开发、CI/CD 流水线,还是为团队统一构建环境,都非常高效。