Turning off wayland for raylib's zig build?

Hoping someone can help me, I fully expect this is some very basic misunderstanding of the zig build system but I’ve been banging my head against the wall for hours now and i just need to scream for help into the void hoping I hear something back :sweat_smile:

I have a very basic raylib setup, where my zig.zon looks like:

    .dependencies = .{
        .raylib = .{
            .url = "git+https://github.com/raysan5/raylib#58fe34d9cc2dd1929efb864e5222f25253c4ad89",
            .hash = "122076f6c16e9917eaa3a878e8e3af0cd358afe5eb4029f974521beeef51181ae5d5",
        },
        .raygui = .{
            .url = "git+https://github.com/raysan5/raygui#dbfd9c78801e31992500bc22b46d5ff98e3b8bd0",
            .hash = "12207b13a5e7e41463ea9748e03aa04f786804fcd7bcd550f44464a201a0a5bfc9da",
        },
    },

which FYI is just the latest master commits, and my build.zig looks like this:

    const raylib_dependency = b.dependency("raylib", .{
        .optimize = optimize,
        .target = target,
        // Default is set to use wayland, which is not on every distro
        .linux_display_backend = .X11,
    });
    const raylib_artifact = raylib_dependency.artifact("raylib");
    raylib_build.addRaygui(b, raylib_artifact, b.dependency("raygui", .{}));

obviously truncating the rest, this is just the important parts. but i get this build error:

pav@linux:~/git/personal/raylib-game$ zig build
error:  `wayland-scanner` may not be installed on the system.
 You can switch to X11 in your `build.zig` by changing `Options.linux_display_backend`

yup, which corresponds to this: raylib/build.zig at master · raysan5/raylib · GitHub

What I think is happening is me trying to set X11 the way i am is not valid somehow and the code in raylibs build.zig will set the option to the default value of .Both if it gets something that isnt a valid LinuxDisplayBackend enum value.

All the google fu brings up people talking about setting options exactly as i am, just as part of the anonymous struct argument for the b.dependency function call. But clearly that isnt working here. I’ve tried silly things like raylib_build.LinuxDisplayBackend.X11 but that doesn’t work and infact ZLS tells me it can’t see .X11 as a value on LinuxDisplayBackend and i’ve also tried using raylib_dependency.builder.addUserInputOption("linux_display_backend", "X11"); and that also fails.

How do i set the valid type for the option? Any help would be greatly appreciated!

You could try setting b.addUserInputOption("linux_display_backend", "X11") at the beginning of your build.zig (before initializing the raylib dependency).

_ = b.addUserInputOption("linux_display_backend", "X11") catch unreachable;

That also doesn’t seem to work :frowning_face:

Does the option show up if you run zig build --help?

I get the same error before any help output is shown :man_shrugging:

pav@linux:~/git/personal/raylib-game$ zig build --help
error:  `wayland-scanner` may not be installed on the system.
 You can switch to X11 in your `build.zig` by changing `Options.linux_display_backend`
thread 22638 panic: `wayland-scanner` not found

Maybe just try adding it as a command-line flag for now?
zig build -Dlinux_display_backend=X11

pav@linux:~/git/personal/raylib-game$ zig build -Dlinux_display_backend=X11
error:  `wayland-scanner` may not be installed on the system.
 You can switch to X11 in your `build.zig` by changing `Options.linux_display_backend`
thread 24278 panic: `wayland-scanner` not found

also doesn’t work :frowning_face:

raylibs build.zig has rapidly changed in the last few months, if you look at the issues and the pull requests for [build] titles that include zig changes and you can see its gone back and forth with the approaches for it. I wonder if its actually in a broken state on the latest master commit and there just isn’t many if us trying to use raylib natively with zig? The pull request itself that is responsible for its current iterations calls out the current approach isnt very idiomatic for zig and it needs a better solution. :man_shrugging: [BUILD][ZIG]: remove raygui from build options and re add addRaygui as a function by kimierik · Pull Request #4485 · raysan5/raylib · GitHub

This issue may be related? Setting a different backend would be a similar challenge as its also not a bool its a specific type that the option is expecting as you can see here: raylib/build.zig at master · raysan5/raylib · GitHub

I’m really questioning if this build.zig actually works for these options :thinking:

Just to try and get a better understanding of the problem I installed the required wayland library on my machine just to get past the compiler error and the help output for zig build doesn’t actually show any available options flags. So I guess you can’t just set this at the cli level regardless?

