const std = @import("std"); const bh = @import("bh"); pub fn addShaderDefinition( b: *std.Build, comptime sdl3Path: []const u8, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, shaderName: []const u8, jsonPath: std.Build.LazyPath, ) *std.Build.Module { // Create the spvReflect2 executable const spvReflect = b.addExecutable(.{ .name = "spvReflect2", .root_module = b.createModule(.{ .target = b.graph.host, .optimize = optimize, .root_source_file = b.path(sdl3Path ++ "/spvreflect/spvReflect2.zig"), }), }); // Run the spvReflect2 executable const runReflect = b.addRunArtifact(spvReflect); runReflect.addFileArg(jsonPath); const reflectedZigOut = runReflect.addOutputFileArg(b.fmt("reflected/{s}.zig", .{shaderName})); const module = b.createModule(.{ .root_source_file = reflectedZigOut, .optimize = optimize }); const dep = b.dependency("shaderTypes", .{ .target = target, .optimize = optimize, }); module.addImport("shaderTypes", dep.module("shaderTypes")); return module; } pub fn shaderDefintion( b: *std.Build, module: *std.Build.Module, comptime sdl3Path: []const u8, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, shaderName: []const u8, jsonPath: std.Build.LazyPath, ) void { const mod = addShaderDefinition(b, sdl3Path, target, optimize, shaderName, jsonPath); module.addImport(shaderName, mod); } pub fn build(b: *std.Build) void { const opts = bh.declareOptions(b); const preferred_linkage: std.builtin.LinkMode = if (opts.static_build) .static else .dynamic; const sdl_dep = b.dependency("sdl", .{ .target = opts.target, .optimize = opts.optimize, .preferred_linkage = preferred_linkage, }); const sdl3_lib = sdl_dep.artifact("SDL3"); const sdl3_fwd = b.addModule("SDL3", .{ .target = opts.target, .optimize = opts.optimize, .root_source_file = b.path("src/sdl3_lib_fwd.zig"), }); sdl3_fwd.linkLibrary(sdl3_lib); const mod = b.addModule("sdl3", .{ .target = opts.target, .optimize = opts.optimize, .root_source_file = b.path("src/sdl3.zig"), }); const shaderTypes = b.dependency("shaderTypes", .{ .target = opts.target, .optimize = opts.optimize, }); mod.addImport("shaderTypes", shaderTypes.module("shaderTypes")); mod.addIncludePath(b.path("SDL/include")); mod.linkLibrary(sdl3_lib); const test_step2 = b.step("test", "run unit tests for sdl3"); const tests2 = b.addExecutable(.{ .name = "hello-sdl", .root_module = b.createModule(.{ .target = opts.target, .optimize = opts.optimize, .root_source_file = b.path("src/samples/compiletest.zig"), .link_libc = true, }), }); const test_step = b.step("test-triangle", "run unit tests for sdl3"); const tests = b.addExecutable(.{ .name = "hello-triangle", .root_module = b.createModule(.{ .target = opts.target, .optimize = opts.optimize, .root_source_file = b.path("src/samples/hello-triangle.zig"), .link_libc = true, }), }); const hello_window = b.step("hello-window", "test window"); const hello_window_exe = b.addExecutable(.{ .name = "hello-window", .root_module = b.createModule(.{ .target = opts.target, .optimize = opts.optimize, .root_source_file = b.path("src/samples/hello-window.zig"), .link_libc = true, }), }); hello_window.dependOn(&hello_window_exe.step); hello_window_exe.root_module.addImport("sdl3", mod); tests.root_module.addImport("sdl3", mod); const vertexDefinitions = addShaderDefinition(b, ".", opts.target, opts.optimize, "hello-triangle.vert", b.path("content/hello-triangle.vert.json")); tests.root_module.addImport("hello-triangle.vert", vertexDefinitions); const runArtifact = b.addRunArtifact(tests); test_step.dependOn(&runArtifact.step); const runArtifact2 = b.addRunArtifact(tests2); test_step2.dependOn(&runArtifact2.step); b.installArtifact(hello_window_exe); b.installArtifact(sdl3_lib); b.installArtifact(tests); b.installArtifact(tests2); // Regenerate GPU bindings step const parser_dep = b.dependency("sdl3_parser", .{ .target = opts.target, .optimize = opts.optimize, }); const parser_exe = parser_dep.artifact("sdl-parser"); const regenerate_gpu = b.addRunArtifact(parser_exe); regenerate_gpu.addFileArg(b.path("SDL/include/SDL3/SDL_gpu.h")); regenerate_gpu.addArg("--output=v2/gpu.zig"); const regenerate_step = b.step("regenerate-zig", "Regenerate GPU bindings from SDL_gpu.h"); regenerate_step.dependOn(®enerate_gpu.step); // Regenerate test mocks step - using SDL_gpu.h for comprehensive testing const test_header_path = b.path("SDL/include/SDL3/SDL_gpu.h"); const test_zig_output = b.path("zig-out/gpu_test.zig"); const test_mock_output = b.path("zig-out/gpu_test_mock.c"); const regenerate_test_mocks = b.addRunArtifact(parser_exe); regenerate_test_mocks.addFileArg(test_header_path); regenerate_test_mocks.addArg(b.fmt("--output={s}", .{test_zig_output.getPath(b)})); regenerate_test_mocks.addArg(b.fmt("--mocks={s}", .{test_mock_output.getPath(b)})); const regenerate_test_mocks_step = b.step("regenerate-test-mocks", "Regenerate test bindings and mocks"); regenerate_test_mocks_step.dependOn(®enerate_test_mocks.step); // Compile mocks into a static library const mock_lib = b.addLibrary(.{ .name = "test_mocks", .linkage = .static, .root_module = b.createModule(.{ .target = opts.target, .optimize = opts.optimize, }), }); mock_lib.addCSourceFile(.{ .file = test_mock_output, .flags = &.{"-std=c99"}, }); mock_lib.addIncludePath(b.path("SDL/include")); mock_lib.linkLibC(); mock_lib.step.dependOn(®enerate_test_mocks.step); // Compile-only check for generated bindings (no tests, just verify it compiles) const compile_check = b.addTest(.{ .root_module = b.createModule(.{ .target = opts.target, .optimize = opts.optimize, .root_source_file = b.path("parser/test/mock_test.zig"), }), }); compile_check.linkLibrary(mock_lib); compile_check.step.dependOn(&mock_lib.step); const compile_check_step = b.step("check-mocks", "Compile check for generated mocks (no tests)"); compile_check_step.dependOn(&compile_check.step); // Test executable that uses the generated bindings and mocks const mock_test = b.addTest(.{ .root_module = b.createModule(.{ .target = opts.target, .optimize = opts.optimize, .root_source_file = b.path("parser/test/mock_test.zig"), }), }); mock_test.linkLibrary(mock_lib); mock_test.step.dependOn(&mock_lib.step); const run_mock_test = b.addRunArtifact(mock_test); run_mock_test.step.dependOn(&mock_test.step); const test_mock_step = b.step("test-mocks", "Compile and test generated mocks"); test_mock_step.dependOn(&run_mock_test.step); // Additional test that demonstrates the dependency issue const import_test = b.addTest(.{ .root_module = b.createModule(.{ .target = opts.target, .optimize = opts.optimize, .root_source_file = b.path("parser/test/import_test.zig"), }), }); const run_import_test = b.addRunArtifact(import_test); const import_test_step = b.step("test-import-issue", "Test demonstrating missing dependency types"); import_test_step.dependOn(&run_import_test.step); }