-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.zig
More file actions
255 lines (216 loc) · 10.7 KB
/
build.zig
File metadata and controls
255 lines (216 loc) · 10.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
const std = @import("std");
// Build steps:
// zig build # Debug build (7.3MB, with symbols)
// zig build -Doptimize=ReleaseFast # Fast release (2.3MB)
// zig build -Doptimize=ReleaseSafe # Safe release (1.9MB)
// zig build -Doptimize=ReleaseSmall # Small release (1.2MB)
// zig build release # Optimized release (1.2MB, stripped)
//
// Test targets:
// zig build test # Run unit tests (1252 tests in src/)
// zig build integration-test # Run integration tests (black-box CLI tests)
// zig build test-perf-streaming # Run performance tests (output streaming)
// zig build test-tui-bench # Run TUI performance benchmarks (regression detection)
// zig build test-all # Run all tests (unit + integration + perf + tui bench)
//
// Fuzz targets (run indefinitely until Ctrl+C):
// zig build fuzz-toml # TOML parser fuzzer
// zig build fuzz-expr # Expression engine fuzzer
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const sailor_dep = b.dependency("sailor", .{ .target = target, .optimize = optimize });
const zuda_dep = b.dependency("zuda", .{ .target = target, .optimize = optimize });
// Extract version from build.zig.zon at comptime and expose as build option
const version: []const u8 = comptime blk: {
const zon = @embedFile("build.zig.zon");
const needle = ".version = \"";
const start = std.mem.indexOf(u8, zon, needle).? + needle.len;
const end = std.mem.indexOfPos(u8, zon, start, "\"").?;
break :blk zon[start..end];
};
const version_opts = b.addOptions();
version_opts.addOption([]const u8, "version", version);
const exe = b.addExecutable(.{
.name = "zr",
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
// Link libc on non-Windows targets for setenv(3) in builtin_env.zig.
// Windows targets don't have bundled MSVC libc in Zig's cross-compiler.
.link_libc = if (target.result.os.tag != .windows) true else null,
}),
});
exe.root_module.addImport("sailor", sailor_dep.module("sailor"));
exe.root_module.addImport("zuda", zuda_dep.module("zuda"));
exe.root_module.addOptions("build_options", version_opts);
// Strip debug symbols in release builds for smaller binary size
// Only keep symbols in Debug mode for easier debugging
exe.root_module.strip = switch (optimize) {
.Debug => false,
else => true,
};
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
const exe_tests = b.addTest(.{
.root_module = exe.root_module,
});
// Run tests without --listen=- protocol (bypasses zig_test server mode).
// Many unit tests write to stdout which corrupts the build system protocol pipe.
const run_exe_tests = std.Build.Step.Run.create(b, "run unit tests");
run_exe_tests.addArtifactArg(exe_tests);
run_exe_tests.has_side_effects = true;
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_exe_tests.step);
// --- Integration Tests ---
// Build options: inject binary path for integration tests
const opts = b.addOptions();
opts.addOption([]const u8, "zr_bin_path", "zig-out/bin/zr");
const int_tests = b.addTest(.{
.root_module = b.createModule(.{
.root_source_file = b.path("tests/integration.zig"),
.target = target,
.optimize = optimize,
}),
});
int_tests.root_module.addOptions("build_options", opts);
// Run integration tests without --listen=- protocol (same as unit tests).
// Integration tests spawn zr binary and capture output, which can interfere with protocol.
const run_int_tests = std.Build.Step.Run.create(b, "run integration tests");
run_int_tests.addArtifactArg(int_tests);
run_int_tests.has_side_effects = true;
run_int_tests.step.dependOn(b.getInstallStep()); // ensures zr binary is built first
const integration_step = b.step("integration-test", "Run integration tests");
integration_step.dependOn(&run_int_tests.step);
// --- zuda WorkStealingDeque API Compatibility Tests ---
const zuda_ws_tests = b.addTest(.{
.root_module = b.createModule(.{
.root_source_file = b.path("tests/zuda_workstealing_test.zig"),
.target = target,
.optimize = optimize,
}),
});
zuda_ws_tests.root_module.addImport("zuda", zuda_dep.module("zuda"));
const run_zuda_ws_tests = std.Build.Step.Run.create(b, "run zuda workstealing tests");
run_zuda_ws_tests.addArtifactArg(zuda_ws_tests);
run_zuda_ws_tests.has_side_effects = true;
const zuda_ws_step = b.step("test-zuda-ws", "Run zuda WorkStealingDeque API compatibility tests");
zuda_ws_step.dependOn(&run_zuda_ws_tests.step);
// --- zuda DAG Compatibility Tests ---
const zuda_compat_tests = b.addTest(.{
.root_module = b.createModule(.{
.root_source_file = b.path("tests/zuda_compat_test.zig"),
.target = target,
.optimize = optimize,
}),
});
zuda_compat_tests.root_module.addImport("zuda", zuda_dep.module("zuda"));
const run_zuda_compat_tests = std.Build.Step.Run.create(b, "run zuda compat tests");
run_zuda_compat_tests.addArtifactArg(zuda_compat_tests);
run_zuda_compat_tests.has_side_effects = true;
const zuda_compat_step = b.step("test-zuda-compat", "Run zuda DAG compatibility tests");
zuda_compat_step.dependOn(&run_zuda_compat_tests.step);
// --- Release Build ---
// Optimized release build with ReleaseSmall + strip for minimal binary size
const release_exe = b.addExecutable(.{
.name = "zr",
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = .ReleaseSmall,
.link_libc = if (target.result.os.tag != .windows) true else null,
}),
});
release_exe.root_module.strip = true;
release_exe.root_module.addImport("sailor", sailor_dep.module("sailor"));
release_exe.root_module.addOptions("build_options", version_opts);
const install_release = b.addInstallArtifact(release_exe, .{});
const release_step = b.step("release", "Build optimized release binary (ReleaseSmall + strip)");
release_step.dependOn(&install_release.step);
// --- Fuzz Tests ---
// Create zr module for fuzz tests to import
const zr_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
.link_libc = if (target.result.os.tag != .windows) true else null,
});
zr_module.addImport("sailor", sailor_dep.module("sailor"));
zr_module.addOptions("build_options", version_opts);
// TOML parser fuzzer
const fuzz_toml = b.addExecutable(.{
.name = "fuzz_toml",
.root_module = b.createModule(.{
.root_source_file = b.path("tests/fuzz_toml.zig"),
.target = target,
.optimize = optimize,
.link_libc = if (target.result.os.tag != .windows) true else null,
}),
});
fuzz_toml.root_module.addImport("zr", zr_module);
const run_fuzz_toml = b.addRunArtifact(fuzz_toml);
const fuzz_toml_step = b.step("fuzz-toml", "Run TOML parser fuzz test (runs until Ctrl+C)");
fuzz_toml_step.dependOn(&run_fuzz_toml.step);
// Expression engine fuzzer
const fuzz_expr = b.addExecutable(.{
.name = "fuzz_expr",
.root_module = b.createModule(.{
.root_source_file = b.path("tests/fuzz_expr.zig"),
.target = target,
.optimize = optimize,
.link_libc = if (target.result.os.tag != .windows) true else null,
}),
});
fuzz_expr.root_module.addImport("zr", zr_module);
const run_fuzz_expr = b.addRunArtifact(fuzz_expr);
const fuzz_expr_step = b.step("fuzz-expr", "Run expression engine fuzz test (runs until Ctrl+C)");
fuzz_expr_step.dependOn(&run_fuzz_expr.step);
// --- Performance Tests ---
// Output streaming performance test (verifies <50MB memory for 1GB+ output)
const perf_streaming_tests = b.addTest(.{
.root_module = b.createModule(.{
.root_source_file = b.path("tests/perf_output_streaming.zig"),
.target = target,
.optimize = optimize,
.link_libc = if (target.result.os.tag != .windows) true else null,
}),
});
perf_streaming_tests.root_module.addImport("zr", zr_module);
perf_streaming_tests.root_module.addImport("zuda", zuda_dep.module("zuda"));
const run_perf_streaming = std.Build.Step.Run.create(b, "run perf streaming tests");
run_perf_streaming.addArtifactArg(perf_streaming_tests);
run_perf_streaming.has_side_effects = true;
const perf_streaming_step = b.step("test-perf-streaming", "Run output streaming performance tests (1GB+ files)");
perf_streaming_step.dependOn(&run_perf_streaming.step);
// TUI performance benchmark tests (regression detection for TUI modes)
const tui_bench_tests = b.addTest(.{
.root_module = b.createModule(.{
.root_source_file = b.path("tests/tui_bench.zig"),
.target = target,
.optimize = optimize,
.link_libc = if (target.result.os.tag != .windows) true else null,
}),
});
tui_bench_tests.root_module.addImport("zr", zr_module);
tui_bench_tests.root_module.addImport("sailor", sailor_dep.module("sailor"));
tui_bench_tests.root_module.addImport("zuda", zuda_dep.module("zuda"));
const run_tui_bench = std.Build.Step.Run.create(b, "run TUI benchmark tests");
run_tui_bench.addArtifactArg(tui_bench_tests);
run_tui_bench.has_side_effects = true;
const tui_bench_step = b.step("test-tui-bench", "Run TUI performance benchmark tests with regression detection");
tui_bench_step.dependOn(&run_tui_bench.step);
// --- Test All ---
// Composite test target that runs all test categories
const test_all_step = b.step("test-all", "Run all tests (unit + integration + performance)");
test_all_step.dependOn(&run_exe_tests.step); // unit tests
test_all_step.dependOn(&run_int_tests.step); // integration tests
test_all_step.dependOn(&run_perf_streaming.step); // performance tests
test_all_step.dependOn(&run_tui_bench.step); // TUI benchmarks
}