const std = @import("std"); const Build = std.Build; const LazyPath = Build.LazyPath; pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); try buildSTBModule(b, target, optimize, .{ .name = "stb_image", .zig_file = b.path("src/stb_image.zig"), .header_name = "stb_image.h", .defines = &.{ "STBI_NO_STDIO" }, .impl_define = "STB_IMAGE_IMPLEMENTATION" }); try buildSTBModule(b, target, optimize, .{ .name = "stb_vorbis", .zig_file = b.path("src/stb_vorbis.zig"), .header_name = "stb_vorbis.c", .defines = &.{ "STB_VORBIS_NO_INTEGER_CONVERSION", "STB_VORBIS_NO_STDIO" }, .header_only_define = "STB_VORBIS_HEADER_ONLY" }); try buildSTBModule(b, target, optimize, .{ .name = "stb_rect_pack", .zig_file = b.path("src/stb_rect_pack.zig"), .header_name = "stb_rect_pack.h", .impl_define = "STB_RECT_PACK_IMPLEMENTATION" }); try buildSTBModule(b, target, optimize, .{ .name = "stb_truetype", .zig_file = b.path("src/stb_truetype.zig"), .header_name = "stb_truetype.h", // TODO: .defines = &.{ "STBTT_STATIC" }, .impl_define = "STB_TRUETYPE_IMPLEMENTATION" }); } const STBModuleOptions = struct { name: []const u8, zig_file: LazyPath, header_name: []const u8, defines: []const []const u8 = &.{}, impl_define: ?[]const u8 = null, header_only_define: ?[]const u8 = null, }; fn buildSTBModule( b: *std.Build, target: Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, opts: STBModuleOptions ) !void { const stb_dependency = b.dependency("stb", .{}); const mod = b.addModule(opts.name, .{ .target = target, .optimize = optimize, .root_source_file = opts.zig_file, .link_libc = true, }); const write_file_step = b.addWriteFiles(); { var translate_c_contents: std.ArrayList(u8) = .empty; try translate_c_contents.appendSlice(b.graph.arena, "#include \""); try translate_c_contents.appendSlice(b.graph.arena, opts.header_name); try translate_c_contents.appendSlice(b.graph.arena, "\""); const translate_c = b.addTranslateC(.{ .root_source_file = write_file_step.add("c.h", translate_c_contents.items), .target = target, .optimize = optimize, }); translate_c.addIncludePath(stb_dependency.path(".")); for (opts.defines) |define| { translate_c.defineCMacro(define, null); } if (opts.header_only_define) |header_only_define| { translate_c.defineCMacro(header_only_define, null); } mod.addImport("c", translate_c.createModule()); } { mod.addCSourceFile(.{ .file = write_file_step.add("impl.c", b.fmt("#include \"{s}\"", .{opts.header_name})), .flags = &.{} }); mod.addIncludePath(stb_dependency.path(".")); for (opts.defines) |define| { mod.addCMacro(define, ""); } if (opts.impl_define) |impl_define| { mod.addCMacro(impl_define, ""); } } }