| 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,12 +227,19 @@ pub fn create( |
| 227 | .h_dir = undefined, | 227 | .h_dir = undefined, |
| 228 | .dest_dir = env_map.get("DESTDIR"), | 228 | .dest_dir = env_map.get("DESTDIR"), |
| 229 | .installed_files = ArrayList(InstalledFile).init(allocator), | 229 | .installed_files = ArrayList(InstalledFile).init(allocator), |
| 230 | .install_tls = TopLevelStep{ | 230 | .install_tls = .{ |
| 231 | .step = Step.initNoOp(.top_level, "install", allocator), | 231 | .step = Step.init(allocator, .{ |
| 232 | .id = .top_level, | ||
| 233 | .name = "install", | ||
| 234 | }), | ||
| 232 | .description = "Copy build artifacts to prefix path", | 235 | .description = "Copy build artifacts to prefix path", |
| 233 | }, | 236 | }, |
| 234 | .uninstall_tls = TopLevelStep{ | 237 | .uninstall_tls = .{ |
| 235 | .step = Step.init(.top_level, "uninstall", allocator, makeUninstall), | 238 | .step = Step.init(allocator, .{ |
| 239 | .id = .top_level, | ||
| 240 | .name = "uninstall", | ||
| 241 | .makeFn = makeUninstall, | ||
| 242 | }), | ||
| 236 | .description = "Remove build artifacts from prefix path", | 243 | .description = "Remove build artifacts from prefix path", |
| 237 | }, | 244 | }, |
| 238 | .zig_lib_dir = null, | 245 | .zig_lib_dir = null, |
| ... | @@ -264,11 +271,18 @@ fn createChildOnly(parent: *Build, dep_name: []const u8, build_root: Cache.Direc | ... | @@ -264,11 +271,18 @@ fn createChildOnly(parent: *Build, dep_name: []const u8, build_root: Cache.Direc |
| 264 | child.* = .{ | 271 | child.* = .{ |
| 265 | .allocator = allocator, | 272 | .allocator = allocator, |
| 266 | .install_tls = .{ | 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 | .description = "Copy build artifacts to prefix path", | 278 | .description = "Copy build artifacts to prefix path", |
| 269 | }, | 279 | }, |
| 270 | .uninstall_tls = .{ | 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 | .description = "Remove build artifacts from prefix path", | 286 | .description = "Remove build artifacts from prefix path", |
| 273 | }, | 287 | }, |
| 274 | .user_input_options = UserInputOptionsMap.init(allocator), | 288 | .user_input_options = UserInputOptionsMap.init(allocator), |
| ... | @@ -634,7 +648,11 @@ pub fn addConfigHeader( | ... | @@ -634,7 +648,11 @@ pub fn addConfigHeader( |
| 634 | options: ConfigHeaderStep.Options, | 648 | options: ConfigHeaderStep.Options, |
| 635 | values: anytype, | 649 | values: anytype, |
| 636 | ) *ConfigHeaderStep { | 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 | config_header_step.addValues(values); | 656 | config_header_step.addValues(values); |
| 639 | return config_header_step; | 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,7 +876,10 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_ |
| 858 | pub fn step(self: *Build, name: []const u8, description: []const u8) *Step { | 876 | pub fn step(self: *Build, name: []const u8, description: []const u8) *Step { |
| 859 | const step_info = self.allocator.create(TopLevelStep) catch @panic("OOM"); | 877 | const step_info = self.allocator.create(TopLevelStep) catch @panic("OOM"); |
| 860 | step_info.* = TopLevelStep{ | 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 | .description = self.dupe(description), | 883 | .description = self.dupe(description), |
| 863 | }; | 884 | }; |
| 864 | self.top_level_steps.put(self.allocator, step_info.step.name, step_info) catch @panic("OOM"); | 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,7 +1174,7 @@ pub fn spawnChildEnvMap(self: *Build, cwd: ?[]const u8, env_map: *const EnvMap, |
| 1153 | printCmd(self.allocator, cwd, argv); | 1174 | printCmd(self.allocator, cwd, argv); |
| 1154 | } | 1175 | } |
| 1155 | 1176 | ||
| 1156 | if (!std.process.can_spawn) | 1177 | if (!process.can_spawn) |
| 1157 | return error.ExecNotSupported; | 1178 | return error.ExecNotSupported; |
| 1158 | 1179 | ||
| 1159 | var child = std.ChildProcess.init(argv, self.allocator); | 1180 | var child = std.ChildProcess.init(argv, self.allocator); |
| ... | @@ -1355,7 +1376,7 @@ pub fn execAllowFail( | ... | @@ -1355,7 +1376,7 @@ pub fn execAllowFail( |
| 1355 | ) ExecError![]u8 { | 1376 | ) ExecError![]u8 { |
| 1356 | assert(argv.len != 0); | 1377 | assert(argv.len != 0); |
| 1357 | 1378 | ||
| 1358 | if (!std.process.can_spawn) | 1379 | if (!process.can_spawn) |
| 1359 | return error.ExecNotSupported; | 1380 | return error.ExecNotSupported; |
| 1360 | 1381 | ||
| 1361 | const max_output_size = 400 * 1024; | 1382 | const max_output_size = 400 * 1024; |
| ... | @@ -1395,7 +1416,7 @@ pub fn execFromStep(b: *Build, argv: []const []const u8, s: *Step) ![]u8 { | ... | @@ -1395,7 +1416,7 @@ pub fn execFromStep(b: *Build, argv: []const []const u8, s: *Step) ![]u8 { |
| 1395 | printCmd(b.allocator, null, argv); | 1416 | printCmd(b.allocator, null, argv); |
| 1396 | } | 1417 | } |
| 1397 | 1418 | ||
| 1398 | if (!std.process.can_spawn) { | 1419 | if (!process.can_spawn) { |
| 1399 | s.result.stderr = b.fmt("Unable to spawn the following command: cannot spawn child processes\n{s}", .{ | 1420 | s.result.stderr = b.fmt("Unable to spawn the following command: cannot spawn child processes\n{s}", .{ |
| 1400 | try allocPrintCmd(b.allocator, null, argv), | 1421 | try allocPrintCmd(b.allocator, null, argv), |
| 1401 | }); | 1422 | }); |
| ... | @@ -1458,7 +1479,7 @@ fn unwrapExecResult( | ... | @@ -1458,7 +1479,7 @@ fn unwrapExecResult( |
| 1458 | /// inside step make() functions. If any errors occur, it fails the build with | 1479 | /// inside step make() functions. If any errors occur, it fails the build with |
| 1459 | /// a helpful message. | 1480 | /// a helpful message. |
| 1460 | pub fn exec(b: *Build, argv: []const []const u8) []u8 { | 1481 | pub fn exec(b: *Build, argv: []const []const u8) []u8 { |
| 1461 | if (!std.process.can_spawn) { | 1482 | if (!process.can_spawn) { |
| 1462 | std.debug.print("unable to spawn the following command: cannot spawn child process\n{s}", .{ | 1483 | std.debug.print("unable to spawn the following command: cannot spawn child process\n{s}", .{ |
| 1463 | try allocPrintCmd(b.allocator, null, argv), | 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,7 +1560,7 @@ pub fn dependency(b: *Build, name: []const u8, args: anytype) *Dependency { |
| 1539 | 1560 | ||
| 1540 | const full_path = b.pathFromRoot("build.zig.zon"); | 1561 | const full_path = b.pathFromRoot("build.zig.zon"); |
| 1541 | 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 }); | 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 | fn dependencyInner( | 1566 | fn dependencyInner( |
| ... | @@ -1555,7 +1576,7 @@ fn dependencyInner( | ... | @@ -1555,7 +1576,7 @@ fn dependencyInner( |
| 1555 | std.debug.print("unable to open '{s}': {s}\n", .{ | 1576 | std.debug.print("unable to open '{s}': {s}\n", .{ |
| 1556 | build_root_string, @errorName(err), | 1577 | build_root_string, @errorName(err), |
| 1557 | }); | 1578 | }); |
| 1558 | std.process.exit(1); | 1579 | process.exit(1); |
| 1559 | }, | 1580 | }, |
| 1560 | }; | 1581 | }; |
| 1561 | const sub_builder = b.createChild(name, build_root, args) catch @panic("unhandled error"); | 1582 | const sub_builder = b.createChild(name, build_root, args) catch @panic("unhandled error"); |
| ... | @@ -1599,7 +1620,7 @@ pub const GeneratedFile = struct { | ... | @@ -1599,7 +1620,7 @@ pub const GeneratedFile = struct { |
| 1599 | 1620 | ||
| 1600 | pub fn getPath(self: GeneratedFile) []const u8 { | 1621 | pub fn getPath(self: GeneratedFile) []const u8 { |
| 1601 | return self.path orelse std.debug.panic( | 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 | .{self.step.name}, | 1624 | .{self.step.name}, |
| 1604 | ); | 1625 | ); |
| 1605 | } | 1626 | } |
| ... | @@ -1639,12 +1660,16 @@ pub const FileSource = union(enum) { | ... | @@ -1639,12 +1660,16 @@ pub const FileSource = union(enum) { |
| 1639 | } | 1660 | } |
| 1640 | 1661 | ||
| 1641 | /// Should only be called during make(), returns a path relative to the build root or absolute. | 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 { | 1663 | pub fn getPath(self: FileSource, src_builder: *Build) []const u8 { |
| 1643 | const path = switch (self) { | 1664 | switch (self) { |
| 1644 | .path => |p| builder.pathFromRoot(p), | 1665 | .path => |p| return src_builder.pathFromRoot(p), |
| 1645 | .generated => |gen| gen.getPath(), | 1666 | .generated => |gen| return gen.path orelse { |
| 1646 | }; | 1667 | std.debug.getStderrMutex().lock(); |
| 1647 | return path; | 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 | /// Duplicates the file source for a given builder. | 1675 | /// Duplicates the file source for a given builder. |
| ... | @@ -1656,6 +1681,27 @@ pub const FileSource = union(enum) { | ... | @@ -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 | /// Allocates a new string for assigning a value to a named macro. | 1705 | /// Allocates a new string for assigning a value to a named macro. |
| 1660 | /// If the value is omitted, it is set to 1. | 1706 | /// If the value is omitted, it is set to 1. |
| 1661 | /// `name` and `value` need not live longer than the function call. | 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,7 +21,11 @@ pub fn create( |
| 21 | const self = builder.allocator.create(CheckFileStep) catch @panic("OOM"); | 21 | const self = builder.allocator.create(CheckFileStep) catch @panic("OOM"); |
| 22 | self.* = CheckFileStep{ | 22 | self.* = CheckFileStep{ |
| 23 | .builder = builder, | 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 | .source = source.dupe(builder), | 29 | .source = source.dupe(builder), |
| 26 | .expected_matches = builder.dupeStrings(expected_matches), | 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,7 +27,11 @@ pub fn create(builder: *std.Build, source: std.Build.FileSource, obj_format: std |
| 27 | const self = gpa.create(CheckObjectStep) catch @panic("OOM"); | 27 | const self = gpa.create(CheckObjectStep) catch @panic("OOM"); |
| 28 | self.* = .{ | 28 | self.* = .{ |
| 29 | .builder = builder, | 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 | .source = source.dupe(builder), | 35 | .source = source.dupe(builder), |
| 32 | .checks = std.ArrayList(Check).init(gpa), | 36 | .checks = std.ArrayList(Check).init(gpa), |
| 33 | .obj_format = obj_format, | 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,7 +326,11 @@ pub fn create(builder: *std.Build, options: Options) *CompileStep { |
| 326 | .root_src = root_src, | 326 | .root_src = root_src, |
| 327 | .name = name, | 327 | .name = name, |
| 328 | .frameworks = StringHashMap(FrameworkLinkInfo).init(builder.allocator), | 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 | .version = options.version, | 334 | .version = options.version, |
| 331 | .out_filename = undefined, | 335 | .out_filename = undefined, |
| 332 | .out_h_filename = builder.fmt("{s}.h", .{name}), | 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,6 +46,7 @@ pub const Options = struct { |
| 46 | style: Style = .blank, | 46 | style: Style = .blank, |
| 47 | max_bytes: usize = 2 * 1024 * 1024, | 47 | max_bytes: usize = 2 * 1024 * 1024, |
| 48 | include_path: ?[]const u8 = null, | 48 | include_path: ?[]const u8 = null, |
| 49 | first_ret_addr: ?usize = null, | ||
| 49 | }; | 50 | }; |
| 50 | 51 | ||
| 51 | pub fn create(builder: *std.Build, options: Options) *ConfigHeaderStep { | 52 | pub fn create(builder: *std.Build, options: Options) *ConfigHeaderStep { |
| ... | @@ -56,7 +57,12 @@ pub fn create(builder: *std.Build, options: Options) *ConfigHeaderStep { | ... | @@ -56,7 +57,12 @@ pub fn create(builder: *std.Build, options: Options) *ConfigHeaderStep { |
| 56 | builder.fmt("configure {s} header", .{@tagName(options.style)}); | 57 | builder.fmt("configure {s} header", .{@tagName(options.style)}); |
| 57 | self.* = .{ | 58 | self.* = .{ |
| 58 | .builder = builder, | 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 | .style = options.style, | 66 | .style = options.style, |
| 61 | .values = std.StringArrayHashMap(Value).init(builder.allocator), | 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,7 +56,11 @@ pub fn create(builder: *std.Build, name: []const u8, artifact: *CompileStep) *Em |
| 56 | 56 | ||
| 57 | self.* = .{ | 57 | self.* = .{ |
| 58 | .builder = builder, | 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 | .exe = artifact, | 64 | .exe = artifact, |
| 61 | .env_map = null, | 65 | .env_map = null, |
| 62 | .cwd = null, | 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,7 +12,11 @@ pub fn create(builder: *std.Build, paths: []const []const u8) *FmtStep { |
| 12 | const self = builder.allocator.create(FmtStep) catch @panic("OOM"); | 12 | const self = builder.allocator.create(FmtStep) catch @panic("OOM"); |
| 13 | const name = "zig fmt"; | 13 | const name = "zig fmt"; |
| 14 | self.* = FmtStep{ | 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 | .builder = builder, | 20 | .builder = builder, |
| 17 | .argv = builder.allocator.alloc([]u8, paths.len + 2) catch @panic("OOM"), | 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,7 +19,11 @@ pub fn create(builder: *std.Build, artifact: *CompileStep) *InstallArtifactStep |
| 19 | const self = builder.allocator.create(InstallArtifactStep) catch @panic("OOM"); | 19 | const self = builder.allocator.create(InstallArtifactStep) catch @panic("OOM"); |
| 20 | self.* = InstallArtifactStep{ | 20 | self.* = InstallArtifactStep{ |
| 21 | .builder = builder, | 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 | .artifact = artifact, | 27 | .artifact = artifact, |
| 24 | .dest_dir = artifact.override_dest_dir orelse switch (artifact.kind) { | 28 | .dest_dir = artifact.override_dest_dir orelse switch (artifact.kind) { |
| 25 | .obj => @panic("Cannot install a .obj build artifact."), | 29 | .obj => @panic("Cannot install a .obj build artifact."), |
lib/std/Build/InstallDirStep.zig+6-2| ... | @@ -45,9 +45,13 @@ pub fn init( | ... | @@ -45,9 +45,13 @@ pub fn init( |
| 45 | options: Options, | 45 | options: Options, |
| 46 | ) InstallDirStep { | 46 | ) InstallDirStep { |
| 47 | builder.pushInstalledFile(options.install_dir, options.install_subdir); | 47 | builder.pushInstalledFile(options.install_dir, options.install_subdir); |
| 48 | return InstallDirStep{ | 48 | return .{ |
| 49 | .builder = builder, | 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 | .options = options.dupe(builder), | 55 | .options = options.dupe(builder), |
| 52 | }; | 56 | }; |
| 53 | } | 57 | } |
lib/std/Build/InstallFileStep.zig+5-1| ... | @@ -24,7 +24,11 @@ pub fn init( | ... | @@ -24,7 +24,11 @@ pub fn init( |
| 24 | builder.pushInstalledFile(dir, dest_rel_path); | 24 | builder.pushInstalledFile(dir, dest_rel_path); |
| 25 | return InstallFileStep{ | 25 | return InstallFileStep{ |
| 26 | .builder = builder, | 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 | .source = source.dupe(builder), | 32 | .source = source.dupe(builder), |
| 29 | .dir = dir.dupe(builder), | 33 | .dir = dir.dupe(builder), |
| 30 | .dest_rel_path = builder.dupePath(dest_rel_path), | 34 | .dest_rel_path = builder.dupePath(dest_rel_path), |
lib/std/Build/LogStep.zig+5-1| ... | @@ -12,7 +12,11 @@ data: []const u8, | ... | @@ -12,7 +12,11 @@ data: []const u8, |
| 12 | pub fn init(builder: *std.Build, data: []const u8) LogStep { | 12 | pub fn init(builder: *std.Build, data: []const u8) LogStep { |
| 13 | return LogStep{ | 13 | return LogStep{ |
| 14 | .builder = builder, | 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 | .data = builder.dupe(data), | 20 | .data = builder.dupe(data), |
| 17 | }; | 21 | }; |
| 18 | } | 22 | } |
lib/std/Build/ObjCopyStep.zig+5-6| ... | @@ -44,12 +44,11 @@ pub fn create( | ... | @@ -44,12 +44,11 @@ pub fn create( |
| 44 | ) *ObjCopyStep { | 44 | ) *ObjCopyStep { |
| 45 | const self = builder.allocator.create(ObjCopyStep) catch @panic("OOM"); | 45 | const self = builder.allocator.create(ObjCopyStep) catch @panic("OOM"); |
| 46 | self.* = ObjCopyStep{ | 46 | self.* = ObjCopyStep{ |
| 47 | .step = Step.init( | 47 | .step = Step.init(builder.allocator, .{ |
| 48 | base_id, | 48 | .id = base_id, |
| 49 | builder.fmt("objcopy {s}", .{file_source.getDisplayName()}), | 49 | .name = builder.fmt("objcopy {s}", .{file_source.getDisplayName()}), |
| 50 | builder.allocator, | 50 | .makeFn = make, |
| 51 | make, | 51 | }), |
| 52 | ), | ||
| 53 | .builder = builder, | 52 | .builder = builder, |
| 54 | .file_source = file_source, | 53 | .file_source = file_source, |
| 55 | .basename = options.basename orelse file_source.getDisplayName(), | 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,7 +22,11 @@ pub fn create(builder: *std.Build) *OptionsStep { |
| 22 | const self = builder.allocator.create(OptionsStep) catch @panic("OOM"); | 22 | const self = builder.allocator.create(OptionsStep) catch @panic("OOM"); |
| 23 | self.* = .{ | 23 | self.* = .{ |
| 24 | .builder = builder, | 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 | .generated_file = undefined, | 30 | .generated_file = undefined, |
| 27 | .contents = std.ArrayList(u8).init(builder.allocator), | 31 | .contents = std.ArrayList(u8).init(builder.allocator), |
| 28 | .artifact_args = std.ArrayList(OptionArtifactArg).init(builder.allocator), | 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,7 +13,11 @@ dir_path: []const u8, |
| 13 | pub fn init(builder: *std.Build, dir_path: []const u8) RemoveDirStep { | 13 | pub fn init(builder: *std.Build, dir_path: []const u8) RemoveDirStep { |
| 14 | return RemoveDirStep{ | 14 | return RemoveDirStep{ |
| 15 | .builder = builder, | 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 | .dir_path = builder.dupePath(dir_path), | 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,9 +69,13 @@ pub const Arg = union(enum) { |
| 69 | 69 | ||
| 70 | pub fn create(builder: *std.Build, name: []const u8) *RunStep { | 70 | pub fn create(builder: *std.Build, name: []const u8) *RunStep { |
| 71 | const self = builder.allocator.create(RunStep) catch @panic("OOM"); | 71 | const self = builder.allocator.create(RunStep) catch @panic("OOM"); |
| 72 | self.* = RunStep{ | 72 | self.* = .{ |
| 73 | .builder = builder, | 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 | .argv = ArrayList(Arg).init(builder.allocator), | 79 | .argv = ArrayList(Arg).init(builder.allocator), |
| 76 | .cwd = null, | 80 | .cwd = null, |
| 77 | .env_map = null, | 81 | .env_map = null, |
lib/std/Build/Step.zig+36-12| ... | @@ -11,6 +11,11 @@ result: struct { | ... | @@ -11,6 +11,11 @@ result: struct { |
| 11 | err_code: anyerror, | 11 | err_code: anyerror, |
| 12 | stderr: []u8, | 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 | pub const State = enum { | 20 | pub const State = enum { |
| 16 | precheck_unstarted, | 21 | precheck_unstarted, |
| ... | @@ -66,16 +71,26 @@ pub const Id = enum { | ... | @@ -66,16 +71,26 @@ pub const Id = enum { |
| 66 | } | 71 | } |
| 67 | }; | 72 | }; |
| 68 | 73 | ||
| 69 | pub fn init( | 74 | pub const Options = struct { |
| 70 | id: Id, | 75 | id: Id, |
| 71 | name: []const u8, | 76 | name: []const u8, |
| 72 | allocator: Allocator, | 77 | makeFn: *const fn (self: *Step) anyerror!void = makeNoOp, |
| 73 | makeFn: *const fn (self: *Step) anyerror!void, | 78 | first_ret_addr: ?usize = null, |
| 74 | ) Step { | 79 | }; |
| 75 | return Step{ | 80 | |
| 76 | .id = id, | 81 | pub fn init(allocator: Allocator, options: Options) Step { |
| 77 | .name = allocator.dupe(u8, name) catch @panic("OOM"), | 82 | var addresses = [1]usize{0} ** n_debug_stack_frames; |
| 78 | .makeFn = makeFn, | 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 | .dependencies = std.ArrayList(*Step).init(allocator), | 94 | .dependencies = std.ArrayList(*Step).init(allocator), |
| 80 | .dependants = .{}, | 95 | .dependants = .{}, |
| 81 | .state = .precheck_unstarted, | 96 | .state = .precheck_unstarted, |
| ... | @@ -83,13 +98,10 @@ pub fn init( | ... | @@ -83,13 +98,10 @@ pub fn init( |
| 83 | .err_code = undefined, | 98 | .err_code = undefined, |
| 84 | .stderr = &.{}, | 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 | pub fn make(self: *Step) !void { | 105 | pub fn make(self: *Step) !void { |
| 94 | try self.makeFn(self); | 106 | try self.makeFn(self); |
| 95 | } | 107 | } |
| ... | @@ -98,6 +110,18 @@ pub fn dependOn(self: *Step, other: *Step) void { | ... | @@ -98,6 +110,18 @@ pub fn dependOn(self: *Step, other: *Step) void { |
| 98 | self.dependencies.append(other) catch @panic("OOM"); | 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 | fn makeNoOp(self: *Step) anyerror!void { | 125 | fn makeNoOp(self: *Step) anyerror!void { |
| 102 | _ = self; | 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,7 +30,11 @@ pub fn create(builder: *std.Build, options: Options) *TranslateCStep { |
| 30 | const self = builder.allocator.create(TranslateCStep) catch @panic("OOM"); | 30 | const self = builder.allocator.create(TranslateCStep) catch @panic("OOM"); |
| 31 | const source = options.source_file.dupe(builder); | 31 | const source = options.source_file.dupe(builder); |
| 32 | self.* = TranslateCStep{ | 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 | .builder = builder, | 38 | .builder = builder, |
| 35 | .source = source, | 39 | .source = source, |
| 36 | .include_dirs = std.ArrayList([]const u8).init(builder.allocator), | 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,7 +37,11 @@ pub const Contents = union(enum) { |
| 37 | pub fn init(builder: *std.Build) WriteFileStep { | 37 | pub fn init(builder: *std.Build) WriteFileStep { |
| 38 | return .{ | 38 | return .{ |
| 39 | .builder = builder, | 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 | .files = .{}, | 45 | .files = .{}, |
| 42 | .output_source_files = .{}, | 46 | .output_source_files = .{}, |
| 43 | }; | 47 | }; |
test/link/macho/uuid/build.zig+12-10| ... | @@ -90,10 +90,13 @@ const InstallWithRename = struct { | ... | @@ -90,10 +90,13 @@ const InstallWithRename = struct { |
| 90 | const self = builder.allocator.create(InstallWithRename) catch @panic("OOM"); | 90 | const self = builder.allocator.create(InstallWithRename) catch @panic("OOM"); |
| 91 | self.* = InstallWithRename{ | 91 | self.* = InstallWithRename{ |
| 92 | .builder = builder, | 92 | .builder = builder, |
| 93 | .step = Step.init(.custom, builder.fmt("install and rename: {s} -> {s}", .{ | 93 | .step = Step.init(builder.allocator, .{ |
| 94 | source.getDisplayName(), | 94 | .id = .custom, |
| 95 | name, | 95 | .name = builder.fmt("install and rename: {s} -> {s}", .{ |
| 96 | }), builder.allocator, make), | 96 | source.getDisplayName(), name, |
| 97 | }), | ||
| 98 | .makeFn = make, | ||
| 99 | }), | ||
| 97 | .source = source, | 100 | .source = source, |
| 98 | .name = builder.dupe(name), | 101 | .name = builder.dupe(name), |
| 99 | }; | 102 | }; |
| ... | @@ -123,15 +126,14 @@ const CompareUuid = struct { | ... | @@ -123,15 +126,14 @@ const CompareUuid = struct { |
| 123 | const self = builder.allocator.create(CompareUuid) catch @panic("OOM"); | 126 | const self = builder.allocator.create(CompareUuid) catch @panic("OOM"); |
| 124 | self.* = CompareUuid{ | 127 | self.* = CompareUuid{ |
| 125 | .builder = builder, | 128 | .builder = builder, |
| 126 | .step = Step.init( | 129 | .step = Step.init(builder.allocator, .{ |
| 127 | .custom, | 130 | .id = .custom, |
| 128 | builder.fmt("compare uuid: {s} and {s}", .{ | 131 | .name = builder.fmt("compare uuid: {s} and {s}", .{ |
| 129 | lhs, | 132 | lhs, |
| 130 | rhs, | 133 | rhs, |
| 131 | }), | 134 | }), |
| 132 | builder.allocator, | 135 | .makeFn = make, |
| 133 | make, | 136 | }), |
| 134 | ), | ||
| 135 | .lhs = lhs, | 137 | .lhs = lhs, |
| 136 | .rhs = rhs, | 138 | .rhs = rhs, |
| 137 | }; | 139 | }; |
test/tests.zig+10-2| ... | @@ -858,7 +858,11 @@ pub const StackTracesContext = struct { | ... | @@ -858,7 +858,11 @@ pub const StackTracesContext = struct { |
| 858 | const allocator = context.b.allocator; | 858 | const allocator = context.b.allocator; |
| 859 | const ptr = allocator.create(RunAndCompareStep) catch unreachable; | 859 | const ptr = allocator.create(RunAndCompareStep) catch unreachable; |
| 860 | ptr.* = RunAndCompareStep{ | 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 | .context = context, | 866 | .context = context, |
| 863 | .exe = exe, | 867 | .exe = exe, |
| 864 | .name = name, | 868 | .name = name, |
| ... | @@ -1194,7 +1198,11 @@ pub const GenHContext = struct { | ... | @@ -1194,7 +1198,11 @@ pub const GenHContext = struct { |
| 1194 | const allocator = context.b.allocator; | 1198 | const allocator = context.b.allocator; |
| 1195 | const ptr = allocator.create(GenHCmpOutputStep) catch unreachable; | 1199 | const ptr = allocator.create(GenHCmpOutputStep) catch unreachable; |
| 1196 | ptr.* = GenHCmpOutputStep{ | 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 | .context = context, | 1206 | .context = context, |
| 1199 | .obj = obj, | 1207 | .obj = obj, |
| 1200 | .name = name, | 1208 | .name = name, |