authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-22 21:51:11-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 18:54:36-07:00
loge435299cfa6a6bd446483e6c95a56bf1cdca8cfd
treeeebe78d6bcd4eaa80e8ed04df576a952c82de172
parented1f00582670df44c15875914a1cc8fc0ff6329f

Maker: progress towards ConfigHeader

however... why is this done in the make phase anyway? making a header like this is typically done by the configure phase...

3 files changed, 139 insertions(+), 120 deletions(-)

lib/compiler/Maker/Step.zig+5-18
...@@ -20,6 +20,7 @@ const Maker = @import("../Maker.zig");...@@ -20,6 +20,7 @@ const Maker = @import("../Maker.zig");
2020
21pub const CheckFile = @import("Step/CheckFile.zig");21pub const CheckFile = @import("Step/CheckFile.zig");
22pub const Compile = @import("Step/Compile.zig");22pub const Compile = @import("Step/Compile.zig");
23pub const ConfigHeader = @import("Step/ConfigHeader.zig");
23pub const FindProgram = @import("Step/FindProgram.zig");24pub const FindProgram = @import("Step/FindProgram.zig");
24pub const Fmt = @import("Step/Fmt.zig");25pub const Fmt = @import("Step/Fmt.zig");
25pub const InstallArtifact = @import("Step/InstallArtifact.zig");26pub const InstallArtifact = @import("Step/InstallArtifact.zig");
...@@ -78,7 +79,7 @@ comptime {...@@ -78,7 +79,7 @@ comptime {
78pub const Extended = union(enum) {79pub const Extended = union(enum) {
79 check_file: CheckFile,80 check_file: CheckFile,
80 compile: Compile,81 compile: Compile,
81 config_header: Todo,82 config_header: ConfigHeader,
82 fail: Fail,83 fail: Fail,
83 find_program: FindProgram,84 find_program: FindProgram,
84 fmt: Fmt,85 fmt: Fmt,
...@@ -114,21 +115,6 @@ pub const Extended = union(enum) {...@@ -114,21 +115,6 @@ pub const Extended = union(enum) {
114 };115 };
115 }116 }
116117
117 pub const Todo = struct {
118 pub fn make(
119 todo: *Todo,
120 step_index: Configuration.Step.Index,
121 maker: *Maker,
122 progress_node: std.Progress.Node,
123 ) Step.ExtendedMakeError!void {
124 _ = todo;
125 _ = progress_node;
126 const conf = &maker.scanned_config.configuration;
127 const conf_step = step_index.ptr(conf);
128 std.debug.panic("TODO implement another step type: {s}", .{conf_step.name.slice(conf)});
129 }
130 };
131
132 pub const TopLevel = struct {118 pub const TopLevel = struct {
133 pub fn make(119 pub fn make(
134 top_level: *TopLevel,120 top_level: *TopLevel,
...@@ -750,8 +736,9 @@ fn failWithCacheError(...@@ -750,8 +736,9 @@ fn failWithCacheError(
750/// separately from using the cache system.736/// separately from using the cache system.
751pub fn writeManifest(s: *Step, maker: *Maker, man: *Cache.Manifest) !void {737pub fn writeManifest(s: *Step, maker: *Maker, man: *Cache.Manifest) !void {
752 if (s.test_results.isSuccess()) {738 if (s.test_results.isSuccess()) {
753 man.writeManifest() catch |err| {739 man.writeManifest() catch |err| switch (err) {
754 try s.addError(maker, "failed writing cache manifest: {t}", .{err});740 error.Canceled => |e| return e,
741 else => |e| try s.addError(maker, "failed writing cache manifest: {t}", .{e}),
755 };742 };
756 }743 }
757}744}
lib/compiler/Maker/Step/ConfigHeader.zig+133-101
...@@ -4,22 +4,35 @@ const std = @import("std");...@@ -4,22 +4,35 @@ const std = @import("std");
4const Io = std.Io;4const Io = std.Io;
5const Configuration = std.Build.Configuration;5const Configuration = std.Build.Configuration;
6const Writer = std.Io.Writer;6const Writer = std.Io.Writer;
7const Path = std.Build.Cache.Path;
8const Allocator = std.mem.Allocator;
79
8const Step = @import("../Step.zig");10const Step = @import("../Step.zig");
9const Maker = @import("../../Maker.zig");11const Maker = @import("../../Maker.zig");
1012
13 const header_text = "This file was generated by ConfigHeader using the Zig Build System.";
14 const c_generated_line = "/* " ++ header_text ++ " */\n";
15 const asm_generated_line = "; " ++ header_text ++ "\n";
16
11pub fn make(17pub fn make(
12 config_header: *ConfigHeader,18 config_header: *ConfigHeader,
13 step_index: Configuration.Step.Index,19 step_index: Configuration.Step.Index,
14 maker: *Maker,20 maker: *Maker,
15 progress_node: std.Progress.Node,21 progress_node: std.Progress.Node,
16) Step.ExtendedMakeError!void {22) Step.ExtendedMakeError!void {
23 _ = config_header;
24 _ = progress_node;
17 const graph = maker.graph;25 const graph = maker.graph;
18 const arena = maker.graph.arena; // TODO don't leak into process arena26 const gpa = maker.gpa;
19 const step = maker.stepByIndex(step_index);27 const step = maker.stepByIndex(step_index);
20 const io = graph.io;28 const io = graph.io;
29 const arena = graph.arena; // TODO don't leak into the process arena
30 const conf = &maker.scanned_config.configuration;
31 const conf_step = step_index.ptr(conf);
32 const conf_ch = conf_step.extended.get(conf.extra).config_header;
33 const cache_root = graph.local_cache_root;
2134
22 if (config_header.style.getPath()) |lp|35 if (conf_ch.style.getPath()) |lp|
23 try step.singleUnchangingWatchInput(maker, arena, lp);36 try step.singleUnchangingWatchInput(maker, arena, lp);
2437
25 var man = graph.cache.obtain();38 var man = graph.cache.obtain();
...@@ -29,45 +42,51 @@ pub fn make(...@@ -29,45 +42,51 @@ pub fn make(
29 // random bytes when ConfigHeader implementation is modified in a42 // random bytes when ConfigHeader implementation is modified in a
30 // non-backwards-compatible way.43 // non-backwards-compatible way.
31 man.hash.add(@as(u32, 0xdef08d23));44 man.hash.add(@as(u32, 0xdef08d23));
32 man.hash.addBytes(config_header.include_path);45 man.hash.addBytes(conf_ch.include_path);
33 man.hash.addOptionalBytes(config_header.include_guard_override);46 man.hash.addOptionalBytes(conf_ch.include_guard_override);
3447
35 var aw: Writer.Allocating = .init(arena);48 var aw: Writer.Allocating = .init(arena);
36 defer aw.deinit();49 defer aw.deinit();
37 const bw = &aw.writer;
3850
39 const header_text = "This file was generated by ConfigHeader using the Zig Build System.";51 switch (conf_ch.flags.style) {
40 const c_generated_line = "/* " ++ header_text ++ " */\n";52 .autoconf_undef => {
41 const asm_generated_line = "; " ++ header_text ++ "\n";53 const src_path = try maker.resolveLazyPathIndex(arena, conf_ch.template_file.value.?, step_index);
4254 const contents = Io.Dir.cwd().readFileAlloc(io, src_path, arena, .limited(conf_ch.max_bytes)) catch |err|
43 switch (config_header.style) {
44 .autoconf_undef, .autoconf_at => |file_source| {
45 try bw.writeAll(c_generated_line);
46 const src_path = file_source.getPath2(b, step);
47 const contents = Io.Dir.cwd().readFileAlloc(io, src_path, arena, .limited(config_header.max_bytes)) catch |err| {
48 return step.fail("unable to read autoconf input file {s}: {t}", .{ src_path, err });55 return step.fail("unable to read autoconf input file {s}: {t}", .{ src_path, err });
56 renderAutoConfUndef(step, contents, &aw.writer, &conf_ch.values, src_path) catch |err| switch (err) {
57 error.WriteFailed => return error.OutOfMemory,
58 else => |e| return e,
59 };
60 },
61 .autoconf_at => {
62 const src_path = try maker.resolveLazyPathIndex(arena, conf_ch.template_file.value.?, step_index);
63 const contents = Io.Dir.cwd().readFileAlloc(io, src_path, arena, .limited(conf_ch.max_bytes)) catch |err|
64 return step.fail("unable to read autoconf input file {s}: {t}", .{ src_path, err });
65 renderAutoconfAt(step, contents, &aw, &conf_ch.values, src_path) catch |err| switch (err) {
66 error.WriteFailed => return error.OutOfMemory,
67 else => |e| return e,
49 };68 };
50 switch (config_header.style) {
51 .autoconf_undef => try render_autoconf_undef(step, contents, bw, &config_header.values, src_path),
52 .autoconf_at => try render_autoconf_at(step, contents, &aw, &config_header.values, src_path),
53 else => unreachable,
54 }
55 },69 },
56 .cmake => |file_source| {70 .cmake => {
57 try bw.writeAll(c_generated_line);71 const src_path = try maker.resolveLazyPathIndex(arena, conf_ch.template_file.value.?, step_index);
58 const src_path = file_source.getPath2(b, step);72 const contents = Io.Dir.cwd().readFileAlloc(io, src_path, arena, .limited(conf_ch.max_bytes)) catch |err|
59 const contents = Io.Dir.cwd().readFileAlloc(io, src_path, arena, .limited(config_header.max_bytes)) catch |err| {
60 return step.fail("unable to read cmake input file {s}: {t}", .{ src_path, err });73 return step.fail("unable to read cmake input file {s}: {t}", .{ src_path, err });
74 renderCmake(step, contents, &aw.writer, conf_ch.values, src_path) catch |err| switch (err) {
75 error.WriteFailed => return error.OutOfMemory,
76 else => |e| return e,
61 };77 };
62 try render_cmake(step, contents, bw, config_header.values, src_path);
63 },78 },
64 .blank => {79 .blank => {
65 try bw.writeAll(c_generated_line);80 renderBlank(gpa, &aw.writer, conf_ch.values, conf_ch.include_path, conf_ch.include_guard_override) catch |err| switch (err) {
66 try render_blank(gpa, bw, config_header.values, config_header.include_path, config_header.include_guard_override);81 error.WriteFailed => return error.OutOfMemory,
82 else => |e| return e,
83 };
67 },84 },
68 .nasm => {85 .nasm => {
69 try bw.writeAll(asm_generated_line);86 renderNasm(&aw.writer, conf_ch.values) catch |err| switch (err) {
70 try render_nasm(bw, config_header.values);87 error.WriteFailed => return error.OutOfMemory,
88 else => |e| return e,
89 };
71 },90 },
72 }91 }
7392
...@@ -76,7 +95,10 @@ pub fn make(...@@ -76,7 +95,10 @@ pub fn make(
7695
77 if (try step.cacheHit(&man)) {96 if (try step.cacheHit(&man)) {
78 const digest = man.final();97 const digest = man.final();
79 config_header.generated_dir.path = try b.cache_root.join(arena, &.{ "o", &digest });98 maker.generatedPath().* = .{
99 .root_dir = cache_root,
100 .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest }),
101 };
80 return;102 return;
81 }103 }
82104
...@@ -87,35 +109,38 @@ pub fn make(...@@ -87,35 +109,38 @@ pub fn make(
87 // output_path is libavutil/avconfig.h109 // output_path is libavutil/avconfig.h
88 // We want to open directory zig-cache/o/HASH/libavutil/110 // We want to open directory zig-cache/o/HASH/libavutil/
89 // but keep output_dir as zig-cache/o/HASH for -I include111 // but keep output_dir as zig-cache/o/HASH for -I include
90 const sub_path = b.pathJoin(&.{ "o", &digest, config_header.include_path });112 const out_path: Path = .{
91 const sub_path_dirname = std.fs.path.dirname(sub_path).?;113 .root_dir = cache_root,
92114 .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest, conf_ch.include_path.slice(conf) }),
93 b.cache_root.handle.createDirPath(io, sub_path_dirname) catch |err| {
94 return step.fail("unable to make path '{f}{s}': {s}", .{
95 b.cache_root, sub_path_dirname, @errorName(err),
96 });
97 };115 };
116 const out_path_dirname = out_path.dirname().?;
117
118 out_path_dirname.root_dir.handle.createDirPath(io, out_path_dirname.sub_path) catch |err|
119 return step.fail("unable to make path {f}: {t}", .{ out_path_dirname, err });
98120
99 b.cache_root.handle.writeFile(io, .{ .sub_path = sub_path, .data = output }) catch |err| {121 out_path.root_dir.handle.writeFile(io, .{ .sub_path = out_path.sub_path, .data = output }) catch |err|
100 return step.fail("unable to write file '{f}{s}': {s}", .{122 return step.fail("unable to write file {f}: {t}", .{ out_path, err });
101 b.cache_root, sub_path, @errorName(err),123
102 });124 maker.generatedPath().* = .{
125 .root_dir = cache_root,
126 .sub_path = try Io.Dir.path.join(arena, &.{ "o", &digest }),
103 };127 };
104128
105 config_header.generated_dir.path = try b.cache_root.join(arena, &.{ "o", &digest });129 try step.writeManifest(maker, &man);
106 try man.writeManifest();
107}130}
108131
109fn render_autoconf_undef(132fn renderAutoConfUndef(
110 step: *Step,133 step: *Step,
111 contents: []const u8,134 contents: []const u8,
112 bw: *Writer,135 w: *Writer,
113 values: *const std.array_hash_map.String(Value),136 values: *const std.array_hash_map.String(Value),
114 src_path: []const u8,137 src_path: []const u8,
115) !void {138) !void {
116 const build = step.owner;139 const build = step.owner;
117 const allocator = build.allocator;140 const allocator = build.allocator;
118141
142 try w.writeAll(c_generated_line);
143
119 var is_used: std.bit_set.Dynamic = try .initEmpty(allocator, values.count());144 var is_used: std.bit_set.Dynamic = try .initEmpty(allocator, values.count());
120 defer is_used.deinit(allocator);145 defer is_used.deinit(allocator);
121146
...@@ -124,15 +149,15 @@ fn render_autoconf_undef(...@@ -124,15 +149,15 @@ fn render_autoconf_undef(
124 var line_it = std.mem.splitScalar(u8, contents, '\n');149 var line_it = std.mem.splitScalar(u8, contents, '\n');
125 while (line_it.next()) |line| : (line_index += 1) {150 while (line_it.next()) |line| : (line_index += 1) {
126 if (!std.mem.startsWith(u8, line, "#")) {151 if (!std.mem.startsWith(u8, line, "#")) {
127 try bw.writeAll(line);152 try w.writeAll(line);
128 try bw.writeByte('\n');153 try w.writeByte('\n');
129 continue;154 continue;
130 }155 }
131 var it = std.mem.tokenizeAny(u8, line[1..], " \t\r");156 var it = std.mem.tokenizeAny(u8, line[1..], " \t\r");
132 const undef = it.next().?;157 const undef = it.next().?;
133 if (!std.mem.eql(u8, undef, "undef")) {158 if (!std.mem.eql(u8, undef, "undef")) {
134 try bw.writeAll(line);159 try w.writeAll(line);
135 try bw.writeByte('\n');160 try w.writeByte('\n');
136 continue;161 continue;
137 }162 }
138 const name = it.next().?;163 const name = it.next().?;
...@@ -144,7 +169,7 @@ fn render_autoconf_undef(...@@ -144,7 +169,7 @@ fn render_autoconf_undef(
144 continue;169 continue;
145 };170 };
146 is_used.set(index);171 is_used.set(index);
147 try renderValueC(bw, name, values.values()[index]);172 try renderValueC(w, name, values.values()[index]);
148 }173 }
149174
150 var unused_value_it = is_used.iterator(.{ .kind = .unset });175 var unused_value_it = is_used.iterator(.{ .kind = .unset });
...@@ -158,7 +183,7 @@ fn render_autoconf_undef(...@@ -158,7 +183,7 @@ fn render_autoconf_undef(
158 }183 }
159}184}
160185
161fn render_autoconf_at(186fn renderAutoconfAt(
162 step: *Step,187 step: *Step,
163 contents: []const u8,188 contents: []const u8,
164 aw: *Writer.Allocating,189 aw: *Writer.Allocating,
...@@ -167,7 +192,9 @@ fn render_autoconf_at(...@@ -167,7 +192,9 @@ fn render_autoconf_at(
167) !void {192) !void {
168 const build = step.owner;193 const build = step.owner;
169 const allocator = build.allocator;194 const allocator = build.allocator;
170 const bw = &aw.writer;195 const w = &aw.writer;
196
197 try w.writeAll(c_generated_line);
171198
172 const used = allocator.alloc(bool, values.count()) catch @panic("OOM");199 const used = allocator.alloc(bool, values.count()) catch @panic("OOM");
173 for (used) |*u| u.* = false;200 for (used) |*u| u.* = false;
...@@ -180,7 +207,7 @@ fn render_autoconf_at(...@@ -180,7 +207,7 @@ fn render_autoconf_at(
180 const last_line = line_it.index == line_it.buffer.len;207 const last_line = line_it.index == line_it.buffer.len;
181208
182 const old_len = aw.written().len;209 const old_len = aw.written().len;
183 expand_variables_autoconf_at(bw, line, values, used) catch |err| switch (err) {210 expandVariablesAutoconfAt(w, line, values, used) catch |err| switch (err) {
184 error.MissingValue => {211 error.MissingValue => {
185 const name = aw.written()[old_len..];212 const name = aw.written()[old_len..];
186 defer aw.shrinkRetainingCapacity(old_len);213 defer aw.shrinkRetainingCapacity(old_len);
...@@ -198,7 +225,7 @@ fn render_autoconf_at(...@@ -198,7 +225,7 @@ fn render_autoconf_at(
198 continue;225 continue;
199 },226 },
200 };227 };
201 if (!last_line) try bw.writeByte('\n');228 if (!last_line) try w.writeByte('\n');
202 }229 }
203230
204 for (values.entries.slice().items(.key), used) |name, u| {231 for (values.entries.slice().items(.key), used) |name, u| {
...@@ -211,16 +238,18 @@ fn render_autoconf_at(...@@ -211,16 +238,18 @@ fn render_autoconf_at(
211 if (any_errors) return error.MakeFailed;238 if (any_errors) return error.MakeFailed;
212}239}
213240
214fn render_cmake(241fn renderCmake(
215 step: *Step,242 step: *Step,
216 contents: []const u8,243 contents: []const u8,
217 bw: *Writer,244 w: *Writer,
218 values: std.array_hash_map.String(Value),245 values: std.array_hash_map.String(Value),
219 src_path: []const u8,246 src_path: []const u8,
220) !void {247) !void {
221 const build = step.owner;248 const build = step.owner;
222 const allocator = build.allocator;249 const allocator = build.allocator;
223250
251 try w.writeAll(c_generated_line);
252
224 var values_copy = try values.clone(allocator);253 var values_copy = try values.clone(allocator);
225 defer values_copy.deinit(allocator);254 defer values_copy.deinit(allocator);
226255
...@@ -230,7 +259,7 @@ fn render_cmake(...@@ -230,7 +259,7 @@ fn render_cmake(
230 while (line_it.next()) |raw_line| : (line_index += 1) {259 while (line_it.next()) |raw_line| : (line_index += 1) {
231 const last_line = line_it.index == line_it.buffer.len;260 const last_line = line_it.index == line_it.buffer.len;
232261
233 const line = expand_variables_cmake(allocator, raw_line, values) catch |err| switch (err) {262 const line = expandVariablesCmake(allocator, raw_line, values) catch |err| switch (err) {
234 error.InvalidCharacter => {263 error.InvalidCharacter => {
235 try step.addError("{s}:{d}: error: invalid character in a variable name", .{264 try step.addError("{s}:{d}: error: invalid character in a variable name", .{
236 src_path, line_index + 1,265 src_path, line_index + 1,
...@@ -249,16 +278,16 @@ fn render_cmake(...@@ -249,16 +278,16 @@ fn render_cmake(
249 defer allocator.free(line);278 defer allocator.free(line);
250279
251 const line_start = std.mem.findNone(u8, line, " \t\r") orelse {280 const line_start = std.mem.findNone(u8, line, " \t\r") orelse {
252 try bw.writeAll(line);281 try w.writeAll(line);
253 if (!last_line) try bw.writeByte('\n');282 if (!last_line) try w.writeByte('\n');
254 continue;283 continue;
255 };284 };
256 const whitespace_prefix = line[0..line_start];285 const whitespace_prefix = line[0..line_start];
257 const trimmed_line = line[line_start..];286 const trimmed_line = line[line_start..];
258287
259 if (!std.mem.startsWith(u8, trimmed_line, "#")) {288 if (!std.mem.startsWith(u8, trimmed_line, "#")) {
260 try bw.writeAll(line);289 try w.writeAll(line);
261 if (!last_line) try bw.writeByte('\n');290 if (!last_line) try w.writeByte('\n');
262 continue;291 continue;
263 }292 }
264293
...@@ -267,8 +296,8 @@ fn render_cmake(...@@ -267,8 +296,8 @@ fn render_cmake(
267 if (!std.mem.eql(u8, cmakedefine, "cmakedefine") and296 if (!std.mem.eql(u8, cmakedefine, "cmakedefine") and
268 !std.mem.eql(u8, cmakedefine, "cmakedefine01"))297 !std.mem.eql(u8, cmakedefine, "cmakedefine01"))
269 {298 {
270 try bw.writeAll(line);299 try w.writeAll(line);
271 if (!last_line) try bw.writeByte('\n');300 if (!last_line) try w.writeByte('\n');
272 continue;301 continue;
273 }302 }
274303
...@@ -339,8 +368,8 @@ fn render_cmake(...@@ -339,8 +368,8 @@ fn render_cmake(
339 value = Value{ .ident = it.rest() };368 value = Value{ .ident = it.rest() };
340 }369 }
341370
342 try bw.writeAll(whitespace_prefix);371 try w.writeAll(whitespace_prefix);
343 try renderValueC(bw, name, value);372 try renderValueC(w, name, value);
344 }373 }
345374
346 if (any_errors) {375 if (any_errors) {
...@@ -348,13 +377,15 @@ fn render_cmake(...@@ -348,13 +377,15 @@ fn render_cmake(
348 }377 }
349}378}
350379
351fn render_blank(380fn renderBlank(
352 gpa: std.mem.Allocator,381 gpa: std.mem.Allocator,
353 bw: *Writer,382 w: *Writer,
354 defines: std.array_hash_map.String(Value),383 defines: std.array_hash_map.String(Value),
355 include_path: []const u8,384 include_path: []const u8,
356 include_guard_override: ?[]const u8,385 include_guard_override: ?[]const u8,
357) !void {386) !void {
387 try w.writeAll(c_generated_line);
388
358 const include_guard_name = include_guard_override orelse blk: {389 const include_guard_name = include_guard_override orelse blk: {
359 const name = try gpa.dupe(u8, include_path);390 const name = try gpa.dupe(u8, include_path);
360 for (name) |*byte| {391 for (name) |*byte| {
...@@ -368,51 +399,52 @@ fn render_blank(...@@ -368,51 +399,52 @@ fn render_blank(
368 };399 };
369 defer if (include_guard_override == null) gpa.free(include_guard_name);400 defer if (include_guard_override == null) gpa.free(include_guard_name);
370401
371 try bw.print(402 try w.print(
372 \\#ifndef {[0]s}403 \\#ifndef {[0]s}
373 \\#define {[0]s}404 \\#define {[0]s}
374 \\405 \\
375 , .{include_guard_name});406 , .{include_guard_name});
376407
377 const values = defines.values();408 const values = defines.values();
378 for (defines.keys(), 0..) |name, i| try renderValueC(bw, name, values[i]);409 for (defines.keys(), 0..) |name, i| try renderValueC(w, name, values[i]);
379410
380 try bw.print(411 try w.print(
381 \\#endif /* {s} */412 \\#endif /* {s} */
382 \\413 \\
383 , .{include_guard_name});414 , .{include_guard_name});
384}415}
385416
386fn render_nasm(bw: *Writer, defines: std.array_hash_map.String(Value)) !void {417fn renderNasm(w: *Writer, defines: std.array_hash_map.String(Value)) !void {
387 for (defines.keys(), defines.values()) |name, value| try renderValueNasm(bw, name, value);418 try w.writeAll(asm_generated_line);
419 for (defines.keys(), defines.values()) |name, value| try renderValueNasm(w, name, value);
388}420}
389421
390fn renderValueC(bw: *Writer, name: []const u8, value: Value) !void {422fn renderValueC(w: *Writer, name: []const u8, value: Value) !void {
391 switch (value) {423 switch (value) {
392 .undef => try bw.print("/* #undef {s} */\n", .{name}),424 .undef => try w.print("/* #undef {s} */\n", .{name}),
393 .defined => try bw.print("#define {s}\n", .{name}),425 .defined => try w.print("#define {s}\n", .{name}),
394 .boolean => |b| try bw.print("#define {s} {c}\n", .{ name, @as(u8, '0') + @intFromBool(b) }),426 .boolean => |b| try w.print("#define {s} {c}\n", .{ name, @as(u8, '0') + @intFromBool(b) }),
395 .int => |i| try bw.print("#define {s} {d}\n", .{ name, i }),427 .int => |i| try w.print("#define {s} {d}\n", .{ name, i }),
396 .ident => |ident| try bw.print("#define {s} {s}\n", .{ name, ident }),428 .ident => |ident| try w.print("#define {s} {s}\n", .{ name, ident }),
397 // TODO: use C-specific escaping instead of zig string literals429 // TODO: use C-specific escaping instead of zig string literals
398 .string => |string| try bw.print("#define {s} \"{f}\"\n", .{ name, std.zig.fmtString(string) }),430 .string => |string| try w.print("#define {s} \"{f}\"\n", .{ name, std.zig.fmtString(string) }),
399 }431 }
400}432}
401433
402fn renderValueNasm(bw: *Writer, name: []const u8, value: Value) !void {434fn renderValueNasm(w: *Writer, name: []const u8, value: Value) !void {
403 switch (value) {435 switch (value) {
404 .undef => try bw.print("; %undef {s}\n", .{name}),436 .undef => try w.print("; %undef {s}\n", .{name}),
405 .defined => try bw.print("%define {s}\n", .{name}),437 .defined => try w.print("%define {s}\n", .{name}),
406 .boolean => |b| try bw.print("%define {s} {c}\n", .{ name, @as(u8, '0') + @intFromBool(b) }),438 .boolean => |b| try w.print("%define {s} {c}\n", .{ name, @as(u8, '0') + @intFromBool(b) }),
407 .int => |i| try bw.print("%define {s} {d}\n", .{ name, i }),439 .int => |i| try w.print("%define {s} {d}\n", .{ name, i }),
408 .ident => |ident| try bw.print("%define {s} {s}\n", .{ name, ident }),440 .ident => |ident| try w.print("%define {s} {s}\n", .{ name, ident }),
409 // TODO: use nasm-specific escaping instead of zig string literals441 // TODO: use nasm-specific escaping instead of zig string literals
410 .string => |string| try bw.print("%define {s} \"{f}\"\n", .{ name, std.zig.fmtString(string) }),442 .string => |string| try w.print("%define {s} \"{f}\"\n", .{ name, std.zig.fmtString(string) }),
411 }443 }
412}444}
413445
414fn expand_variables_autoconf_at(446fn expandVariablesAutoconfAt(
415 bw: *Writer,447 w: *Writer,
416 contents: []const u8,448 contents: []const u8,
417 values: *const std.array_hash_map.String(Value),449 values: *const std.array_hash_map.String(Value),
418 used: []bool,450 used: []bool,
...@@ -437,17 +469,17 @@ fn expand_variables_autoconf_at(...@@ -437,17 +469,17 @@ fn expand_variables_autoconf_at(
437 const key = contents[curr + 1 .. close_pos];469 const key = contents[curr + 1 .. close_pos];
438 const index = values.getIndex(key) orelse {470 const index = values.getIndex(key) orelse {
439 // Report the missing key to the caller.471 // Report the missing key to the caller.
440 try bw.writeAll(key);472 try w.writeAll(key);
441 return error.MissingValue;473 return error.MissingValue;
442 };474 };
443 const value = values.entries.slice().items(.value)[index];475 const value = values.entries.slice().items(.value)[index];
444 used[index] = true;476 used[index] = true;
445 try bw.writeAll(contents[source_offset..curr]);477 try w.writeAll(contents[source_offset..curr]);
446 switch (value) {478 switch (value) {
447 .undef, .defined => {},479 .undef, .defined => {},
448 .boolean => |b| try bw.writeByte(@as(u8, '0') + @intFromBool(b)),480 .boolean => |b| try w.writeByte(@as(u8, '0') + @intFromBool(b)),
449 .int => |i| try bw.print("{d}", .{i}),481 .int => |i| try w.print("{d}", .{i}),
450 .ident, .string => |s| try bw.writeAll(s),482 .ident, .string => |s| try w.writeAll(s),
451 }483 }
452484
453 curr = close_pos;485 curr = close_pos;
...@@ -455,10 +487,10 @@ fn expand_variables_autoconf_at(...@@ -455,10 +487,10 @@ fn expand_variables_autoconf_at(
455 }487 }
456 }488 }
457489
458 try bw.writeAll(contents[source_offset..]);490 try w.writeAll(contents[source_offset..]);
459}491}
460492
461fn expand_variables_cmake(493fn expandVariablesCmake(
462 allocator: Allocator,494 allocator: Allocator,
463 contents: []const u8,495 contents: []const u8,
464 values: std.array_hash_map.String(Value),496 values: std.array_hash_map.String(Value),
...@@ -602,7 +634,7 @@ fn testReplaceVariablesAutoconfAt(...@@ -602,7 +634,7 @@ fn testReplaceVariablesAutoconfAt(
602 for (used) |*u| u.* = false;634 for (used) |*u| u.* = false;
603 defer allocator.free(used);635 defer allocator.free(used);
604636
605 try expand_variables_autoconf_at(&aw.writer, contents, values, used);637 try expandVariablesAutoconfAt(&aw.writer, contents, values, used);
606638
607 for (used) |u| if (!u) return error.UnusedValue;639 for (used) |u| if (!u) return error.UnusedValue;
608 try std.testing.expectEqualStrings(expected, aw.written());640 try std.testing.expectEqualStrings(expected, aw.written());
...@@ -614,13 +646,13 @@ fn testReplaceVariablesCMake(...@@ -614,13 +646,13 @@ fn testReplaceVariablesCMake(
614 expected: []const u8,646 expected: []const u8,
615 values: std.array_hash_map.String(Value),647 values: std.array_hash_map.String(Value),
616) !void {648) !void {
617 const actual = try expand_variables_cmake(allocator, contents, values);649 const actual = try expandVariablesCmake(allocator, contents, values);
618 defer allocator.free(actual);650 defer allocator.free(actual);
619651
620 try std.testing.expectEqualStrings(expected, actual);652 try std.testing.expectEqualStrings(expected, actual);
621}653}
622654
623test "expand_variables_autoconf_at simple cases" {655test "expandVariablesAutoconfAt simple cases" {
624 const allocator = std.testing.allocator;656 const allocator = std.testing.allocator;
625 var values: std.array_hash_map.String(Value) = .init(allocator);657 var values: std.array_hash_map.String(Value) = .init(allocator);
626 defer values.deinit();658 defer values.deinit();
...@@ -716,7 +748,7 @@ test "expand_variables_autoconf_at simple cases" {...@@ -716,7 +748,7 @@ test "expand_variables_autoconf_at simple cases" {
716 values.clearRetainingCapacity();748 values.clearRetainingCapacity();
717}749}
718750
719test "expand_variables_autoconf_at edge cases" {751test "expandVariablesAutoconfAt edge cases" {
720 const allocator = std.testing.allocator;752 const allocator = std.testing.allocator;
721 var values: std.array_hash_map.String(Value) = .init(allocator);753 var values: std.array_hash_map.String(Value) = .init(allocator);
722 defer values.deinit();754 defer values.deinit();
...@@ -732,7 +764,7 @@ test "expand_variables_autoconf_at edge cases" {...@@ -732,7 +764,7 @@ test "expand_variables_autoconf_at edge cases" {
732 values.clearRetainingCapacity();764 values.clearRetainingCapacity();
733}765}
734766
735test "expand_variables_cmake simple cases" {767test "expandVariablesCmake simple cases" {
736 const allocator = std.testing.allocator;768 const allocator = std.testing.allocator;
737 var values: std.array_hash_map.String(Value) = .init(allocator);769 var values: std.array_hash_map.String(Value) = .init(allocator);
738 defer values.deinit();770 defer values.deinit();
...@@ -820,7 +852,7 @@ test "expand_variables_cmake simple cases" {...@@ -820,7 +852,7 @@ test "expand_variables_cmake simple cases" {
820 try std.testing.expectError(error.MissingValue, testReplaceVariablesCMake(allocator, "${bad}", "", values));852 try std.testing.expectError(error.MissingValue, testReplaceVariablesCMake(allocator, "${bad}", "", values));
821}853}
822854
823test "expand_variables_cmake edge cases" {855test "expandVariablesCmake edge cases" {
824 const allocator = std.testing.allocator;856 const allocator = std.testing.allocator;
825 var values: std.array_hash_map.String(Value) = .init(allocator);857 var values: std.array_hash_map.String(Value) = .init(allocator);
826 defer values.deinit();858 defer values.deinit();
...@@ -881,7 +913,7 @@ test "expand_variables_cmake edge cases" {...@@ -881,7 +913,7 @@ test "expand_variables_cmake edge cases" {
881 try std.testing.expectError(error.InvalidCharacter, testReplaceVariablesCMake(allocator, "${str@ing}", "", values));913 try std.testing.expectError(error.InvalidCharacter, testReplaceVariablesCMake(allocator, "${str@ing}", "", values));
882}914}
883915
884test "expand_variables_cmake escaped characters" {916test "expandVariablesCmake escaped characters" {
885 const allocator = std.testing.allocator;917 const allocator = std.testing.allocator;
886 var values: std.array_hash_map.String(Value) = .init(allocator);918 var values: std.array_hash_map.String(Value) = .init(allocator);
887 defer values.deinit();919 defer values.deinit();
lib/compiler/Maker/Step/ObjCopy.zig+1-1
...@@ -166,7 +166,7 @@ pub fn make(...@@ -166,7 +166,7 @@ pub fn make(
166166
167 maker.generatedPath(conf_oc.output_file).* = dest_path;167 maker.generatedPath(conf_oc.output_file).* = dest_path;
168168
169 man.writeManifest() catch |err| switch (err) {169 step.writeManifest(maker, &man) catch |err| switch (err) {
170 error.Canceled => |e| return e,170 error.Canceled => |e| return e,
171 else => |e| try step.addError(maker, "failed writing cache manifest: {t}", .{e}),171 else => |e| try step.addError(maker, "failed writing cache manifest: {t}", .{e}),
172 };172 };