pav@linux:~/git/personal/raylib-game$ zig build --help
Usage: /usr/local/zig/zig build [steps] [options]

Steps:
  install (default)            Copy build artifacts to prefix path
  uninstall                    Remove build artifacts from prefix path
  run                          Run the app
  test                         Run unit tests
  clean                        Clean up

General Options:
  -p, --prefix [path]          Where to install files (default: zig-out)
  --prefix-lib-dir [path]      Where to install libraries
  --prefix-exe-dir [path]      Where to install executables
  --prefix-include-dir [path]  Where to install C header files

  --release[=mode]             Request release mode, optionally specifying a
                               preferred optimization mode: fast, safe, small

  -fdarling,  -fno-darling     Integration with system-installed Darling to
                               execute macOS programs on Linux hosts
                               (default: no)
  -fqemu,     -fno-qemu        Integration with system-installed QEMU to execute
                               foreign-architecture programs on Linux hosts
                               (default: no)
  --glibc-runtimes [path]      Enhances QEMU integration by providing glibc built
                               for multiple foreign architectures, allowing
                               execution of non-native programs that link with glibc.
  -frosetta,  -fno-rosetta     Rely on Rosetta to execute x86_64 programs on
                               ARM64 macOS hosts. (default: no)
  -fwasmtime, -fno-wasmtime    Integration with system-installed wasmtime to
                               execute WASI binaries. (default: no)
  -fwine,     -fno-wine        Integration with system-installed Wine to execute
                               Windows programs on Linux hosts. (default: no)

  -h, --help                   Print this help and exit
  -l, --list-steps             Print available steps
  --verbose                    Print commands before executing them
  --color [auto|off|on]        Enable or disable colored error messages
  --prominent-compile-errors   Buffer compile errors and display at end
  --summary [mode]             Control the printing of the build summary
    all                        Print the build summary in its entirety
    new                        Omit cached steps
    failures                   (Default) Only print failed steps
    none                       Do not print the build summary
  -j<N>                        Limit concurrent jobs (default is to use all CPU cores)
  --maxrss <bytes>             Limit memory usage (default is to use available memory)
  --skip-oom-steps             Instead of failing, skip steps that would exceed --maxrss
  --fetch                      Exit after fetching dependency tree

Project-Specific Options:
  -Dtarget=[string]            The CPU architecture, OS, and ABI to build for
  -Dcpu=[string]               Target CPU features to add or subtract
  -Ddynamic-linker=[string]    Path to interpreter on the target system
  -Doptimize=[enum]            Prioritize performance, safety, or binary size
                                 Supported Values:
                                   Debug
                                   ReleaseSafe
                                   ReleaseFast
                                   ReleaseSmall

System Integration Options:
  --search-prefix [path]       Add a path to look for binaries, libraries, headers
  --sysroot [path]             Set the system root directory (usually /)
  --libc [file]                Provide a file which specifies libc paths

  --system [pkgdir]            Disable package fetching; enable all integrations
  -fsys=[name]                 Enable a system integration
  -fno-sys=[name]              Disable a system integration

  Available System Integrations:                Enabled:
  (none)                                        -

Advanced Options:
  -freference-trace[=num]      How many lines of reference trace should be shown per compile error
  -fno-reference-trace         Disable reference trace
  --build-file [file]          Override path to build.zig
  --cache-dir [path]           Override path to local Zig cache directory
  --global-cache-dir [path]    Override path to global Zig cache directory
  --zig-lib-dir [arg]          Override path to Zig lib directory
  --build-runner [file]        Override path to build runner
  --seed [integer]             For shuffling dependency traversal order (default: random)
  --debug-log [scope]          Enable debugging the compiler
  --debug-pkg-config           Fail if unknown pkg-config flags encountered
  --verbose-link               Enable compiler debug output for linking
  --verbose-air                Enable compiler debug output for Zig AIR
  --verbose-llvm-ir[=file]     Enable compiler debug output for LLVM IR
  --verbose-llvm-bc=[file]     Enable compiler debug output for LLVM BC
  --verbose-cimport            Enable compiler debug output for C imports
  --verbose-cc                 Enable compiler debug output for C compilation
  --verbose-llvm-cpu-features  Enable compiler debug output for LLVM CPU features

Another funny thing is even after installing wayland i still get an error with this setup despite literally copy pasting the code example from the author of the PR for the current iteration of the build.zig :man_facepalming:

pav@linux:~/git/personal/raylib-game$ zig build
install
└─ install raylib-game
   └─ zig build-exe raylib-game Debug native 1 errors
