#iterate over files in a directory in build.zig
1 messages · Page 1 of 1 (latest)
see Dir.walk
.getPath and you supply the builder
Then open it as a dir
getPath or getPath3?
hm? getPath is the one it says Deprecated
i got it mostly working but I still a couple of problems
{ // `zig build eye` command
const eye_step = b.step("eye", "eye test all the files in a given directory");
const args: []const []const u8 = b.args orelse
&.{ "./c_files/", "--lex" }; // least harmful default;
const path = b.path(args[0]).getPath3(b, null);
const dir = try path.openDir("", .{ .access_sub_paths = false });
var walker = try dir.walk(b.allocator);
defer walker.deinit();
while (try walker.next()) |entry| {
if (entry.kind == .file) {
const file = b.pathJoin(&.{ path.root_dir.path.?, path.basename(), entry.path });
const bat = b.addSystemCommand(&.{ "bat", file });
const run_cmd = b.addRunArtifact(exe);
run_cmd.addArg(file);
run_cmd.addArgs(args[1..]);
run_cmd.step.dependOn(&bat.step);
eye_step.dependOn(&run_cmd.step);
}
}
}```
the first problem is that the output for bat and the output for the run steps are not happening next to each other.
The second problem is that the dir walk seems to happen regardless of step and i'd like to only run if that's the step I am invoking
@valid pollen sorry for ping but do you have any tips?
you'll have to make a custom step
?
custom build step
I do it here
it creates a step called CompileCommandStep
so it only runs the code when the step is depended on
makeCdb
so basically just pass a function that takes a *std.Build.Step to a bare step's makeFn ?
@valid pollen so how to make sure the bat command and the run command run sequentially ?
yeah
uhh
make run depend on the bat
it does
hmm
i guess i can make bat depend on the previous run
@valid pollen do you just add step.dependOn at the end there or not? ```ts
fn make_eye_step(step: *std.Build.Step, _: std.Build.Step.MakeOptions) !void {
const b = step.owner;
const closure: *const Closure = @fieldParentPtr("step", step);
const exe = closure.exe;
const args: []const []const u8 = b.args orelse
&.{ "./c_files/", "--lex" }; // least harmful default;
const path = b.path(args[0]).getPath3(b, null);
const dir = try path.openDir("", .{ .access_sub_paths = false });
var walker = try dir.walk(b.allocator);
defer walker.deinit();
while (try walker.next()) |entry| {
if (entry.kind == .file and std.mem.endsWith(u8, entry.basename, ".c")) {
const file = b.pathJoin(&.{ path.root_dir.path.?, path.basename(), entry.path });
const bat = b.addSystemCommand(&.{ "bat", file });
const run_cmd = b.addRunArtifact(exe);
run_cmd.addArg(file);
run_cmd.addArgs(args[1..]);
run_cmd.step.dependOn(&bat.step);
step.dependOn(&run_cmd.step); // <-- here
}
}
}```
build crashed 😮
ok i fixed the crashing part
but now i dont see any output from the commands and i can't tell if they run or not
{ // `zig build eye` command
const eye_step = b.step("eye", "eye test all the files in a given directory");
var closure = b.allocator.create(Closure) catch unreachable;
closure.* = .{ .exe = exe, .step = std.Build.Step.init(.{
.id = .custom,
.name = "inner_eye",
.makeFn = make_eye_step,
.owner = b,
}) };
eye_step.dependOn(&closure.step);
}
}
const Closure = struct {
exe: *std.Build.Step.Compile,
step: std.Build.Step,
};
fn make_eye_step(step: *std.Build.Step, _: std.Build.Step.MakeOptions) !void {
const b = step.owner;
const closure: *const Closure = @fieldParentPtr("step", step);
const exe = closure.exe;
const args: []const []const u8 = b.args orelse
&.{ "./c_files/", "--lex" }; // least harmful default;
const path = b.path(args[0]).getPath3(b, null);
const dir = try path.openDir("", .{ .access_sub_paths = false });
var walker = try dir.walk(b.allocator);
defer walker.deinit();
var prev_run_cmd: ?*std.Build.Step.Run = null;
while (try walker.next()) |entry| {
if (entry.kind == .file and std.mem.endsWith(u8, entry.basename, ".c")) {
const file = b.pathJoin(&.{ path.root_dir.path.?, path.basename(), entry.path });
const bat = b.addSystemCommand(&.{ "bat", file });
bat.stdio = .inherit;
if (prev_run_cmd) |c|
bat.step.dependOn(&c.step);
const run_cmd = b.addRunArtifact(exe);
run_cmd.addArg(file);
run_cmd.addArgs(args[1..]);
run_cmd.stdio = .inherit;
run_cmd.step.dependOn(&bat.step);
prev_run_cmd = run_cmd;
}
}
step.dependOn(&prev_run_cmd.?.step);
}```
to run them all sequentially, you could keep a "previous run step" then dependOn that for the eye step.
last = null
for file in walker:
bat_cmd = addSystemCommand("bat", ...)
if (last) |l| bad_cmd.dependOn(l)
run_cmd = addRunArtifact()
run_cmd.dependOn(bat_cmd)
last = run_cmd
if (last) |l| step.dependOn(l)
yeah i figured as much, but the commands arent running at all when they are steps inside that function. std.debug.print prints fine .. a better writeup is here
Hello. I have been banging my head at this for the better part of three hours. And I cannot figure out how this is solved. As a background, I am building a toy C compiler in Zig based on Nora Sandler’s Writing a C Compiler book. And I am trying to make some testing tasks go through build.zig rather than relying on shell scripts. The project...
oop sorry couldnt reply, was doing a practice exam
using print debugging where does it crash?
Good luck with the exam i hope you scored well.