From fcb82345d40f54b9a95f3c99607e6a1470d771c0 Mon Sep 17 00:00:00 2001 From: Ali Chraghi <63465728+alichraghi@users.noreply.github.com> Date: Sun, 25 Sep 2022 20:32:51 +0330 Subject: [PATCH] all: build: organize build files and reduce unreachables (#567) --- build.zig | 337 ++++++++++++++++----------------- libs/basisu/build.zig | 26 +-- libs/ecs/build.zig | 12 +- libs/glfw/README.md | 36 ++-- libs/glfw/build.zig | 72 ++++---- libs/gpu-dawn/build.zig | 6 +- libs/gpu-dawn/sdk.zig | 338 +++++++++++++++++----------------- libs/gpu/build.zig | 6 +- libs/gpu/sdk.zig | 10 +- tools/wasmserve/wasmserve.zig | 10 +- 10 files changed, 434 insertions(+), 419 deletions(-) diff --git a/build.zig b/build.zig index 703ad484..a2593ae0 100644 --- a/build.zig +++ b/build.zig @@ -1,32 +1,50 @@ const std = @import("std"); const builtin = @import("builtin"); -const gpu_sdk = @import("libs/gpu/sdk.zig"); -const gpu_dawn_sdk = @import("libs/gpu-dawn/sdk.zig"); const system_sdk = @import("libs/glfw/system_sdk.zig"); -const sysaudio_sdk = @import("libs/sysaudio/sdk.zig"); const glfw = @import("libs/glfw/build.zig"); const ecs = @import("libs/ecs/build.zig"); const freetype = @import("libs/freetype/build.zig"); const basisu = @import("libs/basisu/build.zig"); const sysjs = @import("libs/sysjs/build.zig"); const gamemode = @import("libs/gamemode/build.zig"); -const Pkg = std.build.Pkg; - -const gpu_dawn = gpu_dawn_sdk.Sdk(.{ +const wasmserve = @import("tools/wasmserve/wasmserve.zig"); +const gpu_dawn = @import("libs/gpu-dawn/sdk.zig").Sdk(.{ .glfw = glfw, .glfw_include_dir = "glfw/upstream/glfw/include", .system_sdk = system_sdk, }); -const gpu = gpu_sdk.Sdk(.{ +const gpu = @import("libs/gpu/sdk.zig").Sdk(.{ .glfw = glfw, .gpu_dawn = gpu_dawn, }); -const sysaudio = sysaudio_sdk.Sdk(.{ +const sysaudio = @import("libs/sysaudio/sdk.zig").Sdk(.{ .system_sdk = system_sdk, .sysjs = sysjs, }); +const CrossTarget = std.zig.CrossTarget; +const Builder = std.build.Builder; +const Pkg = std.build.Pkg; -pub fn build(b: *std.build.Builder) void { +pub const pkg = Pkg{ + .name = "mach", + .source = .{ .path = thisDir() ++ "/src/main.zig" }, + .dependencies = &.{ gpu.pkg, ecs.pkg, sysaudio.pkg }, +}; + +pub const Options = struct { + glfw_options: glfw.Options = .{}, + gpu_dawn_options: gpu_dawn.Options = .{}, + sysaudio_options: sysaudio.Options = .{}, + + pub fn gpuOptions(options: Options) gpu.Options { + return .{ + .glfw_options = options.glfw_options, + .gpu_dawn_options = options.gpu_dawn_options, + }; + } +}; + +pub fn build(b: *Builder) !void { const mode = b.standardReleaseOptions(); const target = b.standardTargetOptions(.{}); @@ -47,13 +65,12 @@ pub fn build(b: *std.build.Builder) void { const sysaudio_test_step = b.step("test-sysaudio", "Run sysaudio library tests"); const mach_test_step = b.step("test-mach", "Run Mach Core library tests"); - glfw_test_step.dependOn(&glfw.testStep(b, mode, target).step); - gpu_test_step.dependOn(&gpu.testStep(b, mode, target, options.gpuOptions()).step); + glfw_test_step.dependOn(&(try glfw.testStep(b, mode, target)).step); + gpu_test_step.dependOn(&(try gpu.testStep(b, mode, target, options.gpuOptions())).step); freetype_test_step.dependOn(&freetype.testStep(b, mode, target).step); // TODO(self-hosted) uncomment this // ecs_test_step.dependOn(&ecs.testStep(b, mode, target).step); - if (target.isNativeOs()) - basisu_test_step.dependOn(&basisu.testStep(b, mode, target).step); + basisu_test_step.dependOn(&basisu.testStep(b, mode, target).step); sysaudio_test_step.dependOn(&sysaudio.testStep(b, mode, target).step); mach_test_step.dependOn(&testStep(b, mode, target).step); @@ -61,13 +78,17 @@ pub fn build(b: *std.build.Builder) void { all_tests_step.dependOn(gpu_test_step); // TODO(self-hosted) uncomment this // all_tests_step.dependOn(ecs_test_step); - if (target.isNativeOs()) - all_tests_step.dependOn(basisu_test_step); + all_tests_step.dependOn(basisu_test_step); all_tests_step.dependOn(freetype_test_step); all_tests_step.dependOn(sysaudio_test_step); all_tests_step.dependOn(mach_test_step); - const shaderexp_app = App.init( + // TODO: we need a way to test wasm stuff + // const sysjs_test_step = b.step( "test-sysjs", "Run sysjs library tests"); + // sysjs_test_step.dependOn(&sysjs.testStep(b, mode, target).step); + // all_tests_step.dependOn(sysjs_test_step); + + const shaderexp_app = try App.init( b, .{ .name = "shaderexp", @@ -76,106 +97,81 @@ pub fn build(b: *std.build.Builder) void { }, ); shaderexp_app.setBuildMode(mode); - shaderexp_app.link(options); + try shaderexp_app.link(options); shaderexp_app.install(); const shaderexp_compile_step = b.step("shaderexp", "Compile shaderexp"); shaderexp_compile_step.dependOn(&shaderexp_app.getInstallStep().?.step); - const shaderexp_run_cmd = shaderexp_app.run(); + const shaderexp_run_cmd = try shaderexp_app.run(); shaderexp_run_cmd.dependOn(&shaderexp_app.getInstallStep().?.step); const shaderexp_run_step = b.step("run-shaderexp", "Run shaderexp"); shaderexp_run_step.dependOn(shaderexp_run_cmd); - // compiles the `libmach` shared library - const lib = b.addSharedLibrary("mach", "src/platform/libmach.zig", .unversioned); - lib.setTarget(target); - lib.setBuildMode(mode); - lib.main_pkg_path = "src/"; - const app_pkg = std.build.Pkg{ - .name = "app", - .source = .{ .path = "src/platform/libmach.zig" }, - }; - lib.addPackage(app_pkg); - lib.addPackage(gpu.pkg); - lib.addPackage(glfw.pkg); - lib.addPackage(sysaudio.pkg); - if (target.toTarget().os.tag == .linux) - lib.addPackage(gamemode.pkg); - glfw.link(b, lib, options.glfw_options); - gpu.link(b, lib, options.gpuOptions()); - gamemode.link(lib); - lib.setOutputDir("./libmach/build"); - lib.install(); + // Compiles the `libmach` shared library + const shared_lib = try buildSharedLib(b, mode, target, options); + shared_lib.install(); } - // TODO: we need a way to test wasm stuff - // const sysjs_test_step = b.step( "test-sysjs", "Run sysjs library tests"); - // sysjs_test_step.dependOn(&sysjs.testStep(b, mode, target).step); - // all_tests_step.dependOn(sysjs_test_step); - - // TODO(build-system): https://github.com/hexops/mach/issues/229#issuecomment-1100958939 - ensureGit(b.allocator); - ensureDependencySubmodule(b.allocator, "examples/libs/zmath") catch unreachable; - ensureDependencySubmodule(b.allocator, "examples/libs/zigimg") catch unreachable; - ensureDependencySubmodule(b.allocator, "examples/gkurve/assets") catch unreachable; - ensureDependencySubmodule(b.allocator, "examples/image-blur/assets") catch unreachable; - ensureDependencySubmodule(b.allocator, "examples/textured-cube/assets") catch unreachable; - ensureDependencySubmodule(b.allocator, "examples/cubemap/assets") catch unreachable; - - inline for ([_]ExampleDefinition{ + try ensureExamplesDependencySubmodules(b.allocator); + inline for ([_]struct { + name: []const u8, + deps: []const Pkg = &.{}, + std_platform_only: bool = false, + has_assets: bool = false, + }{ .{ .name = "triangle" }, .{ .name = "triangle-msaa" }, .{ .name = "boids" }, - .{ .name = "rotating-cube", .packages = &[_]Pkg{Packages.zmath} }, - .{ .name = "pixel-post-process", .packages = &[_]Pkg{Packages.zmath} }, - .{ .name = "two-cubes", .packages = &[_]Pkg{Packages.zmath} }, - .{ .name = "instanced-cube", .packages = &[_]Pkg{Packages.zmath} }, - .{ .name = "advanced-gen-texture-light", .packages = &[_]Pkg{Packages.zmath} }, - .{ .name = "fractal-cube", .packages = &[_]Pkg{Packages.zmath} }, - .{ .name = "textured-cube", .packages = &[_]Pkg{ Packages.zmath, Packages.zigimg }, .has_assets = true }, + .{ .name = "rotating-cube", .deps = &.{Packages.zmath} }, + .{ .name = "pixel-post-process", .deps = &.{Packages.zmath} }, + .{ .name = "two-cubes", .deps = &.{Packages.zmath} }, + .{ .name = "instanced-cube", .deps = &.{Packages.zmath} }, + .{ .name = "advanced-gen-texture-light", .deps = &.{Packages.zmath} }, + .{ .name = "fractal-cube", .deps = &.{Packages.zmath} }, + .{ .name = "textured-cube", .deps = &.{ Packages.zmath, Packages.zigimg }, .has_assets = true }, // TODO(self-hosted) uncomment this - // .{ .name = "ecs-app", .packages = &[_]Pkg{} }, - .{ .name = "image-blur", .packages = &[_]Pkg{Packages.zigimg}, .has_assets = true }, - .{ .name = "cubemap", .packages = &[_]Pkg{ Packages.zmath, Packages.zigimg }, .has_assets = true }, - .{ .name = "map-async", .packages = &[_]Pkg{} }, - .{ .name = "sysaudio", .packages = &[_]Pkg{} }, - // NOTE: examples with std_platform_only should be placed at last - .{ .name = "gkurve", .packages = &[_]Pkg{ Packages.zmath, Packages.zigimg, freetype.pkg }, .std_platform_only = true, .has_assets = true }, + // .{ .name = "ecs-app", .deps = &.{} }, + .{ .name = "image-blur", .deps = &.{Packages.zigimg}, .has_assets = true }, + .{ .name = "cubemap", .deps = &.{ Packages.zmath, Packages.zigimg }, .has_assets = true }, + .{ .name = "map-async", .deps = &.{} }, + .{ .name = "sysaudio", .deps = &.{} }, + .{ .name = "gkurve", .deps = &.{ Packages.zmath, Packages.zigimg, freetype.pkg }, .std_platform_only = true, .has_assets = true }, }) |example| { - // FIXME: this is workaround for a problem that some examples (having the std_platform_only=true field) as - // well as zigimg uses IO which is not supported in freestanding environments. So break out of this loop - // as soon as any such examples is found. This does means that any example which works on wasm should be + // FIXME: this is workaround for a problem that some examples + // (having the std_platform_only=true field) as well as zigimg + // uses IO which is not supported in freestanding environments. + // So break out of this loop as soon as any such examples is found. + // This does means that any example which works on wasm should be // placed before those who dont. if (example.std_platform_only) - if (target.toTarget().cpu.arch == .wasm32) + if (target.getCpuArch() == .wasm32) break; - const example_app = App.init( + const example_app = try App.init( b, .{ .name = "example-" ++ example.name, .src = "examples/" ++ example.name ++ "/main.zig", .target = target, - .deps = example.packages, + .deps = example.deps, .res_dirs = if (example.has_assets) &.{"examples/" ++ example.name ++ "/assets"} else null, .watch_paths = &.{"examples/" ++ example.name}, }, ); example_app.setBuildMode(mode); - inline for (example.packages) |p| { + inline for (example.deps) |p| { if (std.mem.eql(u8, p.name, freetype.pkg.name)) freetype.link(example_app.b, example_app.step, .{}); } - - example_app.link(options); + try example_app.link(options); example_app.install(); const example_compile_step = b.step("example-" ++ example.name, "Compile '" ++ example.name ++ "' example"); example_compile_step.dependOn(&example_app.getInstallStep().?.step); - const example_run_cmd = example_app.run(); - example_run_cmd.dependOn(&example_app.getInstallStep().?.step); + const example_run_cmd = try example_app.run(); + example_run_cmd.dependOn(example_compile_step); const example_run_step = b.step("run-example-" ++ example.name, "Run '" ++ example.name ++ "' example"); example_run_step.dependOn(example_run_cmd); } @@ -184,7 +180,19 @@ pub fn build(b: *std.build.Builder) void { compile_all.dependOn(b.getInstallStep()); } -fn testStep(b: *std.build.Builder, mode: std.builtin.Mode, target: std.zig.CrossTarget) *std.build.RunStep { +const Packages = struct { + // Declared here because submodule may not be cloned at the time build.zig runs. + const zmath = Pkg{ + .name = "zmath", + .source = .{ .path = "examples/libs/zmath/src/zmath.zig" }, + }; + const zigimg = Pkg{ + .name = "zigimg", + .source = .{ .path = "examples/libs/zigimg/zigimg.zig" }, + }; +}; + +fn testStep(b: *Builder, mode: std.builtin.Mode, target: CrossTarget) *std.build.RunStep { const main_tests = b.addTestExe("mach-tests", "src/main.zig"); main_tests.setBuildMode(mode); main_tests.setTarget(target); @@ -196,48 +204,45 @@ fn testStep(b: *std.build.Builder, mode: std.builtin.Mode, target: std.zig.Cross return main_tests.run(); } -pub const Options = struct { - glfw_options: glfw.Options = .{}, - gpu_dawn_options: gpu_dawn.Options = .{}, - sysaudio_options: sysaudio.Options = .{}, - - pub fn gpuOptions(options: Options) gpu.Options { - return .{ - .glfw_options = options.glfw_options, - .gpu_dawn_options = options.gpu_dawn_options, - }; +fn buildSharedLib(b: *Builder, mode: std.builtin.Mode, target: CrossTarget, options: Options) !*std.build.LibExeObjStep { + const lib = b.addSharedLibrary("mach", "src/platform/libmach.zig", .unversioned); + lib.setTarget(target); + lib.setBuildMode(mode); + lib.main_pkg_path = "src/"; + const app_pkg = Pkg{ + .name = "app", + .source = .{ .path = "src/platform/libmach.zig" }, + }; + lib.addPackage(app_pkg); + lib.addPackage(glfw.pkg); + lib.addPackage(gpu.pkg); + lib.addPackage(sysaudio.pkg); + if (target.isLinux()) { + lib.addPackage(gamemode.pkg); + gamemode.link(lib); } -}; - -const ExampleDefinition = struct { - name: []const u8, - packages: []const Pkg = &[_]Pkg{}, - std_platform_only: bool = false, - has_assets: bool = false, -}; - -const Packages = struct { - // Declared here because submodule may not be cloned at the time build.zig runs. - const zmath = std.build.Pkg{ - .name = "zmath", - .source = .{ .path = "examples/libs/zmath/src/zmath.zig" }, - }; - const zigimg = std.build.Pkg{ - .name = "zigimg", - .source = .{ .path = "examples/libs/zigimg/zigimg.zig" }, - }; -}; + try glfw.link(b, lib, options.glfw_options); + try gpu.link(b, lib, options.gpuOptions()); + lib.setOutputDir("libmach/build"); + return lib; +} const web_install_dir = std.build.InstallDir{ .custom = "www" }; pub const App = struct { - b: *std.build.Builder, + b: *Builder, name: []const u8, step: *std.build.LibExeObjStep, platform: Platform, res_dirs: ?[]const []const u8, watch_paths: ?[]const []const u8, + pub const InitError = std.zig.system.NativeTargetInfo.DetectError; + pub const LinkError = glfw.LinkError; + pub const RunError = error{ + ParsingIpFailed, + } || wasmserve.Error || std.fmt.ParseIntError; + pub const Platform = enum { native, web, @@ -248,28 +253,28 @@ pub const App = struct { } }; - pub fn init(b: *std.build.Builder, options: struct { + pub fn init(b: *Builder, options: struct { name: []const u8, src: []const u8, - target: std.zig.CrossTarget, + target: CrossTarget, deps: ?[]const Pkg = null, res_dirs: ?[]const []const u8 = null, watch_paths: ?[]const []const u8 = null, - }) App { - const target = (std.zig.system.NativeTargetInfo.detect(options.target) catch unreachable).target; + }) InitError!App { + const target = (try std.zig.system.NativeTargetInfo.detect(options.target)).target; const platform = Platform.fromTarget(target); - var deps = std.ArrayList(std.build.Pkg).init(b.allocator); - deps.append(pkg) catch unreachable; - deps.append(gpu.pkg) catch unreachable; - deps.append(sysaudio.pkg) catch unreachable; + var deps = std.ArrayList(Pkg).init(b.allocator); + try deps.append(pkg); + try deps.append(gpu.pkg); + try deps.append(sysaudio.pkg); switch (platform) { - .native => deps.append(glfw.pkg) catch unreachable, - .web => deps.append(sysjs.pkg) catch unreachable, + .native => try deps.append(glfw.pkg), + .web => try deps.append(sysjs.pkg), } - if (options.deps) |app_deps| deps.appendSlice(app_deps) catch unreachable; + if (options.deps) |app_deps| try deps.appendSlice(app_deps); - const app_pkg = std.build.Pkg{ + const app_pkg = Pkg{ .name = "app", .source = .{ .path = options.src }, .dependencies = deps.toOwnedSlice(), @@ -310,6 +315,16 @@ pub const App = struct { }; } + pub fn link(app: *const App, options: Options) LinkError!void { + if (app.platform != .web) { + try glfw.link(app.b, app.step, options.glfw_options); + gpu.link(app.b, app.step, options.gpuOptions()) catch return error.FailedToLinkGPU; + if (app.step.target.isLinux()) + gamemode.link(app.step); + } + sysaudio.link(app.b, app.step, options.sysaudio_options); + } + pub fn install(app: *const App) void { app.step.install(); @@ -356,14 +371,28 @@ pub const App = struct { } } - pub fn link(app: *const App, options: Options) void { - if (app.platform != .web) { - glfw.link(app.b, app.step, options.glfw_options); - gpu.link(app.b, app.step, options.gpuOptions()); - if (app.step.target.isLinux()) - gamemode.link(app.step); + pub fn run(app: *const App) RunError!*std.build.Step { + if (app.platform == .web) { + const address = std.process.getEnvVarOwned(app.b.allocator, "MACH_ADDRESS") catch try app.b.allocator.dupe(u8, "127.0.0.1"); + const port = std.process.getEnvVarOwned(app.b.allocator, "MACH_PORT") catch try app.b.allocator.dupe(u8, "8080"); + const address_parsed = std.net.Address.parseIp4(address, try std.fmt.parseInt(u16, port, 10)) catch return error.ParsingIpFailed; + const install_step_name = if (std.mem.startsWith(u8, app.step.name, "example-")) + app.step.name + else + null; + const serve_step = try wasmserve.serve( + app.step, + .{ + .install_step_name = install_step_name, + .install_dir = web_install_dir, + .watch_paths = app.watch_paths, + .listen_address = address_parsed, + }, + ); + return &serve_step.step; + } else { + return &app.step.run().step; } - sysaudio.link(app.b, app.step, options.sysaudio_options); } pub fn setBuildMode(app: *const App, mode: std.builtin.Mode) void { @@ -373,41 +402,17 @@ pub const App = struct { pub fn getInstallStep(app: *const App) ?*std.build.InstallArtifactStep { return app.step.install_step; } - - pub fn run(app: *const App) *std.build.Step { - if (app.platform == .web) { - const address = std.process.getEnvVarOwned(app.b.allocator, "MACH_ADDRESS") catch app.b.allocator.dupe(u8, "127.0.0.1") catch unreachable; - const port = std.process.getEnvVarOwned(app.b.allocator, "MACH_PORT") catch app.b.allocator.dupe(u8, "8080") catch unreachable; - const address_parsed = std.net.Address.parseIp4(address, std.fmt.parseInt(u16, port, 10) catch unreachable) catch unreachable; - const wasmserve = @import("tools/wasmserve/wasmserve.zig"); - const install_step_name = if (std.mem.startsWith(u8, app.step.name, "example-")) - app.step.name - else - null; - const serve_step = wasmserve.serve( - app.step, - .{ - .install_step_name = install_step_name, - .install_dir = web_install_dir, - .watch_paths = app.watch_paths, - .listen_address = address_parsed, - }, - ) catch unreachable; - return &serve_step.step; - } else { - return &app.step.run().step; - } - } }; -pub const pkg = std.build.Pkg{ - .name = "mach", - .source = .{ .path = thisDir() ++ "/src/main.zig" }, - .dependencies = &.{ gpu.pkg, ecs.pkg, sysaudio.pkg }, -}; - -fn thisDir() []const u8 { - return std.fs.path.dirname(@src().file) orelse "."; +fn ensureExamplesDependencySubmodules(allocator: std.mem.Allocator) !void { + // TODO(build-system): https://github.com/hexops/mach/issues/229#issuecomment-1100958939 + ensureGit(allocator); + try ensureDependencySubmodule(allocator, "examples/libs/zmath"); + try ensureDependencySubmodule(allocator, "examples/libs/zigimg"); + try ensureDependencySubmodule(allocator, "examples/gkurve/assets"); + try ensureDependencySubmodule(allocator, "examples/image-blur/assets"); + try ensureDependencySubmodule(allocator, "examples/textured-cube/assets"); + try ensureDependencySubmodule(allocator, "examples/cubemap/assets"); } fn ensureDependencySubmodule(allocator: std.mem.Allocator, path: []const u8) !void { @@ -424,11 +429,9 @@ fn ensureDependencySubmodule(allocator: std.mem.Allocator, path: []const u8) !vo } fn ensureGit(allocator: std.mem.Allocator) void { - const argv = &[_][]const u8{ "git", "--version" }; const result = std.ChildProcess.exec(.{ .allocator = allocator, - .argv = argv, - .cwd = ".", + .argv = &.{ "git", "--version" }, }) catch { // e.g. FileNotFound std.log.err("mach: error: 'git --version' failed. Is git not installed?", .{}); std.process.exit(1); @@ -442,3 +445,7 @@ fn ensureGit(allocator: std.mem.Allocator) void { std.process.exit(1); } } + +fn thisDir() []const u8 { + return std.fs.path.dirname(@src().file) orelse "."; +} diff --git a/libs/basisu/build.zig b/libs/basisu/build.zig index 5236f81e..c050f9a9 100644 --- a/libs/basisu/build.zig +++ b/libs/basisu/build.zig @@ -10,6 +10,19 @@ pub const pkg = std.build.Pkg{ }, }; +pub const Options = struct { + encoder: ?EncoderOptions, + transcoder: ?TranscoderOptions, +}; + +pub const EncoderOptions = struct { + install_libs: bool = false, +}; + +pub const TranscoderOptions = struct { + install_libs: bool = false, +}; + pub fn build(b: *Builder) void { const mode = b.standardReleaseOptions(); const target = b.standardTargetOptions(.{}); @@ -82,19 +95,6 @@ pub fn buildTranscoder(b: *Builder, target: std.zig.CrossTarget, options: Transc return transcoder; } -pub const Options = struct { - encoder: ?EncoderOptions, - transcoder: ?TranscoderOptions, -}; - -pub const EncoderOptions = struct { - install_libs: bool = false, -}; - -pub const TranscoderOptions = struct { - install_libs: bool = false, -}; - fn thisDir() []const u8 { return std.fs.path.dirname(@src().file) orelse "."; } diff --git a/libs/ecs/build.zig b/libs/ecs/build.zig index f686c53a..dbf04b0e 100644 --- a/libs/ecs/build.zig +++ b/libs/ecs/build.zig @@ -1,5 +1,11 @@ const std = @import("std"); +pub const pkg = std.build.Pkg{ + .name = "ecs", + .source = .{ .path = thisDir() ++ "/src/main.zig" }, + .dependencies = &[_]std.build.Pkg{}, +}; + pub fn build(b: *std.build.Builder) void { const mode = b.standardReleaseOptions(); const target = b.standardTargetOptions(.{}); @@ -15,12 +21,6 @@ pub fn testStep(b: *std.build.Builder, mode: std.builtin.Mode, target: std.zig.C return main_tests.run(); } -pub const pkg = std.build.Pkg{ - .name = "ecs", - .source = .{ .path = thisDir() ++ "/src/main.zig" }, - .dependencies = &[_]std.build.Pkg{}, -}; - fn thisDir() []const u8 { return std.fs.path.dirname(@src().file) orelse "."; } diff --git a/libs/glfw/README.md b/libs/glfw/README.md index adf35178..d9685afc 100644 --- a/libs/glfw/README.md +++ b/libs/glfw/README.md @@ -20,20 +20,20 @@ There are 130+ tests, and CI tests on all major platforms as well as cross-compi Why create a ziggified GLFW wrapper, instead of just using `@cImport` and interfacing with GLFW directly? You get: -* Errors as [zig errors](https://ziglang.org/documentation/master/#Errors) instead of via a callback function. -* `true` and `false` instead of `c.GLFW_TRUE` and `c.GLFW_FALSE` constants. -* Generics, so you can just use `window.hint` instead of `glfwWindowHint`, `glfwWindowHintString`, etc. -* **Enums**, always know what value a GLFW function can accept as everything is strictly typed. And use the nice Zig syntax to access enums, like `window.getKey(.escape)` instead of `c.glfwGetKey(window, c.GLFW_KEY_ESCAPE)` -* Slices instead of C pointers and lengths. -* [packed structs](https://ziglang.org/documentation/master/#packed-struct) represent bit masks, so you can use `if (joystick.down and joystick.right)` instead of `if (joystick & c.GLFW_HAT_DOWN and joystick & c.GLFW_HAT_RIGHT)`, etc. -* Methods, e.g. `my_window.hint(...)` instead of `glfwWindowHint(my_window, ...)` +- Errors as [zig errors](https://ziglang.org/documentation/master/#Errors) instead of via a callback function. +- `true` and `false` instead of `c.GLFW_TRUE` and `c.GLFW_FALSE` constants. +- Generics, so you can just use `window.hint` instead of `glfwWindowHint`, `glfwWindowHintString`, etc. +- **Enums**, always know what value a GLFW function can accept as everything is strictly typed. And use the nice Zig syntax to access enums, like `window.getKey(.escape)` instead of `c.glfwGetKey(window, c.GLFW_KEY_ESCAPE)` +- Slices instead of C pointers and lengths. +- [packed structs](https://ziglang.org/documentation/master/#packed-struct) represent bit masks, so you can use `if (joystick.down and joystick.right)` instead of `if (joystick & c.GLFW_HAT_DOWN and joystick & c.GLFW_HAT_RIGHT)`, etc. +- Methods, e.g. `my_window.hint(...)` instead of `glfwWindowHint(my_window, ...)` ## How do I use OpenGL, Vulkan, WebGPU, etc. with this? You'll need to bring your own library for this. Some are: -* (Vulkan) https://github.com/Snektron/vulkan-zig (also see https://github.com/Avokadoen/zig_vulkan) -* (OpenGL) https://github.com/ziglibs/zgl +- (Vulkan) https://github.com/Snektron/vulkan-zig (also see https://github.com/Avokadoen/zig_vulkan) +- (OpenGL) https://github.com/ziglibs/zgl ## Examples @@ -57,10 +57,10 @@ Then in your `build.zig` add: ... const glfw = @import("libs/mach-glfw/build.zig"); -pub fn build(b: *Builder) void { +pub fn build(b: *Builder) !void { ... exe.addPackage(glfw.pkg); - glfw.link(b, exe, .{}); + try glfw.link(b, exe, .{}); } ``` @@ -83,11 +83,11 @@ Then in your `build.zig` add: const pkgs = @import("deps.zig").pkgs; const glfw = @import("build-glfw"); -pub fn build(b: *Builder) void { +pub fn build(b: *Builder) !void { ... exe.addPackage(pkgs.glfw); - glfw.link(b, exe, .{}); + try glfw.link(b, exe, .{}); } ``` @@ -134,11 +134,11 @@ const pos = window.getPos() catch |err| { Here is a rough list of functionality Wayland does not support: -* `Window.setIcon` -* `Window.setPos`, `Window.getPos` -* `Window.iconify`, `Window.focus` -* `Monitor.setGamma` -* `Monitor.getGammaRamp`, `Monitor.setGammaRamp` +- `Window.setIcon` +- `Window.setPos`, `Window.getPos` +- `Window.iconify`, `Window.focus` +- `Monitor.setGamma` +- `Monitor.getGammaRamp`, `Monitor.setGammaRamp` ## Join the community diff --git a/libs/glfw/build.zig b/libs/glfw/build.zig index a4e8779e..18e711ef 100644 --- a/libs/glfw/build.zig +++ b/libs/glfw/build.zig @@ -13,20 +13,20 @@ pub fn build(b: *Builder) void { test_step.dependOn(&testStepShared(b, mode, target).step); } -pub fn testStep(b: *Builder, mode: std.builtin.Mode, target: std.zig.CrossTarget) *std.build.RunStep { +pub fn testStep(b: *Builder, mode: std.builtin.Mode, target: std.zig.CrossTarget) !*std.build.RunStep { const main_tests = b.addTestExe("glfw-tests", thisDir() ++ "/src/main.zig"); main_tests.setBuildMode(mode); main_tests.setTarget(target); - link(b, main_tests, .{}); + try link(b, main_tests, .{}); main_tests.install(); return main_tests.run(); } -fn testStepShared(b: *Builder, mode: std.builtin.Mode, target: std.zig.CrossTarget) *std.build.RunStep { +fn testStepShared(b: *Builder, mode: std.builtin.Mode, target: std.zig.CrossTarget) !*std.build.RunStep { const main_tests = b.addTestExe("glfw-tests-shared", thisDir() ++ "/src/main.zig"); main_tests.setBuildMode(mode); main_tests.setTarget(target); - link(b, main_tests, .{ .shared = true }); + try link(b, main_tests, .{ .shared = true }); main_tests.install(); return main_tests.run(); } @@ -79,10 +79,11 @@ fn cimportWorkaround() void { std.fs.cwd().copyFile(cn_path, dest_dir, thisDir() ++ "/src/c_native.zig", .{}) catch unreachable; } -pub fn link(b: *Builder, step: *std.build.LibExeObjStep, options: Options) void { +pub const LinkError = error{FailedToLinkGPU} || BuildError; +pub fn link(b: *Builder, step: *std.build.LibExeObjStep, options: Options) LinkError!void { cimportWorkaround(); - const lib = buildLibrary(b, step.build_mode, step.target, options); + const lib = try buildLibrary(b, step.build_mode, step.target, options); step.linkLibrary(lib); addGLFWIncludes(step); if (options.shared) { @@ -93,9 +94,10 @@ pub fn link(b: *Builder, step: *std.build.LibExeObjStep, options: Options) void } } -fn buildLibrary(b: *Builder, mode: std.builtin.Mode, target: std.zig.CrossTarget, options: Options) *std.build.LibExeObjStep { +pub const BuildError = error{CannotEnsureDependency} || std.mem.Allocator.Error; +fn buildLibrary(b: *Builder, mode: std.builtin.Mode, target: std.zig.CrossTarget, options: Options) BuildError!*std.build.LibExeObjStep { // TODO(build-system): https://github.com/hexops/mach/issues/229#issuecomment-1100958939 - ensureDependencySubmodule(b.allocator, "upstream") catch unreachable; + ensureDependencySubmodule(b.allocator, "upstream") catch return error.CannotEnsureDependency; const lib = if (options.shared) b.addSharedLibrary("glfw", null, .unversioned) @@ -108,7 +110,7 @@ fn buildLibrary(b: *Builder, mode: std.builtin.Mode, target: std.zig.CrossTarget lib.defineCMacro("_GLFW_BUILD_DLL", null); addGLFWIncludes(lib); - addGLFWSources(b, lib, options); + try addGLFWSources(b, lib, options); linkGLFWDependencies(b, lib, options); if (options.install_libs) @@ -122,7 +124,7 @@ fn addGLFWIncludes(step: *std.build.LibExeObjStep) void { step.addIncludePath(thisDir() ++ "/upstream/vulkan_headers/include"); } -fn addGLFWSources(b: *Builder, lib: *std.build.LibExeObjStep, options: Options) void { +fn addGLFWSources(b: *Builder, lib: *std.build.LibExeObjStep, options: Options) std.mem.Allocator.Error!void { const include_glfw_src = "-I" ++ thisDir() ++ "/upstream/glfw/src"; switch (lib.target_info.target.os.tag) { .windows => lib.addCSourceFiles(&.{ @@ -143,42 +145,25 @@ fn addGLFWSources(b: *Builder, lib: *std.build.LibExeObjStep, options: Options) // ``` var sources = std.ArrayList([]const u8).init(b.allocator); var flags = std.ArrayList([]const u8).init(b.allocator); - sources.append(thisDir() ++ "/src/sources_all.c") catch unreachable; - sources.append(thisDir() ++ "/src/sources_linux.c") catch unreachable; + try sources.append(thisDir() ++ "/src/sources_all.c"); + try sources.append(thisDir() ++ "/src/sources_linux.c"); if (options.x11) { - sources.append(thisDir() ++ "/src/sources_linux_x11.c") catch unreachable; - flags.append("-D_GLFW_X11") catch unreachable; + try sources.append(thisDir() ++ "/src/sources_linux_x11.c"); + try flags.append("-D_GLFW_X11"); } if (options.wayland) { - sources.append(thisDir() ++ "/src/sources_linux_wayland.c") catch unreachable; - flags.append("-D_GLFW_WAYLAND") catch unreachable; + try sources.append(thisDir() ++ "/src/sources_linux_wayland.c"); + try flags.append("-D_GLFW_WAYLAND"); } - flags.append("-I" ++ thisDir() ++ "/upstream/glfw/src") catch unreachable; + try flags.append("-I" ++ thisDir() ++ "/upstream/glfw/src"); // TODO(upstream): glfw can't compile on clang15 without this flag - flags.append("-Wno-implicit-function-declaration") catch unreachable; + try flags.append("-Wno-implicit-function-declaration"); lib.addCSourceFiles(sources.items, flags.items); }, } } -fn ensureDependencySubmodule(allocator: std.mem.Allocator, path: []const u8) !void { - if (std.process.getEnvVarOwned(allocator, "NO_ENSURE_SUBMODULES")) |no_ensure_submodules| { - defer allocator.free(no_ensure_submodules); - if (std.mem.eql(u8, no_ensure_submodules, "true")) return; - } else |_| {} - var child = std.ChildProcess.init(&.{ "git", "submodule", "update", "--init", path }, allocator); - child.cwd = thisDir(); - child.stderr = std.io.getStdErr(); - child.stdout = std.io.getStdOut(); - - _ = try child.spawnAndWait(); -} - -inline fn thisDir() []const u8 { - return comptime std.fs.path.dirname(@src().file) orelse "."; -} - fn linkGLFWDependencies(b: *Builder, step: *std.build.LibExeObjStep, options: Options) void { step.linkLibC(); system_sdk.include(b, step, options.system_sdk); @@ -217,3 +202,20 @@ fn linkGLFWDependencies(b: *Builder, step: *std.build.LibExeObjStep, options: Op }, } } + +fn ensureDependencySubmodule(allocator: std.mem.Allocator, path: []const u8) !void { + if (std.process.getEnvVarOwned(allocator, "NO_ENSURE_SUBMODULES")) |no_ensure_submodules| { + defer allocator.free(no_ensure_submodules); + if (std.mem.eql(u8, no_ensure_submodules, "true")) return; + } else |_| {} + var child = std.ChildProcess.init(&.{ "git", "submodule", "update", "--init", path }, allocator); + child.cwd = thisDir(); + child.stderr = std.io.getStdErr(); + child.stdout = std.io.getStdOut(); + + _ = try child.spawnAndWait(); +} + +inline fn thisDir() []const u8 { + return comptime std.fs.path.dirname(@src().file) orelse "."; +} diff --git a/libs/gpu-dawn/build.zig b/libs/gpu-dawn/build.zig index bc70e4e2..9dee882d 100644 --- a/libs/gpu-dawn/build.zig +++ b/libs/gpu-dawn/build.zig @@ -4,7 +4,7 @@ const glfw = @import("libs/mach-glfw/build.zig"); const system_sdk = @import("libs/mach-glfw/system_sdk.zig"); const gpu_dawn_sdk = @import("sdk.zig"); -pub fn build(b: *Builder) void { +pub fn build(b: *Builder) !void { const mode = b.standardReleaseOptions(); const target = b.standardTargetOptions(.{}); const gpu_dawn = gpu_dawn_sdk.Sdk(.{ @@ -23,8 +23,8 @@ pub fn build(b: *Builder) void { const example = b.addExecutable("dawn-example", "src/main.zig"); example.setBuildMode(mode); example.setTarget(target); - gpu_dawn.link(b, example, options); - glfw.link(b, example, .{ .system_sdk = .{ .set_sysroot = false } }); + try gpu_dawn.link(b, example, options); + try glfw.link(b, example, .{ .system_sdk = .{ .set_sysroot = false } }); example.addPackage(glfw.pkg); example.install(); } diff --git a/libs/gpu-dawn/sdk.zig b/libs/gpu-dawn/sdk.zig index 52ffee9e..a0eb4908 100644 --- a/libs/gpu-dawn/sdk.zig +++ b/libs/gpu-dawn/sdk.zig @@ -79,50 +79,53 @@ pub fn Sdk(comptime deps: anytype) type { } }; - pub fn link(b: *Builder, step: *std.build.LibExeObjStep, options: Options) void { + pub fn link(b: *Builder, step: *std.build.LibExeObjStep, options: Options) !void { const opt = options.detectDefaults(step.target_info.target); - if (options.from_source) linkFromSource(b, step, opt) else linkFromBinary(b, step, opt); + try if (options.from_source) + linkFromSource(b, step, opt) + else + linkFromBinary(b, step, opt); } - fn linkFromSource(b: *Builder, step: *std.build.LibExeObjStep, options: Options) void { - ensureSubmodules(b.allocator) catch |err| @panic(@errorName(err)); + fn linkFromSource(b: *Builder, step: *std.build.LibExeObjStep, options: Options) !void { + try ensureSubmodules(b.allocator); step.addIncludePath(comptime thisDir() ++ "/libs/dawn/out/Debug/gen/include"); step.addIncludePath(comptime thisDir() ++ "/libs/dawn/include"); step.addIncludePath(comptime thisDir() ++ "/src/dawn"); if (options.separate_libs) { - const lib_mach_dawn_native = buildLibMachDawnNative(b, step, options); + const lib_mach_dawn_native = try buildLibMachDawnNative(b, step, options); step.linkLibrary(lib_mach_dawn_native); - const lib_dawn_common = buildLibDawnCommon(b, step, options); + const lib_dawn_common = try buildLibDawnCommon(b, step, options); step.linkLibrary(lib_dawn_common); - const lib_dawn_platform = buildLibDawnPlatform(b, step, options); + const lib_dawn_platform = try buildLibDawnPlatform(b, step, options); step.linkLibrary(lib_dawn_platform); // dawn-native - const lib_abseil_cpp = buildLibAbseilCpp(b, step, options); + const lib_abseil_cpp = try buildLibAbseilCpp(b, step, options); step.linkLibrary(lib_abseil_cpp); - const lib_dawn_native = buildLibDawnNative(b, step, options); + const lib_dawn_native = try buildLibDawnNative(b, step, options); step.linkLibrary(lib_dawn_native); if (options.d3d12.?) { - const lib_dxcompiler = buildLibDxcompiler(b, step, options); + const lib_dxcompiler = try buildLibDxcompiler(b, step, options); step.linkLibrary(lib_dxcompiler); } - const lib_dawn_wire = buildLibDawnWire(b, step, options); + const lib_dawn_wire = try buildLibDawnWire(b, step, options); step.linkLibrary(lib_dawn_wire); - const lib_dawn_utils = buildLibDawnUtils(b, step, options); + const lib_dawn_utils = try buildLibDawnUtils(b, step, options); step.linkLibrary(lib_dawn_utils); - const lib_spirv_tools = buildLibSPIRVTools(b, step, options); + const lib_spirv_tools = try buildLibSPIRVTools(b, step, options); step.linkLibrary(lib_spirv_tools); - const lib_tint = buildLibTint(b, step, options); + const lib_tint = try buildLibTint(b, step, options); step.linkLibrary(lib_tint); return; } @@ -136,16 +139,16 @@ pub fn Sdk(comptime deps: anytype) type { lib_dawn.install(); step.linkLibrary(lib_dawn); - _ = buildLibMachDawnNative(b, lib_dawn, options); - _ = buildLibDawnCommon(b, lib_dawn, options); - _ = buildLibDawnPlatform(b, lib_dawn, options); - _ = buildLibAbseilCpp(b, lib_dawn, options); - _ = buildLibDawnNative(b, lib_dawn, options); - _ = buildLibDawnWire(b, lib_dawn, options); - _ = buildLibDawnUtils(b, lib_dawn, options); - _ = buildLibSPIRVTools(b, lib_dawn, options); - _ = buildLibTint(b, lib_dawn, options); - if (options.d3d12.?) _ = buildLibDxcompiler(b, lib_dawn, options); + _ = try buildLibMachDawnNative(b, lib_dawn, options); + _ = try buildLibDawnCommon(b, lib_dawn, options); + _ = try buildLibDawnPlatform(b, lib_dawn, options); + _ = try buildLibAbseilCpp(b, lib_dawn, options); + _ = try buildLibDawnNative(b, lib_dawn, options); + _ = try buildLibDawnWire(b, lib_dawn, options); + _ = try buildLibDawnUtils(b, lib_dawn, options); + _ = try buildLibSPIRVTools(b, lib_dawn, options); + _ = try buildLibTint(b, lib_dawn, options); + if (options.d3d12.?) _ = try buildLibDxcompiler(b, lib_dawn, options); } fn ensureSubmodules(allocator: std.mem.Allocator) !void { @@ -178,7 +181,7 @@ pub fn Sdk(comptime deps: anytype) type { } } - pub fn linkFromBinary(b: *Builder, step: *std.build.LibExeObjStep, options: Options) void { + pub fn linkFromBinary(b: *Builder, step: *std.build.LibExeObjStep, options: Options) !void { const target = step.target_info.target; const binaries_available = switch (target.os.tag) { .windows => target.abi.isGnu(), @@ -195,7 +198,7 @@ pub fn Sdk(comptime deps: anytype) type { else => false, }; if (!binaries_available) { - const zig_triple = target.zigTriple(b.allocator) catch unreachable; + const zig_triple = try target.zigTriple(b.allocator); defer b.allocator.free(zig_triple); std.log.err("gpu-dawn binaries for {s} not available.", .{zig_triple}); std.log.err("-> open an issue: https://github.com/hexops/mach/issues", .{}); @@ -215,17 +218,17 @@ pub fn Sdk(comptime deps: anytype) type { binary_target.os_version_min = .{ .none = undefined }; binary_target.os_version_max = .{ .none = undefined }; binary_target.glibc_version = null; - const zig_triple = binary_target.zigTriple(b.allocator) catch unreachable; + const zig_triple = try binary_target.zigTriple(b.allocator); defer b.allocator.free(zig_triple); - ensureBinaryDownloaded(b.allocator, zig_triple, options.debug, target.os.tag == .windows, options.binary_version); + try ensureBinaryDownloaded(b.allocator, zig_triple, options.debug, target.os.tag == .windows, options.binary_version); - const base_cache_dir_rel = std.fs.path.join(b.allocator, &.{ "zig-cache", "mach", "gpu-dawn" }) catch unreachable; - std.fs.cwd().makePath(base_cache_dir_rel) catch unreachable; - const base_cache_dir = std.fs.cwd().realpathAlloc(b.allocator, base_cache_dir_rel) catch unreachable; - const commit_cache_dir = std.fs.path.join(b.allocator, &.{ base_cache_dir, options.binary_version }) catch unreachable; + const base_cache_dir_rel = try std.fs.path.join(b.allocator, &.{ "zig-cache", "mach", "gpu-dawn" }); + try std.fs.cwd().makePath(base_cache_dir_rel); + const base_cache_dir = try std.fs.cwd().realpathAlloc(b.allocator, base_cache_dir_rel); + const commit_cache_dir = try std.fs.path.join(b.allocator, &.{ base_cache_dir, options.binary_version }); const release_tag = if (options.debug) "debug" else "release-fast"; - const target_cache_dir = std.fs.path.join(b.allocator, &.{ commit_cache_dir, zig_triple, release_tag }) catch unreachable; - const include_dir = std.fs.path.join(b.allocator, &.{ commit_cache_dir, "include" }) catch unreachable; + const target_cache_dir = try std.fs.path.join(b.allocator, &.{ commit_cache_dir, zig_triple, release_tag }); + const include_dir = try std.fs.path.join(b.allocator, &.{ commit_cache_dir, "include" }); defer { b.allocator.free(base_cache_dir); b.allocator.free(commit_cache_dir); @@ -263,7 +266,7 @@ pub fn Sdk(comptime deps: anytype) type { is_debug: bool, is_windows: bool, version: []const u8, - ) void { + ) !void { // If zig-cache/mach/gpu-dawn/ does not exist: // If on a commit in the main branch => rm -r zig-cache/mach/gpu-dawn/ // else => noop @@ -274,10 +277,10 @@ pub fn Sdk(comptime deps: anytype) type { // Extract to zig-cache/mach/gpu-dawn//macos-aarch64/libgpu.a // Remove zig-cache/mach/gpu-dawn/download - const base_cache_dir_rel = std.fs.path.join(allocator, &.{ "zig-cache", "mach", "gpu-dawn" }) catch unreachable; - std.fs.cwd().makePath(base_cache_dir_rel) catch unreachable; - const base_cache_dir = std.fs.cwd().realpathAlloc(allocator, base_cache_dir_rel) catch unreachable; - const commit_cache_dir = std.fs.path.join(allocator, &.{ base_cache_dir, version }) catch unreachable; + const base_cache_dir_rel = try std.fs.path.join(allocator, &.{ "zig-cache", "mach", "gpu-dawn" }); + try std.fs.cwd().makePath(base_cache_dir_rel); + const base_cache_dir = try std.fs.cwd().realpathAlloc(allocator, base_cache_dir_rel); + const commit_cache_dir = try std.fs.path.join(allocator, &.{ base_cache_dir, version }); defer { allocator.free(base_cache_dir_rel); allocator.free(base_cache_dir); @@ -287,14 +290,14 @@ pub fn Sdk(comptime deps: anytype) type { if (!dirExists(commit_cache_dir)) { // Commit cache dir does not exist. If the commit we're on is in the main branch, we're // probably moving to a newer commit and so we should cleanup older cached binaries. - const current_git_commit = getCurrentGitCommit(allocator) catch unreachable; + const current_git_commit = try getCurrentGitCommit(allocator); if (gitBranchContainsCommit(allocator, "main", current_git_commit) catch false) { std.fs.deleteTreeAbsolute(base_cache_dir) catch {}; } } const release_tag = if (is_debug) "debug" else "release-fast"; - const target_cache_dir = std.fs.path.join(allocator, &.{ commit_cache_dir, zig_triple, release_tag }) catch unreachable; + const target_cache_dir = try std.fs.path.join(allocator, &.{ commit_cache_dir, zig_triple, release_tag }); defer allocator.free(target_cache_dir); if (dirExists(target_cache_dir)) { return; // nothing to do, already have the binary @@ -484,10 +487,9 @@ pub fn Sdk(comptime deps: anytype) type { } fn ensureCanDownloadFiles(allocator: std.mem.Allocator) void { - const argv = &[_][]const u8{ "curl", "--version" }; const result = std.ChildProcess.exec(.{ .allocator = allocator, - .argv = argv, + .argv = &.{ "curl", "--version" }, .cwd = comptime thisDir(), }) catch { // e.g. FileNotFound std.log.err("mach: error: 'curl --version' failed. Is curl not installed?", .{}); @@ -508,7 +510,7 @@ pub fn Sdk(comptime deps: anytype) type { return !tag.isDarwin() and tag != .windows and tag != .fuchsia and tag != .emscripten and !target.isAndroid(); } - fn buildLibMachDawnNative(b: *Builder, step: *std.build.LibExeObjStep, options: Options) *std.build.LibExeObjStep { + fn buildLibMachDawnNative(b: *Builder, step: *std.build.LibExeObjStep, options: Options) !*std.build.LibExeObjStep { const lib = if (!options.separate_libs) step else blk: { const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const separate_lib = b.addStaticLibrary("dawn-native-mach", main_abs); @@ -521,30 +523,30 @@ pub fn Sdk(comptime deps: anytype) type { }; // TODO(build-system): pass system SDK options through - deps.glfw.link(b, lib, .{ .system_sdk = .{ .set_sysroot = false } }); + try deps.glfw.link(b, lib, .{ .system_sdk = .{ .set_sysroot = false } }); var cpp_flags = std.ArrayList([]const u8).init(b.allocator); - options.appendFlags(&cpp_flags, false, true) catch unreachable; - appendDawnEnableBackendTypeFlags(&cpp_flags, options) catch unreachable; - cpp_flags.appendSlice(&.{ + try options.appendFlags(&cpp_flags, false, true); + try appendDawnEnableBackendTypeFlags(&cpp_flags, options); + try cpp_flags.appendSlice(&.{ include(deps.glfw_include_dir), include("libs/dawn/out/Debug/gen/include"), include("libs/dawn/out/Debug/gen/src"), include("libs/dawn/include"), include("libs/dawn/src"), - }) catch unreachable; + }); if (step.target_info.target.os.tag == .windows) { - cpp_flags.appendSlice(&.{ + try cpp_flags.appendSlice(&.{ "-D_DEBUG", "-D_MT", "-D_DLL", - }) catch unreachable; + }); } return lib; } // Builds common sources; derived from src/common/BUILD.gn - fn buildLibDawnCommon(b: *Builder, step: *std.build.LibExeObjStep, options: Options) *std.build.LibExeObjStep { + fn buildLibDawnCommon(b: *Builder, step: *std.build.LibExeObjStep, options: Options) !*std.build.LibExeObjStep { const lib = if (!options.separate_libs) step else blk: { const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const separate_lib = b.addStaticLibrary("dawn-common", main_abs); @@ -557,12 +559,12 @@ pub fn Sdk(comptime deps: anytype) type { }; var flags = std.ArrayList([]const u8).init(b.allocator); - flags.appendSlice(&.{ + try flags.appendSlice(&.{ include("libs/dawn/src"), include("libs/dawn/out/Debug/gen/include"), include("libs/dawn/out/Debug/gen/src"), - }) catch unreachable; - appendLangScannedSources(b, lib, options, .{ + }); + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/src/dawn/common/", "libs/dawn/out/Debug/gen/src/dawn/common/", @@ -574,7 +576,7 @@ pub fn Sdk(comptime deps: anytype) type { "mock", "WindowsUtils.cpp", }, - }) catch unreachable; + }); var cpp_sources = std.ArrayList([]const u8).init(b.allocator); if (step.target_info.target.os.tag == .macos) { @@ -582,22 +584,22 @@ pub fn Sdk(comptime deps: anytype) type { deps.system_sdk.include(b, lib, .{}); lib.linkFramework("Foundation"); const abs_path = comptime thisDir() ++ "/libs/dawn/src/dawn/common/SystemUtils_mac.mm"; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } if (step.target_info.target.os.tag == .windows) { const abs_path = comptime thisDir() ++ "/libs/dawn/src/dawn/common/WindowsUtils.cpp"; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } var cpp_flags = std.ArrayList([]const u8).init(b.allocator); - cpp_flags.appendSlice(flags.items) catch unreachable; - options.appendFlags(&cpp_flags, false, true) catch unreachable; + try cpp_flags.appendSlice(flags.items); + try options.appendFlags(&cpp_flags, false, true); lib.addCSourceFiles(cpp_sources.items, cpp_flags.items); return lib; } // Build dawn platform sources; derived from src/dawn/platform/BUILD.gn - fn buildLibDawnPlatform(b: *Builder, step: *std.build.LibExeObjStep, options: Options) *std.build.LibExeObjStep { + fn buildLibDawnPlatform(b: *Builder, step: *std.build.LibExeObjStep, options: Options) !*std.build.LibExeObjStep { const lib = if (!options.separate_libs) step else blk: { const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const separate_lib = b.addStaticLibrary("dawn-platform", main_abs); @@ -610,13 +612,13 @@ pub fn Sdk(comptime deps: anytype) type { }; var cpp_flags = std.ArrayList([]const u8).init(b.allocator); - options.appendFlags(&cpp_flags, false, true) catch unreachable; - cpp_flags.appendSlice(&.{ + try options.appendFlags(&cpp_flags, false, true); + try cpp_flags.appendSlice(&.{ include("libs/dawn/src"), include("libs/dawn/include"), include("libs/dawn/out/Debug/gen/include"), - }) catch unreachable; + }); var cpp_sources = std.ArrayList([]const u8).init(b.allocator); inline for ([_][]const u8{ @@ -625,7 +627,7 @@ pub fn Sdk(comptime deps: anytype) type { "src/dawn/platform/tracing/EventTracer.cpp", }) |path| { const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } lib.addCSourceFiles(cpp_sources.items, cpp_flags.items); @@ -669,7 +671,7 @@ pub fn Sdk(comptime deps: anytype) type { }; // Builds dawn native sources; derived from src/dawn/native/BUILD.gn - fn buildLibDawnNative(b: *Builder, step: *std.build.LibExeObjStep, options: Options) *std.build.LibExeObjStep { + fn buildLibDawnNative(b: *Builder, step: *std.build.LibExeObjStep, options: Options) !*std.build.LibExeObjStep { const lib = if (!options.separate_libs) step else blk: { const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const separate_lib = b.addStaticLibrary("dawn-native", main_abs); @@ -683,8 +685,8 @@ pub fn Sdk(comptime deps: anytype) type { deps.system_sdk.include(b, lib, .{}); var flags = std.ArrayList([]const u8).init(b.allocator); - appendDawnEnableBackendTypeFlags(&flags, options) catch unreachable; - flags.appendSlice(&.{ + try appendDawnEnableBackendTypeFlags(&flags, options); + try flags.appendSlice(&.{ include("libs/dawn"), include("libs/dawn/src"), include("libs/dawn/include"), @@ -707,10 +709,10 @@ pub fn Sdk(comptime deps: anytype) type { include("libs/dawn/out/Debug/gen/include"), include("libs/dawn/out/Debug/gen/src"), - }) catch unreachable; - if (options.d3d12.?) flags.appendSlice(dawn_d3d12_flags) catch unreachable; + }); + if (options.d3d12.?) try flags.appendSlice(dawn_d3d12_flags); - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/out/Debug/gen/src/dawn/", "libs/dawn/src/dawn/native/", @@ -725,16 +727,16 @@ pub fn Sdk(comptime deps: anytype) type { "SpirvValidation.cpp", "XlibXcbFunctions.cpp", }, - }) catch unreachable; + }); // dawn_native_gen - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/out/Debug/gen/src/dawn/native/", }, .flags = flags.items, .excluding_contains = &.{ "test", "benchmark", "mock" }, - }) catch unreachable; + }); // TODO(build-system): could allow enable_vulkan_validation_layers here. See src/dawn/native/BUILD.gn // TODO(build-system): allow use_angle here. See src/dawn/native/BUILD.gn @@ -749,16 +751,16 @@ pub fn Sdk(comptime deps: anytype) type { "src/dawn/mingw_helpers.cpp", }) |path| { const abs_path = comptime thisDir() ++ "/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/src/dawn/native/d3d12/", }, .flags = flags.items, .excluding_contains = &.{ "test", "benchmark", "mock" }, - }) catch unreachable; + }); } if (options.metal.?) { lib.linkFramework("Metal"); @@ -768,7 +770,7 @@ pub fn Sdk(comptime deps: anytype) type { lib.linkFramework("IOSurface"); lib.linkFramework("QuartzCore"); - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .objc = true, .rel_dirs = &.{ "libs/dawn/src/dawn/native/metal/", @@ -776,7 +778,7 @@ pub fn Sdk(comptime deps: anytype) type { }, .flags = flags.items, .excluding_contains = &.{ "test", "benchmark", "mock" }, - }) catch unreachable; + }); } if (options.linux_window_manager != null and options.linux_window_manager.? == .X11) { @@ -785,7 +787,7 @@ pub fn Sdk(comptime deps: anytype) type { "src/dawn/native/XlibXcbFunctions.cpp", }) |path| { const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } } @@ -793,7 +795,7 @@ pub fn Sdk(comptime deps: anytype) type { "src/dawn/native/null/DeviceNull.cpp", }) |path| { const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } if (options.desktop_gl.? or options.vulkan.?) { @@ -801,29 +803,29 @@ pub fn Sdk(comptime deps: anytype) type { "src/dawn/native/SpirvValidation.cpp", }) |path| { const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } } if (options.desktop_gl.?) { - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/out/Debug/gen/src/dawn/native/opengl/", "libs/dawn/src/dawn/native/opengl/", }, .flags = flags.items, .excluding_contains = &.{ "test", "benchmark", "mock" }, - }) catch unreachable; + }); } if (options.vulkan.?) { - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/src/dawn/native/vulkan/", }, .flags = flags.items, .excluding_contains = &.{ "test", "benchmark", "mock" }, - }) catch unreachable; + }); if (isLinuxDesktopLike(step.target_info.target)) { inline for ([_][]const u8{ @@ -831,7 +833,7 @@ pub fn Sdk(comptime deps: anytype) type { "src/dawn/native/vulkan/external_semaphore/SemaphoreServiceFD.cpp", }) |path| { const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } } else if (step.target_info.target.os.tag == .fuchsia) { inline for ([_][]const u8{ @@ -839,7 +841,7 @@ pub fn Sdk(comptime deps: anytype) type { "src/dawn/native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp", }) |path| { const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } } else { inline for ([_][]const u8{ @@ -847,7 +849,7 @@ pub fn Sdk(comptime deps: anytype) type { "src/dawn/native/vulkan/external_semaphore/SemaphoreServiceNull.cpp", }) |path| { const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } } } @@ -895,7 +897,7 @@ pub fn Sdk(comptime deps: anytype) type { "src/dawn/native/null/NullBackend.cpp", }) |path| { const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } if (options.d3d12.?) { @@ -903,7 +905,7 @@ pub fn Sdk(comptime deps: anytype) type { "src/dawn/native/d3d12/D3D12Backend.cpp", }) |path| { const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } } if (options.desktop_gl.?) { @@ -911,7 +913,7 @@ pub fn Sdk(comptime deps: anytype) type { "src/dawn/native/opengl/OpenGLBackend.cpp", }) |path| { const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } } if (options.vulkan.?) { @@ -919,7 +921,7 @@ pub fn Sdk(comptime deps: anytype) type { "src/dawn/native/vulkan/VulkanBackend.cpp", }) |path| { const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } // TODO(build-system): vulkan // if (enable_vulkan_validation_layers) { @@ -933,14 +935,14 @@ pub fn Sdk(comptime deps: anytype) type { } var cpp_flags = std.ArrayList([]const u8).init(b.allocator); - cpp_flags.appendSlice(flags.items) catch unreachable; - options.appendFlags(&cpp_flags, false, true) catch unreachable; + try cpp_flags.appendSlice(flags.items); + try options.appendFlags(&cpp_flags, false, true); lib.addCSourceFiles(cpp_sources.items, cpp_flags.items); return lib; } // Builds tint sources; derived from src/tint/BUILD.gn - fn buildLibTint(b: *Builder, step: *std.build.LibExeObjStep, options: Options) *std.build.LibExeObjStep { + fn buildLibTint(b: *Builder, step: *std.build.LibExeObjStep, options: Options) !*std.build.LibExeObjStep { const lib = if (!options.separate_libs) step else blk: { const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const separate_lib = b.addStaticLibrary("tint", main_abs); @@ -953,7 +955,7 @@ pub fn Sdk(comptime deps: anytype) type { }; var flags = std.ArrayList([]const u8).init(b.allocator); - flags.appendSlice(&.{ + try flags.appendSlice(&.{ // TODO(build-system): make these optional "-DTINT_BUILD_SPV_READER=1", "-DTINT_BUILD_SPV_WRITER=1", @@ -974,10 +976,10 @@ pub fn Sdk(comptime deps: anytype) type { include("libs/dawn/out/Debug/gen/third_party/vulkan-deps/spirv-tools/src"), include("libs/dawn/out/Debug/gen/third_party/vulkan-deps/spirv-tools/src/include"), include("libs/dawn/include"), - }) catch unreachable; + }); // libtint_core_all_src - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/src/tint", "libs/dawn/src/tint/diagnostic/", @@ -994,101 +996,101 @@ pub fn Sdk(comptime deps: anytype) type { }, .flags = flags.items, .excluding_contains = &.{ "test", "bench", "printer_windows", "printer_linux", "printer_other", "glsl.cc" }, - }) catch unreachable; + }); var cpp_sources = std.ArrayList([]const u8).init(b.allocator); switch (step.target_info.target.os.tag) { - .windows => cpp_sources.append(comptime thisDir() ++ "/libs/dawn/src/tint/diagnostic/printer_windows.cc") catch unreachable, - .linux => cpp_sources.append(comptime thisDir() ++ "/libs/dawn/src/tint/diagnostic/printer_linux.cc") catch unreachable, - else => cpp_sources.append(comptime thisDir() ++ "/libs/dawn/src/tint/diagnostic/printer_other.cc") catch unreachable, + .windows => try cpp_sources.append(comptime thisDir() ++ "/libs/dawn/src/tint/diagnostic/printer_windows.cc"), + .linux => try cpp_sources.append(comptime thisDir() ++ "/libs/dawn/src/tint/diagnostic/printer_linux.cc"), + else => try cpp_sources.append(comptime thisDir() ++ "/libs/dawn/src/tint/diagnostic/printer_other.cc"), } // libtint_sem_src - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/src/tint/sem/", }, .flags = flags.items, .excluding_contains = &.{ "test", "benchmark" }, - }) catch unreachable; + }); // libtint_spv_reader_src - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/src/tint/reader/spirv/", }, .flags = flags.items, .excluding_contains = &.{ "test", "benchmark" }, - }) catch unreachable; + }); // libtint_spv_writer_src - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/src/tint/writer/spirv/", }, .flags = flags.items, .excluding_contains = &.{ "test", "bench" }, - }) catch unreachable; + }); // TODO(build-system): make optional // libtint_wgsl_reader_src - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/src/tint/reader/wgsl/", }, .flags = flags.items, .excluding_contains = &.{ "test", "bench" }, - }) catch unreachable; + }); // TODO(build-system): make optional // libtint_wgsl_writer_src - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/src/tint/writer/wgsl/", }, .flags = flags.items, .excluding_contains = &.{ "test", "bench" }, - }) catch unreachable; + }); // TODO(build-system): make optional // libtint_msl_writer_src - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/src/tint/writer/msl/", }, .flags = flags.items, .excluding_contains = &.{ "test", "bench" }, - }) catch unreachable; + }); // TODO(build-system): make optional // libtint_hlsl_writer_src - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/src/tint/writer/hlsl/", }, .flags = flags.items, .excluding_contains = &.{ "test", "bench" }, - }) catch unreachable; + }); // TODO(build-system): make optional // libtint_glsl_writer_src - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/src/tint/writer/glsl/", }, .flags = flags.items, .excluding_contains = &.{ "test", "bench" }, - }) catch unreachable; + }); var cpp_flags = std.ArrayList([]const u8).init(b.allocator); - cpp_flags.appendSlice(flags.items) catch unreachable; - options.appendFlags(&cpp_flags, false, true) catch unreachable; + try cpp_flags.appendSlice(flags.items); + try options.appendFlags(&cpp_flags, false, true); lib.addCSourceFiles(cpp_sources.items, cpp_flags.items); return lib; } // Builds third_party/vulkan-deps/spirv-tools sources; derived from third_party/vulkan-deps/spirv-tools/src/BUILD.gn - fn buildLibSPIRVTools(b: *Builder, step: *std.build.LibExeObjStep, options: Options) *std.build.LibExeObjStep { + fn buildLibSPIRVTools(b: *Builder, step: *std.build.LibExeObjStep, options: Options) !*std.build.LibExeObjStep { const lib = if (!options.separate_libs) step else blk: { const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const separate_lib = b.addStaticLibrary("spirv-tools", main_abs); @@ -1101,7 +1103,7 @@ pub fn Sdk(comptime deps: anytype) type { }; var flags = std.ArrayList([]const u8).init(b.allocator); - flags.appendSlice(&.{ + try flags.appendSlice(&.{ include("libs/dawn"), include("libs/dawn/third_party/vulkan-deps/spirv-tools/src"), include("libs/dawn/third_party/vulkan-deps/spirv-tools/src/include"), @@ -1109,44 +1111,44 @@ pub fn Sdk(comptime deps: anytype) type { include("libs/dawn/out/Debug/gen/third_party/vulkan-deps/spirv-tools/src"), include("libs/dawn/out/Debug/gen/third_party/vulkan-deps/spirv-tools/src/include"), include("libs/dawn/third_party/vulkan-deps/spirv-headers/src/include/spirv/unified1"), - }) catch unreachable; + }); // spvtools - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/third_party/vulkan-deps/spirv-tools/src/source/", "libs/dawn/third_party/vulkan-deps/spirv-tools/src/source/util/", }, .flags = flags.items, .excluding_contains = &.{ "test", "benchmark" }, - }) catch unreachable; + }); // spvtools_val - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/third_party/vulkan-deps/spirv-tools/src/source/val/", }, .flags = flags.items, .excluding_contains = &.{ "test", "benchmark" }, - }) catch unreachable; + }); // spvtools_opt - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/third_party/vulkan-deps/spirv-tools/src/source/opt/", }, .flags = flags.items, .excluding_contains = &.{ "test", "benchmark" }, - }) catch unreachable; + }); // spvtools_link - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/third_party/vulkan-deps/spirv-tools/src/source/link/", }, .flags = flags.items, .excluding_contains = &.{ "test", "benchmark" }, - }) catch unreachable; + }); return lib; } @@ -1156,7 +1158,7 @@ pub fn Sdk(comptime deps: anytype) type { // $ find third_party/abseil-cpp/absl | grep '\.cc' | grep -v 'test' | grep -v 'benchmark' | grep -v gaussian_distribution_gentables | grep -v print_hash_of | grep -v chi_square // ``` // - fn buildLibAbseilCpp(b: *Builder, step: *std.build.LibExeObjStep, options: Options) *std.build.LibExeObjStep { + fn buildLibAbseilCpp(b: *Builder, step: *std.build.LibExeObjStep, options: Options) !*std.build.LibExeObjStep { const lib = if (!options.separate_libs) step else blk: { const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const separate_lib = b.addStaticLibrary("abseil-cpp-common", main_abs); @@ -1174,21 +1176,21 @@ pub fn Sdk(comptime deps: anytype) type { if (target.os.tag == .windows) lib.linkSystemLibraryName("bcrypt"); var flags = std.ArrayList([]const u8).init(b.allocator); - flags.appendSlice(&.{ + try flags.appendSlice(&.{ include("libs/dawn"), include("libs/dawn/third_party/abseil-cpp"), - }) catch unreachable; - if (target.os.tag == .windows) flags.appendSlice(&.{ + }); + if (target.os.tag == .windows) try flags.appendSlice(&.{ "-DABSL_FORCE_THREAD_IDENTITY_MODE=2", "-DWIN32_LEAN_AND_MEAN", "-DD3D10_ARBITRARY_HEADER_ORDERING", "-D_CRT_SECURE_NO_WARNINGS", "-DNOMINMAX", include("src/dawn/zig_mingw_pthread"), - }) catch unreachable; + }); // absl - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/third_party/abseil-cpp/absl/strings/", "libs/dawn/third_party/abseil-cpp/absl/strings/internal/", @@ -1213,12 +1215,12 @@ pub fn Sdk(comptime deps: anytype) type { }, .flags = flags.items, .excluding_contains = &.{ "_test", "_testing", "benchmark", "print_hash_of.cc", "gaussian_distribution_gentables.cc" }, - }) catch unreachable; + }); return lib; } // Buids dawn wire sources; derived from src/dawn/wire/BUILD.gn - fn buildLibDawnWire(b: *Builder, step: *std.build.LibExeObjStep, options: Options) *std.build.LibExeObjStep { + fn buildLibDawnWire(b: *Builder, step: *std.build.LibExeObjStep, options: Options) !*std.build.LibExeObjStep { const lib = if (!options.separate_libs) step else blk: { const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const separate_lib = b.addStaticLibrary("dawn-wire", main_abs); @@ -1231,15 +1233,15 @@ pub fn Sdk(comptime deps: anytype) type { }; var flags = std.ArrayList([]const u8).init(b.allocator); - flags.appendSlice(&.{ + try flags.appendSlice(&.{ include("libs/dawn"), include("libs/dawn/src"), include("libs/dawn/include"), include("libs/dawn/out/Debug/gen/include"), include("libs/dawn/out/Debug/gen/src"), - }) catch unreachable; + }); - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .rel_dirs = &.{ "libs/dawn/out/Debug/gen/src/dawn/wire/", "libs/dawn/out/Debug/gen/src/dawn/wire/client/", @@ -1250,12 +1252,12 @@ pub fn Sdk(comptime deps: anytype) type { }, .flags = flags.items, .excluding_contains = &.{ "test", "benchmark", "mock" }, - }) catch unreachable; + }); return lib; } // Builds dawn utils sources; derived from src/dawn/utils/BUILD.gn - fn buildLibDawnUtils(b: *Builder, step: *std.build.LibExeObjStep, options: Options) *std.build.LibExeObjStep { + fn buildLibDawnUtils(b: *Builder, step: *std.build.LibExeObjStep, options: Options) !*std.build.LibExeObjStep { const lib = if (!options.separate_libs) step else blk: { const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const separate_lib = b.addStaticLibrary("dawn-utils", main_abs); @@ -1266,16 +1268,16 @@ pub fn Sdk(comptime deps: anytype) type { separate_lib.install(); break :blk separate_lib; }; - deps.glfw.link(b, lib, .{ .system_sdk = .{ .set_sysroot = false } }); + try deps.glfw.link(b, lib, .{ .system_sdk = .{ .set_sysroot = false } }); var flags = std.ArrayList([]const u8).init(b.allocator); - appendDawnEnableBackendTypeFlags(&flags, options) catch unreachable; - flags.appendSlice(&.{ + try appendDawnEnableBackendTypeFlags(&flags, options); + try flags.appendSlice(&.{ include(deps.glfw_include_dir), include("libs/dawn/src"), include("libs/dawn/include"), include("libs/dawn/out/Debug/gen/include"), - }) catch unreachable; + }); var cpp_sources = std.ArrayList([]const u8).init(b.allocator); inline for ([_][]const u8{ @@ -1283,7 +1285,7 @@ pub fn Sdk(comptime deps: anytype) type { "src/dawn/utils/NullBinding.cpp", }) |path| { const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } if (options.d3d12.?) { @@ -1291,16 +1293,16 @@ pub fn Sdk(comptime deps: anytype) type { "src/dawn/utils/D3D12Binding.cpp", }) |path| { const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } - flags.appendSlice(dawn_d3d12_flags) catch unreachable; + try flags.appendSlice(dawn_d3d12_flags); } if (options.metal.?) { inline for ([_][]const u8{ "src/dawn/utils/MetalBinding.mm", }) |path| { const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } } @@ -1309,7 +1311,7 @@ pub fn Sdk(comptime deps: anytype) type { "src/dawn/utils/OpenGLBinding.cpp", }) |path| { const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } } @@ -1318,19 +1320,19 @@ pub fn Sdk(comptime deps: anytype) type { "src/dawn/utils/VulkanBinding.cpp", }) |path| { const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; - cpp_sources.append(abs_path) catch unreachable; + try cpp_sources.append(abs_path); } } var cpp_flags = std.ArrayList([]const u8).init(b.allocator); - cpp_flags.appendSlice(flags.items) catch unreachable; - options.appendFlags(&cpp_flags, false, true) catch unreachable; + try cpp_flags.appendSlice(flags.items); + try options.appendFlags(&cpp_flags, false, true); lib.addCSourceFiles(cpp_sources.items, cpp_flags.items); return lib; } // Buids dxcompiler sources; derived from libs/DirectXShaderCompiler/CMakeLists.txt - fn buildLibDxcompiler(b: *Builder, step: *std.build.LibExeObjStep, options: Options) *std.build.LibExeObjStep { + fn buildLibDxcompiler(b: *Builder, step: *std.build.LibExeObjStep, options: Options) !*std.build.LibExeObjStep { const lib = if (!options.separate_libs) step else blk: { const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const separate_lib = b.addStaticLibrary("dxcompiler", main_abs); @@ -1350,7 +1352,7 @@ pub fn Sdk(comptime deps: anytype) type { lib.linkLibCpp(); var flags = std.ArrayList([]const u8).init(b.allocator); - flags.appendSlice(&.{ + try flags.appendSlice(&.{ include("libs/"), include("libs/DirectXShaderCompiler/include/llvm/llvm_assert"), include("libs/DirectXShaderCompiler/include"), @@ -1368,9 +1370,9 @@ pub fn Sdk(comptime deps: anytype) type { "-DHAVE_LIBPSAPI=1", "-DHAVE_LIBSHELL32=1", "-DLLVM_ON_WIN32=1", - }) catch unreachable; + }); - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .zero_debug_symbols = true, .rel_dirs = &.{ "libs/DirectXShaderCompiler/lib/Analysis/IPA", @@ -1401,9 +1403,9 @@ pub fn Sdk(comptime deps: anytype) type { "libs/DirectXShaderCompiler/lib/Transforms/Vectorize", }, .flags = flags.items, - }) catch unreachable; + }); - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .zero_debug_symbols = true, .rel_dirs = &.{ "libs/DirectXShaderCompiler/lib/Support", @@ -1415,9 +1417,9 @@ pub fn Sdk(comptime deps: anytype) type { "Path.cpp", // ignore, LLVM_INCLUDE_TESTS "DynamicLibrary.cpp", // ignore }, - }) catch unreachable; + }); - appendLangScannedSources(b, lib, options, .{ + try appendLangScannedSources(b, lib, options, .{ .zero_debug_symbols = true, .rel_dirs = &.{ "libs/DirectXShaderCompiler/lib/Bitcode/Reader", @@ -1426,7 +1428,7 @@ pub fn Sdk(comptime deps: anytype) type { .excluding_contains = &.{ "BitReader.cpp", // ignore }, - }) catch unreachable; + }); return lib; } @@ -1453,7 +1455,7 @@ pub fn Sdk(comptime deps: anytype) type { ) !void { var cpp_flags = std.ArrayList([]const u8).init(b.allocator); try cpp_flags.appendSlice(args.flags); - options.appendFlags(&cpp_flags, args.zero_debug_symbols, true) catch unreachable; + try options.appendFlags(&cpp_flags, args.zero_debug_symbols, true); const cpp_extensions: []const []const u8 = if (args.objc) &.{".mm"} else &.{ ".cpp", ".cc" }; try appendScannedSources(b, step, .{ .flags = cpp_flags.items, @@ -1465,7 +1467,7 @@ pub fn Sdk(comptime deps: anytype) type { var flags = std.ArrayList([]const u8).init(b.allocator); try flags.appendSlice(args.flags); - options.appendFlags(&flags, args.zero_debug_symbols, false) catch unreachable; + try options.appendFlags(&flags, args.zero_debug_symbols, false); const c_extensions: []const []const u8 = if (args.objc) &.{".m"} else &.{".c"}; try appendScannedSources(b, step, .{ .flags = flags.items, diff --git a/libs/gpu/build.zig b/libs/gpu/build.zig index ac46c457..41034166 100644 --- a/libs/gpu/build.zig +++ b/libs/gpu/build.zig @@ -4,7 +4,7 @@ const gpu_dawn_sdk = @import("libs/mach-gpu-dawn/sdk.zig"); const gpu_sdk = @import("sdk.zig"); const system_sdk = @import("libs/mach-glfw/system_sdk.zig"); -pub fn build(b: *std.build.Builder) void { +pub fn build(b: *std.build.Builder) !void { const mode = b.standardReleaseOptions(); const target = b.standardTargetOptions(.{}); const gpu_dawn = gpu_dawn_sdk.Sdk(.{ @@ -23,14 +23,14 @@ pub fn build(b: *std.build.Builder) void { }; const test_step = b.step("test", "Run library tests"); - test_step.dependOn(&gpu.testStep(b, mode, target, .{ .gpu_dawn_options = gpu_dawn_options }).step); + test_step.dependOn(&(try gpu.testStep(b, mode, target, .{ .gpu_dawn_options = gpu_dawn_options })).step); const example = b.addExecutable("gpu-hello-triangle", "examples/main.zig"); example.setBuildMode(mode); example.setTarget(target); example.addPackage(gpu.pkg); example.addPackage(glfw.pkg); - gpu.link(b, example, .{ .gpu_dawn_options = gpu_dawn_options }); + try gpu.link(b, example, .{ .gpu_dawn_options = gpu_dawn_options }); example.install(); const example_run_cmd = example.run(); diff --git a/libs/gpu/sdk.zig b/libs/gpu/sdk.zig index 660d6cd8..e906a5c4 100644 --- a/libs/gpu/sdk.zig +++ b/libs/gpu/sdk.zig @@ -2,11 +2,11 @@ const std = @import("std"); pub fn Sdk(comptime deps: anytype) type { return struct { - pub fn testStep(b: *std.build.Builder, mode: std.builtin.Mode, target: std.zig.CrossTarget, options: Options) *std.build.RunStep { + pub fn testStep(b: *std.build.Builder, mode: std.builtin.Mode, target: std.zig.CrossTarget, options: Options) !*std.build.RunStep { const main_tests = b.addTestExe("gpu-tests", (comptime thisDir()) ++ "/src/main.zig"); main_tests.setBuildMode(mode); main_tests.setTarget(target); - link(b, main_tests, options); + try link(b, main_tests, options); main_tests.install(); return main_tests.run(); } @@ -22,10 +22,10 @@ pub fn Sdk(comptime deps: anytype) type { .dependencies = &.{deps.glfw.pkg}, }; - pub fn link(b: *std.build.Builder, step: *std.build.LibExeObjStep, options: Options) void { + pub fn link(b: *std.build.Builder, step: *std.build.LibExeObjStep, options: Options) !void { if (step.target.toTarget().cpu.arch != .wasm32) { - deps.glfw.link(b, step, options.glfw_options); - deps.gpu_dawn.link(b, step, options.gpu_dawn_options); + try deps.glfw.link(b, step, options.glfw_options); + try deps.gpu_dawn.link(b, step, options.gpu_dawn_options); step.addCSourceFile((comptime thisDir()) ++ "/src/mach_dawn.cpp", &.{"-std=c++17"}); step.addIncludePath((comptime thisDir()) ++ "/src"); } diff --git a/tools/wasmserve/wasmserve.zig b/tools/wasmserve/wasmserve.zig index b35f75a2..0f236aeb 100644 --- a/tools/wasmserve/wasmserve.zig +++ b/tools/wasmserve/wasmserve.zig @@ -24,16 +24,20 @@ pub const Options = struct { listen_address: ?net.Address = null, }; -pub fn serve(step: *build.LibExeObjStep, options: Options) !*Wasmserve { - const self = step.builder.allocator.create(Wasmserve) catch unreachable; +pub const Error = error{CannotOpenDirectory} || mem.Allocator.Error; + +pub fn serve(step: *build.LibExeObjStep, options: Options) Error!*Wasmserve { + const self = try step.builder.allocator.create(Wasmserve); const install_dir = options.install_dir orelse build.InstallDir{ .lib = {} }; + const install_dir_iter = fs.cwd().makeOpenPathIterable(step.builder.getInstallPath(install_dir, ""), .{}) catch + return error.CannotOpenDirectory; self.* = Wasmserve{ .step = build.Step.init(.run, "wasmserve", step.builder.allocator, Wasmserve.make), .b = step.builder, .exe_step = step, .install_step_name = options.install_step_name orelse step.builder.getInstallStep().name, .install_dir = install_dir, - .install_dir_iter = try fs.cwd().makeOpenPathIterable(step.builder.getInstallPath(install_dir, ""), .{}), + .install_dir_iter = install_dir_iter, .address = options.listen_address orelse net.Address.initIp4([4]u8{ 127, 0, 0, 1 }, 8080), .subscriber = null, .watch_paths = options.watch_paths orelse &.{"src"},