src/main.zig:2:24: error: no module named 'raylib' available within module root
const raylib = @import("raylib");

I really think raylibs build.zig in master is broken… or master is only aligned with a very specific dev version of zig perhaps? I’m using the 0.13.0 release.

** edit **
Ok this one was me being dumb, trying to do a zig import instead of a cimport :man_facepalming: but yeah not being able to set options that are not bools DOES seem to be a problem and there is multiple issues about it. I still dont understand if its because its just not intuitive how to pass the correct type, or if its actually broken.

Can you post your full build.zig?

const std = @import("std");
const raylib_build = @import("raylib");

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

    const exe = b.addExecutable(.{
        .name = "raylib-game",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });

    const raylib_dep = b.dependency("raylib", .{
        .target = target,
        .optimize = optimize,
        // Default is set to use wayland, which is not on every distro
        .linux_display_backend = .X11,
    });
    const raylib = raylib_dep.artifact("raylib");
    raylib_build.addRaygui(b, raylib, b.dependency("raygui", .{}));

    exe.linkLibrary(raylib);
    b.installArtifact(exe);

    const run_cmd = b.addRunArtifact(exe);
    run_cmd.step.dependOn(b.getInstallStep());
    if (b.args) |args| {
        run_cmd.addArgs(args);
    }
    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run_cmd.step);

    const unit_tests = b.addTest(.{
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });
    const run_unit_tests = b.addRunArtifact(unit_tests);
    const test_step = b.step("test", "Run unit tests");
    test_step.dependOn(&run_unit_tests.step);
}

removed all the default comments which i do actually have in my build.zig

1 Like

Just to confirm, so that I don’t waste my time: with that you still get the wayland scanner error?

This is exactly my build.zig file when i was getting those errors yes. But i’ve played with so many parameters since then and interestingly enough I can get it to build now. I suspect its a combination of I went to the latest dev version of zig: 0.14.0-dev.2362+a47aa9dd9 and i also installed libwayland-dev on my machine.

The interesting thing about it is obviously if i run the binary it shows its using X11, but im pretty sure thats raylib doing that, as it has logic to detect which backends to use ect. But if i change the build.zig to instead use the line .linux_display_backend = .Wayland, it actually builds but refuses to run, i get this output:

pav@linux:~/git/personal/raylib-game$ ./zig-out/bin/raylib-game
INFO: Initializing raylib 5.6-dev
INFO: Platform backend: DESKTOP (GLFW)
INFO: Supported raylib modules:
INFO:     > rcore:..... loaded (mandatory)
INFO:     > rlgl:...... loaded (mandatory)
INFO:     > rshapes:... loaded (optional)
INFO:     > rtextures:. loaded (optional)
INFO:     > rtext:..... loaded (optional)
INFO:     > rmodels:... loaded (optional)
INFO:     > raudio:.... loaded (optional)
WARNING: GLFW: Error: 65544 Description: Wayland: Failed to connect to display
WARNING: GLFW: Failed to initialize GLFW
Segmentation fault at address 0x0
???:?:?: 0x0 in ??? (???)
Aborted (core dumped)

sooo, setting that option like that DOES WORK on the latest zig version and if you have that specific wayland library on your machine? :man_shrugging: I’m still so confused and been trying to figure this out and i made it hard on myself because i’ve been trying so many different things, often multiple things at once so i’ve lost track of exactly where i started to get it to build.

but as i said and as above shows, when i was on zig 0.13.0 with this exact build.zig file and without the dev wayland library installed i was getting that error that was triggered seemingly because of the option not being set properly and using the default option of .Both

But just to be clear if time is value please do not waste it on this. Like i said at the very first post, i fully expected this to be a me misunderstanding the zig build system rather than perhaps anything else. But going down this path did start to make me think the build.zig file in the raylib repo may be causing some issues.

If you look at how the binding repos are managing their downstream build.zig files, they are basically copy pasting the one from raylibs repos but making their own changes, and one of the bindings repos actually uses raylib as a git submodule rather than using the zig package manager. So why i found that interesting is in that case the bindings maintainer actually had the Options struct in their own build.zig file and thats how they were using it. like this: raylib-zig/build.zig at devel · Not-Nik/raylib-zig · GitHub

I don’t think you can just run a wayland application using X11, or are you actually using wayland to try and run it?

I am not an expert on this stuff, but it seems to me as if you are mixing up concepts here.

