Build system: How to add C macro def to `build.zig.zon` dependency?

I have a dependency chain of 3 Zig pkgs:
mypkg (my project) depends on
wrapper (A Zig interface for pkg clib) depends on
clib (A C project built with Zig)

mypkg/build.zig:

const wrapper = b.dependency("wrapper", .{
    // ...
});
mypkg.addImport("wrapper", wrapper.module("wrapper"));

wrapper/build.zig:

const clib = b.dependency("clib", .{
    // ...
});
wrapper.linkLibrary(clib.artifact("clib"));

clib/build.zig:

const lib = b.addStaticLibrary(.{
    .name = "clib",
    // ...
});

Is there an idiomatic way to add a C macro to the root module of clib (clib.root_module.addCMacro("MYOPT", "1")) within mypkg/build.zig?

If not, I’d have to fork wrapper and clib to achieve this, which I’d like to avoid if possible.

Im not sure this is possible, unless there are some build system shenanigans that i am unaware of.

Can you try addCMacro on the wrapper module?

var wrapper_mod = wrapper.module("wrapper");
wrapper_mod.addCMacro("MYOPT", 1); 

The docs suggest that this adds the macro for all c files in the module.

As shown in the wrapper/build.zig snippet, wrapper contains no C source files, it just links the static library created by clib.

I guess it depends what “owned” means. Again, just spitballing here.

I think your going to have to fork it. You could add a build option that controlls adding the macro and try to upstream the changes.

the wrapper should expose build options to configure the clib

Simplest solution that might work:

wrapper.module("wrapper").import_table.get("clib").?.addCMacro("MYOPT", "1");

But long term adding an option to the wrapper, or at least filing an issue about it, is probably the smarter move.

2 Likes

Building on @geemili’s solution, the following works:

wrapper.module("wrapper").link_objects.items[0].other_step.root_module.addCMacro("MYOPT", "1");

After adding this, other pkgs in the build graph that link clib (besides wrapper) will continue to reference the same clib (now with an added C Macro).

In case of link_objects.items.len > 1, one could iterate these items and pick the correct one by inspecting the item content.

1 Like