Skip to content

[build.zig]: a concrete approach to build for web with zig-build#5157

Merged
raysan5 merged 1 commit into
raysan5:masterfrom
HaxSam:better_emscript_step
Aug 31, 2025
Merged

[build.zig]: a concrete approach to build for web with zig-build#5157
raysan5 merged 1 commit into
raysan5:masterfrom
HaxSam:better_emscript_step

Conversation

@HaxSam
Copy link
Copy Markdown
Contributor

@HaxSam HaxSam commented Aug 30, 2025

For a long time, I didn't like how Zig builds for the web.
The main problem was that there wasn't any helper method and that the build system emsdk was cloned twice—once for the Raylib dependency and once on the user side.
With the helper methods, it will be cloned only once and use the same folder for the operation.

Here is an example of how the build step can look now on the user side:

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

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

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

    const exe_mod = b.createModule(.{
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });
    exe_mod.linkLibrary(raylib_artifact);

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

    //web exports are completely separate
    if (target.query.os_tag == .emscripten) {
        const emsdk = rl.emsdk;
        const wasm = b.addLibrary(.{
            .name = "raylib_testing",
            .root_module = exe_mod,
        });

        const install_dir: std.Build.InstallDir = .{ .custom = "web" };
        const emcc_flags = emsdk.emccDefaultFlags(b.allocator, .{
            .optimize = optimize,
        });
        const emcc_settings = emsdk.emccDefaultSettings(b.allocator, .{
            .optimize = optimize,
        });

        const emcc_step = emsdk.emccStep(b, raylib_artifact, wasm, .{
            .optimize = optimize,
            .flags = emcc_flags,
            .settings = emcc_settings,
            .install_dir = install_dir,
        });
        b.getInstallStep().dependOn(emcc_step);

        const html_filename = try std.fmt.allocPrint(b.allocator, "{s}.html", .{wasm.name});
        const emrun_step = emsdk.emrunStep(
            b,
            b.getInstallPath(install_dir, html_filename),
            &.{},
        );

        emrun_step.dependOn(emcc_step);
        run_step.dependOn(emrun_step);
    } else {
        const exe = b.addExecutable(.{
            .name = "raylib_testing",
            .root_module = exe_mod,
        });
        b.installArtifact(exe);

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

        run_step.dependOn(&run_cmd.step);
    }
}

It relies heavily on the zemscripten library, which provides a solid foundation for using emsdk on different platforms.

I would like to request that @Not-Nik and @maiconpintoabreu review it and share their thoughts, especially from Nik, since he maintains the Zig bindings. This approach also works with the Zig bindings and can be copied and pasted. I already tested it with a local raylib-zig instance, where I replaced the raylib bindings with my own, and it allowed me to remove emsdk.zig.

@HaxSam HaxSam force-pushed the better_emscript_step branch from ddee612 to e778f38 Compare August 30, 2025 13:12
Copy link
Copy Markdown
Contributor

@Not-Nik Not-Nik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, a very nice addition. It seems this will make building games for the web with Zig and raylib much more ergonomic!

Comment thread build.zig Outdated
@HaxSam HaxSam force-pushed the better_emscript_step branch from e778f38 to 4715727 Compare August 30, 2025 17:42
@HaxSam
Copy link
Copy Markdown
Contributor Author

HaxSam commented Aug 30, 2025

@Not-Nik Ok fixed it and did the others too

Comment thread build.zig Outdated
@HaxSam HaxSam force-pushed the better_emscript_step branch from 4715727 to 4e2ed7b Compare August 30, 2025 18:23
@HaxSam HaxSam requested a review from Not-Nik August 31, 2025 08:24
@raysan5 raysan5 merged commit 0d29d8d into raysan5:master Aug 31, 2025
2 checks passed
@raysan5
Copy link
Copy Markdown
Owner

raysan5 commented Aug 31, 2025

@HaxSam @Not-Nik Thanks for the update and review!

mjhanninen pushed a commit to mjhanninen/raylib that referenced this pull request Sep 9, 2025
deathbeam added a commit to deathbeam/Raylib.NET that referenced this pull request Oct 1, 2025
raysan5/raylib#5157 broke the emscripten builds

Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants