Skip to content

Commit dadf417

Browse files
authored
Merge pull request #700 from webui-dev/zig-016
chore: update Zig support to 0.16.0 and keep build compatible
2 parents 65217ef + 39afa97 commit dadf417

2 files changed

Lines changed: 101 additions & 69 deletions

File tree

.github/workflows/zig.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
strategy:
99
matrix:
1010
os: [ubuntu-latest, macos-latest, windows-latest]
11-
version: [0.14.0, 0.15.1]
11+
version: [0.14.0, 0.15.1, 0.16.0]
1212
fail-fast: false
1313
runs-on: ${{ matrix.os }}
1414
steps:
@@ -18,7 +18,7 @@ jobs:
1818
xcode-version: latest-stable
1919
- uses: actions/checkout@v4
2020
- name: Setup Zig
21-
uses: goto-bus-stop/setup-zig@v2
21+
uses: mlugg/setup-zig@v2
2222
with:
2323
version: ${{ matrix.version }}
2424
- name: Build static library

build.zig

Lines changed: 99 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ fn addLinkerFlags(
8181
const is_windows = webui_target.os.tag == .windows;
8282
const is_darwin = webui_target.os.tag == .macos;
8383
const debug = webui.root_module.optimize.? == .Debug;
84+
// In Zig 0.16, methods like addCSourceFile/linkLibC/addIncludePath/linkSystemLibrary/
85+
// linkFramework/addCMacro were removed from *Compile and live only on *Module.
86+
// Routing every call through `mod` keeps the build script compatible with 0.14/0.15/0.16.
87+
const mod = webui.root_module;
8488

8589
// Prepare compiler flags.
8690
const no_tls_flags: []const []const u8 = &.{"-DNO_SSL"};
@@ -93,24 +97,24 @@ fn addLinkerFlags(
9397
};
9498

9599
if (debug and enable_webui_log) {
96-
webui.root_module.addCMacro("WEBUI_LOG", "");
100+
mod.addCMacro("WEBUI_LOG", "");
97101
}
98-
webui.addCSourceFile(.{
102+
mod.addCSourceFile(.{
99103
.file = b.path("src/webui.c"),
100104
.flags = if (enable_tls) tls_flags else no_tls_flags,
101105
});
102106

103107
// Add Win32 WebView2 C++ support on Windows
104108
if (is_windows) {
105-
webui.addCSourceFile(.{
109+
mod.addCSourceFile(.{
106110
.file = b.path("src/webview/win32_wv2.cpp"),
107111
.flags = if (enable_tls) tls_flags else no_tls_flags,
108112
});
109-
webui.linkLibCpp();
113+
mod.link_libcpp = true;
110114
}
111115

112116
const civetweb_debug = debug and debug_dependencies.contains(.civetweb);
113-
webui.addCSourceFile(.{
117+
mod.addCSourceFile(.{
114118
.file = b.path("src/civetweb/civetweb.c"),
115119
.flags = if (enable_tls and !civetweb_debug)
116120
civetweb_flags ++ tls_flags ++ .{"-DNDEBUG"}
@@ -121,34 +125,34 @@ fn addLinkerFlags(
121125
else
122126
civetweb_flags ++ .{"-DUSE_WEBSOCKET"} ++ no_tls_flags,
123127
});
124-
webui.linkLibC();
125-
webui.addIncludePath(b.path("include"));
128+
mod.link_libc = true;
129+
mod.addIncludePath(b.path("include"));
126130
webui.installHeader(b.path("include/webui.h"), "webui.h");
127131
if (is_darwin) {
128-
webui.addCSourceFile(.{
132+
mod.addCSourceFile(.{
129133
.file = b.path("src/webview/wkwebview.m"),
130134
.flags = &.{},
131135
});
132-
webui.linkFramework("Cocoa");
133-
webui.linkFramework("WebKit");
136+
mod.linkFramework("Cocoa", .{});
137+
mod.linkFramework("WebKit", .{});
134138
} else if (is_windows) {
135-
webui.linkSystemLibrary("ws2_32");
136-
webui.linkSystemLibrary("ole32");
139+
mod.linkSystemLibrary("ws2_32", .{});
140+
mod.linkSystemLibrary("ole32", .{});
137141
if (webui_target.abi == .msvc) {
138-
webui.linkSystemLibrary("Advapi32");
139-
webui.linkSystemLibrary("Shell32");
140-
webui.linkSystemLibrary("user32");
142+
mod.linkSystemLibrary("Advapi32", .{});
143+
mod.linkSystemLibrary("Shell32", .{});
144+
mod.linkSystemLibrary("user32", .{});
141145
}
142146
if (enable_tls) {
143-
webui.linkSystemLibrary("bcrypt");
147+
mod.linkSystemLibrary("bcrypt", .{});
144148
}
145149
}
146150
if (enable_tls) {
147-
webui.linkSystemLibrary("ssl");
148-
webui.linkSystemLibrary("crypto");
151+
mod.linkSystemLibrary("ssl", .{});
152+
mod.linkSystemLibrary("crypto", .{});
149153
}
150154

151-
for (webui.root_module.link_objects.items) |lo| {
155+
for (mod.link_objects.items) |lo| {
152156
switch (lo) {
153157
.c_source_file => |csf| {
154158
log(.debug, .WebUI, "{s} linker flags:\n", .{
@@ -165,60 +169,88 @@ fn addLinkerFlags(
165169

166170
fn build_examples(b: *Build, webui: *Compile) !void {
167171
const build_examples_step = b.step("examples", "builds the library and its examples");
168-
const target = webui.root_module.resolved_target.?;
169-
const optimize = webui.root_module.optimize.?;
170172

171-
const examples_path = b.path("examples/C").getPath(b);
172-
var examples_dir = std.fs.cwd().openDir(
173-
examples_path,
174-
.{ .iterate = true },
175-
) catch |e| switch (e) {
176-
// Do not attempt building examples if directory does not exist.
177-
error.FileNotFound => return,
178-
else => return e,
179-
};
180-
defer examples_dir.close();
173+
// Iterate examples/C. Zig 0.16 removed std.fs.cwd() and reworked Dir/Iterator
174+
// to require an Io instance, so split the open+iterate path by version while
175+
// sharing the per-example wiring below.
176+
if (comptime builtin.zig_version.minor >= 16) {
177+
const io = b.graph.io;
178+
var examples_dir = b.build_root.handle.openDir(
179+
io,
180+
"examples/C",
181+
.{ .iterate = true },
182+
) catch |e| switch (e) {
183+
error.FileNotFound => return,
184+
else => return e,
185+
};
186+
defer examples_dir.close(io);
181187

182-
var paths = examples_dir.iterate();
183-
while (try paths.next()) |val| {
184-
if (val.kind != .directory) {
185-
continue;
188+
var paths = examples_dir.iterate();
189+
while (try paths.next(io)) |val| {
190+
if (val.kind != .directory) continue;
191+
try add_example(b, webui, build_examples_step, val.name);
186192
}
187-
const example_name = val.name;
193+
} else {
194+
const examples_path = b.path("examples/C").getPath(b);
195+
var examples_dir = std.fs.cwd().openDir(
196+
examples_path,
197+
.{ .iterate = true },
198+
) catch |e| switch (e) {
199+
error.FileNotFound => return,
200+
else => return e,
201+
};
202+
defer examples_dir.close();
203+
204+
var paths = examples_dir.iterate();
205+
while (try paths.next()) |val| {
206+
if (val.kind != .directory) continue;
207+
try add_example(b, webui, build_examples_step, val.name);
208+
}
209+
}
210+
}
211+
212+
fn add_example(
213+
b: *Build,
214+
webui: *Compile,
215+
build_examples_step: *Build.Step,
216+
example_name: []const u8,
217+
) !void {
218+
const target = webui.root_module.resolved_target.?;
219+
const optimize = webui.root_module.optimize.?;
188220

189-
const exe = b.addExecutable(if (builtin.zig_version.minor == 14) .{
190-
.name = example_name,
221+
const exe = b.addExecutable(if (builtin.zig_version.minor == 14) .{
222+
.name = example_name,
223+
.target = target,
224+
.optimize = optimize,
225+
} else .{
226+
.name = example_name,
227+
.root_module = b.createModule(.{
191228
.target = target,
192229
.optimize = optimize,
193-
} else .{
194-
.name = example_name,
195-
.root_module = b.createModule(.{
196-
.target = target,
197-
.optimize = optimize,
198-
.pic = true,
199-
}),
200-
});
201-
const path = try std.fmt.allocPrint(b.allocator, "examples/C/{s}/main.c", .{example_name});
202-
defer b.allocator.free(path);
203-
204-
exe.addCSourceFile(.{ .file = b.path(path), .flags = &.{} });
205-
exe.linkLibrary(webui);
206-
207-
const exe_install = b.addInstallArtifact(exe, .{});
208-
const exe_run = b.addRunArtifact(exe);
209-
const step_name = try std.fmt.allocPrint(b.allocator, "run_{s}", .{example_name});
210-
defer b.allocator.free(step_name);
211-
const step_desc = try std.fmt.allocPrint(b.allocator, "run example {s}", .{example_name});
212-
defer b.allocator.free(step_desc);
213-
214-
const cwd = try std.fmt.allocPrint(b.allocator, "src/examples/{s}", .{example_name});
215-
defer b.allocator.free(cwd);
216-
exe_run.setCwd(b.path(cwd));
217-
218-
exe_run.step.dependOn(&exe_install.step);
219-
build_examples_step.dependOn(&exe_install.step);
220-
b.step(step_name, step_desc).dependOn(&exe_run.step);
221-
}
230+
.pic = true,
231+
}),
232+
});
233+
const path = try std.fmt.allocPrint(b.allocator, "examples/C/{s}/main.c", .{example_name});
234+
defer b.allocator.free(path);
235+
236+
// Route through root_module so Zig 0.16 (which removed these methods from *Compile) keeps working.
237+
exe.root_module.addCSourceFile(.{ .file = b.path(path), .flags = &.{} });
238+
exe.root_module.linkLibrary(webui);
239+
240+
const exe_install = b.addInstallArtifact(exe, .{});
241+
const exe_run = b.addRunArtifact(exe);
242+
const step_name = try std.fmt.allocPrint(b.allocator, "run_{s}", .{example_name});
243+
defer b.allocator.free(step_name);
244+
const step_desc = try std.fmt.allocPrint(b.allocator, "run example {s}", .{example_name});
245+
defer b.allocator.free(step_desc);
246+
247+
const cwd = try std.fmt.allocPrint(b.allocator, "src/examples/{s}", .{example_name});
248+
defer b.allocator.free(cwd);
249+
exe_run.setCwd(b.path(cwd));
250+
251+
exe_run.step.dependOn(&exe_install.step);
252+
build_examples_step.dependOn(&exe_install.step);
253+
b.step(step_name, step_desc).dependOn(&exe_run.step);
222254
}
223255

224256
/// Function to runtime-scope log levels based on build flag, for all scopes.

0 commit comments

Comments
 (0)