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");