zig/lib/std/Build/Step.zig
Andrew Kelley 9580fbcf35 build system: capture stderr and report it later
Instead of dumping directly to stderr. This prevents processes running
simultaneously from racing their stderr against each other.

For now it only reports at the end, but an improvement would be to
report as soon as a failed step occurs.
2023-03-15 10:48:12 -07:00

117 lines
2.9 KiB
Zig

id: Id,
name: []const u8,
makeFn: *const fn (self: *Step) anyerror!void,
dependencies: std.ArrayList(*Step),
/// This field is empty during execution of the user's build script, and
/// then populated during dependency loop checking in the build runner.
dependants: std.ArrayListUnmanaged(*Step),
state: State,
/// Populated only if state is success.
result: struct {
err_code: anyerror,
stderr: []u8,
},
pub const State = enum {
precheck_unstarted,
precheck_started,
precheck_done,
running,
dependency_failure,
success,
failure,
};
pub const Id = enum {
top_level,
compile,
install_artifact,
install_file,
install_dir,
log,
remove_dir,
fmt,
translate_c,
write_file,
run,
emulatable_run,
check_file,
check_object,
config_header,
objcopy,
options,
custom,
pub fn Type(comptime id: Id) type {
return switch (id) {
.top_level => Build.TopLevelStep,
.compile => Build.CompileStep,
.install_artifact => Build.InstallArtifactStep,
.install_file => Build.InstallFileStep,
.install_dir => Build.InstallDirStep,
.log => Build.LogStep,
.remove_dir => Build.RemoveDirStep,
.fmt => Build.FmtStep,
.translate_c => Build.TranslateCStep,
.write_file => Build.WriteFileStep,
.run => Build.RunStep,
.emulatable_run => Build.EmulatableRunStep,
.check_file => Build.CheckFileStep,
.check_object => Build.CheckObjectStep,
.config_header => Build.ConfigHeaderStep,
.objcopy => Build.ObjCopyStep,
.options => Build.OptionsStep,
.custom => @compileError("no type available for custom step"),
};
}
};
pub fn init(
id: Id,
name: []const u8,
allocator: Allocator,
makeFn: *const fn (self: *Step) anyerror!void,
) Step {
return Step{
.id = id,
.name = allocator.dupe(u8, name) catch @panic("OOM"),
.makeFn = makeFn,
.dependencies = std.ArrayList(*Step).init(allocator),
.dependants = .{},
.state = .precheck_unstarted,
.result = .{
.err_code = undefined,
.stderr = &.{},
},
};
}
pub fn initNoOp(id: Id, name: []const u8, allocator: Allocator) Step {
return init(id, name, allocator, makeNoOp);
}
pub fn make(self: *Step) !void {
try self.makeFn(self);
}
pub fn dependOn(self: *Step, other: *Step) void {
self.dependencies.append(other) catch @panic("OOM");
}
fn makeNoOp(self: *Step) anyerror!void {
_ = self;
}
pub fn cast(step: *Step, comptime T: type) ?*T {
if (step.id == T.base_id) {
return @fieldParentPtr(T, "step", step);
}
return null;
}
const Step = @This();
const std = @import("../std.zig");
const Build = std.Build;
const Allocator = std.mem.Allocator;
const assert = std.debug.assert;