const std = @import("std"); const base_cflags: []const []const u8 = &.{ "-Wall", "-Wextra", "-pedantic", "-Wno-switch", "-Wno-unused-function", "-Wno-implicit-fallthrough", }; const Backend = enum { default, x11, wayland, opengl, gdi, }; const ConfigError = error { PlatformNotSupported, BackendNotSupported, }; /// Returns a comma-separated list of the names of an enum's values /// in declaration order. fn enumNames(comptime E: type) []const u8 { var s: []const u8 = &[_]u8{}; for (std.enums.values(E)) |value| { if (s.len > 0) { s = s ++ ", "; } s = s ++ @tagName(value); } return s; } pub fn build(b: *std.build.Builder) !void { const mode = b.standardReleaseOptions(); const target = b.standardTargetOptions(.{}); var c_flags = try std.ArrayList([]const u8).initCapacity(b.allocator, base_cflags.len); defer c_flags.deinit(); try c_flags.appendSlice(base_cflags); var c_sources = std.ArrayList([]const u8).init(b.allocator); defer c_sources.deinit(); try c_sources.appendSlice(&.{ "src/MiniFB_common.c", "src/MiniFB_internal.c", "src/MiniFB_timer.c", }); const use_backend = b.option(Backend, "backend", "Which rendering back-end to use (" ++ enumNames(Backend) ++ ")") orelse .default; const lib = b.addStaticLibrary("minifb-zig-port", null); lib.addIncludeDir("src"); lib.addIncludeDir("include"); lib.linkLibC(); lib.setBuildMode(mode); lib.install(); switch (target.getOsTag()) { std.Target.Os.Tag.windows => { try c_sources.append("src/windows/WinMiniFB.c"); lib.linkSystemLibrary("gdi32"); try c_flags.append("-D_WIN32_WINNT=0x0601"); switch (use_backend) { .opengl, .default => { try c_flags.append("-DUSE_OPENGL_API"); try c_sources.append("src/gl/MiniFB_GL.c"); lib.linkSystemLibraryName("opengl32"); }, .gdi => {}, else => { return ConfigError.BackendNotSupported; } } }, std.Target.Os.Tag.linux => { try c_sources.append("src/MiniFB_linux.c"); lib.linkSystemLibrary("rt"); switch (use_backend) { .opengl, .default => { try c_sources.append("src/x11/X11MiniFB.c"); lib.linkSystemLibrary("X11"); try c_flags.append("-DUSE_OPENGL_API"); try c_sources.append("src/gl/MiniFB_GL.c"); lib.linkSystemLibrary("GL"); }, .x11 => { try c_sources.append("src/x11/X11MiniFB.c"); lib.linkSystemLibrary("X11"); }, .wayland => { try c_sources.append("src/wayland/WaylandMiniFB.c"); lib.linkSystemLibrary("wayland-client"); lib.linkSystemLibrary("wayland-cursor"); }, else => { return ConfigError.BackendNotSupported; } } }, else => { return ConfigError.PlatformNotSupported; }, } lib.addCSourceFiles(c_sources.items, c_flags.items); addExample(b, "noise", "tests/noise.c", lib, target, mode); addExample(b, "multiple-windows", "tests/multiple_windows.c", lib, target, mode); addExample(b, "input-events", "tests/input_events.c", lib, target, mode); addExample(b, "hidpi", "tests/hidpi.c", lib, target, mode); } fn addExample(b: *std.build.Builder, comptime name: []const u8, file: []const u8, lib: *std.build.LibExeObjStep, target: std.zig.CrossTarget, mode: std.builtin.Mode) void { const exe = b.addExecutable(name, null); exe.setBuildMode(mode); exe.setTarget(target); exe.linkLibrary(lib); exe.addIncludeDir("include"); exe.addCSourceFile(file, base_cflags); exe.install(); const step_name = "run-" ++ name; b.step("run-" ++ name, "Run " ++ name ++ " example").dependOn(&exe.run().step); }