#Run code after build finished

1 messages · Page 1 of 1 (latest)

dense snow
#

How do I run code after build.zig finished building the app?
I'm trying to do it with a custom build step but it segfaults:

const std = @import("std");

pub fn build(b: *std.build.Builder) void {
    const target = b.standardTargetOptions(.{});

    const mode = b.standardReleaseOptions();

    const exe = b.addExecutable("x", "src/main.zig");
    exe.setTarget(target);
    exe.setBuildMode(mode);
    exe.install();

    var x_step = std.build.Step.init(.run, "x", b.allocator, x);
    exe.install_step.?.step.dependOn(&x_step);
}

fn x(step: *std.build.Step) !void {
    _ = step;
}
$ zig build
Segmentation fault at address 0x8

I've been getting segfaults with all kind of things I tried so I'm a bit confused.

viscid lake
#

not sure why you're getting a segfault, but what is the actually dependency you need? If you want to run a step after the build is done, it's not clear that making the install step depend on the step will work, rather you would want the step to run depend on the build step (or a dependent of the build step).

tight plaza
#

You're getting a segfault because the step is stack allocated

#

You need to heap allocate it

#

Because once you return from build, anything that's stack allocated is effectively deleted

viscid lake
#

that'd do it - b.step() is what you want to use

tight plaza
#

Nope

dense snow
tight plaza
#

That creates a subcommand

#

You just need to allocate the variable you put Step.init into

dense snow
#

I can share someone else I tried in a sec

#

so so check that it actually finished building I check zig-out and it still doesn't seem to be fully working yet:

const std = @import("std");

pub fn build(b: *std.build.Builder) !void {
    const target = b.standardTargetOptions(.{});

    const mode = b.standardReleaseOptions();

    const exe = b.addExecutable("x", "src/main.zig");
    exe.setTarget(target);
    exe.setBuildMode(mode);
    exe.install();

    var x_step = try b.allocator.create(std.build.Step);
    x_step.* = std.build.Step.init(.run, "x", b.allocator, x);
    exe.install_step.?.step.dependOn(x_step);
}

fn x(step: *std.build.Step) !void {
    _ = step;
    const dir = try std.fs.cwd().openIterableDir("zig-out", .{});
    var xx = dir.iterate();
    while (try xx.next()) |a| {
        std.debug.print("{}", .{a});
    }
}
#

because thread 37069 panic: attempt to unwrap error: FileNotFound meaning that zig-out isn't there

viscid lake
#

you have the dependencies the wrong way around I think - you have made exe.install_step depend on x_step and exe.step, but x_step really should depend on exe.install_step as it requires the output directory to be made (and presumably in the furture the executable to be installed)

dense snow
#

and if I instead do x_step.dependOn(&exe.install_step.?.step); it doesn't do anything

viscid lake
#

when you have x_step.depenOn(&exe.install_step.?.step); you need to invoke x_step, not just the install step

dense snow
#

by invoke you mean x_step.make()?

viscid lake
#

there are different ways to do this - you could make x_step the default step of the builder, or make it a top level step so you can run with with something like zig build x-step

dense snow
#

i need it to run with zig build alone

viscid lake
#

I don't think you're really meant to manually call make()

#

then make it the default step

dense snow
#

ill try making it the default

viscid lake
#

b.default_step = &x_step;

dense snow
#

yeah

#

nice, that seems to work for now

#

thanks! now i will see if that works in my real app

#

seems to work fine with b.getInstallStep() instead of b.default_step too