Error in Zig file Generated from TranslateC

I’m working on a personal project using raylib and raylibgui, but I am having some trouble with the zig code generated from raylibgui (a single header lib). I wanted to know if anyone had any fixes for this, thanks.

EDIT: I should add that I have never used raylibgui before so it might be me holding it wrong

Zig version 0.16.0

build.zig

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    // https://codeberg.org/ziglang/translate-c/src/branch/main/examples/compile_c/build.zig
    const rl = b.addTranslateC(.{
        .root_source_file = b.path("src/c.h"),
        .target = target,
        .optimize = optimize,
    });
    rl.linkSystemLibrary("raylib", .{});

    const rlgui = b.addTranslateC(.{
        .root_source_file = b.path("src/raygui.c"),
        .target = target,
        .optimize = optimize,
    });
    rlgui.linkSystemLibrary("raylib", .{});
    rlgui.link_libc = true;

    const exe_mod = b.createModule(.{
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
        .imports = &.{
            .{
                .name = "rl",
                .module = rl.createModule(),
            },
            .{
                .name = "rlgui",
                .module = rlgui.createModule(),
            },
        },
    });

    const exe = b.addExecutable(.{
        .name = "barz2",
        .root_module = exe_mod,
    });

    b.installArtifact(exe);

    const run_step = b.step("run", "Run the app");

    const run_cmd = b.addRunArtifact(exe);
    run_step.dependOn(&run_cmd.step);

    run_cmd.step.dependOn(b.getInstallStep());

    if (b.args) |args| {
        run_cmd.addArgs(args);
    }

    const exe_tests = b.addTest(.{
        .root_module = exe.root_module,
    });
    const run_exe_tests = b.addRunArtifact(exe_tests);

    const test_step = b.step("test", "Run tests");
    test_step.dependOn(&run_exe_tests.step);

    const exe_check = b.addExecutable(.{
        .name = "barz2",
        .root_module = exe_mod,
    });

    const check = b.step("check", "Check if barz2 compiles");
    check.dependOn(&exe_check.step);
}

main.zig

const std = @import("std");
const Io = std.Io;

const rl = @import("rl");
const rlgui = @import("rlgui");

const BG: rl.Color = .{ .r = 0x18, .g = 0x18, .b = 0x18, .a = 0xFF };
const WHITE = rl.RAYWHITE;
const RED = rl.RED;
const BLUE = rl.BLUE;

fn drawBars(bar_vals: []i32, red_idx: u32, blue_idx: u32, window_width: i32, window_height: i32) void {
    const base: i32 = @trunc(@as(f32, @floatFromInt(window_height)) * 0.85);
    const scale = @divTrunc(base, @as(i32, @intCast(bar_vals.len)));
    const bar_width = @divTrunc(window_width, (2 * @as(i32, @intCast(bar_vals.len))) + 1);
    for (bar_vals, 0..) |bar_val, i| {
        const bar_height = bar_val * scale;
        const bar_base = base - bar_height;
        const bar_x = ((@as(i32, @intCast(i)) * 2) + 1) * bar_width;
        rl.DrawRectangle(
            bar_x,
            bar_base,
            bar_width,
            bar_height,
            if (red_idx == i) RED else if (blue_idx == i) BLUE else WHITE,
        );
    }
}

/// returns index_from, index_to
fn sort(arr: []i32, reset: bool) struct { usize, usize } {
    const S = struct {
        var i: usize = 0;
        var j: usize = 0;
    };
    if (reset) {
        S.i = 0;
        S.j = 0;
    }
    while (S.i < arr.len) : (S.i += 1) {
        S.j = S.i + 1;
        while (S.j < arr.len) : (S.j += 1) {
            if (arr[S.i] > arr[S.j]) {
                const temp = arr[S.i];
                arr[S.i] = arr[S.j];
                arr[S.j] = temp;
                return .{ S.i, S.j };
            }
        }
    }

    S.i = 0;
    S.j = 0;
    return .{ S.i, S.j };
}

pub fn main(init: std.process.Init) !void {
    const io = init.io;

    // stdout
    var stdout_buf: [1024]u8 = undefined;
    var stdout_writer = Io.File.stdout().writer(io, &stdout_buf);
    const stdout = &stdout_writer.interface;
    defer stdout.flush() catch {};

    try stdout.writeAll("Begin Drawing\n");
    stdout.flush() catch {};

    var bar_vals: [20]i32 = undefined;
    for (0..bar_vals.len) |i| {
        bar_vals[i] = @as(i32, @intCast(i)) + 1;
    }

    // Random stuff
    var buf: [1]u8 = undefined;
    io.random(&buf);
    var prng = std.Random.DefaultPrng.init(buf[0]);
    const rand = prng.random();

    rand.shuffle(i32, &bar_vals);

    // window setup
    var window_height: i32 = 600;
    var window_width: i32 = 800;
    rl.SetConfigFlags(rl.FLAG_WINDOW_RESIZABLE);
    rl.InitWindow(window_width, window_height, "Barz2");
    rl.SetTargetFPS(30);

    // Indexes
    var red_idx: u32 = @truncate(bar_vals.len);
    var blue_idx: u32 = @truncate(bar_vals.len);
    var i: usize = 0;
    var j: usize = 0;
    while (!rl.WindowShouldClose()) {
        if (rl.IsWindowResized()) {
            window_height = rl.GetScreenHeight();
            window_width = rl.GetScreenWidth();
        }

        rl.BeginDrawing();
        {
            rl.ClearBackground(BG);

            // The only function I use from raylibgui
            if (rlgui.GuiButton(.{ .x = 24, .y = 24, .width = 120, .height = 30 }, "#191#Show Message") == 1) {
                std.debug.print("button pressed\n", .{});
            }

            drawBars(bar_vals[0..], red_idx, blue_idx, window_width, window_height);

            i, j = sort(&bar_vals, false);
            red_idx = @truncate(i);
            blue_idx = @truncate(j);
        }
        rl.EndDrawing();
    }
}

