feature. See also
. The project being documented here (as the example) is the Zig library itself.
Step.zigProcessUpdate
fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *ZigProcess, watch: bool) !?Path
File
Code
fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *ZigProcess, watch: bool) !?Path {
const s = maker.stepByIndex(step_index);
const gpa = maker.gpa;
const graph = maker.graph;
const arena = graph.arena;
const io = graph.io;
const start_ts = Io.Clock.awake.now(io);
try sendMessage(io, zp.child.stdin.?, .update);
if (!watch) try sendMessage(io, zp.child.stdin.?, .exit);
var result: ?Path = null;
var eos_err: error{EndOfStream}!void = {};
const stdout = zp.multi_reader.fileReader(0);
while (true) {
const Header = std.zig.Server.Message.Header;
const header = stdout.interface.takeStruct(Header, .little) catch |err| switch (err) {
error.EndOfStream => break,
error.ReadFailed => return stdout.err.?,
};
const body = stdout.interface.take(header.bytes_len) catch |err| switch (err) {
error.EndOfStream => |e| {
// this in case the child exits successfully while violating
// this protocol.
eos_err = e;
break;
},
error.ReadFailed => return stdout.err.?,
};
switch (header.tag) {
.zig_version => {
if (!std.mem.eql(u8, builtin.zig_version_string, body)) {
return s.fail(
maker,
"zig version mismatch build runner vs compiler: {q} vs {q}",
.{ builtin.zig_version_string, body },
);
}
},
.error_bundle => {
s.result_error_bundle = try std.zig.Server.allocErrorBundle(gpa, body);
if (watch) break;
},
.emit_digest => {
const EmitDigest = std.zig.Server.Message.EmitDigest;
const emit_digest: *align(1) const EmitDigest = @ptrCast(body);
s.result_cached = emit_digest.flags.cache_hit;
const digest = body[@sizeOf(EmitDigest)..][0..Cache.bin_digest_len];
result = .{
.root_dir = graph.local_cache_root,
.sub_path = try arena.dupe(u8, "o" ++ Dir.path.sep_str ++ Cache.binToHex(digest.*)),
};
},
.file_system_inputs => {
clearWatchInputs(s, maker);
const conf = &maker.scanned_config.configuration;
const conf_step = step_index.ptr(conf);
var it = std.mem.splitScalar(u8, body, 0);
while (it.next()) |prefixed_path| {
const prefix_index: std.zig.Server.Message.PathPrefix = @fromBackingInt(@intCast(prefixed_path[0] - 1));
const sub_path = try arena.dupe(u8, prefixed_path[1..]);
const sub_path_dirname = Dir.path.dirname(sub_path) orelse "";
switch (prefix_index) {
.cwd => {
const path: Path = .{
.root_dir = .cwd(),
.sub_path = sub_path_dirname,
};
try addWatchInputFromPath(s, maker, path, Dir.path.basename(sub_path));
},
.zig_lib => zl: {
switch (conf_step.extended.get(conf.extra)) {
.compile => |compile| if (compile.zig_lib_dir.value) |zig_lib_dir| {
const resolved = try maker.resolveLazyPathIndex(arena, zig_lib_dir, step_index);
const appended = try resolved.join(arena, sub_path);
try addWatchInputPath(s, maker, appended);
break :zl;
},
else => {},
}
const path: Path = .{
.root_dir = graph.zig_lib_directory,
.sub_path = sub_path_dirname,
};
try addWatchInputFromPath(s, maker, path, Dir.path.basename(sub_path));
},
.local_cache => {
const path: Path = .{
.root_dir = graph.local_cache_root,
.sub_path = sub_path_dirname,
};
try addWatchInputFromPath(s, maker, path, Dir.path.basename(sub_path));
},
.global_cache => {
const path: Path = .{
.root_dir = graph.global_cache_root,
.sub_path = sub_path_dirname,
};
try addWatchInputFromPath(s, maker, path, Dir.path.basename(sub_path));
},
}
}
},
.time_report => if (maker.web_server) |ws| {
const TimeReport = std.zig.Server.Message.TimeReport;
const tr: *align(1) const TimeReport = @ptrCast(body[0..@sizeOf(TimeReport)]);
ws.updateTimeReportCompile(.{
.compile_step = step_index,
.use_llvm = tr.flags.use_llvm,
.stats = tr.stats,
.ns_total = @intCast(start_ts.untilNow(io, .awake).toNanoseconds()),
.llvm_pass_timings_len = tr.llvm_pass_timings_len,
.files_len = tr.files_len,
.decls_len = tr.decls_len,
.trailing = body[@sizeOf(TimeReport)..],
});
},
else => {},
}
}
s.result_duration_ns = @intCast(start_ts.untilNow(io, .awake).toNanoseconds());
const stderr_contents = zp.multi_reader.reader(1).buffered();
if (stderr_contents.len > 0) {
try s.result_error_msgs.append(arena, try arena.dupe(u8, stderr_contents));
}
try eos_err;
return result;
}