this repo has no description
1const std = @import("std");
2const Build = std.Build;
3
4const sokol = @import("sokol");
5const cimgui = @import("cimgui");
6
7const Options = struct {
8 build_gui: bool,
9 mod_ft: *Build.Module,
10 mod_exe: *Build.Module,
11 dep_sokol: *Build.Dependency,
12 dep_cimgui: *Build.Dependency,
13 cimgui_clib_name: []const u8,
14};
15
16pub fn build(b: *std.Build) !void {
17 const target = b.standardTargetOptions(.{});
18 const optimize = b.standardOptimizeOption(.{});
19
20 const opt_docking = b.option(bool, "docking", "Build with docking support") orelse false;
21 const build_gui_opt = b.option(bool, "build-gui", "When disabled only build FT library and not the gui app") orelse true;
22
23 const cimgui_conf = cimgui.getConfig(opt_docking);
24
25 const dep_sokol = b.dependency("sokol", .{
26 .target = target,
27 .optimize = optimize,
28 .with_sokol_imgui = true,
29 });
30 const dep_cimgui = b.dependency("cimgui", .{
31 .target = target,
32 .optimize = optimize,
33 });
34
35 dep_sokol.artifact("sokol_clib").addIncludePath(dep_cimgui.path(cimgui_conf.include_dir));
36
37 const mod_ft = b.addModule("ft", .{
38 .root_source_file = b.path("src/root.zig"),
39 .target = target,
40 });
41
42 const mod_exe = b.createModule(.{
43 .root_source_file = b.path("src/main.zig"),
44 .target = target,
45 .optimize = optimize,
46 .imports = &.{
47 .{ .name = "ft", .module = mod_ft },
48 .{
49 .name = "sokol",
50 .module = dep_sokol.module("sokol"),
51 },
52 .{
53 .name = cimgui_conf.module_name,
54 .module = dep_cimgui.module(cimgui_conf.module_name),
55 },
56 // .{ .name = "shader", .module = try createShaderModule(b, dep_sokol) },
57 },
58 });
59
60 const options_mod_exe = b.addOptions();
61 options_mod_exe.addOption(bool, "docking", opt_docking);
62 mod_exe.addOptions("build_options", options_mod_exe);
63
64 const opts = Options{
65 .build_gui = build_gui_opt,
66 .mod_ft = mod_ft,
67 .mod_exe = mod_exe,
68 .dep_sokol = dep_sokol,
69 .dep_cimgui = dep_cimgui,
70 .cimgui_clib_name = cimgui_conf.clib_name,
71 };
72 if (target.result.cpu.arch.isWasm()) {
73 try buildWebGui(b, opts);
74 } else {
75 if (opts.build_gui) {
76 try buildNativeGui(b, opts);
77 } else {
78 buildFTLib(b, opts);
79 }
80 tests(b, opts);
81 }
82}
83
84fn buildFTLib(b: *Build, opts: Options) void {
85 const lib = b.addLibrary(.{
86 .name = "factorio-toolbox",
87 .root_module = opts.mod_ft,
88 .linkage = if (b.option(bool, "ft-lib-dynamic", "Set linkage option for FT lib to dynamic") orelse false) .dynamic else .static,
89 });
90 b.installArtifact(lib);
91}
92
93fn buildNativeGui(b: *Build, opts: Options) !void {
94 const exe = b.addExecutable(.{
95 .name = "factorio_toolbox",
96 .root_module = opts.mod_exe,
97 });
98
99 b.installArtifact(exe);
100
101 const run_step = b.step("run", "Run the app");
102 const run_cmd = b.addRunArtifact(exe);
103
104 run_step.dependOn(&run_cmd.step);
105 run_cmd.step.dependOn(b.getInstallStep());
106
107 if (b.args) |args| {
108 run_cmd.addArgs(args);
109 }
110}
111
112fn buildWebGui(b: *Build, opts: Options) !void {
113 const lib = b.addLibrary(.{
114 .name = "factorio_toolbox",
115 .root_module = opts.mod_exe,
116 });
117
118 const emsdk = opts.dep_sokol.builder.dependency("emsdk", .{});
119
120 const emsdk_incl_path = emsdk.path("upstream/emscripten/cache/sysroot/include");
121 opts.dep_cimgui.artifact(opts.cimgui_clib_name).addSystemIncludePath(emsdk_incl_path);
122 opts.dep_cimgui.artifact(opts.cimgui_clib_name).step.dependOn(&opts.dep_sokol.artifact("sokol_clib").step);
123
124 const link_step = try sokol.emLinkStep(b, .{
125 .lib_main = lib,
126 .target = opts.mod_exe.resolved_target.?,
127 .optimize = opts.mod_exe.optimize.?,
128 .emsdk = emsdk,
129 .use_webgl2 = true,
130 .use_emmalloc = true,
131 .use_filesystem = false,
132 .shell_file_path = opts.dep_sokol.path("src/sokol/web/shell.html"),
133 });
134 b.getInstallStep().dependOn(&link_step.step);
135
136 const run = sokol.emRunStep(b, .{
137 .name = "factorio_toolbox",
138 .emsdk = emsdk,
139 });
140 run.step.dependOn(&link_step.step);
141 b.step("run", "Run the web app").dependOn(&run.step);
142}
143
144fn tests(b: *Build, opts: Options) void {
145 const test_step = b.step("test", "Run tests");
146
147 const mod_tests = b.addTest(.{
148 .name = "mod tests",
149 .root_module = opts.mod_ft,
150 });
151 const run_mod_tests = b.addRunArtifact(mod_tests);
152 test_step.dependOn(&run_mod_tests.step);
153
154 if (opts.build_gui) {
155 const exe_tests = b.addTest(.{
156 .name = "exe tests",
157 .root_module = opts.mod_exe,
158 });
159 const run_exe_tests = b.addRunArtifact(exe_tests);
160 test_step.dependOn(&run_exe_tests.step);
161 }
162}
163
164fn createShaderModule(b: *Build, dep_sokol: *Build.Dependency) !*Build.Module {
165 const mod_sokol = dep_sokol.module("sokol");
166 const dep_shdc = dep_sokol.builder.dependency("shdc", .{});
167 return sokol.shdc.createModule(b, "shader", mod_sokol, .{
168 .shdc_dep = dep_shdc,
169 .input = "src/shader/shader.glsl",
170 .output = "shader.zig",
171 .slang = .{
172 .glsl410 = true,
173 .glsl300es = true,
174 .hlsl4 = true,
175 .metal_macos = true,
176 .wgsl = true,
177 },
178 });
179}