c.h

#include <raylib.h>

raygui.c

#define RAYGUI_IMPLEMENTATION
#include "raygui.h"

Build command output:

~/projects/barz2$ zig build
install
└─ install barz2
   └─ compile exe barz2 Debug native 3 errors
.zig-cache/o/ca6b0f1b6c37438139f533eb98a29466/raygui.zig:1874:19: error: unused local constant
            const extern_local_feof = struct {
                  ^~~~~~~~~~~~~~~~~
.zig-cache/o/ca6b0f1b6c37438139f533eb98a29466/raygui.zig:4190:27: error: unused local constant
                    const extern_local___ctype_b_loc = struct {
                          ^~~~~~~~~~~~~~~~~~~~~~~~~~
.zig-cache/o/ca6b0f1b6c37438139f533eb98a29466/raygui.zig:4241:27: error: unused local constant
                    const extern_local___ctype_b_loc = struct {
                          ^~~~~~~~~~~~~~~~~~~~~~~~~~
error: 3 compilation errors
failed command: /home/dylanm/.cache/zig/p/N-V-__8AAFFSVRWqblwBIcA-Yqv-u7sbjsJoww8K0mWaHbmJ/zig build-exe -ODebug --dep rl --dep rlgui -Mroot=/home/dylanm/projects/barz2/src/main.zig -lraylib -ODebug -Mrl=.zig-cache/o/210c4b8dc40413d4d58ec1ec4dce4a1f/c.zig -ODebug -Mrlgui=.zig-cache/o/ca6b0f1b6c37438139f533eb98a29466/raygui.zig -lc --cache-dir .zig-cache --global-cache-dir /home/dylanm/.cache/zig --name barz2 --zig-lib-dir /home/dylanm/.cache/zig/p/N-V-__8AAFFSVRWqblwBIcA-Yqv-u7sbjsJoww8K0mWaHbmJ/lib/ --listen=-

Build Summary: 2/5 steps succeeded (1 failed)
install transitive failure
└─ install barz2 transitive failure
   └─ compile exe barz2 Debug native 3 errors

error: the following build command failed with exit code 1:
.zig-cache/o/83670129849765c2d884626fd7e1cf03/build /home/dylanm/.cache/zig/p/N-V-__8AAFFSVRWqblwBIcA-Yqv-u7sbjsJoww8K0mWaHbmJ/zig /home/dylanm/.cache/zig/p/N-V-__8AAFFSVRWqblwBIcA-Yqv-u7sbjsJoww8K0mWaHbmJ/lib /home/dylanm/projects/barz2 .zig-cache /home/dylanm/.cache/zig --seed 0xce9ab507 -Z4eba3540cab1e49c

Translate c is only useable for headers, if you want to compile the implementation use mod.addCSourceFile[s] instead. (ofc, continue translating the header)

4 Likes

Might be related?

https://codeberg.org/ziglang/translate-c/issues/327

In my case it only happens with ReleaseSafe, maybe try using ReleaseFast or Debug.

Thanks. This fixed it:

build.zig

    ///...

    // https://codeberg.org/ziglang/translate-c/src/branch/main/examples/compile_c/build.zig
    const rl = b.addTranslateC(.{
        .root_source_file = b.path("src/c.h"),
        .target = target,
        .optimize = optimize,
    });
    rl.linkSystemLibrary("raylib", .{});

    const rlgui = b.addTranslateC(.{
        .root_source_file = b.path("src/raygui.h"),
        .target = target,
        .optimize = optimize,
        .link_libc = true,
    });
    rlgui.linkSystemLibrary("raylib", .{});

    const exe_mod = b.createModule(.{
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
        .imports = &.{
            .{
                .name = "rl",
                .module = rl.createModule(),
            },
            .{
                .name = "rlgui",
                .module = rlgui.createModule(),
            },
        },
    });
    exe_mod.addCSourceFile(.{ .file = b.path("src/raygui.c") });

    //...

You can, and should, combine the translation of raylib and raygui headers. Otherwise, you may get type mismatches if you pass things between the APIs.

Furthermore, you don’t need a separate c file, you can add the header to be compiled, and define the macro through the build system with mod.addCMacro.

1 Like