From 7ac69f90ef825e403638c7830b188030191e6566 Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Sun, 28 Apr 2024 22:22:01 +0200 Subject: [PATCH] use a separate build.zig for the example This gives a more concrete example of how to use vulkan-zig, including build commands as how a downstream user would use vulkan-zig. --- build.zig | 112 +++++++++++++---------------------------- examples/build.zig | 50 ++++++++++++++++++ examples/build.zig.zon | 14 ++++++ src/index.zig | 8 --- src/main.zig | 10 ++++ 5 files changed, 108 insertions(+), 86 deletions(-) create mode 100644 examples/build.zig create mode 100644 examples/build.zig.zon delete mode 100644 src/index.zig diff --git a/build.zig b/build.zig index 99e6957..9683228 100644 --- a/build.zig +++ b/build.zig @@ -1,12 +1,14 @@ const std = @import("std"); -const vkgen = @import("src/index.zig"); +const vkgen = @import("src/main.zig"); pub const ShaderCompileStep = vkgen.ShaderCompileStep; +pub const VkGenerateStep = vkgen.VkGenerateStep; pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const vk_xml_path: ?[]const u8 = b.option([]const u8, "registry", "Override the path to the Vulkan registry"); + const maybe_registry: ?[]const u8 = b.option([]const u8, "registry", "Set the path to the Vulkan registry (vk.xml)"); + const test_step = b.step("test", "Run all the tests"); // Using the package manager, this artifact can be obtained by the user // through `b.dependency(, .{}).artifact("vulkan-zig-generator")`. @@ -22,87 +24,41 @@ pub fn build(b: *std.Build) void { // Or they can skip all that, and just make sure to pass `.registry = "path/to/vk.xml"` to `b.dependency`, // and then obtain the module directly via `.module("vulkan-zig")`. - if (vk_xml_path) |path| { - const generate_cmd = b.addRunArtifact(generator_exe); + if (maybe_registry) |registry| { + const vk_generate_cmd = b.addRunArtifact(generator_exe); - if (!std.fs.path.isAbsolute(path)) @panic("Make sure to assign an absolute path to the `registry` option (see: std.Build.pathFromRoot).\n"); - generate_cmd.addArg(path); + if (!std.fs.path.isAbsolute(registry)) { + @panic("Make sure to assign an absolute path to the `registry` option (see: std.Build.pathFromRoot).\n"); + } - _ = b.addModule("vulkan-zig", .{ - .root_source_file = generate_cmd.addOutputFileArg("vk.zig"), + vk_generate_cmd.addArg(registry); + + const vk_zig = vk_generate_cmd.addOutputFileArg("vk.zig"); + const vk_zig_module = b.addModule("vulkan-zig", .{ + .root_source_file = vk_zig, }); + + // Also install vk.zig, if passed. + + const vk_zig_install_step = b.addInstallFile(vk_zig, "src/vk.zig"); + b.getInstallStep().dependOn(&vk_zig_install_step.step); + + // And run tests on this vk.zig too. + + // This test needs to be an object so that vulkan-zig can import types from the root. + // It does not need to run anyway. + const ref_all_decls_test = b.addObject(.{ + .name = "ref-all-decls-test", + .root_source_file = .{ .path = "test/ref_all_decls.zig" }, + .target = target, + .optimize = optimize, + }); + ref_all_decls_test.root_module.addImport("vulkan", vk_zig_module); + test_step.dependOn(&ref_all_decls_test.step); } - // This section shows a crude example of how to build a program using vulkan-zig by - // calling the generator executable directly. - - // First, obtain the path to vk.xml. In this example, we will just get it from the command line. - const example_registry = b.option([]const u8, "example-registry", "Override the path to the Vulkan registry used for the examples") orelse "examples/vk.xml"; - - // Obtain a reference to the generator. In a downstream build.zig, you would use - // `const generator_exe = b.dependency().artifact("vulkan-zig-generator");`. - // Here we are just going to use our own `generator_exe`. - - // Now create a run artifact, and pass the registry to the generator. The generator is normally - // invoked as `vulkan-zig-generator ` - const example_registry_generator_cmd = b.addRunArtifact(generator_exe); - example_registry_generator_cmd.addArg(example_registry); - // Obtain a reference to the generated file. - const example_vk_zig = example_registry_generator_cmd.addOutputFileArg("vk.zig"); - // And turn it into a module. - const example_vk_zig_module = b.addModule("example-vulkan-zig", .{ .root_source_file = example_vk_zig }); - - // Now build a Vulkan program. This is just a simple triangle from the vulkan tutorial. - const triangle_exe = b.addExecutable(.{ - .name = "triangle", - .root_source_file = .{ .path = "examples/triangle.zig" }, - .target = target, - .link_libc = true, - .optimize = optimize, - }); - b.installArtifact(triangle_exe); - triangle_exe.linkSystemLibrary("glfw"); - - // Add our module to the list of imports to make vulkan-zig available. - triangle_exe.root_module.addImport("vulkan", example_vk_zig_module); - - const shaders = ShaderCompileStep.create( - b, - &[_][]const u8{ "glslc", "--target-env=vulkan1.2" }, - "-o", - ); - shaders.add("triangle_vert", "examples/shaders/triangle.vert", .{}); - shaders.add("triangle_frag", "examples/shaders/triangle.frag", .{}); - triangle_exe.root_module.addImport("shaders", shaders.getModule()); - - const triangle_run_cmd = b.addRunArtifact(triangle_exe); - triangle_run_cmd.step.dependOn(b.getInstallStep()); - - const triangle_run_step = b.step("run-triangle", "Run the triangle example"); - triangle_run_step.dependOn(&triangle_run_cmd.step); - - // Remainder is for local testing. - - const example_vk_zig_install_step = b.addInstallFile(example_vk_zig, "src/vk.zig"); - b.getInstallStep().dependOn(&example_vk_zig_install_step.step); - const test_target = b.addTest(.{ - .root_source_file = .{ .path = "src/index.zig" }, + .root_source_file = .{ .path = "src/main.zig" }, }); - - const run_test = b.addRunArtifact(test_target); - - const test_step = b.step("test", "Run all the tests"); - test_step.dependOn(&run_test.step); - - // This test needs to be an object so that vulkan-zig can import types from the root. - // It does not need to run anyway. - const ref_all_decls_test = b.addObject(.{ - .name = "ref-all-decls-test", - .root_source_file = .{ .path = "test/ref_all_decls.zig" }, - .target = target, - .optimize = optimize, - }); - ref_all_decls_test.root_module.addImport("vulkan", example_vk_zig_module); - test_step.dependOn(&ref_all_decls_test.step); + test_step.dependOn(&b.addRunArtifact(test_target).step); } diff --git a/examples/build.zig b/examples/build.zig new file mode 100644 index 0000000..1420180 --- /dev/null +++ b/examples/build.zig @@ -0,0 +1,50 @@ +const std = @import("std"); + +const vkgen = @import("vulkan_zig"); +const ShaderCompileStep = vkgen.ShaderCompileStep; + +pub fn build(b: *std.Build) void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + const maybe_override_registry = b.option([]const u8, "override-registry", "Override the path to the Vulkan registry used for the examples"); + + const registry = b.dependency("vulkan_headers", .{}).path("registry/vk.xml"); + + const triangle_exe = b.addExecutable(.{ + .name = "triangle", + .root_source_file = .{ .path = "triangle.zig" }, + .target = target, + .link_libc = true, + .optimize = optimize, + }); + b.installArtifact(triangle_exe); + triangle_exe.linkSystemLibrary("glfw"); + + const vk_gen = b.dependency("vulkan_zig", .{}).artifact("vulkan-zig-generator"); + const vk_generate_cmd = b.addRunArtifact(vk_gen); + + if (maybe_override_registry) |override_registry| { + vk_generate_cmd.addFileArg(.{ .path = override_registry }); + } else { + vk_generate_cmd.addFileArg(registry); + } + + triangle_exe.root_module.addAnonymousImport("vulkan", .{ + .root_source_file = vk_generate_cmd.addOutputFileArg("vk.zig"), + }); + + const shaders = ShaderCompileStep.create( + b, + &[_][]const u8{ "glslc", "--target-env=vulkan1.2" }, + "-o", + ); + shaders.add("triangle_vert", "shaders/triangle.vert", .{}); + shaders.add("triangle_frag", "shaders/triangle.frag", .{}); + triangle_exe.root_module.addImport("shaders", shaders.getModule()); + + const triangle_run_cmd = b.addRunArtifact(triangle_exe); + triangle_run_cmd.step.dependOn(b.getInstallStep()); + + const triangle_run_step = b.step("run-triangle", "Run the triangle example"); + triangle_run_step.dependOn(&triangle_run_cmd.step); +} diff --git a/examples/build.zig.zon b/examples/build.zig.zon new file mode 100644 index 0000000..d461ba2 --- /dev/null +++ b/examples/build.zig.zon @@ -0,0 +1,14 @@ +.{ + .name = "vulkan-zig-examples", + .version = "0.1.0", + .dependencies = .{ + .vulkan_zig = .{ + .path = "..", + }, + .vulkan_headers = .{ + .url = "https://github.com/KhronosGroup/Vulkan-Headers/archive/v1.3.283.tar.gz", + .hash = "1220a7e73d72a0d56bc2a65f9d8999a7c019e42260a0744c408d1cded111bc205e10", + }, + }, + .paths = .{""}, +} diff --git a/src/index.zig b/src/index.zig deleted file mode 100644 index 05ca2fe..0000000 --- a/src/index.zig +++ /dev/null @@ -1,8 +0,0 @@ -pub const generateVk = @import("vulkan/generator.zig").generate; -pub const VkGenerateStep = @import("vulkan/build_integration.zig").GenerateStep; -pub const ShaderCompileStep = @import("build_integration.zig").ShaderCompileStep; - -test "main" { - _ = @import("xml.zig"); - _ = @import("vulkan/c_parse.zig"); -} diff --git a/src/main.zig b/src/main.zig index fc6c012..050d809 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,6 +1,10 @@ const std = @import("std"); const generator = @import("vulkan/generator.zig"); +pub const generateVk = generator.generate; +pub const VkGenerateStep = @import("vulkan/build_integration.zig").GenerateStep; +pub const ShaderCompileStep = @import("build_integration.zig").ShaderCompileStep; + fn invalidUsage(prog_name: []const u8, comptime fmt: []const u8, args: anytype) noreturn { std.log.err(fmt, args); std.log.err("see {s} --help for usage", .{prog_name}); @@ -127,3 +131,9 @@ pub fn main() void { std.process.exit(1); }; } + +test "main" { + _ = @import("xml.zig"); + _ = @import("vulkan/c_parse.zig"); +} +