Format C++ project using `zig build`

I have a C++ project for which I’m creating an executable using the zig build command.

In the project’s root directory, there’s build.zig with:

const std = @import("std");
const specs = @import("specifications.zig");


const CPP_ROOT_DIR = "./src/";

const CPP_FLAGS = &.{
    // turn on (lots of) warnings from the compiler
    "-Wall",
    // treat every warning as an error
    "-Werror",
    // use optimization level 2
    "-O2",
    // use C++ version 20
    "-std=c++20"
};

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

    const exe = b.addExecutable(.{
        .name = "allunittests",
        .target = target,
        .optimize = optimize,
    });

    exe.addCSourceFiles(.{
        .root = b.path(CPP_ROOT_DIR),
        .files = specs.CPP_IMPLS,
        .flags = CPP_FLAGS,
    });

    exe.linkLibCpp();

    b.installArtifact(exe);
}

and specifications.zig has the below (and will keep growing):

pub const CPP_IMPLS = &.{
    // -- entrypoint --
    "main.cpp",

    "foo/a.cpp",
    "foo/b.cpp",

    "bar/c.cpp",
    "bar/d.cpp",
};

Running zig build produces a binary allunittests in zig-out/bin/.

is there a way to format all (preferably using the .clang-format also located at the project root) CPP code before producing the binary ?

Formatting is usually handled by your code editor in some way. Though when working with others, formatting on build is certainly one way to enforce formatting.

You can run external programs from build.zig using b.addSystemCommand which will return a Step.Run, this needs to be depended on by another step. Note that if you want input/output cached you shouldn’t pass them as args directly but use the provided functions on the Step.Run

1 Like