authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-02-14 12:47:45-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-03-15 10:48:12-07:00
log02381c037221937e941e03c5e7439383dde8a2a1
treed51532b9fa4773c498723e581e069b7ddb086e81
parent9580fbcf3596a39ba4c7d7af2f3a1df0e0abb746

std.Build: improve debugging of misconfigured steps

* Step.init() now takes an options struct * Step.init() now captures a small stack trace and stores it in the Step so that it can be accessed when printing user-friendly debugging information, including the lines of code that created the step in question.

20 files changed, 209 insertions(+), 68 deletions(-)

lib/std/Build.zig+67-21
......@@ -227,12 +227,19 @@ pub fn create(
227227 .h_dir = undefined,
228228 .dest_dir = env_map.get("DESTDIR"),
229229 .installed_files = ArrayList(InstalledFile).init(allocator),
230 .install_tls = TopLevelStep{
231 .step = Step.initNoOp(.top_level, "install", allocator),
230 .install_tls = .{
231 .step = Step.init(allocator, .{
232 .id = .top_level,
233 .name = "install",
234 }),
232235 .description = "Copy build artifacts to prefix path",
233236 },
234 .uninstall_tls = TopLevelStep{
235 .step = Step.init(.top_level, "uninstall", allocator, makeUninstall),
237 .uninstall_tls = .{
238 .step = Step.init(allocator, .{
239 .id = .top_level,
240 .name = "uninstall",
241 .makeFn = makeUninstall,
242 }),
236243 .description = "Remove build artifacts from prefix path",
237244 },
238245 .zig_lib_dir = null,
......@@ -264,11 +271,18 @@ fn createChildOnly(parent: *Build, dep_name: []const u8, build_root: Cache.Direc
264271 child.* = .{
265272 .allocator = allocator,
266273 .install_tls = .{
267 .step = Step.initNoOp(.top_level, "install", allocator),
274 .step = Step.init(allocator, .{
275 .id = .top_level,
276 .name = "install",
277 }),
268278 .description = "Copy build artifacts to prefix path",
269279 },
270280 .uninstall_tls = .{
271 .step = Step.init(.top_level, "uninstall", allocator, makeUninstall),
281 .step = Step.init(allocator, .{
282 .id = .top_level,
283 .name = "uninstall",
284 .makeFn = makeUninstall,
285 }),
272286 .description = "Remove build artifacts from prefix path",
273287 },
274288 .user_input_options = UserInputOptionsMap.init(allocator),
......@@ -634,7 +648,11 @@ pub fn addConfigHeader(
634648 options: ConfigHeaderStep.Options,
635649 values: anytype,
636650) *ConfigHeaderStep {
637 const config_header_step = ConfigHeaderStep.create(b, options);
651 var options_copy = options;
652 if (options_copy.first_ret_addr == null)
653 options_copy.first_ret_addr = @returnAddress();
654
655 const config_header_step = ConfigHeaderStep.create(b, options_copy);
638656 config_header_step.addValues(values);
639657 return config_header_step;
640658}
......@@ -858,7 +876,10 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
858876pub fn step(self: *Build, name: []const u8, description: []const u8) *Step {
859877 const step_info = self.allocator.create(TopLevelStep) catch @panic("OOM");
860878 step_info.* = TopLevelStep{
861 .step = Step.initNoOp(.top_level, name, self.allocator),
879 .step = Step.init(self.allocator, .{
880 .id = .top_level,
881 .name = name,
882 }),
862883 .description = self.dupe(description),
863884 };
864885 self.top_level_steps.put(self.allocator, step_info.step.name, step_info) catch @panic("OOM");
......@@ -1153,7 +1174,7 @@ pub fn spawnChildEnvMap(self: *Build, cwd: ?[]const u8, env_map: *const EnvMap,
11531174 printCmd(self.allocator, cwd, argv);
11541175 }
11551176
1156 if (!std.process.can_spawn)
1177 if (!process.can_spawn)
11571178 return error.ExecNotSupported;
11581179
11591180 var child = std.ChildProcess.init(argv, self.allocator);
......@@ -1355,7 +1376,7 @@ pub fn execAllowFail(
13551376) ExecError![]u8 {
13561377 assert(argv.len != 0);
13571378
1358 if (!std.process.can_spawn)
1379 if (!process.can_spawn)
13591380 return error.ExecNotSupported;
13601381
13611382 const max_output_size = 400 * 1024;
......@@ -1395,7 +1416,7 @@ pub fn execFromStep(b: *Build, argv: []const []const u8, s: *Step) ![]u8 {
13951416 printCmd(b.allocator, null, argv);
13961417 }
13971418
1398 if (!std.process.can_spawn) {
1419 if (!process.can_spawn) {
13991420 s.result.stderr = b.fmt("Unable to spawn the following command: cannot spawn child processes\n{s}", .{
14001421 try allocPrintCmd(b.allocator, null, argv),
14011422 });
......@@ -1458,7 +1479,7 @@ fn unwrapExecResult(
14581479/// inside step make() functions. If any errors occur, it fails the build with
14591480/// a helpful message.
14601481pub fn exec(b: *Build, argv: []const []const u8) []u8 {
1461 if (!std.process.can_spawn) {
1482 if (!process.can_spawn) {
14621483 std.debug.print("unable to spawn the following command: cannot spawn child process\n{s}", .{
14631484 try allocPrintCmd(b.allocator, null, argv),
14641485 });
......@@ -1539,7 +1560,7 @@ pub fn dependency(b: *Build, name: []const u8, args: anytype) *Dependency {
15391560
15401561 const full_path = b.pathFromRoot("build.zig.zon");
15411562 std.debug.print("no dependency named '{s}' in '{s}'. All packages used in build.zig must be declared in this file.\n", .{ name, full_path });
1542 std.process.exit(1);
1563 process.exit(1);
15431564}
15441565
15451566fn dependencyInner(
......@@ -1555,7 +1576,7 @@ fn dependencyInner(
15551576 std.debug.print("unable to open '{s}': {s}\n", .{
15561577 build_root_string, @errorName(err),
15571578 });
1558 std.process.exit(1);
1579 process.exit(1);
15591580 },
15601581 };
15611582 const sub_builder = b.createChild(name, build_root, args) catch @panic("unhandled error");
......@@ -1599,7 +1620,7 @@ pub const GeneratedFile = struct {
15991620
16001621 pub fn getPath(self: GeneratedFile) []const u8 {
16011622 return self.path orelse std.debug.panic(
1602 "getPath() was called on a GeneratedFile that wasn't build yet. Is there a missing Step dependency on step '{s}'?",
1623 "getPath() was called on a GeneratedFile that wasn't built yet. Is there a missing Step dependency on step '{s}'?",
16031624 .{self.step.name},
16041625 );
16051626 }
......@@ -1639,12 +1660,16 @@ pub const FileSource = union(enum) {
16391660 }
16401661
16411662 /// Should only be called during make(), returns a path relative to the build root or absolute.
1642 pub fn getPath(self: FileSource, builder: *Build) []const u8 {
1643 const path = switch (self) {
1644 .path => |p| builder.pathFromRoot(p),
1645 .generated => |gen| gen.getPath(),
1646 };
1647 return path;
1663 pub fn getPath(self: FileSource, src_builder: *Build) []const u8 {
1664 switch (self) {
1665 .path => |p| return src_builder.pathFromRoot(p),
1666 .generated => |gen| return gen.path orelse {
1667 std.debug.getStderrMutex().lock();
1668 const stderr = std.io.getStdErr();
1669 dumpBadGetPathHelp(gen.step, stderr, src_builder) catch {};
1670 @panic("unable to get path");
1671 },
1672 }
16481673 }
16491674
16501675 /// Duplicates the file source for a given builder.
......@@ -1656,6 +1681,27 @@ pub const FileSource = union(enum) {
16561681 }
16571682};
16581683
1684fn dumpBadGetPathHelp(s: *Step, stderr: fs.File, src_builder: *Build) anyerror!void {
1685 try stderr.writer().print(
1686 \\getPath() was called on a GeneratedFile that wasn't built yet.
1687 \\ source package path: {s}
1688 \\ Is there a missing Step dependency on step '{s}'?
1689 \\ The step was created by this stack trace:
1690 \\
1691 , .{
1692 src_builder.build_root.path orelse ".",
1693 s.name,
1694 });
1695 const debug_info = std.debug.getSelfDebugInfo() catch |err| {
1696 try stderr.writer().print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)});
1697 return;
1698 };
1699 std.debug.writeStackTrace(s.getStackTrace(), stderr.writer(), debug_info.allocator, debug_info, std.debug.detectTTYConfig(stderr)) catch |err| {
1700 try stderr.writer().print("Unable to dump stack trace: {s}\n", .{@errorName(err)});
1701 return;
1702 };
1703}
1704
16591705/// Allocates a new string for assigning a value to a named macro.
16601706/// If the value is omitted, it is set to 1.
16611707/// `name` and `value` need not live longer than the function call.
lib/std/Build/CheckFileStep.zig+5-1
......@@ -21,7 +21,11 @@ pub fn create(
2121 const self = builder.allocator.create(CheckFileStep) catch @panic("OOM");
2222 self.* = CheckFileStep{
2323 .builder = builder,
24 .step = Step.init(.check_file, "CheckFile", builder.allocator, make),
24 .step = Step.init(builder.allocator, .{
25 .id = .check_file,
26 .name = "CheckFile",
27 .makeFn = make,
28 }),
2529 .source = source.dupe(builder),
2630 .expected_matches = builder.dupeStrings(expected_matches),
2731 };
lib/std/Build/CheckObjectStep.zig+5-1
......@@ -27,7 +27,11 @@ pub fn create(builder: *std.Build, source: std.Build.FileSource, obj_format: std
2727 const self = gpa.create(CheckObjectStep) catch @panic("OOM");
2828 self.* = .{
2929 .builder = builder,
30 .step = Step.init(.check_file, "CheckObject", gpa, make),
30 .step = Step.init(gpa, .{
31 .id = .check_file,
32 .name = "CheckObject",
33 .makeFn = make,
34 }),
3135 .source = source.dupe(builder),
3236 .checks = std.ArrayList(Check).init(gpa),
3337 .obj_format = obj_format,
lib/std/Build/CompileStep.zig+5-1
......@@ -326,7 +326,11 @@ pub fn create(builder: *std.Build, options: Options) *CompileStep {
326326 .root_src = root_src,
327327 .name = name,
328328 .frameworks = StringHashMap(FrameworkLinkInfo).init(builder.allocator),
329 .step = Step.init(base_id, name, builder.allocator, make),
329 .step = Step.init(builder.allocator, .{
330 .id = base_id,
331 .name = name,
332 .makeFn = make,
333 }),
330334 .version = options.version,
331335 .out_filename = undefined,
332336 .out_h_filename = builder.fmt("{s}.h", .{name}),
lib/std/Build/ConfigHeaderStep.zig+7-1
......@@ -46,6 +46,7 @@ pub const Options = struct {
4646 style: Style = .blank,
4747 max_bytes: usize = 2 * 1024 * 1024,
4848 include_path: ?[]const u8 = null,
49 first_ret_addr: ?usize = null,
4950};
5051
5152pub fn create(builder: *std.Build, options: Options) *ConfigHeaderStep {
......@@ -56,7 +57,12 @@ pub fn create(builder: *std.Build, options: Options) *ConfigHeaderStep {
5657 builder.fmt("configure {s} header", .{@tagName(options.style)});
5758 self.* = .{
5859 .builder = builder,
59 .step = Step.init(base_id, name, builder.allocator, make),
60 .step = Step.init(builder.allocator, .{
61 .id = base_id,
62 .name = name,
63 .makeFn = make,
64 .first_ret_addr = options.first_ret_addr orelse @returnAddress(),
65 }),
6066 .style = options.style,
6167 .values = std.StringArrayHashMap(Value).init(builder.allocator),
6268
lib/std/Build/EmulatableRunStep.zig+5-1
......@@ -56,7 +56,11 @@ pub fn create(builder: *std.Build, name: []const u8, artifact: *CompileStep) *Em
5656
5757 self.* = .{
5858 .builder = builder,
59 .step = Step.init(.emulatable_run, name, builder.allocator, make),
59 .step = Step.init(builder.allocator, .{
60 .id = .emulatable_run,
61 .name = name,
62 .makeFn = make,
63 }),
6064 .exe = artifact,
6165 .env_map = null,
6266 .cwd = null,
lib/std/Build/FmtStep.zig+5-1
......@@ -12,7 +12,11 @@ pub fn create(builder: *std.Build, paths: []const []const u8) *FmtStep {
1212 const self = builder.allocator.create(FmtStep) catch @panic("OOM");
1313 const name = "zig fmt";
1414 self.* = FmtStep{
15 .step = Step.init(.fmt, name, builder.allocator, make),
15 .step = Step.init(builder.allocator, .{
16 .id = .fmt,
17 .name = name,
18 .makeFn = make,
19 }),
1620 .builder = builder,
1721 .argv = builder.allocator.alloc([]u8, paths.len + 2) catch @panic("OOM"),
1822 };
lib/std/Build/InstallArtifactStep.zig+5-1
......@@ -19,7 +19,11 @@ pub fn create(builder: *std.Build, artifact: *CompileStep) *InstallArtifactStep
1919 const self = builder.allocator.create(InstallArtifactStep) catch @panic("OOM");
2020 self.* = InstallArtifactStep{
2121 .builder = builder,
22 .step = Step.init(.install_artifact, builder.fmt("install {s}", .{artifact.step.name}), builder.allocator, make),
22 .step = Step.init(builder.allocator, .{
23 .id = base_id,
24 .name = builder.fmt("install {s}", .{artifact.step.name}),
25 .makeFn = make,
26 }),
2327 .artifact = artifact,
2428 .dest_dir = artifact.override_dest_dir orelse switch (artifact.kind) {
2529 .obj => @panic("Cannot install a .obj build artifact."),
lib/std/Build/InstallDirStep.zig+6-2
......@@ -45,9 +45,13 @@ pub fn init(
4545 options: Options,
4646) InstallDirStep {
4747 builder.pushInstalledFile(options.install_dir, options.install_subdir);
48 return InstallDirStep{
48 return .{
4949 .builder = builder,
50 .step = Step.init(.install_dir, builder.fmt("install {s}/", .{options.source_dir}), builder.allocator, make),
50 .step = Step.init(builder.allocator, .{
51 .id = .install_dir,
52 .name = builder.fmt("install {s}/", .{options.source_dir}),
53 .makeFn = make,
54 }),
5155 .options = options.dupe(builder),
5256 };
5357}
lib/std/Build/InstallFileStep.zig+5-1
......@@ -24,7 +24,11 @@ pub fn init(
2424 builder.pushInstalledFile(dir, dest_rel_path);
2525 return InstallFileStep{
2626 .builder = builder,
27 .step = Step.init(.install_file, builder.fmt("install {s} to {s}", .{ source.getDisplayName(), dest_rel_path }), builder.allocator, make),
27 .step = Step.init(builder.allocator, .{
28 .id = .install_file,
29 .name = builder.fmt("install {s} to {s}", .{ source.getDisplayName(), dest_rel_path }),
30 .makeFn = make,
31 }),
2832 .source = source.dupe(builder),
2933 .dir = dir.dupe(builder),
3034 .dest_rel_path = builder.dupePath(dest_rel_path),
lib/std/Build/LogStep.zig+5-1
......@@ -12,7 +12,11 @@ data: []const u8,
1212pub fn init(builder: *std.Build, data: []const u8) LogStep {
1313 return LogStep{
1414 .builder = builder,
15 .step = Step.init(.log, builder.fmt("log {s}", .{data}), builder.allocator, make),
15 .step = Step.init(builder.allocator, .{
16 .id = .log,
17 .name = builder.fmt("log {s}", .{data}),
18 .makeFn = make,
19 }),
1620 .data = builder.dupe(data),
1721 };
1822}
lib/std/Build/ObjCopyStep.zig+5-6
......@@ -44,12 +44,11 @@ pub fn create(
4444) *ObjCopyStep {
4545 const self = builder.allocator.create(ObjCopyStep) catch @panic("OOM");
4646 self.* = ObjCopyStep{
47 .step = Step.init(
48 base_id,
49 builder.fmt("objcopy {s}", .{file_source.getDisplayName()}),
50 builder.allocator,
51 make,
52 ),
47 .step = Step.init(builder.allocator, .{
48 .id = base_id,
49 .name = builder.fmt("objcopy {s}", .{file_source.getDisplayName()}),
50 .makeFn = make,
51 }),
5352 .builder = builder,
5453 .file_source = file_source,
5554 .basename = options.basename orelse file_source.getDisplayName(),
lib/std/Build/OptionsStep.zig+5-1
......@@ -22,7 +22,11 @@ pub fn create(builder: *std.Build) *OptionsStep {
2222 const self = builder.allocator.create(OptionsStep) catch @panic("OOM");
2323 self.* = .{
2424 .builder = builder,
25 .step = Step.init(.options, "options", builder.allocator, make),
25 .step = Step.init(builder.allocator, .{
26 .id = base_id,
27 .name = "options",
28 .makeFn = make,
29 }),
2630 .generated_file = undefined,
2731 .contents = std.ArrayList(u8).init(builder.allocator),
2832 .artifact_args = std.ArrayList(OptionArtifactArg).init(builder.allocator),
lib/std/Build/RemoveDirStep.zig+5-1
......@@ -13,7 +13,11 @@ dir_path: []const u8,
1313pub fn init(builder: *std.Build, dir_path: []const u8) RemoveDirStep {
1414 return RemoveDirStep{
1515 .builder = builder,
16 .step = Step.init(.remove_dir, builder.fmt("RemoveDir {s}", .{dir_path}), builder.allocator, make),
16 .step = Step.init(builder.allocator, .{
17 .id = .remove_dir,
18 .name = builder.fmt("RemoveDir {s}", .{dir_path}),
19 .makeFn = make,
20 }),
1721 .dir_path = builder.dupePath(dir_path),
1822 };
1923}
lib/std/Build/RunStep.zig+6-2
......@@ -69,9 +69,13 @@ pub const Arg = union(enum) {
6969
7070pub fn create(builder: *std.Build, name: []const u8) *RunStep {
7171 const self = builder.allocator.create(RunStep) catch @panic("OOM");
72 self.* = RunStep{
72 self.* = .{
7373 .builder = builder,
74 .step = Step.init(base_id, name, builder.allocator, make),
74 .step = Step.init(builder.allocator, .{
75 .id = base_id,
76 .name = name,
77 .makeFn = make,
78 }),
7579 .argv = ArrayList(Arg).init(builder.allocator),
7680 .cwd = null,
7781 .env_map = null,
lib/std/Build/Step.zig+36-12
......@@ -11,6 +11,11 @@ result: struct {
1111 err_code: anyerror,
1212 stderr: []u8,
1313},
14/// The return addresss associated with creation of this step that can be useful
15/// to print along with debugging messages.
16debug_stack_trace: [n_debug_stack_frames]usize,
17
18const n_debug_stack_frames = 4;
1419
1520pub const State = enum {
1621 precheck_unstarted,
......@@ -66,16 +71,26 @@ pub const Id = enum {
6671 }
6772};
6873
69pub fn init(
74pub const Options = struct {
7075 id: Id,
7176 name: []const u8,
72 allocator: Allocator,
73 makeFn: *const fn (self: *Step) anyerror!void,
74) Step {
75 return Step{
76 .id = id,
77 .name = allocator.dupe(u8, name) catch @panic("OOM"),
78 .makeFn = makeFn,
77 makeFn: *const fn (self: *Step) anyerror!void = makeNoOp,
78 first_ret_addr: ?usize = null,
79};
80
81pub fn init(allocator: Allocator, options: Options) Step {
82 var addresses = [1]usize{0} ** n_debug_stack_frames;
83 const first_ret_addr = options.first_ret_addr orelse @returnAddress();
84 var stack_trace = std.builtin.StackTrace{
85 .instruction_addresses = &addresses,
86 .index = 0,
87 };
88 std.debug.captureStackTrace(first_ret_addr, &stack_trace);
89
90 return .{
91 .id = options.id,
92 .name = allocator.dupe(u8, options.name) catch @panic("OOM"),
93 .makeFn = options.makeFn,
7994 .dependencies = std.ArrayList(*Step).init(allocator),
8095 .dependants = .{},
8196 .state = .precheck_unstarted,
......@@ -83,13 +98,10 @@ pub fn init(
8398 .err_code = undefined,
8499 .stderr = &.{},
85100 },
101 .debug_stack_trace = addresses,
86102 };
87103}
88104
89pub fn initNoOp(id: Id, name: []const u8, allocator: Allocator) Step {
90 return init(id, name, allocator, makeNoOp);
91}
92
93105pub fn make(self: *Step) !void {
94106 try self.makeFn(self);
95107}
......@@ -98,6 +110,18 @@ pub fn dependOn(self: *Step, other: *Step) void {
98110 self.dependencies.append(other) catch @panic("OOM");
99111}
100112
113pub fn getStackTrace(s: *Step) std.builtin.StackTrace {
114 const stack_addresses = &s.debug_stack_trace;
115 var len: usize = 0;
116 while (len < n_debug_stack_frames and stack_addresses[len] != 0) {
117 len += 1;
118 }
119 return .{
120 .instruction_addresses = stack_addresses,
121 .index = len,
122 };
123}
124
101125fn makeNoOp(self: *Step) anyerror!void {
102126 _ = self;
103127}
lib/std/Build/TranslateCStep.zig+5-1
......@@ -30,7 +30,11 @@ pub fn create(builder: *std.Build, options: Options) *TranslateCStep {
3030 const self = builder.allocator.create(TranslateCStep) catch @panic("OOM");
3131 const source = options.source_file.dupe(builder);
3232 self.* = TranslateCStep{
33 .step = Step.init(.translate_c, "translate-c", builder.allocator, make),
33 .step = Step.init(builder.allocator, .{
34 .id = .translate_c,
35 .name = "translate-c",
36 .makeFn = make,
37 }),
3438 .builder = builder,
3539 .source = source,
3640 .include_dirs = std.ArrayList([]const u8).init(builder.allocator),
lib/std/Build/WriteFileStep.zig+5-1
......@@ -37,7 +37,11 @@ pub const Contents = union(enum) {
3737pub fn init(builder: *std.Build) WriteFileStep {
3838 return .{
3939 .builder = builder,
40 .step = Step.init(.write_file, "writefile", builder.allocator, make),
40 .step = Step.init(builder.allocator, .{
41 .id = .write_file,
42 .name = "writefile",
43 .makeFn = make,
44 }),
4145 .files = .{},
4246 .output_source_files = .{},
4347 };
test/link/macho/uuid/build.zig+12-10
......@@ -90,10 +90,13 @@ const InstallWithRename = struct {
9090 const self = builder.allocator.create(InstallWithRename) catch @panic("OOM");
9191 self.* = InstallWithRename{
9292 .builder = builder,
93 .step = Step.init(.custom, builder.fmt("install and rename: {s} -> {s}", .{
94 source.getDisplayName(),
95 name,
96 }), builder.allocator, make),
93 .step = Step.init(builder.allocator, .{
94 .id = .custom,
95 .name = builder.fmt("install and rename: {s} -> {s}", .{
96 source.getDisplayName(), name,
97 }),
98 .makeFn = make,
99 }),
97100 .source = source,
98101 .name = builder.dupe(name),
99102 };
......@@ -123,15 +126,14 @@ const CompareUuid = struct {
123126 const self = builder.allocator.create(CompareUuid) catch @panic("OOM");
124127 self.* = CompareUuid{
125128 .builder = builder,
126 .step = Step.init(
127 .custom,
128 builder.fmt("compare uuid: {s} and {s}", .{
129 .step = Step.init(builder.allocator, .{
130 .id = .custom,
131 .name = builder.fmt("compare uuid: {s} and {s}", .{
129132 lhs,
130133 rhs,
131134 }),
132 builder.allocator,
133 make,
134 ),
135 .makeFn = make,
136 }),
135137 .lhs = lhs,
136138 .rhs = rhs,
137139 };
test/tests.zig+10-2
......@@ -858,7 +858,11 @@ pub const StackTracesContext = struct {
858858 const allocator = context.b.allocator;
859859 const ptr = allocator.create(RunAndCompareStep) catch unreachable;
860860 ptr.* = RunAndCompareStep{
861 .step = Step.init(.custom, "StackTraceCompareOutputStep", allocator, make),
861 .step = Step.init(allocator, .{
862 .id = .custom,
863 .name = "StackTraceCompareOutputStep",
864 .makeFn = make,
865 }),
862866 .context = context,
863867 .exe = exe,
864868 .name = name,
......@@ -1194,7 +1198,11 @@ pub const GenHContext = struct {
11941198 const allocator = context.b.allocator;
11951199 const ptr = allocator.create(GenHCmpOutputStep) catch unreachable;
11961200 ptr.* = GenHCmpOutputStep{
1197 .step = Step.init(.Custom, "ParseCCmpOutput", allocator, make),
1201 .step = Step.init(allocator, .{
1202 .id = .custom,
1203 .name = "ParseCCmpOutput",
1204 .makeFn = make,
1205 }),
11981206 .context = context,
11991207 .obj = obj,
12001208 .name = name,