Zig Build Autoconf name detection is too strict?

I’ve been trying to use Zig build system for GPGME and libgpg-error, but it seems the code generation step is too strict about variable names? https://codeberg.org/ziglang/zig/src/commit/4ad8bc341328e289744a0cc796043d0dd52bb32d/lib/std/Build/Step/ConfigHeader.zig#L578

fn expand_variables_autoconf_at(
    bw: *Writer,
    contents: []const u8,
    values: std.StringArrayHashMap(Value),
    used: []bool,
) !void {
    // vvv here
    const valid_varname_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";

Those libraries occasionally use @define:some_name@, so Zig fails to detect these vars which results in a bunch of errors.

/* System specific type definitions.  */
@define:gpgrt_ssize_t@
@define:gpgrt_off_t@

@include:os-add@

Should the allowed chars string be extended or is there a workaround?

That’s m4, not C (the .in in the file tells you that).

It’s not clear to me exactly what you’re trying to do here, but I don’t think that treating m4 macro calls as C variables will accomplish it. Those get replaced with “something else”, you most likely want to be working with the output of that process, not its input.

I was trying to replace Autoconf build system with Zig Build to have easy cross-compilation/static linking.

I thought this is the way to do it, for example https://github.com/allyourcodebase/binutils/blob/a11bcdf655e54dd5ce2328feb03baaad4f33b53a/build.zig#L687-L696. But you think in this case I should generate headers and vendor them?

I’m not the best person to answer these questions, all I can contribute is: the file you link to is a .h, not a .h.in, and autoconf will run m4 on those, supplemented with whatever-it-needs.

My guess(!) is that the @define:thing@ output vars get transformed into something without a : in it, in that process. That’s without having spent any time in the guts of autoconf, but having written more m4 than none at all. May that amount never increase!

1 Like

I don’t think this is about name strictness. I’m assuming @define: and @include: are keywords, and from the code that you linked, it seems like zig did not implement them. I’m not familiar with autoconf, are these standard keywords? If so, maybe you could implement the code for them, as the code looks rather simple.

1 Like

I tried libgpg-error and it uses an undef style config.h.in.
To generate it you need to install automake and to run ./autogen.sh.

Then in build.zig you can generate config.h using:

const config = b.addConfigHeader(.{
        .include_path = "config.h",
        .style = .{ .autoconf_undef = b.path("config.h.in") },
    }, .{
        .BUILD_COMMITID = null,
        .BUILD_TIMESTAMP = null,
        // ...
    });
lib.root_module.addConfigHeader(config);
2 Likes

Thanks. I thought Zig addConfigHeader replaces the generation step. I’ll try again with generated config.h.in files.

Thanks everyone. I figured out how to do that. Why do C people like code generation so much… It seems libgpg-error uses custom tool to replace @define:.. with some strings. I decided to link to system’s libgpg-error instead.

Here’s the final code, but it’s mostly for myself though https://codeberg.org/knightpp/gpgme-zig.

Static linking gives error: fatal linker error: unhandled relocation type R_X86_64_JUMP_SLOT at offset 0x14c40 identical to

:face_with_bags_under_eyes:

2 Likes

When all you have is a hammer…

2 Likes