1const std = @import("std");
2const builtin = @import("builtin");
3
4pub fn build(b: *std.Build) void {
5 const step = b.step("test", "Run standalone test cases");
6 b.default_step = step;
7
8 const enable_ios_sdk = b.option(bool, "enable_ios_sdk", "Run tests requiring presence of iOS SDK and frameworks") orelse false;
9 const enable_macos_sdk = b.option(bool, "enable_macos_sdk", "Run tests requiring presence of macOS SDK and frameworks") orelse enable_ios_sdk;
10 const enable_symlinks_windows = b.option(bool, "enable_symlinks_windows", "Run tests requiring presence of symlinks on Windows") orelse false;
11 const omit_symlinks = builtin.os.tag == .windows and !enable_symlinks_windows;
12
13 const simple_skip_debug = b.option(bool, "simple_skip_debug", "Simple tests skip debug builds") orelse false;
14 const simple_skip_release_safe = b.option(bool, "simple_skip_release_safe", "Simple tests skip release-safe builds") orelse false;
15 const simple_skip_release_fast = b.option(bool, "simple_skip_release_fast", "Simple tests skip release-fast builds") orelse false;
16 const simple_skip_release_small = b.option(bool, "simple_skip_release_small", "Simple tests skip release-small builds") orelse false;
17
18 const simple_dep = b.dependency("simple", .{
19 .skip_debug = simple_skip_debug,
20 .skip_release_safe = simple_skip_release_safe,
21 .skip_release_fast = simple_skip_release_fast,
22 .skip_release_small = simple_skip_release_small,
23 });
24 const simple_dep_step = simple_dep.builder.default_step;
25 simple_dep_step.name = "standalone_test_cases.simple";
26 step.dependOn(simple_dep_step);
27
28 // Ensure the development tools are buildable.
29 const tools_tests_step = b.step("standalone_test_cases.tools", "Test tools");
30 step.dependOn(tools_tests_step);
31 const tools_target = b.resolveTargetQuery(.{});
32 for ([_][]const u8{
33 // Alphabetically sorted. No need to build `tools/spirv/grammar.zig`.
34 "../../tools/bsp.zig",
35 "../../tools/check_mingw.zig",
36 "../../tools/dump-cov.zig",
37 "../../tools/fetch_them_macos_headers.zig",
38 "../../tools/gen_macos_headers_c.zig",
39 "../../tools/gen_outline_atomics.zig",
40 "../../tools/gen_parser_oracle.zig",
41 "../../tools/gen_spirv_spec.zig",
42 "../../tools/gen_stubs.zig",
43 "../../tools/generate_JSONTestSuite.zig",
44 "../../tools/generate_linux_syscalls.zig",
45 "../../tools/process_headers.zig",
46 "../../tools/migrate_langref.zig",
47 "../../tools/update-linux-headers.zig",
48 "../../tools/update_clang_options.zig",
49 "../../tools/update_cpu_features.zig",
50 "../../tools/update_crc_catalog.zig",
51 "../../tools/update_freebsd_libc.zig",
52 "../../tools/update_glibc.zig",
53 "../../tools/update_mingw.zig",
54 "../../tools/update_netbsd_libc.zig",
55 "../../tools/update_openbsd_libc.zig",
56 }) |tool_src_path| {
57 if (std.mem.endsWith(u8, tool_src_path, "dump-cov.zig") and tools_target.result.os.tag == .windows) continue;
58
59 const tool = b.addExecutable(.{
60 .name = std.fs.path.stem(tool_src_path),
61 .root_module = b.createModule(.{
62 .root_source_file = b.path(tool_src_path),
63 .target = tools_target,
64 }),
65 });
66 if (std.mem.endsWith(u8, tool_src_path, "check_mingw.zig")) {
67 const mingw_preprocessor_mod = b.createModule(.{
68 .root_source_file = b.path("../../src/libs/mingw/Preprocessor.zig"),
69 .target = tools_target,
70 });
71 tool.root_module.addImport("preprocessor", mingw_preprocessor_mod);
72 }
73 if (std.mem.endsWith(u8, tool_src_path, "update_cpu_features.zig")) {
74 const spirv_spec = b.createModule(.{
75 .root_source_file = b.path("../../src/codegen/spirv/spec.zig"),
76 .target = tools_target,
77 });
78 tool.root_module.addImport("spirv_spec", spirv_spec);
79 }
80
81 tools_tests_step.dependOn(&tool.step);
82 }
83 for ([_][]const u8{
84 // Alphabetically sorted. Only ones with `test` blocks.
85 "../../tools/doctest.zig",
86 }) |tool_src_path| {
87 const tool = b.addTest(.{
88 .name = std.fs.path.stem(tool_src_path),
89 .root_module = b.createModule(.{
90 .root_source_file = b.path(tool_src_path),
91 .target = tools_target,
92 }),
93 });
94 const run = b.addRunArtifact(tool);
95 tools_tests_step.dependOn(&run.step);
96 }
97
98 add_dep_steps: for (b.available_deps) |available_dep| {
99 const dep_name, const dep_hash = available_dep;
100
101 // The 'simple' dependency was already handled manually above.
102 if (std.mem.eql(u8, dep_name, "simple")) continue;
103
104 const all_pkgs = @import("root").dependencies.packages;
105 inline for (@typeInfo(all_pkgs).@"struct".decl_names) |pkg_hash| {
106 if (std.mem.eql(u8, dep_hash, pkg_hash)) {
107 const pkg = @field(all_pkgs, pkg_hash);
108 if (!@hasDecl(pkg, "build_zig")) {
109 std.debug.panic("standalone test case '{s}' is missing a 'build.zig' file", .{dep_name});
110 }
111 const requires_ios_sdk = @hasDecl(pkg.build_zig, "requires_ios_sdk") and
112 pkg.build_zig.requires_ios_sdk;
113 const requires_macos_sdk = @hasDecl(pkg.build_zig, "requires_macos_sdk") and
114 pkg.build_zig.requires_macos_sdk;
115 const requires_symlinks = @hasDecl(pkg.build_zig, "requires_symlinks") and
116 pkg.build_zig.requires_symlinks;
117 if ((requires_symlinks and omit_symlinks) or
118 (requires_macos_sdk and !enable_macos_sdk) or
119 (requires_ios_sdk and !enable_ios_sdk))
120 {
121 continue :add_dep_steps;
122 }
123 break;
124 }
125 } else unreachable;
126
127 const dep = b.dependency(dep_name, .{});
128 const dep_step = dep.builder.default_step;
129 dep_step.name = b.fmt("standalone_test_cases.{s}", .{dep_name});
130 step.dependOn(dep_step);
131 }
132}