Not-Nik / raylib-zig

Manually tweaked, auto-generated raylib bindings for zig. https://github.com/raysan5/raylib
MIT License
677 stars 122 forks source link

Global Artifact Caching Breaks Multi-Target Builds #170

Open ArielBenichou opened 1 week ago

ArielBenichou commented 1 week ago

Hey o, 👋 I'm pretty new to both Zig and raylib-zig, and I think I stumbled upon a bug while trying to build my project for different platforms. I've discussed this in the Zig Discord server, and they suggested I should report it.

What's Happening

I'm trying to build a simple project for multiple targets (like macOS and Windows), but it seems there's an issue with how artifacts are being cached. From what I understand after discussing it in Discord, the problem is that raylib-zig is using global variables to cache build artifacts, which doesn't play well with Zig's build system when trying to build for multiple targets.

How to Reproduce

I created a minimal test project to demonstrate the issue. Here's how you can try it yourself:

  1. First, create a new project with this structure:

    my-project/
    ├── build.zig
    └── build.zig.zon
    └── src/
    └── main.zig
  2. Here's my build.zig.zon:

    .{
    .name = "raylib-test",
    .version = "0.1.0",
    .dependencies = .{
        .raylib = .{
            .url = "https://github.com/Not-Nik/raylib-zig/archive/19db777449c0f56ca621121a00087d341eb77080.tar.gz",
            .hash = "1220608d53a1e0e295f8367be3aa7b1439d044af1551ae64cf5ae6ce9edb05858e73",
        },
    },
    .paths = .{
        "build.zig",
        "build.zig.zon",
        "src",
    },
    }
  3. My build.zig:

    
    const std = @import("std");

const Target = struct { query: std.Target.Query, name: []const u8, };

const targets = [_]Target{ .{ .query = .{ .cpu_arch = .aarch64, .os_tag = .macos }, .name = "aarch64-macos" }, .{ .query = .{ .cpu_arch = .x86_64, .os_tag = .windows }, .name = "x86_64-windows" }, };

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

// =================
// ==== INSTALL ====
// =================
const exe = try createExecutable(b, target, optimize);
b.installArtifact(exe);

// =================
// ==== RELEASE ====
// =================
const release_step = b.step("release", "Create release builds for all targets");

for (targets) |t| {
    const target_query = b.resolveTargetQuery(t.query);
    const release_exe = try createExecutable(b, target_query, .ReleaseFast);

    const release_dir_name = try std.fmt.allocPrint(
        b.allocator,
        "{s}.{s}",
        .{ "raylib-test", t.name },
    );

    // Create release directory
    const release_path = try std.fs.path.join(b.allocator, &.{ "releases", release_dir_name });
    const install_step = b.addInstallArtifact(release_exe, .{
        .dest_dir = .{ .override = .{ .custom = release_path } },
    });
    release_step.dependOn(&install_step.step);
}

}

fn createExecutable( b: std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, ) !std.Build.Step.Compile { const exe = b.addExecutable(.{ .name = "raylib-test", .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, }); exe.linkLibCpp();

// Raylib & Raygui
const raylib_dep = b.dependency("raylib", .{
    .target = target,
    .optimize = optimize,
});
const raylib = raylib_dep.module("raylib");
const raygui = raylib_dep.module("raygui");
const raylib_artifact = raylib_dep.artifact("raylib");
exe.linkLibrary(raylib_artifact);
exe.root_module.addImport("raylib", raylib);
exe.root_module.addImport("raygui", raygui);

return exe;

}


4. And a simple `src/main.zig`:
```zig
const rl = @import("raylib");

pub fn main() !void {
    rl.initWindow(800, 450, "Test");
    defer rl.closeWindow();

    rl.setTargetFPS(60);

    while (!rl.windowShouldClose()) {
        rl.beginDrawing();
        defer rl.endDrawing();

        rl.clearBackground(rl.Color.white);
    }
}

The Error

When I run zig build, I get this error:

thread 31355508 panic: unable to find artifact 'raylib'

From what I learned in the Discord discussion, this happens because the caching system is reusing the first cached artifact instead of creating new ones for different targets.

What Should Happen

The build system should create separate artifacts for each target, allowing us to successfully build for multiple platforms.

Additional Context

The issue seems to be related to the global caching in build.zig here: https://github.com/Not-Nik/raylib-zig/blob/c191e12e7c50e5dc2b1addd1e5dbd16bd405d2b5/build.zig#L100

I'm still learning Zig and raylib, so please let me know if you need any additional information or if I should test something else! 😊

Not-Nik commented 6 days ago

Should be fixed

Not-Nik commented 6 days ago

The fix I tried broke the build. Maybe we would need to give each artifact a unique name?

ArielBenichou commented 5 days ago

Well, i don't really know. Can raylib-zig be built without caching the artifact?