1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
const std = @import("std");
const generate = @import("generator.zig").generate;
const path = std.fs.path;
const bufPrint = std.fmt.bufPrint;
const Builder = std.build.Builder;
const Step = std.build.Step;
const RunStep = std.build.RunStep;
const LibExeObjStep = std.build.LibExeObjStep;
const modules = [_][]const u8{ "DiligentCore", "DiligentFX", "DiligentTools" };
/// build.zig integration for Diligent binding generation. This step can be used to generate
/// bindings at compiletime from header files. The final package can then be obtained by
/// `package()`, the result of which can be added to the project using `std.build.Builder.addPackage`.
pub const GenerateStep = struct {
step: Step,
builder: *Builder,
/// base path for the DiligentCore repository
diligent_path: []const u8,
/// The package representing the generated bindings. The generated bindings will be placed
/// in `package.path`. When using this step, this member should be passed to
/// `std.build.Builder.addPackage`, which causes the bindings to become available under the
/// name `diligent`.
package: std.build.Pkg,
generator_exe: *LibExeObjStep,
run_step: *RunStep,
/// Add runtime dependencies to a parent build step
pub fn addDeps(self: *GenerateStep, step: *LibExeObjStep, diligent_build_type: []const u8) void {
var buffer = [_]u8{0} ** 1024;
const vulkan_include = bufPrint(
buffer[0..],
"{}/DiligentCore/ThirdParty/Vulkan-Headers/include",
.{self.diligent_path},
) catch unreachable;
step.addIncludeDir(vulkan_include);
inline for (modules) |module| {
const module_path = bufPrint(
buffer[0..],
"{}/build/install/include/{}",
.{ self.diligent_path, module },
) catch unreachable;
step.addIncludeDir(module_path);
const lib_path = bufPrint(
buffer[0..],
"{}/build/install/lib/{}/{}",
.{ self.diligent_path, module, diligent_build_type },
) catch unreachable;
step.addLibPath(lib_path);
}
step.step.dependOn(&self.run_step.step);
step.addPackage(self.package);
}
/// Initialize a Vulkan generation step, for `builder`. `interfaces` are the paths
/// to interface headers, relative to the project root. The generated bindings will be placed at
/// `out_path`, which is relative to the zig-cache directory.
pub fn init(builder: *Builder, diligent_path: []const u8, out_path: []const u8) *GenerateStep {
const self = builder.allocator.create(GenerateStep) catch unreachable;
const full_out_path = path.join(builder.allocator, &[_][]const u8{
builder.build_root,
builder.cache_root,
out_path,
}) catch unreachable;
const generator_exe = builder.addExecutable("dg-gen", "lib/diligent/generator.zig");
var buffer = [_]u8{0} ** 1024;
const vulkan_include = bufPrint(
buffer[0..],
"{}/DiligentCore/ThirdParty/Vulkan-Headers/include",
.{diligent_path},
) catch unreachable;
generator_exe.addIncludeDir(vulkan_include);
inline for (modules) |module| {
const module_path = bufPrint(
buffer[0..],
"{}/build/install/include/{}",
.{ diligent_path, module },
) catch unreachable;
generator_exe.addIncludeDir(module_path);
}
const run_step = generator_exe.run();
run_step.addArg(full_out_path);
generator_exe.linkSystemLibrary("c");
self.* = .{
.step = Step.init(.Custom, "diligent-generate", builder.allocator, make),
.builder = builder,
.diligent_path = builder.dupe(diligent_path),
.package = .{
.name = "diligent",
.path = full_out_path,
.dependencies = null,
},
.generator_exe = generator_exe,
.run_step = run_step,
};
return self;
}
/// Internal build function. The resulting generated bindings are not formatted, which is why an
/// ArrayList writer is passed instead of a file writer. This is then formatted into standard
/// formatting by parsing it and rendering with `std.zig.parse` and `std.zig.render` respectively.
fn make(step: *Step) !void {
const self = @fieldParentPtr(GenerateStep, "step", step);
try self.run_step.step.make();
}
};
|