-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.zig
More file actions
752 lines (709 loc) · 36.4 KB
/
Copy pathbuild.zig
File metadata and controls
752 lines (709 loc) · 36.4 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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const injection_dependency = b.dependency("injection", .{
.target = target,
.optimize = optimize,
});
const regex_dependency = b.dependency("regex", .{
.target = target,
.optimize = optimize,
});
const xml_dependency = b.dependency("xml", .{
.target = target,
.optimize = optimize,
});
const lmdb_translate = b.addTranslateC(.{
.root_source_file = b.path("pantry/openldap.org/liblmdb/v0.9.35/include/lmdb.h"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
const lmdb_module = lmdb_translate.createModule();
const waf = b.addModule("waf", .{
.root_source_file = b.path("src/root.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
waf.addIncludePath(b.path("pantry/openldap.org/liblmdb/v0.9.35/include"));
waf.addObjectFile(b.path("pantry/openldap.org/liblmdb/v0.9.35/lib/liblmdb.a"));
waf.addImport("injection", injection_dependency.module("injection"));
waf.addImport("regex", regex_dependency.module("regex"));
waf.addImport("xml", xml_dependency.module("xml"));
waf.addImport("lmdb", lmdb_module);
const cli_module = b.createModule(.{
.root_source_file = b.path("src/cli.zig"),
.target = target,
.optimize = optimize,
});
cli_module.addImport("waf", waf);
const cli = b.addExecutable(.{ .name = "zig-waf", .root_module = cli_module });
b.installArtifact(cli);
const daemon_module = b.createModule(.{
.root_source_file = b.path("src/daemon.zig"),
.target = target,
.optimize = optimize,
});
daemon_module.addImport("waf", waf);
const daemon = b.addExecutable(.{ .name = "zig-wafd", .root_module = daemon_module });
b.installArtifact(daemon);
const c_api_module = b.createModule(.{
.root_source_file = b.path("src/c_api.zig"),
.target = target,
.optimize = optimize,
});
c_api_module.addImport("waf", waf);
const c_api = b.addLibrary(.{
.name = "zig-waf",
.linkage = .static,
.root_module = c_api_module,
});
c_api.installHeader(b.path("include/zig_waf.h"), "zig_waf.h");
b.installArtifact(c_api);
const c_smoke = b.addExecutable(.{
.name = "c-api-smoke",
.root_module = b.createModule(.{
.target = target,
.optimize = optimize,
.link_libc = true,
}),
});
c_smoke.root_module.addCSourceFile(.{ .file = b.path("tests/c_api_smoke.c") });
c_smoke.root_module.addIncludePath(b.path("include"));
c_smoke.root_module.linkLibrary(c_api);
const run_c_smoke = b.addRunArtifact(c_smoke);
const tests = b.addTest(.{ .root_module = waf });
const run_tests = b.addRunArtifact(tests);
const c_api_tests = b.addTest(.{ .root_module = c_api_module });
const run_c_api_tests = b.addRunArtifact(c_api_tests);
const transformation_evidence_module = b.createModule(.{
.root_source_file = b.path("tests/transformation_evidence.zig"),
.target = target,
.optimize = optimize,
});
transformation_evidence_module.addImport("waf", waf);
const transformation_evidence_tests = b.addTest(.{ .root_module = transformation_evidence_module });
const run_transformation_evidence_tests = b.addRunArtifact(transformation_evidence_tests);
const transformation_differential_module = b.createModule(.{
.root_source_file = b.path("tests/transformation_differential.zig"),
.target = target,
.optimize = optimize,
});
transformation_differential_module.addImport("waf", waf);
const transformation_differential_tests = b.addTest(.{ .root_module = transformation_differential_module });
const run_transformation_differential_tests = b.addRunArtifact(transformation_differential_tests);
const operator_evidence_module = b.createModule(.{
.root_source_file = b.path("tests/operator_evidence.zig"),
.target = target,
.optimize = optimize,
});
operator_evidence_module.addImport("waf", waf);
const operator_evidence_tests = b.addTest(.{ .root_module = operator_evidence_module });
const run_operator_evidence_tests = b.addRunArtifact(operator_evidence_tests);
// PostgreSQL fleet-storage foundation: a libpq-backed client + migration
// runner. Kept out of the default `test` step (it links libpq and its
// integration tests need a live database); run it with `zig build pg-test`
// after setting PG_TEST_DSN.
//
// The shared library's extension follows the host, so the same step builds on a
// developer's macOS and on a Linux runner. Naming one of them would not fail at
// configure time — it fails when the linker is already running, which reads as a
// broken build rather than as an unportable path.
const libpq_prefix = "pantry/postgresql.org/libpq/v18.0.0";
const libpq_library = switch (target.result.os.tag) {
.macos, .ios, .tvos, .watchos => libpq_prefix ++ "/lib/libpq.dylib",
.windows => libpq_prefix ++ "/lib/libpq.lib",
else => libpq_prefix ++ "/lib/libpq.so",
};
const pq_translate = b.addTranslateC(.{
.root_source_file = b.path(libpq_prefix ++ "/include/libpq-fe.h"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
const pq_module = pq_translate.createModule();
// Zstandard, for compressing a node's durable event queue (#55). Linked
// statically, like liblmdb, so no runtime library path is needed.
const zstd_translate = b.addTranslateC(.{
.root_source_file = b.path("pantry/facebook.com/zstd/v1.5.7/include/zstd.h"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
const zstd_c_module = zstd_translate.createModule();
const zstd_module = b.createModule(.{
.root_source_file = b.path("src/zstd.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
zstd_module.addImport("zstd_c", zstd_c_module);
zstd_module.addIncludePath(b.path("pantry/facebook.com/zstd/v1.5.7/include"));
zstd_module.addObjectFile(b.path("pantry/facebook.com/zstd/v1.5.7/lib/libzstd.a"));
const zstd_tests = b.addTest(.{ .root_module = zstd_module });
const run_zstd_tests = b.addRunArtifact(zstd_tests);
// libxml2, for the XPath/XSD/DTD operators the pure-Zig parser cannot serve
// (#28). Kept out of the default `test` step: it links a shared library, so its
// tests need that library on the loader path. Run with `zig build xml2-test`.
//
// One translated header including all of libxml2's, rather than several
// translations, because the types are shared and separate translations would make
// distinct Zig types for them.
const libxml2_prefix = "pantry/gnome.org/libxml2/v2.13.9";
const libxml2_library = switch (target.result.os.tag) {
.macos, .ios, .tvos, .watchos => libxml2_prefix ++ "/lib/libxml2.dylib",
.windows => libxml2_prefix ++ "/lib/libxml2.lib",
else => libxml2_prefix ++ "/lib/libxml2.so",
};
const xml2_translate = b.addTranslateC(.{
.root_source_file = b.path("src/xml2_includes.h"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
xml2_translate.addIncludePath(b.path(libxml2_prefix ++ "/include/libxml2"));
const xml2_module = b.createModule(.{
.root_source_file = b.path("src/xml2.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
xml2_module.addImport("xml2_c", xml2_translate.createModule());
xml2_module.addIncludePath(b.path(libxml2_prefix ++ "/include/libxml2"));
xml2_module.addObjectFile(b.path(libxml2_library));
const xml2_tests = b.addTest(.{ .root_module = xml2_module });
const run_xml2_tests = b.addRunArtifact(xml2_tests);
const xml2_test_step = b.step("xml2-test", "Run the libxml2 adapter tests (needs libxml2 on the loader path)");
xml2_test_step.dependOn(&run_xml2_tests.step);
const pg_module = b.createModule(.{
.root_source_file = b.path("src/pg.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
pg_module.addImport("pq", pq_module);
pg_module.addImport("zstd", zstd_module);
pg_module.addIncludePath(b.path(libpq_prefix ++ "/include"));
pg_module.addObjectFile(b.path(libpq_library));
const pg_tests = b.addTest(.{ .root_module = pg_module });
const run_pg_tests = b.addRunArtifact(pg_tests);
const pg_test_step = b.step("pg-test", "Run PostgreSQL integration tests (needs PG_TEST_DSN)");
pg_test_step.dependOn(&run_pg_tests.step);
pg_test_step.dependOn(&run_zstd_tests.step);
// The ingestion benchmark links the same libpq and needs a live database, so
// it is a separate step alongside pg-test rather than part of `bench-*` runs.
const fleet_module = b.createModule(.{
.root_source_file = b.path("src/fleet.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
fleet_module.addImport("pq", pq_module);
fleet_module.addImport("zstd", zstd_module);
fleet_module.addIncludePath(b.path(libpq_prefix ++ "/include"));
fleet_module.addObjectFile(b.path(libpq_library));
const ingestion_benchmark_module = b.createModule(.{
.root_source_file = b.path("benchmarks/ingestion.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
ingestion_benchmark_module.addImport("fleet", fleet_module);
const ingestion_benchmark = b.addExecutable(.{
.name = "ingestion-benchmark",
.root_module = ingestion_benchmark_module,
});
const run_ingestion_benchmark = b.addRunArtifact(ingestion_benchmark);
const ingestion_benchmark_step = b.step("bench-ingestion", "Benchmark event ingestion paths (needs PG_TEST_DSN)");
ingestion_benchmark_step.dependOn(&run_ingestion_benchmark.step);
// SQLite embedded backend (#57): an in-process, serverless store mirroring
// the PostgreSQL client for single-node deployments and dependency-free
// tests. Kept out of the default `test` step (it links libsqlite3); run it
// with `zig build sqlite-test`. libsqlite3 resolves from the platform SDK.
const sqlite_translate = b.addTranslateC(.{
.root_source_file = b.path("src/sqlite_c.h"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
const sqlite_c_module = sqlite_translate.createModule();
const sqlite_module = b.createModule(.{
.root_source_file = b.path("src/sqlite.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
sqlite_module.addImport("sqlite3", sqlite_c_module);
sqlite_module.linkSystemLibrary("sqlite3", .{});
const sqlite_tests = b.addTest(.{ .root_module = sqlite_module });
const run_sqlite_tests = b.addRunArtifact(sqlite_tests);
const sqlite_test_step = b.step("sqlite-test", "Run SQLite backend tests");
sqlite_test_step.dependOn(&run_sqlite_tests.step);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_tests.step);
test_step.dependOn(&run_c_api_tests.step);
test_step.dependOn(&run_c_smoke.step);
test_step.dependOn(&run_transformation_evidence_tests.step);
test_step.dependOn(&run_transformation_differential_tests.step);
test_step.dependOn(&run_operator_evidence_tests.step);
const check_step = b.step("check", "Compile libraries and executables");
check_step.dependOn(&cli.step);
check_step.dependOn(&daemon.step);
check_step.dependOn(&c_api.step);
check_step.dependOn(&tests.step);
check_step.dependOn(&transformation_evidence_tests.step);
check_step.dependOn(&transformation_differential_tests.step);
check_step.dependOn(&operator_evidence_tests.step);
const parser_corpus_module = b.createModule(.{
.root_source_file = b.path("tools/parser_corpus.zig"),
.target = target,
.optimize = optimize,
});
parser_corpus_module.addImport("waf", waf);
const parser_corpus = b.addExecutable(.{
.name = "parser-corpus",
.root_module = parser_corpus_module,
});
const run_parser_corpus = b.addRunArtifact(parser_corpus);
if (b.option([]const []const u8, "parser-corpus", "SecLang corpus file or directory (repeatable)")) |corpus_roots|
run_parser_corpus.addArgs(corpus_roots);
const parser_corpus_step = b.step("test-parser-corpus", "Parse SecLang files beneath corpus roots");
parser_corpus_step.dependOn(&run_parser_corpus.step);
const run_plan_corpus = b.addRunArtifact(parser_corpus);
run_plan_corpus.addArg("--compile-plan");
// Files expected to fail because they use an operator zig-waf deliberately does
// not implement. Declaring them keeps that boundary tested rather than hidden:
// the corpus fails if such a file compiles after all.
if (b.option([]const []const u8, "plan-corpus-unsupported", "Corpus file expected to use an unimplemented operator (repeatable)")) |unsupported|
for (unsupported) |path| {
run_plan_corpus.addArg("--expect-unsupported");
run_plan_corpus.addArg(path);
};
if (b.option([]const []const u8, "plan-corpus", "SecLang structural plan corpus file or directory (repeatable)")) |corpus_roots|
run_plan_corpus.addArgs(corpus_roots);
const plan_corpus_step = b.step("test-plan-corpus", "Compile structural plans beneath corpus roots");
plan_corpus_step.dependOn(&run_plan_corpus.step);
const run_directive_corpus = b.addRunArtifact(parser_corpus);
run_directive_corpus.addArg("--validate-directives");
// The directive corpus compiles plans too, so it needs the same declared
// boundary as the plan corpus.
if (b.option([]const []const u8, "directive-corpus-unsupported", "Corpus file expected to use an unimplemented operator (repeatable)")) |unsupported|
for (unsupported) |path| {
run_directive_corpus.addArg("--expect-unsupported");
run_directive_corpus.addArg(path);
};
if (b.option([]const []const u8, "directive-corpus", "SecLang directive corpus file or directory (repeatable)")) |corpus_roots|
run_directive_corpus.addArgs(corpus_roots);
const directive_corpus_step = b.step("test-directive-corpus", "Validate stable directives beneath corpus roots");
directive_corpus_step.dependOn(&run_directive_corpus.step);
const directive_inventory_module = b.createModule(.{
.root_source_file = b.path("tools/directive_inventory.zig"),
.target = target,
.optimize = optimize,
});
directive_inventory_module.addImport("waf", waf);
const directive_inventory = b.addExecutable(.{
.name = "directive-inventory",
.root_module = directive_inventory_module,
});
const run_directive_inventory = b.addRunArtifact(directive_inventory);
if (b.option([]const u8, "modsecurity-scanner", "Pinned ModSecurity seclang-scanner.ll")) |path|
run_directive_inventory.addArg(path);
if (b.option([]const u8, "modsecurity-parser", "Pinned ModSecurity seclang-parser.yy")) |path|
run_directive_inventory.addArg(path);
if (b.option([]const u8, "coraza-directives", "Pinned Coraza directivesmap.gen.go")) |path|
run_directive_inventory.addArg(path);
const directive_inventory_step = b.step("test-directive-inventory", "Compare the registry with pinned upstream inventories");
directive_inventory_step.dependOn(&run_directive_inventory.step);
const transformation_inventory_module = b.createModule(.{
.root_source_file = b.path("tools/transformation_inventory.zig"),
.target = target,
.optimize = optimize,
});
transformation_inventory_module.addImport("waf", waf);
const transformation_inventory = b.addExecutable(.{
.name = "transformation-inventory",
.root_module = transformation_inventory_module,
});
const run_transformation_inventory = b.addRunArtifact(transformation_inventory);
if (b.option([]const u8, "modsecurity-transformation-scanner", "Pinned ModSecurity seclang-scanner.ll")) |path|
run_transformation_inventory.addArg(path);
if (b.option([]const u8, "modsecurity-transformation-parser", "Pinned ModSecurity seclang-parser.yy")) |path|
run_transformation_inventory.addArg(path);
if (b.option([]const u8, "coraza-transformations", "Pinned Coraza transformations.go")) |path|
run_transformation_inventory.addArg(path);
const transformation_inventory_step = b.step("test-transformation-inventory", "Compare the typed transformation registry with pinned upstream inventories");
transformation_inventory_step.dependOn(&run_transformation_inventory.step);
const crs_configuration_module = b.createModule(.{
.root_source_file = b.path("tools/crs_configuration.zig"),
.target = target,
.optimize = optimize,
});
crs_configuration_module.addImport("waf", waf);
const crs_configuration = b.addExecutable(.{
.name = "crs-configuration",
.root_module = crs_configuration_module,
});
const run_crs_configuration = b.addRunArtifact(crs_configuration);
if (b.option([]const []const u8, "crs-configuration", "Ordered CRS configuration root (repeatable)")) |roots|
run_crs_configuration.addArgs(roots);
const crs_configuration_step = b.step("test-crs-configuration", "Compile CRS as one ordered directive configuration");
crs_configuration_step.dependOn(&run_crs_configuration.step);
const parser_fuzz_module = b.createModule(.{
.root_source_file = b.path("tools/parser_fuzz.zig"),
.target = target,
.optimize = optimize,
});
parser_fuzz_module.addImport("waf", waf);
const parser_fuzz = b.addExecutable(.{
.name = "parser-fuzz",
.root_module = parser_fuzz_module,
});
const run_parser_fuzz = b.addRunArtifact(parser_fuzz);
const parser_fuzz_iterations = b.option(usize, "parser-fuzz-iterations", "Deterministic parser fuzz case count") orelse 10_000;
const parser_fuzz_seed = b.option(u64, "parser-fuzz-seed", "Deterministic parser fuzz seed") orelse 6_840_335_614_489_015_467;
run_parser_fuzz.addArgs(&.{ b.fmt("{d}", .{parser_fuzz_iterations}), b.fmt("{d}", .{parser_fuzz_seed}) });
const parser_fuzz_step = b.step("fuzz-parser", "Run deterministic SecLang parser fuzz cases");
parser_fuzz_step.dependOn(&run_parser_fuzz.step);
const plan_fuzz_module = b.createModule(.{
.root_source_file = b.path("tools/plan_fuzz.zig"),
.target = target,
.optimize = optimize,
});
plan_fuzz_module.addImport("waf", waf);
const plan_fuzz = b.addExecutable(.{
.name = "plan-fuzz",
.root_module = plan_fuzz_module,
});
const run_plan_fuzz = b.addRunArtifact(plan_fuzz);
const plan_fuzz_iterations = b.option(usize, "plan-fuzz-iterations", "Deterministic plan fuzz case count") orelse 10_000;
const plan_fuzz_seed = b.option(u64, "plan-fuzz-seed", "Deterministic plan fuzz seed") orelse 11_936_128_518_282_651_045;
run_plan_fuzz.addArgs(&.{ b.fmt("{d}", .{plan_fuzz_iterations}), b.fmt("{d}", .{plan_fuzz_seed}) });
const plan_fuzz_step = b.step("fuzz-plan", "Run deterministic structural plan fuzz cases");
plan_fuzz_step.dependOn(&run_plan_fuzz.step);
const run_directive_fuzz = b.addRunArtifact(plan_fuzz);
const directive_fuzz_iterations = b.option(usize, "directive-fuzz-iterations", "Deterministic directive fuzz case count") orelse 10_000;
const directive_fuzz_seed = b.option(u64, "directive-fuzz-seed", "Deterministic directive fuzz seed") orelse 15_781_766_438_473_941_791;
run_directive_fuzz.addArgs(&.{ b.fmt("{d}", .{directive_fuzz_iterations}), b.fmt("{d}", .{directive_fuzz_seed}) });
const directive_fuzz_step = b.step("fuzz-directives", "Run deterministic typed directive fuzz cases");
directive_fuzz_step.dependOn(&run_directive_fuzz.step);
const body_fuzz_module = b.createModule(.{
.root_source_file = b.path("tools/body_fuzz.zig"),
.target = target,
.optimize = optimize,
});
body_fuzz_module.addImport("waf", waf);
const body_fuzz = b.addExecutable(.{
.name = "body-fuzz",
.root_module = body_fuzz_module,
});
const run_body_fuzz = b.addRunArtifact(body_fuzz);
const body_fuzz_iterations = b.option(usize, "body-fuzz-iterations", "Deterministic body-processor fuzz case count") orelse 5_000;
const body_fuzz_seed = b.option(u64, "body-fuzz-seed", "Deterministic body-processor fuzz seed") orelse 9_151_314_442_816_847_872;
run_body_fuzz.addArgs(&.{ b.fmt("{d}", .{body_fuzz_iterations}), b.fmt("{d}", .{body_fuzz_seed}) });
const body_fuzz_step = b.step("fuzz-bodies", "Run deterministic request-body processor fuzz cases");
body_fuzz_step.dependOn(&run_body_fuzz.step);
// Request-path release gate (#40): throughput, tail latency, and peak RSS.
const request_path_module = b.createModule(.{
.root_source_file = b.path("benchmarks/request_path.zig"),
.target = target,
.optimize = optimize,
});
request_path_module.addImport("waf", waf);
const request_path_gate = b.addExecutable(.{
.name = "request-path-gate",
.root_module = request_path_module,
});
const run_request_path_gate = b.addRunArtifact(request_path_gate);
const gate_iterations = b.option(usize, "gate-iterations", "Request-path gate iteration count") orelse 20_000;
// Zero disables a threshold, so the same binary measures and enforces.
const gate_p99 = b.option(u64, "gate-max-p99-ns", "Fail when p99 request latency exceeds this") orelse 0;
const gate_throughput = b.option(u64, "gate-min-throughput", "Fail when throughput falls below this (requests/second)") orelse 0;
const gate_rss = b.option(u64, "gate-max-rss-bytes", "Fail when peak RSS exceeds this") orelse 0;
run_request_path_gate.addArgs(&.{
b.fmt("{d}", .{gate_iterations}),
b.fmt("{d}", .{gate_p99}),
b.fmt("{d}", .{gate_throughput}),
b.fmt("{d}", .{gate_rss}),
});
const gate_step = b.step("gate-request-path", "Enforce request-path throughput, p99, and RSS thresholds");
gate_step.dependOn(&run_request_path_gate.step);
const matrix_module = b.createModule(.{
.root_source_file = b.path("tools/matrix.zig"),
.target = target,
.optimize = optimize,
});
matrix_module.addImport("waf", waf);
const matrix_tool = b.addExecutable(.{ .name = "matrix", .root_module = matrix_module });
const run_matrix = b.addRunArtifact(matrix_tool);
const matrix_step = b.step("matrix", "Emit the per-item compatibility matrix from the engine registries");
matrix_step.dependOn(&run_matrix.step);
const sbom_module = b.createModule(.{
.root_source_file = b.path("tools/sbom.zig"),
.target = target,
.optimize = optimize,
});
const sbom_tool = b.addExecutable(.{ .name = "sbom", .root_module = sbom_module });
const run_sbom = b.addRunArtifact(sbom_tool);
run_sbom.addArgs(&.{ "build.zig.zon", "pantry.lock" });
// The timestamp is an input, not the clock: an SBOM that changes on every run
// cannot be compared between builds, which is the property it exists to support.
if (b.option([]const u8, "sbom-timestamp", "ISO-8601 timestamp recorded in the SBOM")) |stamp|
run_sbom.addArg(stamp);
const sbom_step = b.step("sbom", "Generate a CycloneDX SBOM from the pinned manifests");
sbom_step.dependOn(&run_sbom.step);
const audit_fuzz_module = b.createModule(.{
.root_source_file = b.path("tools/audit_fuzz.zig"),
.target = target,
.optimize = optimize,
});
audit_fuzz_module.addImport("waf", waf);
const audit_fuzz = b.addExecutable(.{
.name = "audit-fuzz",
.root_module = audit_fuzz_module,
});
const run_audit_fuzz = b.addRunArtifact(audit_fuzz);
const audit_fuzz_iterations = b.option(usize, "audit-fuzz-iterations", "Deterministic audit-serialization fuzz case count") orelse 5_000;
const audit_fuzz_seed = b.option(u64, "audit-fuzz-seed", "Deterministic audit-serialization fuzz seed") orelse 7_043_215_681_320_074_321;
run_audit_fuzz.addArgs(&.{ b.fmt("{d}", .{audit_fuzz_iterations}), b.fmt("{d}", .{audit_fuzz_seed}) });
const audit_fuzz_step = b.step("fuzz-audit", "Run deterministic audit-serialization fuzz cases");
audit_fuzz_step.dependOn(&run_audit_fuzz.step);
const action_fuzz_module = b.createModule(.{
.root_source_file = b.path("tools/action_fuzz.zig"),
.target = target,
.optimize = optimize,
});
action_fuzz_module.addImport("waf", waf);
const action_fuzz = b.addExecutable(.{
.name = "action-fuzz",
.root_module = action_fuzz_module,
});
const run_action_fuzz = b.addRunArtifact(action_fuzz);
const action_fuzz_iterations = b.option(usize, "action-fuzz-iterations", "Deterministic action runtime fuzz case count") orelse 10_000;
const action_fuzz_seed = b.option(u64, "action-fuzz-seed", "Deterministic action runtime fuzz seed") orelse 13_907_095_936_298_285_211;
run_action_fuzz.addArgs(&.{ b.fmt("{d}", .{action_fuzz_iterations}), b.fmt("{d}", .{action_fuzz_seed}) });
const action_fuzz_step = b.step("fuzz-actions", "Run deterministic SecLang action runtime fuzz cases");
action_fuzz_step.dependOn(&run_action_fuzz.step);
const transformation_fuzz_module = b.createModule(.{
.root_source_file = b.path("tools/transformation_fuzz.zig"),
.target = target,
.optimize = optimize,
});
transformation_fuzz_module.addImport("waf", waf);
const transformation_fuzz = b.addExecutable(.{
.name = "transformation-fuzz",
.root_module = transformation_fuzz_module,
});
const run_transformation_fuzz = b.addRunArtifact(transformation_fuzz);
const transformation_fuzz_iterations = b.option(usize, "transformation-fuzz-iterations", "Deterministic transformation fuzz case count") orelse 10_000;
const transformation_fuzz_seed = b.option(u64, "transformation-fuzz-seed", "Deterministic transformation fuzz seed") orelse 16_045_690_984_503_098_046;
run_transformation_fuzz.addArgs(&.{ b.fmt("{d}", .{transformation_fuzz_iterations}), b.fmt("{d}", .{transformation_fuzz_seed}) });
const transformation_fuzz_step = b.step("fuzz-transformations", "Run deterministic transformation and pipeline fuzz cases");
transformation_fuzz_step.dependOn(&run_transformation_fuzz.step);
const operator_fuzz_module = b.createModule(.{
.root_source_file = b.path("tools/operator_fuzz.zig"),
.target = target,
.optimize = optimize,
});
operator_fuzz_module.addImport("waf", waf);
const operator_fuzz = b.addExecutable(.{
.name = "operator-fuzz",
.root_module = operator_fuzz_module,
});
const run_operator_fuzz = b.addRunArtifact(operator_fuzz);
const operator_fuzz_iterations = b.option(usize, "operator-fuzz-iterations", "Deterministic operator fuzz case count") orelse 10_000;
const operator_fuzz_seed = b.option(u64, "operator-fuzz-seed", "Deterministic operator fuzz seed") orelse 11_400_714_819_323_198_485;
run_operator_fuzz.addArgs(&.{ b.fmt("{d}", .{operator_fuzz_iterations}), b.fmt("{d}", .{operator_fuzz_seed}) });
const operator_fuzz_step = b.step("fuzz-operators", "Run deterministic scalar and regex operator fuzz cases");
operator_fuzz_step.dependOn(&run_operator_fuzz.step);
const ownership_benchmark_module = b.createModule(.{
.root_source_file = b.path("benchmarks/ownership.zig"),
.target = target,
.optimize = optimize,
});
ownership_benchmark_module.addImport("waf", waf);
const ownership_benchmark = b.addExecutable(.{
.name = "ownership-benchmark",
.root_module = ownership_benchmark_module,
});
const run_ownership_benchmark = b.addRunArtifact(ownership_benchmark);
const benchmark_step = b.step("bench-ownership", "Benchmark transaction ownership and generation pinning");
benchmark_step.dependOn(&run_ownership_benchmark.step);
const lifecycle_benchmark_module = b.createModule(.{
.root_source_file = b.path("benchmarks/lifecycle.zig"),
.target = target,
.optimize = optimize,
});
lifecycle_benchmark_module.addImport("waf", waf);
const lifecycle_benchmark = b.addExecutable(.{
.name = "lifecycle-benchmark",
.root_module = lifecycle_benchmark_module,
});
const run_lifecycle_benchmark = b.addRunArtifact(lifecycle_benchmark);
const lifecycle_benchmark_step = b.step("bench-lifecycle", "Benchmark the complete connector lifecycle");
lifecycle_benchmark_step.dependOn(&run_lifecycle_benchmark.step);
const scalar_benchmark_module = b.createModule(.{
.root_source_file = b.path("benchmarks/scalars.zig"),
.target = target,
.optimize = optimize,
});
scalar_benchmark_module.addImport("waf", waf);
const scalar_benchmark = b.addExecutable(.{
.name = "scalar-benchmark",
.root_module = scalar_benchmark_module,
});
const run_scalar_benchmark = b.addRunArtifact(scalar_benchmark);
const scalar_benchmark_step = b.step("bench-scalars", "Benchmark populated scalar transaction state");
scalar_benchmark_step.dependOn(&run_scalar_benchmark.step);
const collection_benchmark_module = b.createModule(.{
.root_source_file = b.path("benchmarks/collections.zig"),
.target = target,
.optimize = optimize,
});
collection_benchmark_module.addImport("waf", waf);
const collection_benchmark = b.addExecutable(.{
.name = "collection-benchmark",
.root_module = collection_benchmark_module,
});
const run_collection_benchmark = b.addRunArtifact(collection_benchmark);
const collection_benchmark_step = b.step("bench-collections", "Benchmark collection targets and runtime macros");
collection_benchmark_step.dependOn(&run_collection_benchmark.step);
const persistence_benchmark_module = b.createModule(.{
.root_source_file = b.path("benchmarks/persistence.zig"),
.target = target,
.optimize = optimize,
});
persistence_benchmark_module.addImport("waf", waf);
const persistence_benchmark = b.addExecutable(.{
.name = "persistence-benchmark",
.root_module = persistence_benchmark_module,
});
const run_persistence_benchmark = b.addRunArtifact(persistence_benchmark);
const persistence_benchmark_step = b.step("bench-persistence", "Benchmark disabled and initialized persistent collection paths");
persistence_benchmark_step.dependOn(&run_persistence_benchmark.step);
const action_benchmark_module = b.createModule(.{
.root_source_file = b.path("benchmarks/actions.zig"),
.target = target,
.optimize = optimize,
});
action_benchmark_module.addImport("waf", waf);
const action_benchmark = b.addExecutable(.{
.name = "action-benchmark",
.root_module = action_benchmark_module,
});
const run_action_benchmark = b.addRunArtifact(action_benchmark);
const action_benchmark_step = b.step("bench-actions", "Benchmark bounded non-disruptive action application");
action_benchmark_step.dependOn(&run_action_benchmark.step);
const parser_benchmark_module = b.createModule(.{
.root_source_file = b.path("benchmarks/parser.zig"),
.target = target,
.optimize = optimize,
});
parser_benchmark_module.addImport("waf", waf);
const parser_benchmark = b.addExecutable(.{
.name = "parser-benchmark",
.root_module = parser_benchmark_module,
});
const run_parser_benchmark = b.addRunArtifact(parser_benchmark);
if (b.option([]const u8, "parser-benchmark", "Optional SecLang file for the parser benchmark")) |benchmark_path|
run_parser_benchmark.addArg(benchmark_path);
const parser_benchmark_step = b.step("bench-parser", "Benchmark SecLang parsing throughput and ownership");
parser_benchmark_step.dependOn(&run_parser_benchmark.step);
const plan_benchmark_module = b.createModule(.{
.root_source_file = b.path("benchmarks/plan.zig"),
.target = target,
.optimize = optimize,
});
plan_benchmark_module.addImport("waf", waf);
const plan_benchmark = b.addExecutable(.{
.name = "plan-benchmark",
.root_module = plan_benchmark_module,
});
const run_plan_benchmark = b.addRunArtifact(plan_benchmark);
if (b.option([]const u8, "plan-benchmark", "Optional SecLang file for the plan benchmark")) |benchmark_path|
run_plan_benchmark.addArg(benchmark_path);
const plan_benchmark_step = b.step("bench-plan", "Benchmark structural plan compilation, traversal, reuse, and publication");
plan_benchmark_step.dependOn(&run_plan_benchmark.step);
const directive_benchmark_module = b.createModule(.{
.root_source_file = b.path("benchmarks/directives.zig"),
.target = target,
.optimize = optimize,
});
directive_benchmark_module.addImport("waf", waf);
const directive_benchmark = b.addExecutable(.{
.name = "directive-benchmark",
.root_module = directive_benchmark_module,
});
const run_directive_benchmark = b.addRunArtifact(directive_benchmark);
if (b.option([]const u8, "directive-benchmark", "Optional SecLang file for the directive benchmark")) |benchmark_path|
run_directive_benchmark.addArg(benchmark_path);
const directive_benchmark_step = b.step("bench-directives", "Benchmark validation and typed configuration throughput");
directive_benchmark_step.dependOn(&run_directive_benchmark.step);
const transformation_benchmark_module = b.createModule(.{
.root_source_file = b.path("benchmarks/transformations.zig"),
.target = target,
.optimize = optimize,
});
transformation_benchmark_module.addImport("waf", waf);
const transformation_benchmark = b.addExecutable(.{
.name = "transformation-benchmark",
.root_module = transformation_benchmark_module,
});
const run_transformation_benchmark = b.addRunArtifact(transformation_benchmark);
const transformation_benchmark_step = b.step("bench-transformations", "Benchmark borrowed steps, decoder pipelines, digests, multiMatch, and cache behavior");
transformation_benchmark_step.dependOn(&run_transformation_benchmark.step);
const operator_benchmark_module = b.createModule(.{
.root_source_file = b.path("benchmarks/operators.zig"),
.target = target,
.optimize = optimize,
});
operator_benchmark_module.addImport("waf", waf);
const operator_benchmark = b.addExecutable(.{
.name = "operator-benchmark",
.root_module = operator_benchmark_module,
});
const run_operator_benchmark = b.addRunArtifact(operator_benchmark);
const operator_benchmark_step = b.step("bench-operators", "Benchmark scalar comparison, regex match/capture, rxGlobal, and memoized operators");
operator_benchmark_step.dependOn(&run_operator_benchmark.step);
const request_benchmark_module = b.createModule(.{
.root_source_file = b.path("benchmarks/request.zig"),
.target = target,
.optimize = optimize,
});
request_benchmark_module.addImport("waf", waf);
const request_benchmark = b.addExecutable(.{
.name = "request-benchmark",
.root_module = request_benchmark_module,
});
const run_request_benchmark = b.addRunArtifact(request_benchmark);
const request_benchmark_step = b.step("bench-request", "Benchmark query-string and cookie parsing throughput");
request_benchmark_step.dependOn(&run_request_benchmark.step);
// Compile every corpus, inventory, fuzz, and benchmark executable under
// `zig build check` so an API change that breaks a tool or benchmark fails
// locally instead of only in the hosted corpus and benchmark steps.
for ([_]*std.Build.Step.Compile{
parser_corpus,
directive_inventory,
transformation_inventory,
crs_configuration,
parser_fuzz,
plan_fuzz,
action_fuzz,
transformation_fuzz,
operator_fuzz,
ownership_benchmark,
lifecycle_benchmark,
scalar_benchmark,
collection_benchmark,
persistence_benchmark,
action_benchmark,
parser_benchmark,
plan_benchmark,
directive_benchmark,
transformation_benchmark,
operator_benchmark,
request_benchmark,
}) |artifact| check_step.dependOn(&artifact.step);
}