From 7141f145509be96df2ce96c5adccafe507762e64 Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sat, 5 Aug 2023 15:58:29 +0200 Subject: [PATCH 01/20] experimental package manager support --- README.md | 8 ++- build.zig | 144 +++++++++++++++++++++++++++++++----------------------- 2 files changed, 88 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index e18518a..ab0bacd 100644 --- a/README.md +++ b/README.md @@ -73,12 +73,16 @@ const sokol = @import("lib/sokol-zig/build.zig"); // pub fn build(b: *std.build.Builder) void { // ... -const sokol_build = sokol.buildSokol(b, target, mode, .{}, "lib/sokol-zig/"); +const lib_sokol = sokol.buildLibSokol(b, "lib/sokol-zig/", .{ + .target = ..., + .optimize = ..., + ... +}); // ... // const exe = b.addExecutable("demo", "src/main.zig"); // ... exe.addPackagePath("sokol", "lib/sokol-zig/src/sokol/sokol.zig"); -exe.linkLibrary(sokol_build); +exe.linkLibrary(lib_sokol); ``` diff --git a/build.zig b/build.zig index df5bc54..97d17af 100644 --- a/build.zig +++ b/build.zig @@ -1,10 +1,63 @@ const std = @import("std"); const builtin = @import("builtin"); -const Builder = std.build.Builder; -const CompileStep = std.build.CompileStep; +const Build = std.Build; +const CompileStep = std.build.Step.Compile; +const Module = std.build.Module; const CrossTarget = std.zig.CrossTarget; const OptimizeMode = std.builtin.OptimizeMode; +pub fn build(b: *Build) void { + const force_gl = b.option(bool, "gl", "Force GL backend") orelse false; + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + // NOTE: Wayland support is *not* currently supported in the standard sokol-zig bindings, + // you need to generate your own bindings using this PR: https://github.com/floooh/sokol/pull/425 + + const lib_sokol = buildLibSokol(b, "", .{ + .target = target, + .optimize = optimize, + .backend = if (force_gl) .gl else .auto, + .enable_wayland = b.option(bool, "wayland", "Compile with wayland-support (default: false)") orelse false, + .enable_x11 = b.option(bool, "x11", "Compile with x11-support (default: true)") orelse true, + .force_egl = b.option(bool, "egl", "Use EGL instead of GLX if possible (default: false)") orelse false, + }); + + b.installArtifact(lib_sokol); + const mod_sokol = b.addModule("sokol", .{ .source_file = .{ .path = "src/sokol/sokol.zig" } }); + + const examples = .{ + "clear", + "triangle", + "quad", + "bufferoffsets", + "cube", + "noninterleaved", + "texcube", + "blend", + "offscreen", + "instancing", + "mrt", + "saudio", + "sgl", + "sgl-context", + "sgl-points", + "debugtext", + "debugtext-print", + "debugtext-userfont", + "shapes", + }; + inline for (examples) |example| { + buildExample(b, example, .{ + .target = target, + .optimize = optimize, + .lib_sokol = lib_sokol, + .mod_sokol = mod_sokol, + }); + } + buildShaders(b); +} + pub const Backend = enum { auto, // Windows: D3D11, macOS/iOS: Metal, otherwise: GL d3d11, @@ -15,19 +68,28 @@ pub const Backend = enum { wgpu, }; -pub const Config = struct { +pub const LibSokolOptions = struct { + target: CrossTarget, + optimize: OptimizeMode, backend: Backend = .auto, force_egl: bool = false, enable_x11: bool = true, enable_wayland: bool = false, }; +const ExampleOptions = struct { + target: CrossTarget, + optimize: OptimizeMode, + lib_sokol: *CompileStep, + mod_sokol: *Module, +}; + // build sokol into a static library -pub fn buildSokol(b: *Builder, target: CrossTarget, optimize: OptimizeMode, config: Config, comptime prefix_path: []const u8) *CompileStep { +pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSokolOptions) *CompileStep { const lib = b.addStaticLibrary(.{ .name = "sokol", - .target = target, - .optimize = optimize, + .target = options.target, + .optimize = options.optimize, }); lib.linkLibC(); const sokol_path = prefix_path ++ "src/sokol/c/"; @@ -41,7 +103,7 @@ pub fn buildSokol(b: *Builder, target: CrossTarget, optimize: OptimizeMode, conf "sokol_debugtext.c", "sokol_shape.c", }; - var _backend = config.backend; + var _backend = options.backend; if (_backend == .auto) { if (lib.target.isDarwin()) { _backend = .metal; @@ -78,9 +140,9 @@ pub fn buildSokol(b: *Builder, target: CrossTarget, optimize: OptimizeMode, conf lib.linkFramework("OpenGL"); } } else { - var egl_flag = if (config.force_egl) "-DSOKOL_FORCE_EGL " else ""; - var x11_flag = if (!config.enable_x11) "-DSOKOL_DISABLE_X11 " else ""; - var wayland_flag = if (!config.enable_wayland) "-DSOKOL_DISABLE_WAYLAND" else ""; + var egl_flag = if (options.force_egl) "-DSOKOL_FORCE_EGL " else ""; + var x11_flag = if (!options.enable_x11) "-DSOKOL_DISABLE_X11 " else ""; + var wayland_flag = if (!options.enable_wayland) "-DSOKOL_DISABLE_WAYLAND" else ""; inline for (csources) |csrc| { lib.addCSourceFile(.{ @@ -90,8 +152,8 @@ pub fn buildSokol(b: *Builder, target: CrossTarget, optimize: OptimizeMode, conf } if (lib.target.isLinux()) { - var link_egl = config.force_egl or config.enable_wayland; - var egl_ensured = (config.force_egl and config.enable_x11) or config.enable_wayland; + var link_egl = options.force_egl or options.enable_wayland; + var egl_ensured = (options.force_egl and options.enable_x11) or options.enable_wayland; lib.linkSystemLibrary("asound"); @@ -103,12 +165,12 @@ pub fn buildSokol(b: *Builder, target: CrossTarget, optimize: OptimizeMode, conf } else { lib.linkSystemLibrary("GL"); } - if (config.enable_x11) { + if (options.enable_x11) { lib.linkSystemLibrary("X11"); lib.linkSystemLibrary("Xi"); lib.linkSystemLibrary("Xcursor"); } - if (config.enable_wayland) { + if (options.enable_wayland) { lib.linkSystemLibrary("wayland-client"); lib.linkSystemLibrary("wayland-cursor"); lib.linkSystemLibrary("wayland-egl"); @@ -132,64 +194,22 @@ pub fn buildSokol(b: *Builder, target: CrossTarget, optimize: OptimizeMode, conf } // build one of the example exes -fn buildExample(b: *Builder, target: CrossTarget, optimize: OptimizeMode, sokol: *CompileStep, comptime name: []const u8) void { +fn buildExample(b: *Build, comptime name: []const u8, options: ExampleOptions) void { const e = b.addExecutable(.{ .name = name, .root_source_file = .{ .path = "src/examples/" ++ name ++ ".zig" }, - .target = target, - .optimize = optimize, + .target = options.target, + .optimize = options.optimize, }); - e.linkLibrary(sokol); - e.addAnonymousModule("sokol", .{ .source_file = .{ .path = "src/sokol/sokol.zig" } }); + e.linkLibrary(options.lib_sokol); + e.addModule("sokol", options.mod_sokol); b.installArtifact(e); const run = b.addRunArtifact(e); b.step("run-" ++ name, "Run " ++ name).dependOn(&run.step); } -pub fn build(b: *Builder) void { - var config: Config = .{}; - - const force_gl = b.option(bool, "gl", "Force GL backend") orelse false; - config.backend = if (force_gl) .gl else .auto; - - // NOTE: Wayland support is *not* currently supported in the standard sokol-zig bindings, - // you need to generate your own bindings using this PR: https://github.com/floooh/sokol/pull/425 - config.enable_wayland = b.option(bool, "wayland", "Compile with wayland-support (default: false)") orelse false; - config.enable_x11 = b.option(bool, "x11", "Compile with x11-support (default: true)") orelse true; - config.force_egl = b.option(bool, "egl", "Use EGL instead of GLX if possible (default: false)") orelse false; - - const target = b.standardTargetOptions(.{}); - const optimize = b.standardOptimizeOption(.{}); - const sokol = buildSokol(b, target, optimize, config, ""); - const examples = .{ - "clear", - "triangle", - "quad", - "bufferoffsets", - "cube", - "noninterleaved", - "texcube", - "blend", - "offscreen", - "instancing", - "mrt", - "saudio", - "sgl", - "sgl-context", - "sgl-points", - "debugtext", - "debugtext-print", - "debugtext-userfont", - "shapes", - }; - inline for (examples) |example| { - buildExample(b, target, optimize, sokol, example); - } - buildShaders(b); -} - // a separate step to compile shaders, expects the shader compiler in ../sokol-tools-bin/ -fn buildShaders(b: *Builder) void { +fn buildShaders(b: *Build) void { const sokol_tools_bin_dir = "../sokol-tools-bin/bin/"; const shaders_dir = "src/examples/shaders/"; const shaders = .{ From 72cc89a76825999e7a26a64db5c7c2c9dced8551 Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sat, 5 Aug 2023 16:13:48 +0200 Subject: [PATCH 02/20] add a build.zig.zon file --- build.zig.zon | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 build.zig.zon diff --git a/build.zig.zon b/build.zig.zon new file mode 100644 index 0000000..50de20d --- /dev/null +++ b/build.zig.zon @@ -0,0 +1,4 @@ +.{ + .name = "sokol", + .version = "0.1.0", +} From 97851a3f10fb7d92c79971798dcc73151f7e9986 Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sat, 5 Aug 2023 16:18:14 +0200 Subject: [PATCH 03/20] don't need the build.zig.zon file afterall --- build.zig.zon | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 build.zig.zon diff --git a/build.zig.zon b/build.zig.zon deleted file mode 100644 index 50de20d..0000000 --- a/build.zig.zon +++ /dev/null @@ -1,4 +0,0 @@ -.{ - .name = "sokol", - .version = "0.1.0", -} From c9bc7c3ea128d31ac9e251b1073e6648604024c8 Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sat, 5 Aug 2023 16:58:04 +0200 Subject: [PATCH 04/20] fix build.zig for building an Emscripten sokol-lib --- build.zig | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/build.zig b/build.zig index 97d17af..d22d5a5 100644 --- a/build.zig +++ b/build.zig @@ -21,7 +21,10 @@ pub fn build(b: *Build) void { .enable_wayland = b.option(bool, "wayland", "Compile with wayland-support (default: false)") orelse false, .enable_x11 = b.option(bool, "x11", "Compile with x11-support (default: true)") orelse true, .force_egl = b.option(bool, "egl", "Use EGL instead of GLX if possible (default: false)") orelse false, - }); + }) catch |err| { + std.log.err("buildLibSokol return with error {}", .{err}); + return; + }; b.installArtifact(lib_sokol); const mod_sokol = b.addModule("sokol", .{ .source_file = .{ .path = "src/sokol/sokol.zig" } }); @@ -63,7 +66,6 @@ pub const Backend = enum { d3d11, metal, gl, - gles2, gles3, wgpu, }; @@ -85,13 +87,32 @@ const ExampleOptions = struct { }; // build sokol into a static library -pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSokolOptions) *CompileStep { +pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSokolOptions) !*CompileStep { + var target = options.target; + const is_wasm = options.target.getCpu().arch == .wasm32; + + // special case wasm, must compile as wasm32-emscripten, not wasm32-freestanding + if (is_wasm) { + if (b.sysroot == null) { + std.log.err("Must provide Emscripten sysroot via '--sysroot [path/to/emsdk]/upstream/emscripten/cache/sysroot'", .{}); + return error.Wasm32SysRootExpected; + } + target.os_tag = .emscripten; + } + const lib = b.addStaticLibrary(.{ .name = "sokol", - .target = options.target, + .target = target, .optimize = options.optimize, }); lib.linkLibC(); + if (is_wasm) { + // need to add Emscripten include path + const include_path = try std.fs.path.join(b.allocator, &.{ b.sysroot.?, "include" }); + defer b.allocator.free(include_path); + lib.addIncludePath(.{ .path = include_path }); + lib.defineCMacro("__EMSCRIPTEN__", "1"); + } const sokol_path = prefix_path ++ "src/sokol/c/"; const csources = [_][]const u8{ "sokol_log.c", @@ -109,6 +130,8 @@ pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSo _backend = .metal; } else if (lib.target.isWindows()) { _backend = .d3d11; + } else if (lib.target.getCpu().arch == .wasm32) { + _backend = .gles3; } else { _backend = .gl; } @@ -117,7 +140,6 @@ pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSo .d3d11 => "-DSOKOL_D3D11", .metal => "-DSOKOL_METAL", .gl => "-DSOKOL_GLCORE33", - .gles2 => "-DSOKOL_GLES2", .gles3 => "-DSOKOL_GLES3", .wgpu => "-DSOKOL_WGPU", else => unreachable, @@ -154,17 +176,10 @@ pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSo if (lib.target.isLinux()) { var link_egl = options.force_egl or options.enable_wayland; var egl_ensured = (options.force_egl and options.enable_x11) or options.enable_wayland; + _ = egl_ensured; lib.linkSystemLibrary("asound"); - - if (.gles2 == _backend) { - lib.linkSystemLibrary("glesv2"); - if (!egl_ensured) { - @panic("GLES2 in Linux only available with Config.force_egl and/or Wayland"); - } - } else { - lib.linkSystemLibrary("GL"); - } + lib.linkSystemLibrary("GL"); if (options.enable_x11) { lib.linkSystemLibrary("X11"); lib.linkSystemLibrary("Xi"); From 95c141a9d02284f0d3a6ad44fa057170d88ffddc Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sat, 5 Aug 2023 17:15:27 +0200 Subject: [PATCH 05/20] build.zig fixes --- build.zig | 88 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 40 deletions(-) diff --git a/build.zig b/build.zig index d22d5a5..fe86911 100644 --- a/build.zig +++ b/build.zig @@ -88,15 +88,11 @@ const ExampleOptions = struct { // build sokol into a static library pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSokolOptions) !*CompileStep { - var target = options.target; const is_wasm = options.target.getCpu().arch == .wasm32; // special case wasm, must compile as wasm32-emscripten, not wasm32-freestanding + var target = options.target; if (is_wasm) { - if (b.sysroot == null) { - std.log.err("Must provide Emscripten sysroot via '--sysroot [path/to/emsdk]/upstream/emscripten/cache/sysroot'", .{}); - return error.Wasm32SysRootExpected; - } target.os_tag = .emscripten; } @@ -107,7 +103,11 @@ pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSo }); lib.linkLibC(); if (is_wasm) { - // need to add Emscripten include path + // need to add Emscripten SDK include path + if (b.sysroot == null) { + std.log.err("Must provide Emscripten sysroot via '--sysroot [path/to/emsdk]/upstream/emscripten/cache/sysroot'", .{}); + return error.Wasm32SysRootExpected; + } const include_path = try std.fs.path.join(b.allocator, &.{ b.sysroot.?, "include" }); defer b.allocator.free(include_path); lib.addIncludePath(.{ .path = include_path }); @@ -161,10 +161,10 @@ pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSo } else { lib.linkFramework("OpenGL"); } - } else { - var egl_flag = if (options.force_egl) "-DSOKOL_FORCE_EGL " else ""; - var x11_flag = if (!options.enable_x11) "-DSOKOL_DISABLE_X11 " else ""; - var wayland_flag = if (!options.enable_wayland) "-DSOKOL_DISABLE_WAYLAND" else ""; + } else if (lib.target.isLinux()) { + const egl_flag = if (options.force_egl) "-DSOKOL_FORCE_EGL " else ""; + const x11_flag = if (!options.enable_x11) "-DSOKOL_DISABLE_X11 " else ""; + const wayland_flag = if (!options.enable_wayland) "-DSOKOL_DISABLE_WAYLAND" else ""; inline for (csources) |csrc| { lib.addCSourceFile(.{ @@ -172,37 +172,45 @@ pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSo .flags = &[_][]const u8{ "-DIMPL", backend_option, egl_flag, x11_flag, wayland_flag }, }); } + const link_egl = options.force_egl or options.enable_wayland; - if (lib.target.isLinux()) { - var link_egl = options.force_egl or options.enable_wayland; - var egl_ensured = (options.force_egl and options.enable_x11) or options.enable_wayland; - _ = egl_ensured; - - lib.linkSystemLibrary("asound"); - lib.linkSystemLibrary("GL"); - if (options.enable_x11) { - lib.linkSystemLibrary("X11"); - lib.linkSystemLibrary("Xi"); - lib.linkSystemLibrary("Xcursor"); - } - if (options.enable_wayland) { - lib.linkSystemLibrary("wayland-client"); - lib.linkSystemLibrary("wayland-cursor"); - lib.linkSystemLibrary("wayland-egl"); - lib.linkSystemLibrary("xkbcommon"); - } - if (link_egl) { - lib.linkSystemLibrary("egl"); - } - } else if (lib.target.isWindows()) { - lib.linkSystemLibraryName("kernel32"); - lib.linkSystemLibraryName("user32"); - lib.linkSystemLibraryName("gdi32"); - lib.linkSystemLibraryName("ole32"); - if (.d3d11 == _backend) { - lib.linkSystemLibraryName("d3d11"); - lib.linkSystemLibraryName("dxgi"); - } + lib.linkSystemLibrary("asound"); + lib.linkSystemLibrary("GL"); + if (options.enable_x11) { + lib.linkSystemLibrary("X11"); + lib.linkSystemLibrary("Xi"); + lib.linkSystemLibrary("Xcursor"); + } + if (options.enable_wayland) { + lib.linkSystemLibrary("wayland-client"); + lib.linkSystemLibrary("wayland-cursor"); + lib.linkSystemLibrary("wayland-egl"); + lib.linkSystemLibrary("xkbcommon"); + } + if (link_egl) { + lib.linkSystemLibrary("egl"); + } + } else if (lib.target.isWindows()) { + inline for (csources) |csrc| { + lib.addCSourceFile(.{ + .file = .{ .path = sokol_path ++ csrc }, + .flags = &[_][]const u8{ "-DIMPL", backend_option }, + }); + } + lib.linkSystemLibraryName("kernel32"); + lib.linkSystemLibraryName("user32"); + lib.linkSystemLibraryName("gdi32"); + lib.linkSystemLibraryName("ole32"); + if (.d3d11 == _backend) { + lib.linkSystemLibraryName("d3d11"); + lib.linkSystemLibraryName("dxgi"); + } + } else { + inline for (csources) |csrc| { + lib.addCSourceFile(.{ + .file = .{ .path = sokol_path ++ csrc }, + .flags = &[_][]const u8{ "-DIMPL", backend_option }, + }); } } return lib; From 7c6204f650e1eb49058af59a9d93cfbc1c1b8c49 Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sat, 5 Aug 2023 17:18:50 +0200 Subject: [PATCH 06/20] add log output to build.zig --- build.zig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.zig b/build.zig index fe86911..8dc5884 100644 --- a/build.zig +++ b/build.zig @@ -93,7 +93,10 @@ pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSo // special case wasm, must compile as wasm32-emscripten, not wasm32-freestanding var target = options.target; if (is_wasm) { + std.log.info("Build libsokol for wasm32.", .{}); target.os_tag = .emscripten; + } else { + std.log.info("Building libsokol for native.", .{}); } const lib = b.addStaticLibrary(.{ From f83d071c9e70c59491ea90063312f1d006b5372d Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sat, 5 Aug 2023 17:30:07 +0200 Subject: [PATCH 07/20] more logging in build.zig --- build.zig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.zig b/build.zig index 8dc5884..f0d9982 100644 --- a/build.zig +++ b/build.zig @@ -10,6 +10,8 @@ pub fn build(b: *Build) void { const force_gl = b.option(bool, "gl", "Force GL backend") orelse false; const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); + std.log.info("sokol target cpu_arch: {?}", .{target.cpu_arch}); + std.log.info("sokol target os_tag: {?}", .{target.os_tag}); // NOTE: Wayland support is *not* currently supported in the standard sokol-zig bindings, // you need to generate your own bindings using this PR: https://github.com/floooh/sokol/pull/425 From 230bd0cc1d22cf47a43a0281d4d357a99a7a5440 Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sat, 5 Aug 2023 18:02:01 +0200 Subject: [PATCH 08/20] build.zig log out the sysroot --- build.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/build.zig b/build.zig index f0d9982..45b1087 100644 --- a/build.zig +++ b/build.zig @@ -12,6 +12,7 @@ pub fn build(b: *Build) void { const optimize = b.standardOptimizeOption(.{}); std.log.info("sokol target cpu_arch: {?}", .{target.cpu_arch}); std.log.info("sokol target os_tag: {?}", .{target.os_tag}); + std.log.info("sokol sysroot: {?s}", .{b.sysroot}); // NOTE: Wayland support is *not* currently supported in the standard sokol-zig bindings, // you need to generate your own bindings using this PR: https://github.com/floooh/sokol/pull/425 From 97e247d256bd5c5f3c0db8a94d84b156c5c3ac36 Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sat, 5 Aug 2023 18:33:25 +0200 Subject: [PATCH 09/20] build.zig allow runtime string for build_root (formerly path_prefix) --- build.zig | 70 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/build.zig b/build.zig index 45b1087..0eb13fe 100644 --- a/build.zig +++ b/build.zig @@ -6,6 +6,26 @@ const Module = std.build.Module; const CrossTarget = std.zig.CrossTarget; const OptimizeMode = std.builtin.OptimizeMode; +pub const Backend = enum { + auto, // Windows: D3D11, macOS/iOS: Metal, otherwise: GL + d3d11, + metal, + gl, + gles3, + wgpu, +}; + +pub const LibSokolOptions = struct { + build_root: ?[]const u8, + target: CrossTarget, + optimize: OptimizeMode, + sysroot: ?[]const u8, + backend: Backend = .auto, + force_egl: bool = false, + enable_x11: bool = true, + enable_wayland: bool = false, +}; + pub fn build(b: *Build) void { const force_gl = b.option(bool, "gl", "Force GL backend") orelse false; const target = b.standardTargetOptions(.{}); @@ -17,9 +37,11 @@ pub fn build(b: *Build) void { // NOTE: Wayland support is *not* currently supported in the standard sokol-zig bindings, // you need to generate your own bindings using this PR: https://github.com/floooh/sokol/pull/425 - const lib_sokol = buildLibSokol(b, "", .{ + const lib_sokol = buildLibSokol(b, .{ + .build_root = null, .target = target, .optimize = optimize, + .sysroot = b.sysroot, .backend = if (force_gl) .gl else .auto, .enable_wayland = b.option(bool, "wayland", "Compile with wayland-support (default: false)") orelse false, .enable_x11 = b.option(bool, "x11", "Compile with x11-support (default: true)") orelse true, @@ -29,7 +51,6 @@ pub fn build(b: *Build) void { return; }; - b.installArtifact(lib_sokol); const mod_sokol = b.addModule("sokol", .{ .source_file = .{ .path = "src/sokol/sokol.zig" } }); const examples = .{ @@ -64,24 +85,6 @@ pub fn build(b: *Build) void { buildShaders(b); } -pub const Backend = enum { - auto, // Windows: D3D11, macOS/iOS: Metal, otherwise: GL - d3d11, - metal, - gl, - gles3, - wgpu, -}; - -pub const LibSokolOptions = struct { - target: CrossTarget, - optimize: OptimizeMode, - backend: Backend = .auto, - force_egl: bool = false, - enable_x11: bool = true, - enable_wayland: bool = false, -}; - const ExampleOptions = struct { target: CrossTarget, optimize: OptimizeMode, @@ -90,7 +93,7 @@ const ExampleOptions = struct { }; // build sokol into a static library -pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSokolOptions) !*CompileStep { +pub fn buildLibSokol(b: *Build, options: LibSokolOptions) !*CompileStep { const is_wasm = options.target.getCpu().arch == .wasm32; // special case wasm, must compile as wasm32-emscripten, not wasm32-freestanding @@ -110,16 +113,19 @@ pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSo lib.linkLibC(); if (is_wasm) { // need to add Emscripten SDK include path - if (b.sysroot == null) { + if (options.sysroot == null) { std.log.err("Must provide Emscripten sysroot via '--sysroot [path/to/emsdk]/upstream/emscripten/cache/sysroot'", .{}); return error.Wasm32SysRootExpected; } - const include_path = try std.fs.path.join(b.allocator, &.{ b.sysroot.?, "include" }); + const include_path = try std.fs.path.join(b.allocator, &.{ options.sysroot.?, "include" }); defer b.allocator.free(include_path); lib.addIncludePath(.{ .path = include_path }); lib.defineCMacro("__EMSCRIPTEN__", "1"); } - const sokol_path = prefix_path ++ "src/sokol/c/"; + var sokol_path: []const u8 = "src/sokol/c"; + if (options.build_root) |build_root| { + sokol_path = try std.fmt.allocPrint(b.allocator, "{s}/src/sokol/c", .{build_root}); + } const csources = [_][]const u8{ "sokol_log.c", "sokol_app.c", @@ -152,9 +158,9 @@ pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSo }; if (lib.target.isDarwin()) { - inline for (csources) |csrc| { + for (csources) |csrc| { lib.addCSourceFile(.{ - .file = .{ .path = sokol_path ++ csrc }, + .file = .{ .path = try std.fmt.allocPrint(b.allocator, "{s}/{s}", .{ sokol_path, csrc }) }, .flags = &[_][]const u8{ "-ObjC", "-DIMPL", backend_option }, }); } @@ -172,9 +178,9 @@ pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSo const x11_flag = if (!options.enable_x11) "-DSOKOL_DISABLE_X11 " else ""; const wayland_flag = if (!options.enable_wayland) "-DSOKOL_DISABLE_WAYLAND" else ""; - inline for (csources) |csrc| { + for (csources) |csrc| { lib.addCSourceFile(.{ - .file = .{ .path = sokol_path ++ csrc }, + .file = .{ .path = try std.fmt.allocPrint(b.allocator, "{s}/{s}", .{ sokol_path, csrc }) }, .flags = &[_][]const u8{ "-DIMPL", backend_option, egl_flag, x11_flag, wayland_flag }, }); } @@ -197,9 +203,9 @@ pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSo lib.linkSystemLibrary("egl"); } } else if (lib.target.isWindows()) { - inline for (csources) |csrc| { + for (csources) |csrc| { lib.addCSourceFile(.{ - .file = .{ .path = sokol_path ++ csrc }, + .file = .{ .path = try std.fmt.allocPrint(b.allocator, "{s}/{s}", .{ sokol_path, csrc }) }, .flags = &[_][]const u8{ "-DIMPL", backend_option }, }); } @@ -212,9 +218,9 @@ pub fn buildLibSokol(b: *Build, comptime prefix_path: []const u8, options: LibSo lib.linkSystemLibraryName("dxgi"); } } else { - inline for (csources) |csrc| { + for (csources) |csrc| { lib.addCSourceFile(.{ - .file = .{ .path = sokol_path ++ csrc }, + .file = .{ .path = try std.fmt.allocPrint(b.allocator, "{s}/{s}", .{ sokol_path, csrc }) }, .flags = &[_][]const u8{ "-DIMPL", backend_option }, }); } From 37a20349dc7a5b4d30c6073bcf9430b86a9183de Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sat, 5 Aug 2023 18:35:42 +0200 Subject: [PATCH 10/20] fix build.zig --- build.zig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/build.zig b/build.zig index 0eb13fe..d291409 100644 --- a/build.zig +++ b/build.zig @@ -16,10 +16,10 @@ pub const Backend = enum { }; pub const LibSokolOptions = struct { - build_root: ?[]const u8, target: CrossTarget, optimize: OptimizeMode, - sysroot: ?[]const u8, + build_root: ?[]const u8 = null, + sysroot: ?[]const u8 = null, backend: Backend = .auto, force_egl: bool = false, enable_x11: bool = true, @@ -38,7 +38,6 @@ pub fn build(b: *Build) void { // you need to generate your own bindings using this PR: https://github.com/floooh/sokol/pull/425 const lib_sokol = buildLibSokol(b, .{ - .build_root = null, .target = target, .optimize = optimize, .sysroot = b.sysroot, From 561fe5e2a9a99055a0a56e2f68e4da20332e60b3 Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sat, 5 Aug 2023 18:46:29 +0200 Subject: [PATCH 11/20] build.zig: remove info logs --- build.zig | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/build.zig b/build.zig index d291409..3a1cc99 100644 --- a/build.zig +++ b/build.zig @@ -30,9 +30,8 @@ pub fn build(b: *Build) void { const force_gl = b.option(bool, "gl", "Force GL backend") orelse false; const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - std.log.info("sokol target cpu_arch: {?}", .{target.cpu_arch}); - std.log.info("sokol target os_tag: {?}", .{target.os_tag}); - std.log.info("sokol sysroot: {?s}", .{b.sysroot}); + + const mod_sokol = b.addModule("sokol", .{ .source_file = .{ .path = "src/sokol/sokol.zig" } }); // NOTE: Wayland support is *not* currently supported in the standard sokol-zig bindings, // you need to generate your own bindings using this PR: https://github.com/floooh/sokol/pull/425 @@ -50,8 +49,6 @@ pub fn build(b: *Build) void { return; }; - const mod_sokol = b.addModule("sokol", .{ .source_file = .{ .path = "src/sokol/sokol.zig" } }); - const examples = .{ "clear", "triangle", @@ -98,10 +95,7 @@ pub fn buildLibSokol(b: *Build, options: LibSokolOptions) !*CompileStep { // special case wasm, must compile as wasm32-emscripten, not wasm32-freestanding var target = options.target; if (is_wasm) { - std.log.info("Build libsokol for wasm32.", .{}); target.os_tag = .emscripten; - } else { - std.log.info("Building libsokol for native.", .{}); } const lib = b.addStaticLibrary(.{ From e30da6b87f81cce4640a79121bfd5776e11d4370 Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sun, 6 Aug 2023 15:12:06 +0200 Subject: [PATCH 12/20] move lib.linkLibC => addStaticLibrary option --- build.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.zig b/build.zig index 3a1cc99..470242d 100644 --- a/build.zig +++ b/build.zig @@ -102,8 +102,8 @@ pub fn buildLibSokol(b: *Build, options: LibSokolOptions) !*CompileStep { .name = "sokol", .target = target, .optimize = options.optimize, + .link_libc = true, }); - lib.linkLibC(); if (is_wasm) { // need to add Emscripten SDK include path if (options.sysroot == null) { From 664a13a5cf6d0439bd2c4d5d0cd92c3ecf8f4e15 Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sun, 6 Aug 2023 15:17:58 +0200 Subject: [PATCH 13/20] log out the build root --- build.zig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.zig b/build.zig index 470242d..5d0bbcd 100644 --- a/build.zig +++ b/build.zig @@ -92,6 +92,8 @@ const ExampleOptions = struct { pub fn buildLibSokol(b: *Build, options: LibSokolOptions) !*CompileStep { const is_wasm = options.target.getCpu().arch == .wasm32; + std.log.info("sokol build root: {?s}", .{b.build_root.path}); + // special case wasm, must compile as wasm32-emscripten, not wasm32-freestanding var target = options.target; if (is_wasm) { From 16e78f8aafff61eab7c36da795d258bb466b5d20 Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sun, 6 Aug 2023 15:23:30 +0200 Subject: [PATCH 14/20] remove the build root logging again --- build.zig | 2 -- 1 file changed, 2 deletions(-) diff --git a/build.zig b/build.zig index 5d0bbcd..470242d 100644 --- a/build.zig +++ b/build.zig @@ -92,8 +92,6 @@ const ExampleOptions = struct { pub fn buildLibSokol(b: *Build, options: LibSokolOptions) !*CompileStep { const is_wasm = options.target.getCpu().arch == .wasm32; - std.log.info("sokol build root: {?s}", .{b.build_root.path}); - // special case wasm, must compile as wasm32-emscripten, not wasm32-freestanding var target = options.target; if (is_wasm) { From 78b2720d5952749c9a615faf69f6e511133a087e Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sun, 6 Aug 2023 16:19:05 +0200 Subject: [PATCH 15/20] remove sysroot from LibSokolOptions --- build.zig | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/build.zig b/build.zig index 470242d..5638ad2 100644 --- a/build.zig +++ b/build.zig @@ -19,7 +19,6 @@ pub const LibSokolOptions = struct { target: CrossTarget, optimize: OptimizeMode, build_root: ?[]const u8 = null, - sysroot: ?[]const u8 = null, backend: Backend = .auto, force_egl: bool = false, enable_x11: bool = true, @@ -39,7 +38,6 @@ pub fn build(b: *Build) void { const lib_sokol = buildLibSokol(b, .{ .target = target, .optimize = optimize, - .sysroot = b.sysroot, .backend = if (force_gl) .gl else .auto, .enable_wayland = b.option(bool, "wayland", "Compile with wayland-support (default: false)") orelse false, .enable_x11 = b.option(bool, "x11", "Compile with x11-support (default: true)") orelse true, @@ -106,11 +104,11 @@ pub fn buildLibSokol(b: *Build, options: LibSokolOptions) !*CompileStep { }); if (is_wasm) { // need to add Emscripten SDK include path - if (options.sysroot == null) { + if (b.sysroot == null) { std.log.err("Must provide Emscripten sysroot via '--sysroot [path/to/emsdk]/upstream/emscripten/cache/sysroot'", .{}); return error.Wasm32SysRootExpected; } - const include_path = try std.fs.path.join(b.allocator, &.{ options.sysroot.?, "include" }); + const include_path = try std.fs.path.join(b.allocator, &.{ b.sysroot.?, "include" }); defer b.allocator.free(include_path); lib.addIncludePath(.{ .path = include_path }); lib.defineCMacro("__EMSCRIPTEN__", "1"); From 2941d891a9347b2354e0064e2e5f2b0a8b7ea8e9 Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sun, 6 Aug 2023 16:30:00 +0200 Subject: [PATCH 16/20] log out provided builder target and sysroot --- build.zig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.zig b/build.zig index 5638ad2..f4a36f6 100644 --- a/build.zig +++ b/build.zig @@ -30,6 +30,10 @@ pub fn build(b: *Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); + std.log.info("sokol target cpu: {?}", .{target.getCpu().arch}); + std.log.info("sokol target os_tag: {?}", .{target.os_tag}); + std.log.info("sokol sysroot: {?s}", .{b.sysroot}); + const mod_sokol = b.addModule("sokol", .{ .source_file = .{ .path = "src/sokol/sokol.zig" } }); // NOTE: Wayland support is *not* currently supported in the standard sokol-zig bindings, From da12f8b5559d4b8211e85129c48be60c08b9e465 Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sun, 6 Aug 2023 16:53:48 +0200 Subject: [PATCH 17/20] build.zig make sokol c library available as artifact --- build.zig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/build.zig b/build.zig index f4a36f6..2c0d1b4 100644 --- a/build.zig +++ b/build.zig @@ -36,9 +36,6 @@ pub fn build(b: *Build) void { const mod_sokol = b.addModule("sokol", .{ .source_file = .{ .path = "src/sokol/sokol.zig" } }); - // NOTE: Wayland support is *not* currently supported in the standard sokol-zig bindings, - // you need to generate your own bindings using this PR: https://github.com/floooh/sokol/pull/425 - const lib_sokol = buildLibSokol(b, .{ .target = target, .optimize = optimize, @@ -50,6 +47,8 @@ pub fn build(b: *Build) void { std.log.err("buildLibSokol return with error {}", .{err}); return; }; + // make the sokol library available to the package manager as artifact + b.installArtifact(lib_sokol); const examples = .{ "clear", From 38844abd7f26d486d95ec3b19a4bfbb63a48959a Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sun, 6 Aug 2023 17:11:04 +0200 Subject: [PATCH 18/20] log info => warn --- build.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.zig b/build.zig index 2c0d1b4..53e26de 100644 --- a/build.zig +++ b/build.zig @@ -30,9 +30,9 @@ pub fn build(b: *Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - std.log.info("sokol target cpu: {?}", .{target.getCpu().arch}); - std.log.info("sokol target os_tag: {?}", .{target.os_tag}); - std.log.info("sokol sysroot: {?s}", .{b.sysroot}); + std.log.warn("sokol target cpu: {?}", .{target.getCpu().arch}); + std.log.warn("sokol target os_tag: {?}", .{target.os_tag}); + std.log.warn("sokol sysroot: {?s}", .{b.sysroot}); const mod_sokol = b.addModule("sokol", .{ .source_file = .{ .path = "src/sokol/sokol.zig" } }); From 24a47f10231e45875452a110aacb78aa1a8e9648 Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sun, 6 Aug 2023 17:14:37 +0200 Subject: [PATCH 19/20] build.zig: remove log messages --- build.zig | 4 ---- 1 file changed, 4 deletions(-) diff --git a/build.zig b/build.zig index 53e26de..d69b006 100644 --- a/build.zig +++ b/build.zig @@ -30,10 +30,6 @@ pub fn build(b: *Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - std.log.warn("sokol target cpu: {?}", .{target.getCpu().arch}); - std.log.warn("sokol target os_tag: {?}", .{target.os_tag}); - std.log.warn("sokol sysroot: {?s}", .{b.sysroot}); - const mod_sokol = b.addModule("sokol", .{ .source_file = .{ .path = "src/sokol/sokol.zig" } }); const lib_sokol = buildLibSokol(b, .{ From ae51b3ba16b85d48834652c6ff9da06e5d407cef Mon Sep 17 00:00:00 2001 From: Andre Weissflog Date: Sun, 6 Aug 2023 18:13:06 +0200 Subject: [PATCH 20/20] add instructions to readme how to use as a package --- README.md | 55 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index ab0bacd..797a591 100644 --- a/README.md +++ b/README.md @@ -61,28 +61,49 @@ sokol-zig ➤ zig build -Dgl=true run-clear Backend: .sokol.gfx.Backend.GLCORE33 ``` -## Use as Library +## Use with the Zig package manager -Clone this repo into your project via ``git submodule add https://github.com/floooh/sokol-zig.git`` (for this example into a folder called ``lib`` within your project). +Add a build.zig.zon file to your project: -Add to your ``build.zig``: ```zig -const sokol = @import("lib/sokol-zig/build.zig"); +.{ + .name = "xxx", + .version = "0.1.0", + .dependencies = .{ + .sokol = .{ + .url = "https://github.com/floooh/sokol-zig/archive/[commit-sha].tar.gz", + .hash = "[content-hash]", + }, + }, +} +``` + +For the `[commit-sha]` just pick the latest from here: https://github.com/floooh/sokol-zig/commits/master + +To find out the `[content-hash]`, just omit the `.hash` line, and run `zig build`, this will then output +the expected hash on the terminal. Copy-paste this into the build.zig.zon file. -// ... -// pub fn build(b: *std.build.Builder) void { -// ... +Next in your build.zig file, get a Dependency object like this: -const lib_sokol = sokol.buildLibSokol(b, "lib/sokol-zig/", .{ - .target = ..., - .optimize = ..., - ... -}); +```zig + const dep_sokol = b.dependency("sokol", .{ + .target = target, + .optimize = optimize, + // optionally more options like `.gl: true` + }); +``` -// ... -// const exe = b.addExecutable("demo", "src/main.zig"); -// ... +This dependency contains one module and one static-library artifact which can be added +to your executable CompileStep like this: -exe.addPackagePath("sokol", "lib/sokol-zig/src/sokol/sokol.zig"); -exe.linkLibrary(lib_sokol); +```zig + const exe = b.addExecutable(.{ + .name = "pacman", + .target = target, + .optimize = optimize, + .root_source_file = .{ .path = "src/pacman.zig" }, + }); + exe.addModule("sokol", dep_sokol.module("sokol")); + exe.linkLibrary(dep_sokol.artifact("sokol")); + b.installArtifact(exe); ```