Best Practices for Structuring Zig Projects with External Dependencies

The idiomatic way would be to add extern/libmytools to the root build.zig.zon manifest as a relative dependency by using the .path field:

// http-server/build.zig.zon
.{
    .name = "http-server",
    .version = "0.0.0",
    .dependencies = .{
        .libmytools = .{
            .path = "extern/libmytools",
        },
    },
    .paths = .{""},
}

Your root build.zig script can then use b.dependency("libmytools", .{ ... }) to resolve that dependency and access exported artifacts, modules and files:

// http-server/build.zig
pub fn build(b: *std.Build) void {
    // ...
    const libmytools = b.dependency("libmytools", .{
        .target = target,
        .optimize = optimize,
        .net = true,
    });
    const mytools = libmytools.artifact("mytools");
    exe.linkLibrary(mytools);
}

See this post for a slightly more elaborate example: I want to create a complex lib - #5 by castholm

I believe .path was added after the 0.11.0 release, so it’s only available on master and the soon to be released 0.12.0 tagged release.

Are there best practices for making a library within a Zig project configurable with compile-time options?

You can use b.addOptions for compilation options; see https://ziglang.org/learn/build-system/#options-for-conditional-compilation for an example.

7 Likes