Just because you build the app with wayland support doesn’t mean that you can run it on that system, especially if you aren’t actually using wayland. I think there are specific compatibility shims that allow to run apps on the other like Xwayland allowing people to run x11 apps on wayland, but normally you would try to just use either wayland or x11 apps and match that to whether you are using x11 or wayland.

The whole idea behind the .both flag is that both get compiled into the app and then the app selects the right one based on which one it is running on.

But both is the right option because it allows people to create builds that work regardless of what the linux user uses, it just requires that you have that package installed on the machine that builds it.

No that isn’t correct, the bindings had that stuff way before the raylib repo did, it is actually the other way around somebody looked at a bunch of bindings and different examples and then improved the raylib build.zig with those ideas.

Hmm I think for the Options you are actually correct, but it is confusing because there are so many people all working on their own and just coordinated by reacting to another.

And the one that uses submodules, does that because it worked when the package manager didn’t exist yet.

There are a lot of different people who have created things independently and then also collaborated in different ways, updating their projects in specific ways that suits those projects.

Please don’t spread misinformation through hastily made assumptions presented as facts, it is already difficult enough to keep up with all those people who independently work on their wrappers and also update the build.zig, thats why I don’t want any additional factors causing confusion in communication.

I apologize, I think I was wrong, but yeah it is a bit of a mess and gets too confusing.

I maintain this project GitHub - SimonLSchlee/zigraylib: a fairly minimal raylib zig example codebase using the zig package manager (which I locally have working with the new build.zig but still need to make some changes before I create an update) and it can be annoying having to react to changes in the raylib build.zig and figuring out how to properly use it, but I think the recent changes to the build zig have been an improvement and overall I am impressed how well the people who have touched that build.zig have done that, without breaking users of it.

I think overall for the raylib build.zig there is a unspoken understanding there to add capabilities and try not to break existing use cases, sometimes options / the way something needs to be accomplished changes, but that is unavoidable.

So first of all i really appreciate putting effort into replying. Its only with discussion in the open that this stuff slowly gets all worked out and people can get on the same page and understand where their assumptions are wrong.

I definitely do not intend to spread wrong information with bad assumptions! I was definitely “thinking” out loud though in the hopes that others would see where i’ve gone wrong and know how to correct me, and thats always a hard line to walk because yes if it just adds to the confusion or worse it never gets responded to my potentially incorrect assumptions are on the internet now potentially being searched and found by others confused and now may have incorrect information.

and on that topic i think you are correct. I think i do fundamentally misunderstand what this linux_display_backend option is for. I was reading some of the code and issues specifically around graphics backends so i did know that raylib is doing checks and selections on its own when running, but i thought this option was specifically for getting around the exact issue i had, which is where my host machine cannot build the wayland support because i do not have the correct librarys on my distro (it saddens me that raylib dynamically links to many system libraries :frowning: i wish zig could solve that problem for them forever, i guess there is lots of libraries we would need to port over to the all your codebase organisation?)

anyway, like i said, i was assuming that if i explicitly set only x11 as the backend for my build options that it would solve the problem where i can actually build it. Is this assumption still incorrect? I actually tried to “go back” to where i didnt have the wayland library installed so i could check if thats still the case but apparently just sudo apt remove that specific library doesn’t get me back there, clearly it installed a bunch of other dependencies which make a difference and allow me to still not hit my original build error now.

all that is to say, yes i think im still confused and have wrong assumptions around if i can even set linux_display_backend correct and what it actually does for the build process :sweat_smile:

1 Like

Also your repo is one of the ones i was reading to see how others are doing it! I believe that was the first downstream one i found that wasn’t using git submodules (which i do NOT want to use myself)

I wonder how much of a difference it makes when you are not opting into raygui also?

I’ve also seen some other repos using the addRaylib function instead to build raylib. I believe that function takes options as an argument directly. But it still wasn’t clear to me even if you do that (have the Options struct in your own build.zig and call that function) that your options wouldn’t just refer to defaults anyway because of how the upstream build.zig is written.

edit
Oh i see you have a raygui branch and you use that function call in that branch! I don’t think that works like that anymore. They have removed the raygui flag in the upstream build.zig now :frowning:

It actually should be able to be built if you set x11 as backend and doing that worked for me, but maybe I had the headers for wayland hanging around somewhere. Do you think that the headers caused the issue, I had trouble reproducing the error and could create a x11 raygui example.

If you want I can push a repo for what I tried and you can test that.

What I meant is that the default of .both is correct, but if you only select one than that should allow building without needing the other and if it doesn’t work then that is a bug that needs to be fixed.