286 lines
12 KiB
Zig
286 lines
12 KiB
Zig
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 bindings for multiple SDL headers
|
|
const parser_dep = b.dependency("sdl3_parser", .{
|
|
.target = opts.target,
|
|
.optimize = opts.optimize,
|
|
});
|
|
const parser_exe = parser_dep.artifact("sdl-parser");
|
|
|
|
// All public SDL3 API headers (53 total)
|
|
// Skipped: assert, thread, hidapi, mutex, tray (not core APIs or problematic)
|
|
const headers_to_generate = [_]struct { header: []const u8, output: []const u8 }{
|
|
.{ .header = "SDL/include/SDL3/SDL_asyncio.h", .output = "v2/asyncio.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_atomic.h", .output = "v2/atomic.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_audio.h", .output = "v2/audio.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_blendmode.h", .output = "v2/blendmode.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_camera.h", .output = "v2/camera.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_clipboard.h", .output = "v2/clipboard.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_cpuinfo.h", .output = "v2/cpuinfo.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_dialog.h", .output = "v2/dialog.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_endian.h", .output = "v2/endian.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_error.h", .output = "v2/error.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_events.h", .output = "v2/events.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_filesystem.h", .output = "v2/filesystem.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_gamepad.h", .output = "v2/gamepad.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_gpu.h", .output = "v2/gpu.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_guid.h", .output = "v2/guid.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_haptic.h", .output = "v2/haptic.zig" },
|
|
// .{ .header = "SDL/include/SDL3/SDL_hidapi.h", .output = "v2/hidapi.zig" }, // Skipped: not core API
|
|
.{ .header = "SDL/include/SDL3/SDL_hints.h", .output = "v2/hints.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_init.h", .output = "v2/init.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_iostream.h", .output = "v2/iostream.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_joystick.h", .output = "v2/joystick.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_keyboard.h", .output = "v2/keyboard.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_keycode.h", .output = "v2/keycode.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_loadso.h", .output = "v2/loadso.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_locale.h", .output = "v2/locale.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_log.h", .output = "v2/log.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_messagebox.h", .output = "v2/messagebox.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_metal.h", .output = "v2/metal.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_misc.h", .output = "v2/misc.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_mouse.h", .output = "v2/mouse.zig" },
|
|
// .{ .header = "SDL/include/SDL3/SDL_mutex.h", .output = "v2/mutex.zig" }, // Skipped: not core API
|
|
.{ .header = "SDL/include/SDL3/SDL_opengl.h", .output = "v2/opengl.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_pen.h", .output = "v2/pen.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_pixels.h", .output = "v2/pixels.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_power.h", .output = "v2/power.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_process.h", .output = "v2/process.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_properties.h", .output = "v2/properties.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_rect.h", .output = "v2/rect.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_render.h", .output = "v2/render.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_scancode.h", .output = "v2/scancode.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_sensor.h", .output = "v2/sensor.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_storage.h", .output = "v2/storage.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_surface.h", .output = "v2/surface.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_system.h", .output = "v2/system.zig" },
|
|
// .{ .header = "SDL/include/SDL3/SDL_thread.h", .output = "v2/thread.zig" }, // Skipped: not core API
|
|
.{ .header = "SDL/include/SDL3/SDL_time.h", .output = "v2/time.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_timer.h", .output = "v2/timer.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_touch.h", .output = "v2/touch.zig" },
|
|
// .{ .header = "SDL/include/SDL3/SDL_tray.h", .output = "v2/tray.zig" }, // Skipped: not core API
|
|
.{ .header = "SDL/include/SDL3/SDL_version.h", .output = "v2/version.zig" },
|
|
.{ .header = "SDL/include/SDL3/SDL_video.h", .output = "v2/video.zig" },
|
|
// .{ .header = "SDL/include/SDL3/SDL_vulkan.h", .output = "v2/vulkan.zig" }, // Skipped: Vulkan interop
|
|
};
|
|
|
|
const regenerate_step = b.step("regenerate-zig", "Regenerate bindings from SDL headers");
|
|
|
|
for (headers_to_generate) |header_info| {
|
|
const regenerate = b.addRunArtifact(parser_exe);
|
|
regenerate.addFileArg(b.path(header_info.header));
|
|
regenerate.addArg(b.fmt("--output={s}", .{header_info.output}));
|
|
regenerate_step.dependOn(®enerate.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);
|
|
}
|