Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emscripten build fail #1

Open
Gandalf-Le-Dev opened this issue Oct 21, 2024 · 0 comments
Open

Emscripten build fail #1

Gandalf-Le-Dev opened this issue Oct 21, 2024 · 0 comments

Comments

@Gandalf-Le-Dev
Copy link

I would like to render a textured quad with sokol using zstbi to load the texture and I managed to run it on native systems but with emscripten I get two errors:

Uncaught RuntimeError: Aborted(Cannot use convertFrameToPC (needed by __builtin_return_address) without -sUSE_OFFSET_CONVERTER). Build with -sASSERTIONS for more info.

and when I add the flag -sUSE_OFFSET_CONVERTER I get this error:

panic: zstbi: out of memory
onerror: Uncaught RuntimeError: unreachable

How can I fix this ?

Here is my build.zig

const std = @import("std");
const log = std.log;
const fs = std.fs;
const builtin = @import("builtin");
const Build = std.Build;
const OptimizeMode = std.builtin.OptimizeMode;
const sokol = @import("sokol");

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

    const dep_sokol = b.dependency("sokol", .{
        .target = target,
        .optimize = optimize,
        .with_sokol_imgui = true,
    });

    const dep_cimgui = b.dependency("cimgui", .{
        .target = target,
        .optimize = optimize,
    });

    const dep_zigbeam = b.dependency("zigbeam", .{
        .target = target,
        .optimize = optimize,
    });

    const dep_zstbi = b.dependency("zstbi", .{
        .target = target,
        .optimize = optimize,
    });

    // inject the cimgui header search path into the sokol C library compile step
    const cimgui_root = dep_cimgui.namedWriteFiles("cimgui").getDirectory();
    dep_sokol.artifact("sokol_clib").addIncludePath(cimgui_root);

    // special case handling for native vs web build
    if (target.result.isWasm()) {
        try buildWeb(b, target, optimize, dep_sokol, dep_cimgui, dep_zigbeam, dep_zstbi);
    } else {
        try buildNative(b, target, optimize, dep_sokol, dep_cimgui, dep_zigbeam, dep_zstbi);
    }
}

// this is the regular build for all native platforms, nothing surprising here
fn buildNative(b: *Build, target: Build.ResolvedTarget, optimize: OptimizeMode, dep_sokol: *Build.Dependency, dep_cimgui: *Build.Dependency, dep_zigbeam: *Build.Dependency, dep_zstbi: *Build.Dependency) !void {
    const exe = b.addExecutable(.{
        .name = "sokol-game",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });
    addAssets(b, exe);
    exe.root_module.addImport("sokol", dep_sokol.module("sokol"));
    exe.root_module.addImport("cimgui", dep_cimgui.module("cimgui"));
    exe.root_module.addImport("zigbeam", dep_zigbeam.module("zigbeam"));
    exe.root_module.addImport("zstbi", dep_zstbi.module("root"));
    exe.linkLibrary(dep_zstbi.artifact("zstbi"));


    b.installArtifact(exe);
    const run = b.addRunArtifact(exe);
    b.step("run", "Run").dependOn(&run.step);
}

// for web builds, the Zig code needs to be built into a library and linked with the Emscripten linker
fn buildWeb(b: *Build, target: Build.ResolvedTarget, optimize: OptimizeMode, dep_sokol: *Build.Dependency, dep_cimgui: *Build.Dependency, dep_zigbeam: *Build.Dependency, dep_zstbi: *Build.Dependency) !void {
    const lib = b.addStaticLibrary(.{
        .name = "game",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });
    addAssets(b, lib);
    lib.root_module.addImport("sokol", dep_sokol.module("sokol"));
    lib.root_module.addImport("cimgui", dep_cimgui.module("cimgui"));
    lib.root_module.addImport("zigbeam", dep_zigbeam.module("zigbeam"));
    lib.root_module.addImport("zstbi", dep_zstbi.module("root"));
    lib.linkLibrary(dep_zstbi.artifact("zstbi"));

    // get the Emscripten SDK dependency from the sokol dependency
    const dep_emsdk = dep_sokol.builder.dependency("emsdk", .{});

    // need to inject the Emscripten system header include path into
    // the cimgui C library otherwise the C/C++ code won't find
    // C stdlib headers
    const emsdk_incl_path = dep_emsdk.path("upstream/emscripten/cache/sysroot/include");
    dep_cimgui.artifact("cimgui_clib").addSystemIncludePath(emsdk_incl_path);
    dep_zstbi.artifact("zstbi").addSystemIncludePath(emsdk_incl_path);

    // all C libraries need to depend on the sokol library, when building for
    // WASM this makes sure that the Emscripten SDK has been setup before
    // C compilation is attempted (since the sokol C library depends on the
    // Emscripten SDK setup step)
    dep_cimgui.artifact("cimgui_clib").step.dependOn(&dep_sokol.artifact("sokol_clib").step);
    dep_zstbi.artifact("zstbi").step.dependOn(&dep_sokol.artifact("sokol_clib").step);

    // create a build step which invokes the Emscripten linker
    const link_step = try sokol.emLinkStep(b, .{
        .lib_main = lib,
        .target = target,
        .optimize = optimize,
        .emsdk = dep_emsdk,
        .use_webgl2 = true,
        .use_emmalloc = true,
        .use_filesystem = false,
        .shell_file_path = b.path("web/shell.html"),
    });
    // ...and a special run step to start the web build output via 'emrun'
    const run = sokol.emRunStep(b, .{ .name = "game", .emsdk = dep_emsdk });
    run.step.dependOn(&link_step.step);
    b.step("run", "Run").dependOn(&run.step);
}

fn addAssets(b: *std.Build, exe: *std.Build.Step.Compile) void {
    const assets = [_]struct { []const u8, []const u8 }{
        .{ "assets/sPlayerIdle_strip4_40x40.png", "playerSprite" },
    };

    for (assets) |asset| {
        const path, const name = asset;
        exe.root_module.addAnonymousImport(name, .{ .root_source_file = b.path(path) });
    }
}

Thanks

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

No branches or pull requests

1 participant