master
1b: *std.Build,
2options: Options,
3root_step: *std.Build.Step,
4
5libc_test_src_path: std.Build.LazyPath,
6
7test_cases: std.ArrayList(TestCase) = .empty,
8
9pub const Options = struct {
10 optimize_modes: []const std.builtin.OptimizeMode,
11 test_filters: []const []const u8,
12 test_target_filters: []const []const u8,
13 max_rss: usize,
14};
15
16const TestCase = struct {
17 name: []const u8,
18 src_file: std.Build.LazyPath,
19 additional_src_file: ?std.Build.LazyPath,
20 supports_wasi_libc: bool,
21};
22
23pub const LibcTestCaseOption = struct {
24 additional_src_file: ?[]const u8 = null,
25};
26
27pub fn addLibcTestCase(
28 libc: *Libc,
29 path: []const u8,
30 supports_wasi_libc: bool,
31 options: LibcTestCaseOption,
32) void {
33 const name = libc.b.dupe(path[0 .. path.len - std.fs.path.extension(path).len]);
34 std.mem.replaceScalar(u8, name, '/', '.');
35 libc.test_cases.append(libc.b.allocator, .{
36 .name = name,
37 .src_file = libc.libc_test_src_path.path(libc.b, path),
38 .additional_src_file = if (options.additional_src_file) |additional_src_file| libc.libc_test_src_path.path(libc.b, additional_src_file) else null,
39 .supports_wasi_libc = supports_wasi_libc,
40 }) catch @panic("OOM");
41}
42
43pub fn addTarget(libc: *const Libc, target: std.Build.ResolvedTarget) void {
44 if (libc.options.test_target_filters.len > 0) {
45 const triple_txt = target.query.zigTriple(libc.b.allocator) catch @panic("OOM");
46 for (libc.options.test_target_filters) |filter| {
47 if (std.mem.indexOf(u8, triple_txt, filter)) |_| break;
48 } else return;
49 }
50
51 const common = libc.libc_test_src_path.path(libc.b, "common");
52
53 for (libc.options.optimize_modes) |optimize| {
54 const libtest_mod = libc.b.createModule(.{
55 .target = target,
56 .optimize = optimize,
57 .link_libc = true,
58 });
59
60 var libtest_c_source_files: []const []const u8 = &.{ "print.c", "rand.c", "setrlim.c", "memfill.c", "vmfill.c", "fdfill.c", "utf8.c" };
61 libtest_mod.addCSourceFiles(.{
62 .root = common,
63 .files = libtest_c_source_files[0..if (target.result.isMuslLibC()) 7 else 2],
64 .flags = &.{"-fno-builtin"},
65 });
66
67 const libtest = libc.b.addLibrary(.{
68 .name = "test",
69 .root_module = libtest_mod,
70 });
71
72 for (libc.test_cases.items) |*test_case| {
73 if (target.result.isWasiLibC() and !test_case.supports_wasi_libc)
74 continue;
75
76 const annotated_case_name = libc.b.fmt("run libc-test {s} ({t})", .{ test_case.name, optimize });
77 for (libc.options.test_filters) |test_filter| {
78 if (std.mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
79 } else if (libc.options.test_filters.len > 0) continue;
80
81 const mod = libc.b.createModule(.{
82 .target = target,
83 .optimize = optimize,
84 .link_libc = true,
85 });
86 mod.addIncludePath(common);
87 if (target.result.isWasiLibC())
88 mod.addCMacro("_WASI_EMULATED_SIGNAL", "");
89 mod.addCSourceFile(.{
90 .file = test_case.src_file,
91 .flags = &.{"-fno-builtin"},
92 });
93 if (test_case.additional_src_file) |additional_src_file| {
94 mod.addCSourceFile(.{
95 .file = additional_src_file,
96 .flags = &.{"-fno-builtin"},
97 });
98 }
99 mod.linkLibrary(libtest);
100
101 const exe = libc.b.addExecutable(.{
102 .name = test_case.name,
103 .root_module = mod,
104 .max_rss = libc.options.max_rss,
105 });
106
107 const run = libc.b.addRunArtifact(exe);
108 run.setName(annotated_case_name);
109 run.skip_foreign_checks = true;
110 run.expectStdErrEqual("");
111 run.expectStdOutEqual("");
112 run.expectExitCode(0);
113 run.step.max_rss = libc.options.max_rss;
114
115 libc.root_step.dependOn(&run.step);
116 }
117 }
118}
119
120const Libc = @This();
121const std = @import("std");