zig icon indicating copy to clipboard operation
zig copied to clipboard

Importing miniaudio.h library results in dependency loop error

Open kavika13 opened this issue 1 year ago • 4 comments

Zig Version

0.12.0-dev.3403+b5cef9e8b

Steps to Reproduce and Observed Behavior

  1. zig init

  2. git clone https://github.com/mackron/miniaudio

  3. edit build.zig, and add these lines just after the const exe = ... declaration:

    exe.addIncludePath(.{ .path = "miniaudio" });
    exe.linkLibC();
  1. edit src/main.zig, and delete all the code but the const std = @import("std"); line.

  2. add the following additional code code:

const miniaudio = @cImport({
    @cDefine("MINIAUDIO_IMPLEMENTATION", {});
    @cInclude("miniaudio.h");
});

fn data_callback(_: *ma_device, _: *void, _: *const void, _: u32) void {}

pub fn main() !void {
    var config: miniaudio.ma_device_config = miniaudio.ma_device_config_init(miniaudio.ma_device_type_playback);
    config.playback.format = miniaudio.ma_format_f32;
    config.playback.channels = 2;
    config.sampleRate = 48000;
    config.dataCallback = data_callback;
}
  1. Run zig build

Behavior:

<srcroot>\zig-cache\o\3ce1300da0f0bde9e958a78552702100\cimport.zig:118:5: error: dependency loop detected
pub const ma_device_data_proc = ?*const fn ([*c]ma_device, ?*anyopaque, ?*const anyopaque, ma_uint32) callconv(.C) void;

Expected Behavior

I expected the program to compile successfully, or at least get further. There may be other errors to fix in the zig code, but the error in the C import would go away.

kavika13 avatar Mar 22 '24 09:03 kavika13

I stripped the miniaudio.h header down as much as I could, and here's zig and C code that replicate the problem about as minimally as I could manage:

const std = @import("std");
const miniaudio = @cImport({
    @cInclude("repro.h");
});

pub fn main() !void {
    miniaudio.ma_device_config_init();
}
typedef struct ma_device ma_device;

typedef void (* ma_device_data_proc)(struct ma_device* pDevice);

struct ma_device_config
{
    ma_device_data_proc dataCallback;
};

struct ma_device
{
    ma_device_data_proc onData;
};

void ma_device_config_init(void) {
    struct ma_device_config val;
}

The generated zig code from cimport.zig looks likes this:

pub const ma_device_data_proc = ?*const fn ([*c]struct_ma_device) callconv(.C) void;
pub const struct_ma_device = extern struct {
    onData: ma_device_data_proc = @import("std").mem.zeroes(ma_device_data_proc),
};
pub const ma_device = struct_ma_device;
pub const struct_ma_device_config = extern struct {
    dataCallback: ma_device_data_proc = @import("std").mem.zeroes(ma_device_data_proc),
};
pub export fn ma_device_config_init() void {
    var val: struct_ma_device_config = undefined;
    _ = &val;
}

kavika13 avatar Mar 22 '24 09:03 kavika13

i think this looks like https://github.com/ziglang/zig/issues/12325

xdBronch avatar Mar 22 '24 10:03 xdBronch

I've had a similar issue using miniaudio in the past, but it got fixed by #17692, according to @kcbanner

odecaux avatar Mar 22 '24 21:03 odecaux