Using raylib with translateC command

Knowing that we would remove @cImport at some point, I had a little trouble trying to import Raylib using std.Build.addTranslateC. It turns out it wasn’t as simple as I thought.

Anyway, here’s the resulting code snippet:

pub fn build(b: *std.Build) void {
    ...

    //get the raylib artifact from dependencies
    const raylib = b.dependency(
        "raylib",
        .{ .target = target, .optimize = optimize },
    ).artifact("raylib");

    //raylib bindings
    const translate_raylib = b.addTranslateC(.{
        .target = target,
        .optimize = optimize,
        .root_source_file = b.addWriteFiles().add("all.h",
            \\#include <raylib.h>
            \\#include <rcamera.h>
            \\#include <raymath.h>
            \\#include <rlgl.h>
        ),
    });

   //Little hack to include the raylib headers
   // another way to do this is just: 
   // translate_raylib.addIncludePath(raylib_dep.path("src"));
   //I do think this is more correct through, as it doesn't
   // depends on the internal folder structure of raylib 
    translate_raylib.include_dirs.append(.{ .other_step = raylib }) 
        catch @panic("OOM");
    translate_raylib.step.dependOn(&raylib.step);

    //Finish by linking to the raylib
    const raylib_mod = translate_raylib.createModule();
    raylib_mod.linkLibrary(raylib);
    
    main_exe.root_module.addImport("raylib", raylib_mod);

    ...

}

Hopefully this makes someone’s work easier, haha!

7 Likes

Trying to do this with version 0.17.0-dev.830+1f43e049d gives an error:

❯ zig build run
zig-pkg/raylib-6.0.0-whq8uA2ZLwU-cs7BBrig0P89QBOpHN7TKr3nqlsKvXFn/build.zig:95:10: error: member function expected 1 argument(s), found 2
_ = b.findProgram(&.{"wayland-scanner"}, &.{}) catch {
~^~~~~~~~~~~~
/home/saurabh/source/zig/build/stage3/lib/zig/std/Build.zig:1785:5: note: function declared here
pub fn findProgram(b: *Build, options: FindProgramOptions) ?[]const u8 {
~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
referenced by:
compileRaylib: zig-pkg/raylib-6.0.0-whq8uA2ZLwU-cs7BBrig0P89QBOpHN7TKr3nqlsKvXFn/build.zig:246:43
build: zig-pkg/raylib-6.0.0-whq8uA2ZLwU-cs7BBrig0P89QBOpHN7TKr3nqlsKvXFn/build.zig:611:34
11 reference(s) hidden; use '-freference-trace=13' to see all references
zig-pkg/raylib-6.0.0-whq8uA2ZLwU-cs7BBrig0P89QBOpHN7TKr3nqlsKvXFn/build.zig:762:23: error: no field named 'build_root' in struct 'Build'
const dir = try b.build_root.handle.openDir(b.graph.io, waylandDir, .{ .iterate = true });
^~~~~~~~~~
/home/saurabh/source/zig/build/stage3/lib/zig/std/Build.zig:1:1: note: struct declared here
const Build = @This();
^~~~~

My build.zig is:

const std = @import("std");

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

    const translator = b.addTranslateC(.{
        .root_source_file = b.path("zig-pkg/raylib-6.0.0-whq8uA2ZLwU-cs7BBrig0P89QBOpHN7TKr3nqlsKvXFn/src/raylib.h"),
        .target = target,
        .optimize = optimize,
    });

    const raylib_dep = b.dependency("raylib", .{
        .target = target,
        .optimize = optimize,
    });

    const raylib_artifact = raylib_dep.artifact("raylib");

    const exe = b.addExecutable(.{
        .name = "invaders",
        .root_module = b.createModule(.{
            .root_source_file = b.path("src/main.zig"),
            .target = target,
            .optimize = optimize,
            .imports = &.{
                .{ .name = "raylib", .module = translator.createModule() },
            },
        }),
    });

    exe.root_module.linkLibrary(raylib_artifact);

    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());

    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);
}

I tried installing wayland-scanner with pacman and yay, but the package doesn’t exist. Do I need to install something else or is there something wrong with build.zig ?


Edit:

Additional info:

KDE Plasma Version: 6.6.5
KDE Frameworks Version: 6.26.0
Qt Version: 6.11.1
Kernel Version: 7.0.10-artix1-1 (64-bit)
Graphics Platform: Wayland

I think it’s under the wayland package.

wayland-scanner should be in the wayland devel packages.

I think it’s under the wayland package.

The wayland package is already installed -

world/wayland                1.25.0-1      1.25.0-1        0.00 MiB       0.14 MiB

wayland-scanner should be in the wayland devel packages.

I’m not sure what the exact name is in Arch Packages or AUR


that’s odd…

Yeah, wayland-scanner exists in /usr/bin/

It seems the signature of findProgram changed to accept a FindProgramOptions struct. This error comes from raylib, so you’ll have to wait until raylib updates, which will probably only happen when 0.17 is released. In the meantime, you can use zig 0.16, which should work.

2 Likes

Here’s my version of it.
I misread this thread thinking that you didn’t have it working, turns out what I’ve impl is pretty much the same as yours. I love myself.

Huh… the error hasn’t changed for me

Sorry, I thought you meant you got it working with 0.17-. Didn’t go through build.zig.zon before trying .. Will give it a shot with 0.16

1 Like

Hi @saurabh, i didn’t check this thread in while, sorry for the late answer.
My current setup for running raylib in 0.16 is:

    const translate_c = b.addTranslateC(.{
        .target = target,
        .optimize = optimize,
        .root_source_file = b.addWriteFiles().add("c.h",
            \\#include <raylib.h>
            \\#include <raymath.h>
            \\#include <rcamera.h>
        ),
    });
    const raylib = b.dependency("raylib", .{
        .target = target,
        .optimize = optimize,
        .config = "-fno-sanitize=undefined -fno-lto", //have to do this, otherwise it wont compile (at least for me)
    }).artifact("raylib");
    translate_c.addIncludePath(raylib.getEmittedIncludeTree());

    exe.root_module.addImport("raylib", c_module);

Hopefully this works for you too (in case you didn’t make it work already)