Search code examples
zig

How to organize large projects in Zig language


I used to break down my large c/c++ projects with CMake and then add each part to main project using add_submodule command (the smaller parts were static or dynamic libraries). Also I used the same solution to use third-party libraries in my project.

But I have trouble with doing the same in my zig projects. I had a hard time to search and try to find a reliable and reusable project structure just like CMake projects.

Is there any solution that make me be able to create smaller libraries (with a build.zig inside each) and use those parts in my projects? for example something like this structure:

|-- projectA
|-----| src
|-----|----| main.zig
|-----| libs
|-----|----| projectB
|-----|----------| src
|-----|---------------| hello.zig
|-----|----------| build.zig
|-----|----| projectC
|-----|----------| src
|-----|---------------| bye.zig
|-----|----------| build.zig
|-----| build.zig

I tried to use build.zig file to build each dependency but was not successful, also it's not a straightforward solution, I searched to find a solution but I found nothing.

I found something like exe.addModule but there is not such a function called addModule() in added executable structure.


Solution

  • You can add a dependency as a local package.

    Let's say you have this folder structure:

    |-- foo
    |-----| src
    |-----|----| root.zig
    |-----| build.zig
    |-- project
    |-----| src
    |-----|----| main.zig
    |-----| build.zig
    |-----| build.zig.zon
    

    In foo, in build.zig:

    _ = b.addModule("foo", .{
        .root_source_file = b.path("src/root.zig"),
        .target = target,
        .optimize = optimize,
    });
    

    In the project, in build.zig.zon:

    .dependencies = .{
        .foo = .{
            .path = "../foo/",
        },
    },
    

    And, in build.zig:

    const foo = b.dependency("foo", .{
        .target = target,
        .optimize = optimize,
    });
    exe.root_module.addImport("foo", foo.module("foo"));
    

    So, in main.zig you can just do:

    const foo = @import("foo");
    

    I believe this code works in 0.12 and 0.13.