Should a module link C libraries it depends on?

Question in the title.

If you have some Zig module that depends on a C library, the module needs to include the header files from the C library, but it doesn’t strictly speaking need to link the library. The importing application can do that.

What’s considered best practice here?

1 Like

Not sure if it’s “best practice”, but for the sokol-zig bindings (which consists of a Zig module and a C library) I link the library to the module.

That way a sokol-zig user only needs to depend on the module in order to get the C library linked, and the top-level project build.zig can be free of “C shenanigans”.

I still expose the C library as an artifact though:

…this is mainly useful for projects which have some C code themselves which wants to directly use the C API of the C library, e.g. see this issue:

1 Like

If you write CABI binding, you don’t need header files.

pub extern "c" fn some_func_1(fd: c.fd_t, buf: *c.Stat) c_int;
pub extern "c" fn some_func_2(fd: c.fd_t, buf: *c.Stat) c_int;
pub extern "c" fn some_func_3(fd: c.fd_t, buf: *c.Stat) c_int;
....

A Zig language is supported generating bindings from header files.
In this case, you will need bundle header files.

const c = @cImport({
    @cInclude("path/to/foo.h");
});

Or you can use translate-c to create bindings.

1 Like

I’d consider how it obtains the bindings an implementation detail of the module, but good point.