forked from mirror/vulkan-zig
Add CLI interface
This commit is contained in:
12
README.md
12
README.md
@@ -11,9 +11,15 @@ vulkan-zig attempts to provide a better experience to programming Vulkan applica
|
|||||||
vulkan-zig is automatically tested against the latest vk.xml and zig, and supports vk.xml from version 1.x.141.
|
vulkan-zig is automatically tested against the latest vk.xml and zig, and supports vk.xml from version 1.x.141.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
### CLI-interface
|
||||||
|
A CLI-interface is provided to generate vk.zig from the [Vulkan XML registry](https://github.com/KhronosGroup/Vulkan-Docs/blob/master/xml), which is built by default when invoking `zig build` in the project root. To generate vk.zig, simply invoke the program as follows:
|
||||||
|
```
|
||||||
|
$ zig-cache/bin/vulkan-zig-generator path/to/vk.xml output/path/to/vk.zig
|
||||||
|
```
|
||||||
|
This reads the xml file, parses its contents, renders the Vulkan bindings, and formats file, before writing the result to the output path. While the intended usage of vulkan-zig is through direct generation from build.zig (see below), the CLI-interface can be used for one-off generation and vendoring the result.
|
||||||
|
|
||||||
### Generation from build.zig
|
### Generation from build.zig
|
||||||
Vulkan bindings can be generated directly from the [Vulkan XML registry](https://github.com/KhronosGroup/Vulkan-Docs/blob/master/xml) build.zig at compiletime, by using the provided
|
Vulkan bindings can be generated from the Vulkan XML registry at compile time with build.zig, by using the provided Vulkan generation step:
|
||||||
vulkan generation step:
|
|
||||||
```zig
|
```zig
|
||||||
const vkgen = @import("vulkan-zig/generator/index.zig");
|
const vkgen = @import("vulkan-zig/generator/index.zig");
|
||||||
|
|
||||||
@@ -236,5 +242,5 @@ Upon compilation, glslc is then invoked to compile each shader, and the result i
|
|||||||
A partial implementation of https://vulkan-tutorial.org is implemented in [examples/triangle.zig](examples/triangle.zig). This example can be ran by executing `zig build run-triangle` in vulkan-zig's root.
|
A partial implementation of https://vulkan-tutorial.org is implemented in [examples/triangle.zig](examples/triangle.zig). This example can be ran by executing `zig build run-triangle` in vulkan-zig's root.
|
||||||
|
|
||||||
## See also
|
## See also
|
||||||
* (Outdated) implementation of https://vulkan-tutorial.org using translate-c: https://github.com/andrewrk/zig-vulkan-triangle.
|
* Implementation of https://vulkan-tutorial.org: https://github.com/andrewrk/zig-vulkan-triangle.
|
||||||
* Alternative binding generator: https://github.com/SpexGuy/Zig-Vulkan-Headers
|
* Alternative binding generator: https://github.com/SpexGuy/Zig-Vulkan-Headers
|
||||||
|
|||||||
@@ -75,6 +75,12 @@ pub fn build(b: *Builder) void {
|
|||||||
|
|
||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
const mode = b.standardReleaseOptions();
|
const mode = b.standardReleaseOptions();
|
||||||
|
|
||||||
|
const generator_exe = b.addExecutable("vulkan-zig-generator", "generator/main.zig");
|
||||||
|
generator_exe.setTarget(target);
|
||||||
|
generator_exe.setBuildMode(mode);
|
||||||
|
generator_exe.install();
|
||||||
|
|
||||||
const triangle_exe = b.addExecutable("triangle", "examples/triangle.zig");
|
const triangle_exe = b.addExecutable("triangle", "examples/triangle.zig");
|
||||||
triangle_exe.setTarget(target);
|
triangle_exe.setTarget(target);
|
||||||
triangle_exe.setBuildMode(mode);
|
triangle_exe.setBuildMode(mode);
|
||||||
|
|||||||
74
generator/main.zig
Normal file
74
generator/main.zig
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const generate = @import("vulkan/generator.zig").generate;
|
||||||
|
|
||||||
|
const usage = "Usage: {} [-h|--help] <spec xml path> <output zig source>\n";
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
const stderr = std.io.getStdErr();
|
||||||
|
const stdout = std.io.getStdOut();
|
||||||
|
|
||||||
|
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||||
|
defer arena.deinit();
|
||||||
|
const allocator = &arena.allocator;
|
||||||
|
|
||||||
|
var args = std.process.args();
|
||||||
|
const prog_name = try args.next(allocator) orelse return error.ExecutableNameMissing;
|
||||||
|
|
||||||
|
var maybe_xml_path: ?[]const u8 = null;
|
||||||
|
var maybe_out_path: ?[]const u8 = null;
|
||||||
|
|
||||||
|
while (args.next(allocator)) |err_or_arg| {
|
||||||
|
const arg = try err_or_arg;
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, arg, "--help") or std.mem.eql(u8, arg, "-h")) {
|
||||||
|
@setEvalBranchQuota(2000);
|
||||||
|
try stderr.writer().print(
|
||||||
|
\\Utility to generate a Zig binding from the Vulkan XML API registry.
|
||||||
|
\\
|
||||||
|
\\The most recent Vulkan XML API registry can be obtained from
|
||||||
|
\\https://github.com/KhronosGroup/Vulkan-Docs/blob/master/xml/vk.xml,
|
||||||
|
\\and the most recent LunarG Vulkan SDK version can be found at
|
||||||
|
\\$VULKAN_SDK/x86_64/share/vulkan/registry/vk.xml.
|
||||||
|
\\
|
||||||
|
\\
|
||||||
|
++ usage,
|
||||||
|
.{ prog_name },
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
} else if (maybe_xml_path == null) {
|
||||||
|
maybe_xml_path = arg;
|
||||||
|
} else if (maybe_out_path == null) {
|
||||||
|
maybe_out_path = arg;
|
||||||
|
} else {
|
||||||
|
try stderr.writer().print("Error: Superficial argument '{}'\n", .{ arg });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const xml_path = maybe_xml_path orelse {
|
||||||
|
try stderr.writer().print("Error: Missing required argument <spec xml path>\n" ++ usage, .{ prog_name });
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
const out_path = maybe_out_path orelse {
|
||||||
|
try stderr.writer().print("Error: Missing required argument <output zig source>\n" ++ usage, .{ prog_name });
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
const cwd = std.fs.cwd();
|
||||||
|
const xml_src = cwd.readFileAlloc(allocator, xml_path, std.math.maxInt(usize)) catch |err| {
|
||||||
|
try stderr.writer().print("Error: Failed to open input file '{}' ({})\n", .{ xml_path, @errorName(err) });
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
const out_file = cwd.createFile(out_path, .{}) catch |err| {
|
||||||
|
try stderr.writer().print("Error: Failed to create output file '{}' ({})\n", .{ out_path, @errorName(err) });
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
defer out_file.close();
|
||||||
|
|
||||||
|
var out_buffer = std.ArrayList(u8).init(allocator);
|
||||||
|
try generate(allocator, xml_src, out_buffer.writer());
|
||||||
|
const tree = try std.zig.parse(allocator, out_buffer.items);
|
||||||
|
|
||||||
|
_ = try std.zig.render(allocator, out_file.writer(), tree);
|
||||||
|
}
|
||||||
@@ -75,6 +75,6 @@ pub const GenerateStep = struct {
|
|||||||
try cwd.makePath(dir);
|
try cwd.makePath(dir);
|
||||||
const output_file = cwd.createFile(self.package.path, .{}) catch unreachable;
|
const output_file = cwd.createFile(self.package.path, .{}) catch unreachable;
|
||||||
defer output_file.close();
|
defer output_file.close();
|
||||||
_ = try std.zig.render(self.builder.allocator, output_file.outStream(), tree);
|
_ = try std.zig.render(self.builder.allocator, output_file.writer(), tree);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user