Linking dbus in zig fails

Hi,

I have an empty project where I wanted to add the dbus lib and play around a little bit.
In my understanding it should be possible to add c libraries to zig. Unfortunately I get an error when compiling and as there is not really an error message I have a hard time finding out what to do. Maybe someone can help me or show me what I am doing wrong.

Right now my main.zig just looks like this:

const std = @import("std");
const dbus = @cImport({
    @cInclude("dbus/dbus.h");
});

pub fn main() !void {
    const err: dbus.DBusError = undefined;
    const conn: *dbus.DBusConnection = undefined;
    _ = err;
    _ = conn;
}

When I run this command:

zig build-exe -dynamic src/main.zig -lc -ldbus-1 -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include

I get the following error:

[1]    10569 trace trap (core dumped)  zig build-exe -dynamic src/main.zig -lc -ldbus-1 -I/usr/include/dbus-1.0 

I also used the build.zig file with addSystemLibrary which also fails.
Thanks in advance for any help.

There is no need for the -dynamic flag.
I could build and run the following:

const dbus = @cImport({
    @cInclude("dbus/dbus.h");
});

pub fn main() !void {
    _ = dbus;
}

in debian with the flags: -lc -ldbus-1 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include

Thanks a lot. I am on arch and unfortunately it does not work.
I can compile c code with gcc. Is there a way to get more error output from the build?

The problem is that DBusError struct definition have bit fields that zig cInclude cannot handle.

In the following code I am defining a DBusError with the same memory layout as in dbus/dbus-errors.h and cast to the opaque pointer that cInclude defines for DBusError.

const std = @import("std");
const dbus = @cImport({
    @cInclude("dbus/dbus.h");
});

const DBusError = extern struct {
    name: [*c]const u8,
    message: [*c]const u8,
    dummy: isize,
    padding: *opaque {},
};

pub fn main() !void {
    var buf: DBusError = undefined;
    const err: *dbus.DBusError = @ptrCast(&buf);
    dbus.dbus_error_init(err);
    const conn = dbus.dbus_bus_get(dbus.DBUS_BUS_SESSION, err);
    _ = conn; // autofix
    if (dbus.dbus_error_is_set(err) != 0) {
        std.debug.print("{s}\n", .{std.mem.span(buf.message)});
        dbus.dbus_error_free(err);
    }
    // do not close shared DBUS_BUS_SESSION
    // defer dbus.dbus_connection_close(conn);
}

okay this might be a future error. I still cannot build it. I still get the core dump even without the dynamic flag

Okay thanks a lot. I got it wrong with the dbus. I did not realize that your code example was different from mine. But you directly add the

_ = dbus;

and it compiles now.

Is there somewhere resources where i can read up on how cInclude works and what it can handle and what not?

Zig Reference - C section
cInclude is using the zig translate-c under the hood.

The Translation failures subsection in the Zig Reference C section.

1 Like