Skip to content

Commit

Permalink
更新一部分 构建系统
Browse files Browse the repository at this point in the history
  • Loading branch information
jinzhongjia committed Dec 9, 2023
1 parent c81eb33 commit 7bc402f
Showing 1 changed file with 85 additions and 7 deletions.
92 changes: 85 additions & 7 deletions learn/engineering/build-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ zig 提供了四种构建模式(**Build Mode**):

:::details 关于 Debug 不可复现的原因

关于为什么 Debug 是不可复现的,ziglang 的文档并未给出具体说明,经过询问TG群,给出的答案是
关于为什么 Debug 是不可复现的,ziglang 的文档并未给出具体说明:

它可以添加一些基于随机种子的字段,例如在标准库中暴露多线程错误,或在常规类型中检查非法行为等。
效果是在 Debug 构建模式下,编译器会添加一些随机因素进入到程序中(例如内存结构不同),所以任何没有明确说明内存布局的容器在 Debug 构建下可能会有所不同,这便于我们在 Debug 模式下快速暴露某些错误。有意思的是,这并不会影响程序正常运行,除非你的程序逻辑有问题。

**_这是 zig 加强安全性的一种方式(尽可能提高安全性但又不至于造成类似 Rust 开发时过重的心智负担)。_**

:::

Expand Down Expand Up @@ -125,8 +127,21 @@ pub fn build(b: *std.Build) void {
// zig 提供了一个方便的函数允许我们直接运行构建结果
const run_exe = b.addRunArtifact(exe);
// 注意:这个步骤不是必要的,显示声明运行依赖于构建
// 这会使运行是从构建输出目录(默认为 zig-out/bin )运行而不是构建缓存中运行
// 不过,如果应用程序运行依赖于其他已存在的文件(例如某些 ini 配置文件),这可以确保它们正确的运行
run_exe.step.dependOn(b.getInstallStep());
// 注意:此步骤不是必要的
// 此操作允许用户通过构建系统的命令传递参数,例如 zig build -- arg1 arg2
// 当前是将参数传递给运行构建结果
if (b.args) |args| {
run_cmd.addArgs(args);
}
// 指定一个 step 为 run
const run_step = b.step("run", "Run the application");
// 指定该 step 依赖于 run_exe,即实际的运行
run_step.dependOn(&run_exe.step);
}
Expand Down Expand Up @@ -238,8 +253,6 @@ pub fn build(b: *std.Build) void {

:::code-group



```zig [nightly]
const std = @import("std");
Expand Down Expand Up @@ -338,9 +351,15 @@ pub fn build(b: *std.Build) void {
zig 本身提供了一个实验性的文档生成器,它支持搜索查询,操作如下:

```zig
const std = @import("std");
pub fn build(b: *std.Build) void {
// ...
// 添加 step
const docs_step = b.step("docs", "Emit docs");
// 构建文档
const docs_install = b.addInstallDirectory(.{
// lib 库
.source_dir = lib.getEmittedDocs(),
Expand All @@ -351,12 +370,67 @@ zig 本身提供了一个实验性的文档生成器,它支持搜索查询,
// 依赖step
docs_step.dependOn(&docs_install.step);
// ...
}
```

TODO
以上代码定义了一个名为 `docs` 的 Step,并将 `addInstallDirectory` 操作作为依赖添加到 `docs` Step 上。

## Test

每个文件可以使用 `zig test` 命令来执行测试,但实际开发中这样很不方便,zig 的构建系统提供了另外一种方式来处理当项目变得复杂时的测试。

使用构建系统执行单元测试时,构建器和测试器会通过 stdin 和 stdout 进行通信,以便同时运行多个测试,并且可以有效地报告错误(不会将错误混到一起),但这导致了无法[在单元测试中写入 stdin](https://github.com/ziglang/zig/issues/15091),这会扰乱测试器的正常工作。另外, zig 将引入一个额外的机制,允许预测 [`panic`](https://github.com/ziglang/zig/issues/1356)

```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 = "zig",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
// 添加到顶级 install step 中作为依赖
b.installArtifact(exe);
// 此处开始构建单元测试
// 构建一个单元测试的 Compile
const exe_unit_tests = b.addTest(.{
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
// 执行单元测试
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
// 如果想要跳过外部来自于其他包的单元测试(例如依赖中的包),可以使用 skip_foreign_checks
run_unit_tests.skip_foreign_checks = true;
// 构建一个 step,用于执行测试
const test_step = b.step("test", "Run unit tests");
// 测试 step 依赖上方构建的 run_exe_unit_tests
test_step.dependOn(&run_exe_unit_tests.step);
}
```

以上代码中,先通过 `b.addTest` 构建一个单元测试的 `Compile`,随后进行执行并将其绑定到 `test` Step 上。

## 交叉编译

TODO

## `embedFile`
Expand All @@ -365,12 +439,16 @@ TODO

## 执行其他命令

zig 的构建系统还允许我们执行一些额外的命令,录入根据 json 生成某些特定的文件(例如 zig 源代码),构建其他的编程语言(不只是 C / C++),如Golang、Rust、前端项目构建等等!

### 文件生成

TODO

## 文件生成
### 构建纯 C 项目

TODO

## 交叉编译
### 构建纯 C++ 项目

TODO

0 comments on commit 7bc402f

Please sign in to comment.