From c26d9a40d1616871e0c513b30c1c03ec61f12d9c Mon Sep 17 00:00:00 2001 From: Stephen Gutekanst Date: Sat, 20 Apr 2024 09:06:36 -0700 Subject: [PATCH] build: use lazy dependencies Signed-off-by: Stephen Gutekanst --- build.zig | 414 ++++++++++++++++++++------------------------------ build.zig.zon | 27 ++++ 2 files changed, 191 insertions(+), 250 deletions(-) diff --git a/build.zig b/build.zig index c8d57cc2..2f89593b 100644 --- a/build.zig +++ b/build.zig @@ -44,16 +44,24 @@ pub const SysgpuBackend = enum { pub fn build(b: *std.Build) !void { const optimize = b.standardOptimizeOption(.{}); const target = b.standardTargetOptions(.{}); - const core_deps = b.option(bool, "core", "build core specifically"); - const sysaudio_deps = b.option(bool, "sysaudio", "build sysaudio specifically"); - const sysgpu_deps = b.option(bool, "sysgpu", "build sysgpu specifically"); + const sysgpu_backend = b.option(SysgpuBackend, "sysgpu_backend", "sysgpu API backend") orelse .default; const core_platform = b.option(CoreApp.Platform, "core_platform", "mach core platform to use") orelse CoreApp.Platform.fromTarget(target.result); - const want_mach = core_deps == null and sysaudio_deps == null and sysgpu_deps == null; - const want_core = want_mach or (core_deps orelse false); - const want_sysaudio = want_mach or (sysaudio_deps orelse false); - const want_sysgpu = want_mach or want_core or (sysgpu_deps orelse false); + const build_examples = b.option(bool, "examples", "build/install examples specifically"); + const build_libs = b.option(bool, "libs", "build/install libraries specifically"); + const build_mach = b.option(bool, "mach", "build mach specifically"); + const build_core = b.option(bool, "core", "build core specifically"); + const build_sysaudio = b.option(bool, "sysaudio", "build sysaudio specifically"); + const build_sysgpu = b.option(bool, "sysgpu", "build sysgpu specifically"); + const build_all = build_examples == null and build_libs == null and build_mach == null and build_core == null and build_sysaudio == null and build_sysgpu == null; + + const want_examples = build_all or (build_examples orelse false); + const want_libs = build_all or (build_libs orelse false); + const want_mach = build_all or (build_mach orelse false); + const want_core = build_all or (build_core orelse false); + const want_sysaudio = build_all or (build_sysaudio orelse false); + const want_sysgpu = build_all or want_core or (build_sysgpu orelse false); const build_options = b.addOptions(); build_options.addOption(bool, "want_mach", want_mach); @@ -92,7 +100,7 @@ pub fn build(b: *std.Build) !void { } if (b.lazyDependency("font_assets", .{})) |dep| module.addImport("font-assets", dep.module("font-assets")); - try buildExamples(b, optimize, target, module); + if (want_examples) try buildExamples(b, optimize, target, module); } if (want_core) { if (target.result.cpu.arch != .wasm32) { @@ -134,34 +142,36 @@ pub fn build(b: *std.Build) !void { lib.linkLibrary(dep.artifact("wayland-headers")); } } - try buildCoreExamples(b, optimize, target, module, core_platform); + if (want_examples) try buildCoreExamples(b, optimize, target, module, core_platform); } if (want_sysaudio) { // Can build sysaudio examples if desired, then. if (target.result.cpu.arch != .wasm32) { - inline for ([_][]const u8{ - "sine", - "record", - }) |example| { - const example_exe = b.addExecutable(.{ - .name = "sysaudio-" ++ example, - .root_source_file = .{ .path = "src/sysaudio/examples/" ++ example ++ ".zig" }, - .target = target, - .optimize = optimize, - }); - example_exe.root_module.addImport("mach", module); - addPaths(&example_exe.root_module); - b.installArtifact(example_exe); + if (want_examples) { + inline for ([_][]const u8{ + "sine", + "record", + }) |example| { + const example_exe = b.addExecutable(.{ + .name = "sysaudio-" ++ example, + .root_source_file = .{ .path = "src/sysaudio/examples/" ++ example ++ ".zig" }, + .target = target, + .optimize = optimize, + }); + example_exe.root_module.addImport("mach", module); + addPaths(&example_exe.root_module); + // b.installArtifact(example_exe); - const example_compile_step = b.step("sysaudio-" ++ example, "Compile 'sysaudio-" ++ example ++ "' example"); - example_compile_step.dependOn(b.getInstallStep()); + const example_compile_step = b.step("sysaudio-" ++ example, "Compile 'sysaudio-" ++ example ++ "' example"); + example_compile_step.dependOn(b.getInstallStep()); - const example_run_cmd = b.addRunArtifact(example_exe); - example_run_cmd.step.dependOn(b.getInstallStep()); - if (b.args) |args| example_run_cmd.addArgs(args); + const example_run_cmd = b.addRunArtifact(example_exe); + example_run_cmd.step.dependOn(b.getInstallStep()); + if (b.args) |args| example_run_cmd.addArgs(args); - const example_run_step = b.step("run-sysaudio-" ++ example, "Run '" ++ example ++ "' example"); - example_run_step.dependOn(&example_run_cmd.step); + const example_run_step = b.step("run-sysaudio-" ++ example, "Run '" ++ example ++ "' example"); + example_run_step.dependOn(&example_run_cmd.step); + } } if (b.lazyDependency("mach_objc", .{ .target = target, @@ -224,49 +234,59 @@ pub fn build(b: *std.Build) !void { })) |dep| module.addImport("objc", dep.module("mach-objc")); linkSysgpu(b, module); - const lib = b.addStaticLibrary(.{ - .name = "mach-sysgpu", - .root_source_file = b.addWriteFiles().add("empty.c", ""), - .target = target, - .optimize = optimize, - }); - var iter = module.import_table.iterator(); - while (iter.next()) |e| { - lib.root_module.addImport(e.key_ptr.*, e.value_ptr.*); + if (want_libs) { + const lib = b.addStaticLibrary(.{ + .name = "mach-sysgpu", + .root_source_file = b.addWriteFiles().add("empty.c", ""), + .target = target, + .optimize = optimize, + }); + var iter = module.import_table.iterator(); + while (iter.next()) |e| { + lib.root_module.addImport(e.key_ptr.*, e.value_ptr.*); + } + linkSysgpu(b, &lib.root_module); + addPaths(&lib.root_module); + b.installArtifact(lib); } - linkSysgpu(b, &lib.root_module); - addPaths(&lib.root_module); - b.installArtifact(lib); } if (true) { // want_gpu - const gpu_dawn = @import("mach_gpu_dawn"); - gpu_dawn.addPathsToModule(b, module, .{}); - module.addIncludePath(.{ .path = sdkPath("/src/gpu") }); - - const example_exe = b.addExecutable(.{ - .name = "dawn-gpu-hello-triangle", - .root_source_file = .{ .path = "src/gpu/example/main.zig" }, + if (b.lazyDependency("mach_gpu_dawn", .{ .target = target, .optimize = optimize, - }); - example_exe.root_module.addImport("mach", module); - link(b, example_exe, &example_exe.root_module); + })) |dep| { + _ = dep; + const gpu_dawn = @import("mach_gpu_dawn"); + gpu_dawn.addPathsToModule(b, module, .{}); + module.addIncludePath(.{ .path = sdkPath("/src/gpu") }); + } - if (b.lazyDependency("mach_glfw", .{ - .target = target, - .optimize = optimize, - })) |dep| example_exe.root_module.addImport("mach-glfw", dep.module("mach-glfw")); + if (want_examples) { + const example_exe = b.addExecutable(.{ + .name = "dawn-gpu-hello-triangle", + .root_source_file = .{ .path = "src/gpu/example/main.zig" }, + .target = target, + .optimize = optimize, + }); + example_exe.root_module.addImport("mach", module); + link(b, example_exe, &example_exe.root_module); - const example_compile_step = b.step("dawn-gpu-hello-triangle", "Install 'dawn-gpu-hello-triangle'"); - example_compile_step.dependOn(b.getInstallStep()); + if (b.lazyDependency("mach_glfw", .{ + .target = target, + .optimize = optimize, + })) |dep| example_exe.root_module.addImport("mach-glfw", dep.module("mach-glfw")); - const example_run_cmd = b.addRunArtifact(example_exe); - example_run_cmd.step.dependOn(b.getInstallStep()); - if (b.args) |args| example_run_cmd.addArgs(args); + const example_compile_step = b.step("dawn-gpu-hello-triangle", "Install 'dawn-gpu-hello-triangle'"); + example_compile_step.dependOn(b.getInstallStep()); - const example_run_step = b.step("run-dawn-gpu-hello-triangle", "Run 'dawn-gpu-hello-triangle' example"); - example_run_step.dependOn(&example_run_cmd.step); + const example_run_cmd = b.addRunArtifact(example_exe); + example_run_cmd.step.dependOn(b.getInstallStep()); + if (b.args) |args| example_run_cmd.addArgs(args); + + const example_run_step = b.step("run-dawn-gpu-hello-triangle", "Run 'dawn-gpu-hello-triangle' example"); + example_run_step.dependOn(&example_run_cmd.step); + } } if (target.result.cpu.arch != .wasm32) { @@ -441,23 +461,26 @@ pub const CoreApp = struct { pub fn link(mach_builder: *std.Build, step: *std.Build.Step.Compile, mod: *std.Build.Module) void { const target = mod.resolved_target.?.result; if (target.cpu.arch != .wasm32) { - const gpu_dawn = @import("mach_gpu_dawn"); - const Options = struct { - gpu_dawn_options: gpu_dawn.Options = .{}, - }; - const options: Options = .{}; + if (mach_builder.lazyDependency("mach_gpu_dawn", .{ + .target = step.root_module.resolved_target.?, + .optimize = step.root_module.optimize.?, + })) |dep| { + _ = dep; + const gpu_dawn = @import("mach_gpu_dawn"); + const Options = struct { + gpu_dawn_options: gpu_dawn.Options = .{}, + }; + const options: Options = .{}; - gpu_dawn.link( - mach_builder.dependency("mach_gpu_dawn", .{ - .target = step.root_module.resolved_target.?, - .optimize = step.root_module.optimize.?, - }).builder, - step, - mod, - options.gpu_dawn_options, - ); - step.addCSourceFile(.{ .file = .{ .path = sdkPath("/src/gpu/mach_dawn.cpp") }, .flags = &.{"-std=c++17"} }); - step.addIncludePath(.{ .path = sdkPath("/src/gpu") }); + gpu_dawn.link( + mach_builder, + step, + mod, + options.gpu_dawn_options, + ); + step.addCSourceFile(.{ .file = .{ .path = sdkPath("/src/gpu/mach_dawn.cpp") }, .flags = &.{"-std=c++17"} }); + step.addIncludePath(.{ .path = sdkPath("/src/gpu") }); + } } } @@ -527,49 +550,11 @@ fn buildExamples( target: std.Build.ResolvedTarget, mach_mod: *std.Build.Module, ) !void { - try ensureDependencies(b.allocator); - const Dependency = enum { assets, model3d, freetype, zigimg, - - pub fn dependency( - dep: @This(), - b2: *std.Build, - target2: std.Build.ResolvedTarget, - optimize2: std.builtin.OptimizeMode, - ) std.Build.Module.Import { - const path = switch (dep) { - .zigimg => "src/core/examples/libs/zigimg/zigimg.zig", - .assets => return std.Build.Module.Import{ - .name = "assets", - .module = b2.dependency("mach_example_assets", .{ - .target = target2, - .optimize = optimize2, - }).module("mach-example-assets"), - }, - .model3d => return std.Build.Module.Import{ - .name = "model3d", - .module = b2.dependency("mach_model3d", .{ - .target = target2, - .optimize = optimize2, - }).module("mach-model3d"), - }, - .freetype => return std.Build.Module.Import{ - .name = "freetype", - .module = b2.dependency("mach_freetype", .{ - .target = target2, - .optimize = optimize2, - }).module("mach-freetype"), - }, - }; - return std.Build.Module.Import{ - .name = @tagName(dep), - .module = b2.createModule(.{ .root_source_file = .{ .path = path } }), - }; - } }; for ([_]struct { @@ -607,8 +592,32 @@ fn buildExamples( b.installArtifact(exe); for (example.deps) |d| { - const dep = d.dependency(b, target, optimize); - exe.root_module.addImport(dep.name, dep.module); + switch (d) { + .assets => { + if (b.lazyDependency("mach_example_assets", .{ + .target = target, + .optimize = optimize, + })) |dep| exe.root_module.addImport("assets", dep.module("mach-example-assets")); + }, + .model3d => { + if (b.lazyDependency("mach_model3d", .{ + .target = target, + .optimize = optimize, + })) |dep| exe.root_module.addImport("model3d", dep.module("mach-model3d")); + }, + .freetype => { + if (b.lazyDependency("mach_freetype", .{ + .target = target, + .optimize = optimize, + })) |dep| exe.root_module.addImport("freetype", dep.module("mach-freetype")); + }, + .zigimg => { + if (b.lazyDependency("zigimg", .{ + .target = target, + .optimize = optimize, + })) |dep| exe.root_module.addImport("zigimg", dep.module("zigimg")); + }, + } } const compile_step = b.step(example.name, b.fmt("Compile {s}", .{example.name})); @@ -630,41 +639,11 @@ fn buildCoreExamples( mach_mod: *std.Build.Module, platform: CoreApp.Platform, ) !void { - try ensureDependencies(b.allocator); - const Dependency = enum { zigimg, model3d, assets, - - pub fn dependency( - dep: @This(), - b2: *std.Build, - target2: std.Build.ResolvedTarget, - optimize2: std.builtin.OptimizeMode, - ) std.Build.Module.Import { - const path = switch (dep) { - .zigimg => "src/core/examples/libs/zigimg/zigimg.zig", - .assets => return std.Build.Module.Import{ - .name = "assets", - .module = b2.dependency("mach_example_assets", .{ - .target = target2, - .optimize = optimize2, - }).module("mach-example-assets"), - }, - .model3d => return std.Build.Module.Import{ - .name = "model3d", - .module = b2.dependency("mach_model3d", .{ - .target = target2, - .optimize = optimize2, - }).module("mach-model3d"), - }, - }; - return std.Build.Module.Import{ - .name = @tagName(dep), - .module = b2.createModule(.{ .root_source_file = .{ .path = path } }), - }; - } + zmath, }; inline for ([_]struct { @@ -737,14 +716,6 @@ fn buildCoreExamples( if (target.result.cpu.arch == .wasm32) break; - var deps = std.ArrayList(std.Build.Module.Import).init(b.allocator); - try deps.append(std.Build.Module.Import{ - .name = "zmath", - .module = b.createModule(.{ - .root_source_file = .{ .path = "src/core/examples/zmath.zig" }, - }), - }); - for (example.deps) |d| try deps.append(d.dependency(b, target, optimize)); const cmd_name = if (example.sysgpu) "sysgpu-" ++ example.name else example.name; const app = try CoreApp.init( b, @@ -757,7 +728,6 @@ fn buildCoreExamples( "src/core/examples/" ++ example.name ++ "/main.zig", .target = target, .optimize = optimize, - .deps = deps.items, .watch_paths = if (example.sysgpu) &.{"src/core/examples/sysgpu/" ++ example.name} else @@ -767,13 +737,42 @@ fn buildCoreExamples( }, ); - for (example.deps) |dep| switch (dep) { - .model3d => if (b.lazyDependency("mach_model3d", .{ - .target = target, - .optimize = optimize, - })) |d| app.compile.linkLibrary(d.artifact("mach-model3d")), - else => {}, - }; + // for (example.deps) |dep| switch (dep) { + // .model3d => if (b.lazyDependency("mach_model3d", .{ + // .target = target, + // .optimize = optimize, + // })) |d| app.compile.linkLibrary(d.artifact("mach-model3d")), + // else => {}, + // }; + + for (example.deps) |d| { + switch (d) { + .zigimg => { + if (b.lazyDependency("zigimg", .{ + .target = target, + .optimize = optimize, + })) |dep| app.compile.root_module.addImport("zigimg", dep.module("zigimg")); + }, + .model3d => { + if (b.lazyDependency("mach_model3d", .{ + .target = target, + .optimize = optimize, + })) |dep| app.compile.root_module.addImport("model3d", dep.module("mach-model3d")); + }, + .assets => { + if (b.lazyDependency("mach_example_assets", .{ + .target = target, + .optimize = optimize, + })) |dep| app.compile.root_module.addImport("assets", dep.module("mach-example-assets")); + }, + .zmath => { + const zmath = b.createModule(.{ + .root_source_file = .{ .path = "src/core/examples/zmath.zig" }, + }); + app.compile.root_module.addImport("zmath", zmath); + }, + } + } const install_step = b.step("core-" ++ cmd_name, "Install core-" ++ cmd_name); install_step.dependOn(&app.install.step); @@ -783,88 +782,3 @@ fn buildCoreExamples( run_step.dependOn(&app.run.step); } } - -// TODO(Zig 2024.03): use b.lazyDependency -fn ensureDependencies(allocator: std.mem.Allocator) !void { - try optional_dependency.ensureGitRepoCloned( - allocator, - "https://github.com/slimsag/zigimg", - "19a49a7e44fb4b1c22341dfbd6566019de742055", - sdkPath("/src/core/examples/libs/zigimg"), - ); -} - -// TODO(Zig 2024.03): use b.lazyDependency -const optional_dependency = struct { - fn ensureGitRepoCloned(allocator: std.mem.Allocator, clone_url: []const u8, revision: []const u8, dir: []const u8) !void { - if (xIsEnvVarTruthy(allocator, "NO_ENSURE_SUBMODULES") or xIsEnvVarTruthy(allocator, "NO_ENSURE_GIT")) { - return; - } - - xEnsureGit(allocator); - - if (std.fs.openDirAbsolute(dir, .{})) |_| { - const current_revision = try xGetCurrentGitRevision(allocator, dir); - if (!std.mem.eql(u8, current_revision, revision)) { - // Reset to the desired revision - xExec(allocator, &[_][]const u8{ "git", "fetch" }, dir) catch |err| std.debug.print("warning: failed to 'git fetch' in {s}: {s}\n", .{ dir, @errorName(err) }); - try xExec(allocator, &[_][]const u8{ "git", "checkout", "--quiet", "--force", revision }, dir); - try xExec(allocator, &[_][]const u8{ "git", "submodule", "update", "--init", "--recursive" }, dir); - } - return; - } else |err| return switch (err) { - error.FileNotFound => { - std.log.info("cloning required dependency..\ngit clone {s} {s}..\n", .{ clone_url, dir }); - - try xExec(allocator, &[_][]const u8{ "git", "clone", "-c", "core.longpaths=true", clone_url, dir }, "."); - try xExec(allocator, &[_][]const u8{ "git", "checkout", "--quiet", "--force", revision }, dir); - try xExec(allocator, &[_][]const u8{ "git", "submodule", "update", "--init", "--recursive" }, dir); - return; - }, - else => err, - }; - } - - fn xExec(allocator: std.mem.Allocator, argv: []const []const u8, cwd: []const u8) !void { - var child = std.ChildProcess.init(argv, allocator); - child.cwd = cwd; - _ = try child.spawnAndWait(); - } - - fn xGetCurrentGitRevision(allocator: std.mem.Allocator, cwd: []const u8) ![]const u8 { - const result = try std.ChildProcess.run(.{ .allocator = allocator, .argv = &.{ "git", "rev-parse", "HEAD" }, .cwd = cwd }); - allocator.free(result.stderr); - if (result.stdout.len > 0) return result.stdout[0 .. result.stdout.len - 1]; // trim newline - return result.stdout; - } - - fn xEnsureGit(allocator: std.mem.Allocator) void { - const argv = &[_][]const u8{ "git", "--version" }; - const result = std.ChildProcess.run(.{ - .allocator = allocator, - .argv = argv, - .cwd = ".", - }) catch { // e.g. FileNotFound - std.log.err("mach: error: 'git --version' failed. Is git not installed?", .{}); - std.process.exit(1); - }; - defer { - allocator.free(result.stderr); - allocator.free(result.stdout); - } - if (result.term.Exited != 0) { - std.log.err("mach: error: 'git --version' failed. Is git not installed?", .{}); - std.process.exit(1); - } - } - - fn xIsEnvVarTruthy(allocator: std.mem.Allocator, name: []const u8) bool { - if (std.process.getEnvVarOwned(allocator, name)) |truthy| { - defer allocator.free(truthy); - if (std.mem.eql(u8, truthy, "true")) return true; - return false; - } else |_| { - return false; - } - } -}; diff --git a/build.zig.zon b/build.zig.zon index d1318e54..9bf4c9f1 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -14,70 +14,97 @@ .mach_freetype = .{ .url = "https://pkg.machengine.org/mach-freetype/100c7f65f654dbdcab7adc290d28ff6aab7b8d0c.tar.gz", .hash = "12201c1eb9856e133f66ae904ced3a965a53a2098104036cac91b90686cdd9ccb859", + .lazy = true, }, .font_assets = .{ .url = "https://github.com/hexops/font-assets/archive/7977df057e855140a207de49039114f1ab8e6c2d.tar.gz", .hash = "12208106eef051bc730bac17c2d10f7e42ea63b579b919480fec86b7c75a620c75d4", + // TODO(build): be able to mark this dependency as lazy + // .lazy = true, }, .mach_sysjs = .{ .url = "https://pkg.machengine.org/mach-sysjs/eeef024f79beae189b7a4ed85e64ed076e76d538.tar.gz", .hash = "1220db6845ce34743ae2a1ab0222efc942496adde2736c20e3443d4fde4ef64b11b9", + // TODO(build): be able to mark this dependency as lazy + // .lazy = true, }, .mach_gpu_dawn = .{ .url = "https://pkg.machengine.org/mach-gpu-dawn/cce4d19945ca6102162b0cbbc546648edb38dc41.tar.gz", .hash = "1220a6e3f4772fed665bb5b1792cf5cff8ac51af42a57ad8d276e394ae19f310a92e", + // TODO(build): be able to mark this dependency as lazy + // .lazy = true, }, .mach_glfw = .{ .url = "https://pkg.machengine.org/mach-glfw/26e8af73d7d4fbdac3ff60492c44294fc0d139b7.tar.gz", .hash = "12206b8eddf19167cc9ec83f353f97b8b9cdc2bc8c082fe33df6de11c1f00661bc8d", + .lazy = true, }, .mach_objc = .{ .url = "https://pkg.machengine.org/mach-objc/a7c3483702998aa0e960a788b9f611389f17d402.tar.gz", .hash = "1220049052fca861248fa6fb8bc24ecdb038049be0a3b22352bebc40e4dc2d2c981b", + .lazy = true, }, .mach_example_assets = .{ .url = "https://pkg.machengine.org/mach-example-assets/591715d872f4aa2d74e01447139c2000db0f7d96.tar.gz", .hash = "12206ef714c72a3e934990e5fbe7160824c5bad0a917a42cdd5ba31f7c85142f18d6", + .lazy = true, }, .mach_model3d = .{ .url = "https://pkg.machengine.org/mach-model3d/5d4dd54db2da123b38656d4574afaa4c04fd3838.tar.gz", .hash = "1220c1c16fa17783379f773c291af3693b84744200099f1cf5c1ddb66c4fe88bcf3a", + .lazy = true, }, .spirv_cross = .{ .url = "https://pkg.machengine.org/SPIRV-Cross/828af70fa8c20f9559eada5723ceb8a7b5999585.tar.gz", .hash = "1220922b722e291ae7f432b3a144863d76bd01e7d1f0f05ca883f3e09e48306103aa", + .lazy = true, }, .spirv_tools = .{ .url = "https://pkg.machengine.org/SPIRV-Tools/673bbbb2d1a8ed8740a91160a24c87caa14f80de.tar.gz", .hash = "1220ec815dfda171b5bf65f6078932d79e034508e9ecef51be660f6a89cc7c70aef9", + .lazy = true, }, .xcode_frameworks = .{ .url = "https://pkg.machengine.org/xcode-frameworks/2fca968efa90a4060803c56dd0f027890353f0a9.tar.gz", .hash = "122010c1a745ea06dee3012fbd3b311bd3d75ec39ded6bf566b36ebe3cd8da482347", + // TODO(build): be able to mark this dependency as lazy + // .lazy = true, }, .vulkan_zig_generated = .{ .url = "https://pkg.machengine.org/vulkan-zig-generated/78b3c3838ffcb64d537b4af340c9d3fcc41944ce.tar.gz", .hash = "1220c4a2a02e0bd81827225deea58b18f5ea9373cf932c073b977469e298eef1f54f", + .lazy = true, }, .direct3d_headers = .{ .url = "https://pkg.machengine.org/direct3d-headers/bc2fafe176dbd36bff6d1c036488c015bd4c0f7b.tar.gz", .hash = "12201f3096410a22af7978c7c57636f251669c335919740e42fc1785180435f63f1c", + // TODO(build): be able to mark this dependency as lazy + // .lazy = true, }, .opengl_headers = .{ .url = "https://pkg.machengine.org/opengl-headers/6d2f01d92576d23d1ff5fe6dfe1e448190c09bb7.tar.gz", .hash = "122007972c24513e1478bba5b628f294c43a710437356f1a3194fe42e17a36e42a3a", + .lazy = true, }, .x11_headers = .{ .url = "https://pkg.machengine.org/x11-headers/ad1c4891f70302c61ba956cfd565758dc1ca9d28.tar.gz", .hash = "1220ce35d8f1556afd5bf4796a7899d459f9c628b989f247eaf6aa00fbad10a88c9f", + .lazy = true, }, .linux_audio_headers = .{ .url = "https://pkg.machengine.org/linux-audio-headers/c22324c2be215b49078d369cff9b0c49b0282e40.tar.gz", .hash = "12207c50df3073e15cd0e8a1530937e0f8e224e02eda05953c703a6c69076576494a", + .lazy = true, }, .wayland_headers = .{ .url = "https://pkg.machengine.org/wayland-headers/4926b8c635aa2f215b0d5382060fc4091aa7b705.tar.gz", .hash = "12207decf58bee217ae9c5340a6852a62e7f5af9901bef9b1468d93e480798898285", + .lazy = true, + }, + .zigimg = .{ + .url = "https://github.com/slimsag/zigimg/archive/19a49a7e44fb4b1c22341dfbd6566019de742055.tar.gz", + .hash = "1220ebfa8587cfd644995fc08e218dbb3ebd7344fb8e129ff02bc5a6d52a2325370d", + .lazy = true, }, }, }