diff --git a/build.zig b/build.zig index 84fa82d..c8345d4 100644 --- a/build.zig +++ b/build.zig @@ -15,9 +15,21 @@ pub const Backend = enum { wgpu, }; +pub const SokolBuildOpts = struct { + zig_assert_hook: bool = false, + zig_log_hook: bool = false, + backend: Backend, +}; + // build sokol into a static library -pub fn buildSokol(b: *Builder, target: CrossTarget, mode: Mode, backend: Backend, comptime prefix_path: []const u8) *LibExeObjStep { - const lib = b.addStaticLibrary("sokol", null); +pub fn buildSokol( + b: *Builder, + target: CrossTarget, + mode: Mode, + opts: SokolBuildOpts, + comptime prefix_path: []const u8, +) *LibExeObjStep { + const lib = b.addStaticLibrary("sokol", prefix_path ++ "/src/sokol_zig_hooks.zig"); lib.setBuildMode(mode); lib.setTarget(target); lib.linkLibC(); @@ -31,7 +43,7 @@ pub fn buildSokol(b: *Builder, target: CrossTarget, mode: Mode, backend: Backend "sokol_debugtext.c", "sokol_shape.c", }; - var _backend = backend; + var _backend = opts.backend; if (_backend == .auto) { if (lib.target.isDarwin()) { _backend = .metal; } else if (lib.target.isWindows()) { _backend = .d3d11; } @@ -46,10 +58,14 @@ pub fn buildSokol(b: *Builder, target: CrossTarget, mode: Mode, backend: Backend .wgpu => "-DSOKOL_WGPU", else => unreachable, }; + const log_def = if (opts.zig_log_hook) "-DSOKOL_ZIG_LOG_HOOK" else ""; + const assert_def = if (opts.zig_assert_hook) "-DSOKOL_ZIG_ASSERT_HOOK" else ""; + if (lib.target.isDarwin()) { inline for (csources) |csrc| { - lib.addCSourceFile(sokol_path ++ csrc, &[_][]const u8{"-ObjC", "-DIMPL", backend_option}); + lib.addCSourceFile(sokol_path ++ csrc, &[_][]const u8{"-ObjC", "-DIMPL", backend_option, log_def, assert_def}); } + lib.linkFramework("Cocoa"); lib.linkFramework("QuartzCore"); lib.linkFramework("AudioToolbox"); @@ -62,8 +78,9 @@ pub fn buildSokol(b: *Builder, target: CrossTarget, mode: Mode, backend: Backend } } else { inline for (csources) |csrc| { - lib.addCSourceFile(sokol_path ++ csrc, &[_][]const u8{"-DIMPL", backend_option}); + lib.addCSourceFile(sokol_path ++ csrc, &[_][]const u8{"-DIMPL", backend_option, log_def, assert_def}); } + if (lib.target.isLinux()) { lib.linkSystemLibrary("X11"); lib.linkSystemLibrary("Xi"); @@ -102,7 +119,7 @@ pub fn build(b: *Builder) void { const target = b.standardTargetOptions(.{}); const mode = b.standardReleaseOptions(); - const sokol = buildSokol(b, target, mode, backend, ""); + const sokol = buildSokol(b, target, mode, .{.backend = backend}, ""); const examples = .{ "clear", "triangle", diff --git a/src/sokol/c/sokol_defines.h b/src/sokol/c/sokol_defines.h index c89125c..122be02 100644 --- a/src/sokol/c/sokol_defines.h +++ b/src/sokol/c/sokol_defines.h @@ -1,9 +1,21 @@ #define SOKOL_ZIG_BINDINGS #define SOKOL_NO_ENTRY -#if defined(_WIN32) - #define SOKOL_WIN32_FORCE_MAIN - #define SOKOL_LOG(msg) OutputDebugStringA(msg) + +#if defined(SOKOL_ZIG_LOG_HOOK) + void sokol_zig_log(const char *s); + #define SOKOL_LOG sokol_zig_log +#else + #if defined(_WIN32) + #define SOKOL_WIN32_FORCE_MAIN + #define SOKOL_LOG(msg) OutputDebugStringA(msg) + #endif #endif + +#if defined(SOKOL_ZIG_ASSERT_HOOK) + void sokol_zig_assert(unsigned int c, const char *s); + #define SOKOL_ASSERT(c) sokol_zig_assert((unsigned int)c, #c) +#endif + // FIXME: macOS Zig HACK without this, some C stdlib headers throw errors #if defined(__APPLE__) #include diff --git a/src/sokol_zig_hooks.zig b/src/sokol_zig_hooks.zig new file mode 100644 index 0000000..96db493 --- /dev/null +++ b/src/sokol_zig_hooks.zig @@ -0,0 +1,12 @@ +const std = @import("std"); + +export fn sokol_zig_log(s: [*:0]const u8) callconv(.C) void { + std.log.info("{s}", .{s}); +} + +export fn sokol_zig_assert(c: c_uint, s: [*:0]const u8) callconv(.C) void { + if (c == 0) { + std.log.err("Assertion: {s}", .{s}); + @panic(s[0..std.mem.len(s)]); + } +}