master
1const std = @import("std");
2const builtin = @import("builtin");
3
4pub fn build(b: *std.Build) !void {
5 const test_step = b.step("test", "Test it");
6 b.default_step = test_step;
7
8 if (builtin.os.tag != .windows) return;
9
10 const optimize: std.builtin.OptimizeMode = .Debug;
11
12 const lib_gnu = b.addLibrary(.{
13 .linkage = .static,
14 .name = "toargv-gnu",
15 .root_module = b.createModule(.{
16 .root_source_file = b.path("lib.zig"),
17 .target = b.resolveTargetQuery(.{
18 .abi = .gnu,
19 }),
20 .optimize = optimize,
21 }),
22 });
23 const verify_gnu = b.addExecutable(.{
24 .name = "verify-gnu",
25 .root_module = b.createModule(.{
26 .root_source_file = null,
27 .target = b.resolveTargetQuery(.{
28 .abi = .gnu,
29 }),
30 .optimize = optimize,
31 }),
32 });
33 verify_gnu.root_module.addCSourceFile(.{
34 .file = b.path("verify.c"),
35 .flags = &.{ "-DUNICODE", "-D_UNICODE" },
36 });
37 verify_gnu.mingw_unicode_entry_point = true;
38 verify_gnu.root_module.linkLibrary(lib_gnu);
39 verify_gnu.root_module.link_libc = true;
40
41 const fuzz = b.addExecutable(.{
42 .name = "fuzz",
43 .root_module = b.createModule(.{
44 .root_source_file = b.path("fuzz.zig"),
45 .target = b.graph.host,
46 .optimize = optimize,
47 }),
48 });
49
50 const fuzz_max_iterations = b.option(u64, "iterations", "The max fuzz iterations (default: 100)") orelse 100;
51 const fuzz_iterations_arg = std.fmt.allocPrint(b.allocator, "{}", .{fuzz_max_iterations}) catch @panic("oom");
52
53 const fuzz_seed = b.option(u64, "seed", "Seed to use for the PRNG (default: random)") orelse seed: {
54 var buf: [8]u8 = undefined;
55 try std.posix.getrandom(&buf);
56 break :seed std.mem.readInt(u64, &buf, builtin.cpu.arch.endian());
57 };
58 const fuzz_seed_arg = std.fmt.allocPrint(b.allocator, "{}", .{fuzz_seed}) catch @panic("oom");
59
60 const run_gnu = b.addRunArtifact(fuzz);
61 run_gnu.setName("fuzz-gnu");
62 run_gnu.addArtifactArg(verify_gnu);
63 run_gnu.addArgs(&.{ fuzz_iterations_arg, fuzz_seed_arg });
64 run_gnu.expectExitCode(0);
65
66 test_step.dependOn(&run_gnu.step);
67
68 // Only target the MSVC ABI if MSVC/Windows SDK is available
69 const has_msvc = has_msvc: {
70 const sdk = std.zig.WindowsSdk.find(b.allocator, builtin.cpu.arch) catch |err| switch (err) {
71 error.OutOfMemory => @panic("oom"),
72 else => break :has_msvc false,
73 };
74 defer sdk.free(b.allocator);
75 break :has_msvc true;
76 };
77 if (has_msvc) {
78 const lib_msvc = b.addLibrary(.{
79 .linkage = .static,
80 .name = "toargv-msvc",
81 .root_module = b.createModule(.{
82 .root_source_file = b.path("lib.zig"),
83 .target = b.resolveTargetQuery(.{
84 .abi = .msvc,
85 }),
86 .optimize = optimize,
87 }),
88 });
89 const verify_msvc = b.addExecutable(.{
90 .name = "verify-msvc",
91 .root_module = b.createModule(.{
92 .root_source_file = null,
93 .target = b.resolveTargetQuery(.{
94 .abi = .msvc,
95 }),
96 .optimize = optimize,
97 }),
98 });
99 verify_msvc.root_module.addCSourceFile(.{
100 .file = b.path("verify.c"),
101 .flags = &.{ "-DUNICODE", "-D_UNICODE" },
102 });
103 verify_msvc.root_module.linkLibrary(lib_msvc);
104 verify_msvc.root_module.link_libc = true;
105
106 const run_msvc = b.addRunArtifact(fuzz);
107 run_msvc.setName("fuzz-msvc");
108 run_msvc.addArtifactArg(verify_msvc);
109 run_msvc.addArgs(&.{ fuzz_iterations_arg, fuzz_seed_arg });
110 run_msvc.expectExitCode(0);
111
112 test_step.dependOn(&run_msvc.step);
113 }
114}