-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.zig
More file actions
159 lines (139 loc) · 5.68 KB
/
Copy pathbuild.zig
File metadata and controls
159 lines (139 loc) · 5.68 KB
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
const std = @import("std");
const Build = std.Build;
const OptimizeMode = std.builtin.OptimizeMode;
const ResolvedTarget = Build.ResolvedTarget;
const Dependency = Build.Dependency;
const sokol = @import("sokol");
const cimgui = @import("cimgui");
pub const shdc = sokol.shdc;
const ShaderFile = struct {
file_name: []const u8,
};
const shader_files = [_]ShaderFile{
.{ .file_name = "scene" },
.{ .file_name = "overlay" },
};
fn buildShaders(b: *Build, file: ShaderFile, dep_shdc: *Build.Dependency) !*Build.Step {
const shaders_dir = "src/shaders/";
return shdc.createSourceFile(b, .{
.shdc_dep = dep_shdc,
.input = b.fmt("{s}{s}.glsl", .{ shaders_dir, file.file_name }),
.output = b.fmt("{s}{s}.glsl.zig", .{ shaders_dir, file.file_name }),
.slang = .{
.glsl430 = true,
.glsl310es = false, // Android
.glsl300es = true, // WebGL
.metal_macos = true,
.hlsl5 = true,
.wgsl = true, // WebGPU
.spirv_vk = true,
},
.reflection = true,
});
}
pub fn build(b: *Build) !void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// ImGui Docking
const opt_docking = b.option(bool, "docking", "Build with docking support") orelse false;
// Get the matching Zig module name, C header search path and C library for
// vanilla imgui vs the imgui docking branch.
const cimgui_conf = cimgui.getConfig(opt_docking);
// note that the sokol dependency is built with `.with_sokol_imgui = true`
const dep_sokol = b.dependency("sokol", .{
.target = target,
.optimize = optimize,
.with_sokol_imgui = true,
.with_tracing = true,
});
const dep_shdc = dep_sokol.builder.dependency("shdc", .{});
const dep_cimgui = b.dependency("cimgui", .{
.target = target,
.optimize = optimize,
});
// inject the cimgui header search path into the sokol C library compile step
dep_sokol.artifact("sokol_clib").root_module.addIncludePath(dep_cimgui.path(cimgui_conf.include_dir));
// main module with sokol and cimgui imports
const mod_main = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
.imports = &.{
.{ .name = "sokol", .module = dep_sokol.module("sokol") },
.{ .name = cimgui_conf.module_name, .module = dep_cimgui.module(cimgui_conf.module_name) },
},
});
const mod_options = b.addOptions();
mod_options.addOption(bool, "docking", opt_docking);
mod_main.addOptions("build_options", mod_options);
// from here on different handling for native vs wasm builds
if (target.result.cpu.arch.isWasm()) {
try buildWasm(b, .{
.mod_main = mod_main,
.dep_sokol = dep_sokol,
.dep_cimgui = dep_cimgui,
.cimgui_clib_name = cimgui_conf.clib_name,
}, dep_shdc);
} else {
try buildNative(b, mod_main, dep_shdc);
}
}
fn buildNative(b: *Build, mod: *Build.Module, dep_shdc: *Build.Dependency) !void {
const exe = b.addExecutable(.{
.name = "donut",
.root_module = mod,
});
for (shader_files) |cur_file| {
const shd_step = try buildShaders(b, cur_file, dep_shdc);
exe.step.dependOn(shd_step);
}
b.installArtifact(exe);
b.step("run", "Run donut").dependOn(&b.addRunArtifact(exe).step);
}
const BuildWasmOptions = struct {
mod_main: *Build.Module,
dep_sokol: *Dependency,
dep_cimgui: *Dependency,
cimgui_clib_name: []const u8,
};
fn buildWasm(b: *Build, opts: BuildWasmOptions, dep_shdc: *Build.Dependency) !void {
// build the main file into a library, this is because the WASM 'exe'
// needs to be linked in a separate build step with the Emscripten linker
const donut = b.addLibrary(.{
.name = "donut",
.root_module = opts.mod_main,
});
for (shader_files) |cur_file| {
const shd_step = try buildShaders(b, cur_file, dep_shdc);
donut.step.dependOn(shd_step);
}
// get the Emscripten SDK dependency from the sokol dependency
const dep_emsdk = opts.dep_sokol.builder.dependency("emsdk", .{});
// need to inject the Emscripten system header include path into
// the cimgui C library otherwise the C/C++ code won't find
// C stdlib headers
const emsdk_incl_path = dep_emsdk.path("upstream/emscripten/cache/sysroot/include");
opts.dep_cimgui.artifact(opts.cimgui_clib_name).root_module.addSystemIncludePath(emsdk_incl_path);
// all C libraries need to depend on the sokol library, when building for
// WASM this makes sure that the Emscripten SDK has been setup before
// C compilation is attempted (since the sokol C library depends on the
// Emscripten SDK setup step)
opts.dep_cimgui.artifact(opts.cimgui_clib_name).step.dependOn(&opts.dep_sokol.artifact("sokol_clib").step);
// create a build step which invokes the Emscripten linker
const link_step = try sokol.emLinkStep(b, .{
.lib_main = donut,
.target = opts.mod_main.resolved_target.?,
.optimize = opts.mod_main.optimize.?,
.emsdk = dep_emsdk,
.use_webgl2 = true,
.use_emmalloc = true,
.use_filesystem = false,
.shell_file_path = opts.dep_sokol.path("src/sokol/web/shell.html"),
});
// attach to default target
b.getInstallStep().dependOn(&link_step.step);
// ...and a special run step to start the web build output via 'emrun'
const run = sokol.emRunStep(b, .{ .name = "donut", .emsdk = dep_emsdk });
run.step.dependOn(&link_step.step);
b.step("run", "Run donut").dependOn(&run.step);
}