| author | |
| committer | |
| log | 02381c037221937e941e03c5e7439383dde8a2a1 |
| tree | d51532b9fa4773c498723e581e069b7ddb086e81 |
| parent | 9580fbcf3596a39ba4c7d7af2f3a1df0e0abb746 |
* 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( |
| 227 | 227 | .h_dir = undefined, |
| 228 | 228 | .dest_dir = env_map.get("DESTDIR"), |
| 229 | 229 | .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 | }), | |
| 232 | 235 | .description = "Copy build artifacts to prefix path", |
| 233 | 236 | }, |
| 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 | }), | |
| 236 | 243 | .description = "Remove build artifacts from prefix path", |
| 237 | 244 | }, |
| 238 | 245 | .zig_lib_dir = null, |
| ... | ... | @@ -264,11 +271,18 @@ fn createChildOnly(parent: *Build, dep_name: []const u8, build_root: Cache.Direc |
| 264 | 271 | child.* = .{ |
| 265 | 272 | .allocator = allocator, |
| 266 | 273 | .install_tls = .{ |
| 267 | .step = Step.initNoOp(.top_level, "install", allocator), | |
| 274 | .step = Step.init(allocator, .{ | |
| 275 | .id = .top_level, | |
| 276 | .name = "install", | |
| 277 | }), | |
| 268 | 278 | .description = "Copy build artifacts to prefix path", |
| 269 | 279 | }, |
| 270 | 280 | .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 | }), | |
| 272 | 286 | .description = "Remove build artifacts from prefix path", |
| 273 | 287 | }, |
| 274 | 288 | .user_input_options = UserInputOptionsMap.init(allocator), |
| ... | ... | @@ -634,7 +648,11 @@ pub fn addConfigHeader( |
| 634 | 648 | options: ConfigHeaderStep.Options, |
| 635 | 649 | values: anytype, |
| 636 | 650 | ) *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); | |
| 638 | 656 | config_header_step.addValues(values); |
| 639 | 657 | return config_header_step; |
| 640 | 658 | } |
| ... | ... | @@ -858,7 +876,10 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_ |
| 858 | 876 | pub fn step(self: *Build, name: []const u8, description: []const u8) *Step { |
| 859 | 877 | const step_info = self.allocator.create(TopLevelStep) catch @panic("OOM"); |
| 860 | 878 | 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 | }), | |
| 862 | 883 | .description = self.dupe(description), |
| 863 | 884 | }; |
| 864 | 885 | 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, |
| 1153 | 1174 | printCmd(self.allocator, cwd, argv); |
| 1154 | 1175 | } |
| 1155 | 1176 | |
| 1156 | if (!std.process.can_spawn) | |
| 1177 | if (!process.can_spawn) | |
| 1157 | 1178 | return error.ExecNotSupported; |
| 1158 | 1179 | |
| 1159 | 1180 | var child = std.ChildProcess.init(argv, self.allocator); |
| ... | ... | @@ -1355,7 +1376,7 @@ pub fn execAllowFail( |
| 1355 | 1376 | ) ExecError![]u8 { |
| 1356 | 1377 | assert(argv.len != 0); |
| 1357 | 1378 | |
| 1358 | if (!std.process.can_spawn) | |
| 1379 | if (!process.can_spawn) | |
| 1359 | 1380 | return error.ExecNotSupported; |
| 1360 | 1381 | |
| 1361 | 1382 | const max_output_size = 400 * 1024; |
| ... | ... | @@ -1395,7 +1416,7 @@ pub fn execFromStep(b: *Build, argv: []const []const u8, s: *Step) ![]u8 { |
| 1395 | 1416 | printCmd(b.allocator, null, argv); |
| 1396 | 1417 | } |
| 1397 | 1418 | |
| 1398 | if (!std.process.can_spawn) { | |
| 1419 | if (!process.can_spawn) { | |
| 1399 | 1420 | s.result.stderr = b.fmt("Unable to spawn the following command: cannot spawn child processes\n{s}", .{ |
| 1400 | 1421 | try allocPrintCmd(b.allocator, null, argv), |
| 1401 | 1422 | }); |
| ... | ... | @@ -1458,7 +1479,7 @@ fn unwrapExecResult( |
| 1458 | 1479 | /// inside step make() functions. If any errors occur, it fails the build with |
| 1459 | 1480 | /// a helpful message. |
| 1460 | 1481 | pub fn exec(b: *Build, argv: []const []const u8) []u8 { |
| 1461 | if (!std.process.can_spawn) { | |
| 1482 | if (!process.can_spawn) { | |
| 1462 | 1483 | std.debug.print("unable to spawn the following command: cannot spawn child process\n{s}", .{ |
| 1463 | 1484 | try allocPrintCmd(b.allocator, null, argv), |
| 1464 | 1485 | }); |
| ... | ... | @@ -1539,7 +1560,7 @@ pub fn dependency(b: *Build, name: []const u8, args: anytype) *Dependency { |
| 1539 | 1560 | |
| 1540 | 1561 | const full_path = b.pathFromRoot("build.zig.zon"); |
| 1541 | 1562 | 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); | |
| 1543 | 1564 | } |
| 1544 | 1565 | |
| 1545 | 1566 | fn dependencyInner( |
| ... | ... | @@ -1555,7 +1576,7 @@ fn dependencyInner( |
| 1555 | 1576 | std.debug.print("unable to open '{s}': {s}\n", .{ |
| 1556 | 1577 | build_root_string, @errorName(err), |
| 1557 | 1578 | }); |
| 1558 | std.process.exit(1); | |
| 1579 | process.exit(1); | |
| 1559 | 1580 | }, |
| 1560 | 1581 | }; |
| 1561 | 1582 | const sub_builder = b.createChild(name, build_root, args) catch @panic("unhandled error"); |
| ... | ... | @@ -1599,7 +1620,7 @@ pub const GeneratedFile = struct { |
| 1599 | 1620 | |
| 1600 | 1621 | pub fn getPath(self: GeneratedFile) []const u8 { |
| 1601 | 1622 | 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}'?", | |
| 1603 | 1624 | .{self.step.name}, |
| 1604 | 1625 | ); |
| 1605 | 1626 | } |
| ... | ... | @@ -1639,12 +1660,16 @@ pub const FileSource = union(enum) { |
| 1639 | 1660 | } |
| 1640 | 1661 | |
| 1641 | 1662 | /// 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 | } | |
| 1648 | 1673 | } |
| 1649 | 1674 | |
| 1650 | 1675 | /// Duplicates the file source for a given builder. |
| ... | ... | @@ -1656,6 +1681,27 @@ pub const FileSource = union(enum) { |
| 1656 | 1681 | } |
| 1657 | 1682 | }; |
| 1658 | 1683 | |
| 1684 | fn 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 | ||
| 1659 | 1705 | /// Allocates a new string for assigning a value to a named macro. |
| 1660 | 1706 | /// If the value is omitted, it is set to 1. |
| 1661 | 1707 | /// `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( |
| 21 | 21 | const self = builder.allocator.create(CheckFileStep) catch @panic("OOM"); |
| 22 | 22 | self.* = CheckFileStep{ |
| 23 | 23 | .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 | }), | |
| 25 | 29 | .source = source.dupe(builder), |
| 26 | 30 | .expected_matches = builder.dupeStrings(expected_matches), |
| 27 | 31 | }; |
lib/std/Build/CheckObjectStep.zig+5-1| ... | ... | @@ -27,7 +27,11 @@ pub fn create(builder: *std.Build, source: std.Build.FileSource, obj_format: std |
| 27 | 27 | const self = gpa.create(CheckObjectStep) catch @panic("OOM"); |
| 28 | 28 | self.* = .{ |
| 29 | 29 | .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 | }), | |
| 31 | 35 | .source = source.dupe(builder), |
| 32 | 36 | .checks = std.ArrayList(Check).init(gpa), |
| 33 | 37 | .obj_format = obj_format, |
lib/std/Build/CompileStep.zig+5-1| ... | ... | @@ -326,7 +326,11 @@ pub fn create(builder: *std.Build, options: Options) *CompileStep { |
| 326 | 326 | .root_src = root_src, |
| 327 | 327 | .name = name, |
| 328 | 328 | .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 | }), | |
| 330 | 334 | .version = options.version, |
| 331 | 335 | .out_filename = undefined, |
| 332 | 336 | .out_h_filename = builder.fmt("{s}.h", .{name}), |
lib/std/Build/ConfigHeaderStep.zig+7-1| ... | ... | @@ -46,6 +46,7 @@ pub const Options = struct { |
| 46 | 46 | style: Style = .blank, |
| 47 | 47 | max_bytes: usize = 2 * 1024 * 1024, |
| 48 | 48 | include_path: ?[]const u8 = null, |
| 49 | first_ret_addr: ?usize = null, | |
| 49 | 50 | }; |
| 50 | 51 | |
| 51 | 52 | pub fn create(builder: *std.Build, options: Options) *ConfigHeaderStep { |
| ... | ... | @@ -56,7 +57,12 @@ pub fn create(builder: *std.Build, options: Options) *ConfigHeaderStep { |
| 56 | 57 | builder.fmt("configure {s} header", .{@tagName(options.style)}); |
| 57 | 58 | self.* = .{ |
| 58 | 59 | .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 | }), | |
| 60 | 66 | .style = options.style, |
| 61 | 67 | .values = std.StringArrayHashMap(Value).init(builder.allocator), |
| 62 | 68 |
lib/std/Build/EmulatableRunStep.zig+5-1| ... | ... | @@ -56,7 +56,11 @@ pub fn create(builder: *std.Build, name: []const u8, artifact: *CompileStep) *Em |
| 56 | 56 | |
| 57 | 57 | self.* = .{ |
| 58 | 58 | .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 | }), | |
| 60 | 64 | .exe = artifact, |
| 61 | 65 | .env_map = null, |
| 62 | 66 | .cwd = null, |
lib/std/Build/FmtStep.zig+5-1| ... | ... | @@ -12,7 +12,11 @@ pub fn create(builder: *std.Build, paths: []const []const u8) *FmtStep { |
| 12 | 12 | const self = builder.allocator.create(FmtStep) catch @panic("OOM"); |
| 13 | 13 | const name = "zig fmt"; |
| 14 | 14 | 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 | }), | |
| 16 | 20 | .builder = builder, |
| 17 | 21 | .argv = builder.allocator.alloc([]u8, paths.len + 2) catch @panic("OOM"), |
| 18 | 22 | }; |
lib/std/Build/InstallArtifactStep.zig+5-1| ... | ... | @@ -19,7 +19,11 @@ pub fn create(builder: *std.Build, artifact: *CompileStep) *InstallArtifactStep |
| 19 | 19 | const self = builder.allocator.create(InstallArtifactStep) catch @panic("OOM"); |
| 20 | 20 | self.* = InstallArtifactStep{ |
| 21 | 21 | .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 | }), | |
| 23 | 27 | .artifact = artifact, |
| 24 | 28 | .dest_dir = artifact.override_dest_dir orelse switch (artifact.kind) { |
| 25 | 29 | .obj => @panic("Cannot install a .obj build artifact."), |
lib/std/Build/InstallDirStep.zig+6-2| ... | ... | @@ -45,9 +45,13 @@ pub fn init( |
| 45 | 45 | options: Options, |
| 46 | 46 | ) InstallDirStep { |
| 47 | 47 | builder.pushInstalledFile(options.install_dir, options.install_subdir); |
| 48 | return InstallDirStep{ | |
| 48 | return .{ | |
| 49 | 49 | .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 | }), | |
| 51 | 55 | .options = options.dupe(builder), |
| 52 | 56 | }; |
| 53 | 57 | } |
lib/std/Build/InstallFileStep.zig+5-1| ... | ... | @@ -24,7 +24,11 @@ pub fn init( |
| 24 | 24 | builder.pushInstalledFile(dir, dest_rel_path); |
| 25 | 25 | return InstallFileStep{ |
| 26 | 26 | .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 | }), | |
| 28 | 32 | .source = source.dupe(builder), |
| 29 | 33 | .dir = dir.dupe(builder), |
| 30 | 34 | .dest_rel_path = builder.dupePath(dest_rel_path), |
lib/std/Build/LogStep.zig+5-1| ... | ... | @@ -12,7 +12,11 @@ data: []const u8, |
| 12 | 12 | pub fn init(builder: *std.Build, data: []const u8) LogStep { |
| 13 | 13 | return LogStep{ |
| 14 | 14 | .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 | }), | |
| 16 | 20 | .data = builder.dupe(data), |
| 17 | 21 | }; |
| 18 | 22 | } |
lib/std/Build/ObjCopyStep.zig+5-6| ... | ... | @@ -44,12 +44,11 @@ pub fn create( |
| 44 | 44 | ) *ObjCopyStep { |
| 45 | 45 | const self = builder.allocator.create(ObjCopyStep) catch @panic("OOM"); |
| 46 | 46 | 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 | }), | |
| 53 | 52 | .builder = builder, |
| 54 | 53 | .file_source = file_source, |
| 55 | 54 | .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 { |
| 22 | 22 | const self = builder.allocator.create(OptionsStep) catch @panic("OOM"); |
| 23 | 23 | self.* = .{ |
| 24 | 24 | .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 | }), | |
| 26 | 30 | .generated_file = undefined, |
| 27 | 31 | .contents = std.ArrayList(u8).init(builder.allocator), |
| 28 | 32 | .artifact_args = std.ArrayList(OptionArtifactArg).init(builder.allocator), |
lib/std/Build/RemoveDirStep.zig+5-1| ... | ... | @@ -13,7 +13,11 @@ dir_path: []const u8, |
| 13 | 13 | pub fn init(builder: *std.Build, dir_path: []const u8) RemoveDirStep { |
| 14 | 14 | return RemoveDirStep{ |
| 15 | 15 | .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 | }), | |
| 17 | 21 | .dir_path = builder.dupePath(dir_path), |
| 18 | 22 | }; |
| 19 | 23 | } |
lib/std/Build/RunStep.zig+6-2| ... | ... | @@ -69,9 +69,13 @@ pub const Arg = union(enum) { |
| 69 | 69 | |
| 70 | 70 | pub fn create(builder: *std.Build, name: []const u8) *RunStep { |
| 71 | 71 | const self = builder.allocator.create(RunStep) catch @panic("OOM"); |
| 72 | self.* = RunStep{ | |
| 72 | self.* = .{ | |
| 73 | 73 | .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 | }), | |
| 75 | 79 | .argv = ArrayList(Arg).init(builder.allocator), |
| 76 | 80 | .cwd = null, |
| 77 | 81 | .env_map = null, |
lib/std/Build/Step.zig+36-12| ... | ... | @@ -11,6 +11,11 @@ result: struct { |
| 11 | 11 | err_code: anyerror, |
| 12 | 12 | stderr: []u8, |
| 13 | 13 | }, |
| 14 | /// The return addresss associated with creation of this step that can be useful | |
| 15 | /// to print along with debugging messages. | |
| 16 | debug_stack_trace: [n_debug_stack_frames]usize, | |
| 17 | ||
| 18 | const n_debug_stack_frames = 4; | |
| 14 | 19 | |
| 15 | 20 | pub const State = enum { |
| 16 | 21 | precheck_unstarted, |
| ... | ... | @@ -66,16 +71,26 @@ pub const Id = enum { |
| 66 | 71 | } |
| 67 | 72 | }; |
| 68 | 73 | |
| 69 | pub fn init( | |
| 74 | pub const Options = struct { | |
| 70 | 75 | id: Id, |
| 71 | 76 | 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 | ||
| 81 | pub 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, | |
| 79 | 94 | .dependencies = std.ArrayList(*Step).init(allocator), |
| 80 | 95 | .dependants = .{}, |
| 81 | 96 | .state = .precheck_unstarted, |
| ... | ... | @@ -83,13 +98,10 @@ pub fn init( |
| 83 | 98 | .err_code = undefined, |
| 84 | 99 | .stderr = &.{}, |
| 85 | 100 | }, |
| 101 | .debug_stack_trace = addresses, | |
| 86 | 102 | }; |
| 87 | 103 | } |
| 88 | 104 | |
| 89 | pub fn initNoOp(id: Id, name: []const u8, allocator: Allocator) Step { | |
| 90 | return init(id, name, allocator, makeNoOp); | |
| 91 | } | |
| 92 | ||
| 93 | 105 | pub fn make(self: *Step) !void { |
| 94 | 106 | try self.makeFn(self); |
| 95 | 107 | } |
| ... | ... | @@ -98,6 +110,18 @@ pub fn dependOn(self: *Step, other: *Step) void { |
| 98 | 110 | self.dependencies.append(other) catch @panic("OOM"); |
| 99 | 111 | } |
| 100 | 112 | |
| 113 | pub 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 | ||
| 101 | 125 | fn makeNoOp(self: *Step) anyerror!void { |
| 102 | 126 | _ = self; |
| 103 | 127 | } |
lib/std/Build/TranslateCStep.zig+5-1| ... | ... | @@ -30,7 +30,11 @@ pub fn create(builder: *std.Build, options: Options) *TranslateCStep { |
| 30 | 30 | const self = builder.allocator.create(TranslateCStep) catch @panic("OOM"); |
| 31 | 31 | const source = options.source_file.dupe(builder); |
| 32 | 32 | 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 | }), | |
| 34 | 38 | .builder = builder, |
| 35 | 39 | .source = source, |
| 36 | 40 | .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) { |
| 37 | 37 | pub fn init(builder: *std.Build) WriteFileStep { |
| 38 | 38 | return .{ |
| 39 | 39 | .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 | }), | |
| 41 | 45 | .files = .{}, |
| 42 | 46 | .output_source_files = .{}, |
| 43 | 47 | }; |
test/link/macho/uuid/build.zig+12-10| ... | ... | @@ -90,10 +90,13 @@ const InstallWithRename = struct { |
| 90 | 90 | const self = builder.allocator.create(InstallWithRename) catch @panic("OOM"); |
| 91 | 91 | self.* = InstallWithRename{ |
| 92 | 92 | .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 | }), | |
| 97 | 100 | .source = source, |
| 98 | 101 | .name = builder.dupe(name), |
| 99 | 102 | }; |
| ... | ... | @@ -123,15 +126,14 @@ const CompareUuid = struct { |
| 123 | 126 | const self = builder.allocator.create(CompareUuid) catch @panic("OOM"); |
| 124 | 127 | self.* = CompareUuid{ |
| 125 | 128 | .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}", .{ | |
| 129 | 132 | lhs, |
| 130 | 133 | rhs, |
| 131 | 134 | }), |
| 132 | builder.allocator, | |
| 133 | make, | |
| 134 | ), | |
| 135 | .makeFn = make, | |
| 136 | }), | |
| 135 | 137 | .lhs = lhs, |
| 136 | 138 | .rhs = rhs, |
| 137 | 139 | }; |
test/tests.zig+10-2| ... | ... | @@ -858,7 +858,11 @@ pub const StackTracesContext = struct { |
| 858 | 858 | const allocator = context.b.allocator; |
| 859 | 859 | const ptr = allocator.create(RunAndCompareStep) catch unreachable; |
| 860 | 860 | 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 | }), | |
| 862 | 866 | .context = context, |
| 863 | 867 | .exe = exe, |
| 864 | 868 | .name = name, |
| ... | ... | @@ -1194,7 +1198,11 @@ pub const GenHContext = struct { |
| 1194 | 1198 | const allocator = context.b.allocator; |
| 1195 | 1199 | const ptr = allocator.create(GenHCmpOutputStep) catch unreachable; |
| 1196 | 1200 | 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 | }), | |
| 1198 | 1206 | .context = context, |
| 1199 | 1207 | .obj = obj, |
| 1200 | 1208 | .name = name, |