all: build: organize build files and reduce unreachables (#567)

This commit is contained in:
Ali Chraghi 2022-09-25 20:32:51 +03:30 committed by GitHub
parent cc301493ca
commit fcb82345d4
Failed to generate hash of commit
10 changed files with 434 additions and 419 deletions

337
build.zig
View file

@ -1,32 +1,50 @@
const std = @import("std"); const std = @import("std");
const builtin = @import("builtin"); 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 system_sdk = @import("libs/glfw/system_sdk.zig");
const sysaudio_sdk = @import("libs/sysaudio/sdk.zig");
const glfw = @import("libs/glfw/build.zig"); const glfw = @import("libs/glfw/build.zig");
const ecs = @import("libs/ecs/build.zig"); const ecs = @import("libs/ecs/build.zig");
const freetype = @import("libs/freetype/build.zig"); const freetype = @import("libs/freetype/build.zig");
const basisu = @import("libs/basisu/build.zig"); const basisu = @import("libs/basisu/build.zig");
const sysjs = @import("libs/sysjs/build.zig"); const sysjs = @import("libs/sysjs/build.zig");
const gamemode = @import("libs/gamemode/build.zig"); const gamemode = @import("libs/gamemode/build.zig");
const Pkg = std.build.Pkg; const wasmserve = @import("tools/wasmserve/wasmserve.zig");
const gpu_dawn = @import("libs/gpu-dawn/sdk.zig").Sdk(.{
const gpu_dawn = gpu_dawn_sdk.Sdk(.{
.glfw = glfw, .glfw = glfw,
.glfw_include_dir = "glfw/upstream/glfw/include", .glfw_include_dir = "glfw/upstream/glfw/include",
.system_sdk = system_sdk, .system_sdk = system_sdk,
}); });
const gpu = gpu_sdk.Sdk(.{ const gpu = @import("libs/gpu/sdk.zig").Sdk(.{
.glfw = glfw, .glfw = glfw,
.gpu_dawn = gpu_dawn, .gpu_dawn = gpu_dawn,
}); });
const sysaudio = sysaudio_sdk.Sdk(.{ const sysaudio = @import("libs/sysaudio/sdk.zig").Sdk(.{
.system_sdk = system_sdk, .system_sdk = system_sdk,
.sysjs = sysjs, .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 mode = b.standardReleaseOptions();
const target = b.standardTargetOptions(.{}); 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 sysaudio_test_step = b.step("test-sysaudio", "Run sysaudio library tests");
const mach_test_step = b.step("test-mach", "Run Mach Core 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); glfw_test_step.dependOn(&(try glfw.testStep(b, mode, target)).step);
gpu_test_step.dependOn(&gpu.testStep(b, mode, target, options.gpuOptions()).step); gpu_test_step.dependOn(&(try gpu.testStep(b, mode, target, options.gpuOptions())).step);
freetype_test_step.dependOn(&freetype.testStep(b, mode, target).step); freetype_test_step.dependOn(&freetype.testStep(b, mode, target).step);
// TODO(self-hosted) uncomment this // TODO(self-hosted) uncomment this
// ecs_test_step.dependOn(&ecs.testStep(b, mode, target).step); // 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); sysaudio_test_step.dependOn(&sysaudio.testStep(b, mode, target).step);
mach_test_step.dependOn(&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); all_tests_step.dependOn(gpu_test_step);
// TODO(self-hosted) uncomment this // TODO(self-hosted) uncomment this
// all_tests_step.dependOn(ecs_test_step); // 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(freetype_test_step);
all_tests_step.dependOn(sysaudio_test_step); all_tests_step.dependOn(sysaudio_test_step);
all_tests_step.dependOn(mach_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, b,
.{ .{
.name = "shaderexp", .name = "shaderexp",
@ -76,106 +97,81 @@ pub fn build(b: *std.build.Builder) void {
}, },
); );
shaderexp_app.setBuildMode(mode); shaderexp_app.setBuildMode(mode);
shaderexp_app.link(options); try shaderexp_app.link(options);
shaderexp_app.install(); shaderexp_app.install();
const shaderexp_compile_step = b.step("shaderexp", "Compile shaderexp"); const shaderexp_compile_step = b.step("shaderexp", "Compile shaderexp");
shaderexp_compile_step.dependOn(&shaderexp_app.getInstallStep().?.step); 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); shaderexp_run_cmd.dependOn(&shaderexp_app.getInstallStep().?.step);
const shaderexp_run_step = b.step("run-shaderexp", "Run shaderexp"); const shaderexp_run_step = b.step("run-shaderexp", "Run shaderexp");
shaderexp_run_step.dependOn(shaderexp_run_cmd); shaderexp_run_step.dependOn(shaderexp_run_cmd);
// compiles the `libmach` shared library // Compiles the `libmach` shared library
const lib = b.addSharedLibrary("mach", "src/platform/libmach.zig", .unversioned); const shared_lib = try buildSharedLib(b, mode, target, options);
lib.setTarget(target); shared_lib.install();
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();
} }
// TODO: we need a way to test wasm stuff try ensureExamplesDependencySubmodules(b.allocator);
// const sysjs_test_step = b.step( "test-sysjs", "Run sysjs library tests"); inline for ([_]struct {
// sysjs_test_step.dependOn(&sysjs.testStep(b, mode, target).step); name: []const u8,
// all_tests_step.dependOn(sysjs_test_step); deps: []const Pkg = &.{},
std_platform_only: bool = false,
// TODO(build-system): https://github.com/hexops/mach/issues/229#issuecomment-1100958939 has_assets: bool = false,
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{
.{ .name = "triangle" }, .{ .name = "triangle" },
.{ .name = "triangle-msaa" }, .{ .name = "triangle-msaa" },
.{ .name = "boids" }, .{ .name = "boids" },
.{ .name = "rotating-cube", .packages = &[_]Pkg{Packages.zmath} }, .{ .name = "rotating-cube", .deps = &.{Packages.zmath} },
.{ .name = "pixel-post-process", .packages = &[_]Pkg{Packages.zmath} }, .{ .name = "pixel-post-process", .deps = &.{Packages.zmath} },
.{ .name = "two-cubes", .packages = &[_]Pkg{Packages.zmath} }, .{ .name = "two-cubes", .deps = &.{Packages.zmath} },
.{ .name = "instanced-cube", .packages = &[_]Pkg{Packages.zmath} }, .{ .name = "instanced-cube", .deps = &.{Packages.zmath} },
.{ .name = "advanced-gen-texture-light", .packages = &[_]Pkg{Packages.zmath} }, .{ .name = "advanced-gen-texture-light", .deps = &.{Packages.zmath} },
.{ .name = "fractal-cube", .packages = &[_]Pkg{Packages.zmath} }, .{ .name = "fractal-cube", .deps = &.{Packages.zmath} },
.{ .name = "textured-cube", .packages = &[_]Pkg{ Packages.zmath, Packages.zigimg }, .has_assets = true }, .{ .name = "textured-cube", .deps = &.{ Packages.zmath, Packages.zigimg }, .has_assets = true },
// TODO(self-hosted) uncomment this // TODO(self-hosted) uncomment this
// .{ .name = "ecs-app", .packages = &[_]Pkg{} }, // .{ .name = "ecs-app", .deps = &.{} },
.{ .name = "image-blur", .packages = &[_]Pkg{Packages.zigimg}, .has_assets = true }, .{ .name = "image-blur", .deps = &.{Packages.zigimg}, .has_assets = true },
.{ .name = "cubemap", .packages = &[_]Pkg{ Packages.zmath, Packages.zigimg }, .has_assets = true }, .{ .name = "cubemap", .deps = &.{ Packages.zmath, Packages.zigimg }, .has_assets = true },
.{ .name = "map-async", .packages = &[_]Pkg{} }, .{ .name = "map-async", .deps = &.{} },
.{ .name = "sysaudio", .packages = &[_]Pkg{} }, .{ .name = "sysaudio", .deps = &.{} },
// NOTE: examples with std_platform_only should be placed at last .{ .name = "gkurve", .deps = &.{ Packages.zmath, Packages.zigimg, freetype.pkg }, .std_platform_only = true, .has_assets = true },
.{ .name = "gkurve", .packages = &[_]Pkg{ Packages.zmath, Packages.zigimg, freetype.pkg }, .std_platform_only = true, .has_assets = true },
}) |example| { }) |example| {
// FIXME: this is workaround for a problem that some examples (having the std_platform_only=true field) as // FIXME: this is workaround for a problem that some examples
// well as zigimg uses IO which is not supported in freestanding environments. So break out of this loop // (having the std_platform_only=true field) as well as zigimg
// as soon as any such examples is found. This does means that any example which works on wasm should be // 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. // placed before those who dont.
if (example.std_platform_only) if (example.std_platform_only)
if (target.toTarget().cpu.arch == .wasm32) if (target.getCpuArch() == .wasm32)
break; break;
const example_app = App.init( const example_app = try App.init(
b, b,
.{ .{
.name = "example-" ++ example.name, .name = "example-" ++ example.name,
.src = "examples/" ++ example.name ++ "/main.zig", .src = "examples/" ++ example.name ++ "/main.zig",
.target = target, .target = target,
.deps = example.packages, .deps = example.deps,
.res_dirs = if (example.has_assets) &.{"examples/" ++ example.name ++ "/assets"} else null, .res_dirs = if (example.has_assets) &.{"examples/" ++ example.name ++ "/assets"} else null,
.watch_paths = &.{"examples/" ++ example.name}, .watch_paths = &.{"examples/" ++ example.name},
}, },
); );
example_app.setBuildMode(mode); example_app.setBuildMode(mode);
inline for (example.packages) |p| { inline for (example.deps) |p| {
if (std.mem.eql(u8, p.name, freetype.pkg.name)) if (std.mem.eql(u8, p.name, freetype.pkg.name))
freetype.link(example_app.b, example_app.step, .{}); freetype.link(example_app.b, example_app.step, .{});
} }
try example_app.link(options);
example_app.link(options);
example_app.install(); example_app.install();
const example_compile_step = b.step("example-" ++ example.name, "Compile '" ++ example.name ++ "' example"); const example_compile_step = b.step("example-" ++ example.name, "Compile '" ++ example.name ++ "' example");
example_compile_step.dependOn(&example_app.getInstallStep().?.step); example_compile_step.dependOn(&example_app.getInstallStep().?.step);
const example_run_cmd = example_app.run(); const example_run_cmd = try example_app.run();
example_run_cmd.dependOn(&example_app.getInstallStep().?.step); example_run_cmd.dependOn(example_compile_step);
const example_run_step = b.step("run-example-" ++ example.name, "Run '" ++ example.name ++ "' example"); const example_run_step = b.step("run-example-" ++ example.name, "Run '" ++ example.name ++ "' example");
example_run_step.dependOn(example_run_cmd); example_run_step.dependOn(example_run_cmd);
} }
@ -184,7 +180,19 @@ pub fn build(b: *std.build.Builder) void {
compile_all.dependOn(b.getInstallStep()); 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"); const main_tests = b.addTestExe("mach-tests", "src/main.zig");
main_tests.setBuildMode(mode); main_tests.setBuildMode(mode);
main_tests.setTarget(target); 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(); return main_tests.run();
} }
pub const Options = struct { fn buildSharedLib(b: *Builder, mode: std.builtin.Mode, target: CrossTarget, options: Options) !*std.build.LibExeObjStep {
glfw_options: glfw.Options = .{}, const lib = b.addSharedLibrary("mach", "src/platform/libmach.zig", .unversioned);
gpu_dawn_options: gpu_dawn.Options = .{}, lib.setTarget(target);
sysaudio_options: sysaudio.Options = .{}, lib.setBuildMode(mode);
lib.main_pkg_path = "src/";
pub fn gpuOptions(options: Options) gpu.Options { const app_pkg = Pkg{
return .{ .name = "app",
.glfw_options = options.glfw_options, .source = .{ .path = "src/platform/libmach.zig" },
.gpu_dawn_options = options.gpu_dawn_options, };
}; 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);
} }
}; try glfw.link(b, lib, options.glfw_options);
try gpu.link(b, lib, options.gpuOptions());
const ExampleDefinition = struct { lib.setOutputDir("libmach/build");
name: []const u8, return lib;
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" },
};
};
const web_install_dir = std.build.InstallDir{ .custom = "www" }; const web_install_dir = std.build.InstallDir{ .custom = "www" };
pub const App = struct { pub const App = struct {
b: *std.build.Builder, b: *Builder,
name: []const u8, name: []const u8,
step: *std.build.LibExeObjStep, step: *std.build.LibExeObjStep,
platform: Platform, platform: Platform,
res_dirs: ?[]const []const u8, res_dirs: ?[]const []const u8,
watch_paths: ?[]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 { pub const Platform = enum {
native, native,
web, 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, name: []const u8,
src: []const u8, src: []const u8,
target: std.zig.CrossTarget, target: CrossTarget,
deps: ?[]const Pkg = null, deps: ?[]const Pkg = null,
res_dirs: ?[]const []const u8 = null, res_dirs: ?[]const []const u8 = null,
watch_paths: ?[]const []const u8 = null, watch_paths: ?[]const []const u8 = null,
}) App { }) InitError!App {
const target = (std.zig.system.NativeTargetInfo.detect(options.target) catch unreachable).target; const target = (try std.zig.system.NativeTargetInfo.detect(options.target)).target;
const platform = Platform.fromTarget(target); const platform = Platform.fromTarget(target);
var deps = std.ArrayList(std.build.Pkg).init(b.allocator); var deps = std.ArrayList(Pkg).init(b.allocator);
deps.append(pkg) catch unreachable; try deps.append(pkg);
deps.append(gpu.pkg) catch unreachable; try deps.append(gpu.pkg);
deps.append(sysaudio.pkg) catch unreachable; try deps.append(sysaudio.pkg);
switch (platform) { switch (platform) {
.native => deps.append(glfw.pkg) catch unreachable, .native => try deps.append(glfw.pkg),
.web => deps.append(sysjs.pkg) catch unreachable, .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", .name = "app",
.source = .{ .path = options.src }, .source = .{ .path = options.src },
.dependencies = deps.toOwnedSlice(), .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 { pub fn install(app: *const App) void {
app.step.install(); app.step.install();
@ -356,14 +371,28 @@ pub const App = struct {
} }
} }
pub fn link(app: *const App, options: Options) void { pub fn run(app: *const App) RunError!*std.build.Step {
if (app.platform != .web) { if (app.platform == .web) {
glfw.link(app.b, app.step, options.glfw_options); const address = std.process.getEnvVarOwned(app.b.allocator, "MACH_ADDRESS") catch try app.b.allocator.dupe(u8, "127.0.0.1");
gpu.link(app.b, app.step, options.gpuOptions()); const port = std.process.getEnvVarOwned(app.b.allocator, "MACH_PORT") catch try app.b.allocator.dupe(u8, "8080");
if (app.step.target.isLinux()) const address_parsed = std.net.Address.parseIp4(address, try std.fmt.parseInt(u16, port, 10)) catch return error.ParsingIpFailed;
gamemode.link(app.step); 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 { 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 { pub fn getInstallStep(app: *const App) ?*std.build.InstallArtifactStep {
return app.step.install_step; 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{ fn ensureExamplesDependencySubmodules(allocator: std.mem.Allocator) !void {
.name = "mach", // TODO(build-system): https://github.com/hexops/mach/issues/229#issuecomment-1100958939
.source = .{ .path = thisDir() ++ "/src/main.zig" }, ensureGit(allocator);
.dependencies = &.{ gpu.pkg, ecs.pkg, sysaudio.pkg }, try ensureDependencySubmodule(allocator, "examples/libs/zmath");
}; try ensureDependencySubmodule(allocator, "examples/libs/zigimg");
try ensureDependencySubmodule(allocator, "examples/gkurve/assets");
fn thisDir() []const u8 { try ensureDependencySubmodule(allocator, "examples/image-blur/assets");
return std.fs.path.dirname(@src().file) orelse "."; try ensureDependencySubmodule(allocator, "examples/textured-cube/assets");
try ensureDependencySubmodule(allocator, "examples/cubemap/assets");
} }
fn ensureDependencySubmodule(allocator: std.mem.Allocator, path: []const u8) !void { 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 { fn ensureGit(allocator: std.mem.Allocator) void {
const argv = &[_][]const u8{ "git", "--version" };
const result = std.ChildProcess.exec(.{ const result = std.ChildProcess.exec(.{
.allocator = allocator, .allocator = allocator,
.argv = argv, .argv = &.{ "git", "--version" },
.cwd = ".",
}) catch { // e.g. FileNotFound }) catch { // e.g. FileNotFound
std.log.err("mach: error: 'git --version' failed. Is git not installed?", .{}); std.log.err("mach: error: 'git --version' failed. Is git not installed?", .{});
std.process.exit(1); std.process.exit(1);
@ -442,3 +445,7 @@ fn ensureGit(allocator: std.mem.Allocator) void {
std.process.exit(1); std.process.exit(1);
} }
} }
fn thisDir() []const u8 {
return std.fs.path.dirname(@src().file) orelse ".";
}

View file

@ -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 { pub fn build(b: *Builder) void {
const mode = b.standardReleaseOptions(); const mode = b.standardReleaseOptions();
const target = b.standardTargetOptions(.{}); const target = b.standardTargetOptions(.{});
@ -82,19 +95,6 @@ pub fn buildTranscoder(b: *Builder, target: std.zig.CrossTarget, options: Transc
return transcoder; 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 { fn thisDir() []const u8 {
return std.fs.path.dirname(@src().file) orelse "."; return std.fs.path.dirname(@src().file) orelse ".";
} }

View file

@ -1,5 +1,11 @@
const std = @import("std"); 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 { pub fn build(b: *std.build.Builder) void {
const mode = b.standardReleaseOptions(); const mode = b.standardReleaseOptions();
const target = b.standardTargetOptions(.{}); 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(); 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 { fn thisDir() []const u8 {
return std.fs.path.dirname(@src().file) orelse "."; return std.fs.path.dirname(@src().file) orelse ".";
} }

View file

@ -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: 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. - 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. - `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. - 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)` - **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. - 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. - [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, ...)` - Methods, e.g. `my_window.hint(...)` instead of `glfwWindowHint(my_window, ...)`
## How do I use OpenGL, Vulkan, WebGPU, etc. with this? ## How do I use OpenGL, Vulkan, WebGPU, etc. with this?
You'll need to bring your own library for this. Some are: 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) - (Vulkan) https://github.com/Snektron/vulkan-zig (also see https://github.com/Avokadoen/zig_vulkan)
* (OpenGL) https://github.com/ziglibs/zgl - (OpenGL) https://github.com/ziglibs/zgl
## Examples ## Examples
@ -57,10 +57,10 @@ Then in your `build.zig` add:
... ...
const glfw = @import("libs/mach-glfw/build.zig"); const glfw = @import("libs/mach-glfw/build.zig");
pub fn build(b: *Builder) void { pub fn build(b: *Builder) !void {
... ...
exe.addPackage(glfw.pkg); 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 pkgs = @import("deps.zig").pkgs;
const glfw = @import("build-glfw"); const glfw = @import("build-glfw");
pub fn build(b: *Builder) void { pub fn build(b: *Builder) !void {
... ...
exe.addPackage(pkgs.glfw); 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: Here is a rough list of functionality Wayland does not support:
* `Window.setIcon` - `Window.setIcon`
* `Window.setPos`, `Window.getPos` - `Window.setPos`, `Window.getPos`
* `Window.iconify`, `Window.focus` - `Window.iconify`, `Window.focus`
* `Monitor.setGamma` - `Monitor.setGamma`
* `Monitor.getGammaRamp`, `Monitor.setGammaRamp` - `Monitor.getGammaRamp`, `Monitor.setGammaRamp`
## Join the community ## Join the community

View file

@ -13,20 +13,20 @@ pub fn build(b: *Builder) void {
test_step.dependOn(&testStepShared(b, mode, target).step); 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"); const main_tests = b.addTestExe("glfw-tests", thisDir() ++ "/src/main.zig");
main_tests.setBuildMode(mode); main_tests.setBuildMode(mode);
main_tests.setTarget(target); main_tests.setTarget(target);
link(b, main_tests, .{}); try link(b, main_tests, .{});
main_tests.install(); main_tests.install();
return main_tests.run(); 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"); const main_tests = b.addTestExe("glfw-tests-shared", thisDir() ++ "/src/main.zig");
main_tests.setBuildMode(mode); main_tests.setBuildMode(mode);
main_tests.setTarget(target); main_tests.setTarget(target);
link(b, main_tests, .{ .shared = true }); try link(b, main_tests, .{ .shared = true });
main_tests.install(); main_tests.install();
return main_tests.run(); 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; 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(); 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); step.linkLibrary(lib);
addGLFWIncludes(step); addGLFWIncludes(step);
if (options.shared) { 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 // 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) const lib = if (options.shared)
b.addSharedLibrary("glfw", null, .unversioned) 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); lib.defineCMacro("_GLFW_BUILD_DLL", null);
addGLFWIncludes(lib); addGLFWIncludes(lib);
addGLFWSources(b, lib, options); try addGLFWSources(b, lib, options);
linkGLFWDependencies(b, lib, options); linkGLFWDependencies(b, lib, options);
if (options.install_libs) if (options.install_libs)
@ -122,7 +124,7 @@ fn addGLFWIncludes(step: *std.build.LibExeObjStep) void {
step.addIncludePath(thisDir() ++ "/upstream/vulkan_headers/include"); 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"; const include_glfw_src = "-I" ++ thisDir() ++ "/upstream/glfw/src";
switch (lib.target_info.target.os.tag) { switch (lib.target_info.target.os.tag) {
.windows => lib.addCSourceFiles(&.{ .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 sources = std.ArrayList([]const u8).init(b.allocator);
var flags = 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; try sources.append(thisDir() ++ "/src/sources_all.c");
sources.append(thisDir() ++ "/src/sources_linux.c") catch unreachable; try sources.append(thisDir() ++ "/src/sources_linux.c");
if (options.x11) { if (options.x11) {
sources.append(thisDir() ++ "/src/sources_linux_x11.c") catch unreachable; try sources.append(thisDir() ++ "/src/sources_linux_x11.c");
flags.append("-D_GLFW_X11") catch unreachable; try flags.append("-D_GLFW_X11");
} }
if (options.wayland) { if (options.wayland) {
sources.append(thisDir() ++ "/src/sources_linux_wayland.c") catch unreachable; try sources.append(thisDir() ++ "/src/sources_linux_wayland.c");
flags.append("-D_GLFW_WAYLAND") catch unreachable; 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 // 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); 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 { fn linkGLFWDependencies(b: *Builder, step: *std.build.LibExeObjStep, options: Options) void {
step.linkLibC(); step.linkLibC();
system_sdk.include(b, step, options.system_sdk); 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 ".";
}

View file

@ -4,7 +4,7 @@ const glfw = @import("libs/mach-glfw/build.zig");
const system_sdk = @import("libs/mach-glfw/system_sdk.zig"); const system_sdk = @import("libs/mach-glfw/system_sdk.zig");
const gpu_dawn_sdk = @import("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 mode = b.standardReleaseOptions();
const target = b.standardTargetOptions(.{}); const target = b.standardTargetOptions(.{});
const gpu_dawn = gpu_dawn_sdk.Sdk(.{ 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"); const example = b.addExecutable("dawn-example", "src/main.zig");
example.setBuildMode(mode); example.setBuildMode(mode);
example.setTarget(target); example.setTarget(target);
gpu_dawn.link(b, example, options); try gpu_dawn.link(b, example, options);
glfw.link(b, example, .{ .system_sdk = .{ .set_sysroot = false } }); try glfw.link(b, example, .{ .system_sdk = .{ .set_sysroot = false } });
example.addPackage(glfw.pkg); example.addPackage(glfw.pkg);
example.install(); example.install();
} }

View file

@ -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); 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 { fn linkFromSource(b: *Builder, step: *std.build.LibExeObjStep, options: Options) !void {
ensureSubmodules(b.allocator) catch |err| @panic(@errorName(err)); try ensureSubmodules(b.allocator);
step.addIncludePath(comptime thisDir() ++ "/libs/dawn/out/Debug/gen/include"); step.addIncludePath(comptime thisDir() ++ "/libs/dawn/out/Debug/gen/include");
step.addIncludePath(comptime thisDir() ++ "/libs/dawn/include"); step.addIncludePath(comptime thisDir() ++ "/libs/dawn/include");
step.addIncludePath(comptime thisDir() ++ "/src/dawn"); step.addIncludePath(comptime thisDir() ++ "/src/dawn");
if (options.separate_libs) { 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); 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); 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); step.linkLibrary(lib_dawn_platform);
// dawn-native // dawn-native
const lib_abseil_cpp = buildLibAbseilCpp(b, step, options); const lib_abseil_cpp = try buildLibAbseilCpp(b, step, options);
step.linkLibrary(lib_abseil_cpp); 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); step.linkLibrary(lib_dawn_native);
if (options.d3d12.?) { if (options.d3d12.?) {
const lib_dxcompiler = buildLibDxcompiler(b, step, options); const lib_dxcompiler = try buildLibDxcompiler(b, step, options);
step.linkLibrary(lib_dxcompiler); 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); 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); 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); step.linkLibrary(lib_spirv_tools);
const lib_tint = buildLibTint(b, step, options); const lib_tint = try buildLibTint(b, step, options);
step.linkLibrary(lib_tint); step.linkLibrary(lib_tint);
return; return;
} }
@ -136,16 +139,16 @@ pub fn Sdk(comptime deps: anytype) type {
lib_dawn.install(); lib_dawn.install();
step.linkLibrary(lib_dawn); step.linkLibrary(lib_dawn);
_ = buildLibMachDawnNative(b, lib_dawn, options); _ = try buildLibMachDawnNative(b, lib_dawn, options);
_ = buildLibDawnCommon(b, lib_dawn, options); _ = try buildLibDawnCommon(b, lib_dawn, options);
_ = buildLibDawnPlatform(b, lib_dawn, options); _ = try buildLibDawnPlatform(b, lib_dawn, options);
_ = buildLibAbseilCpp(b, lib_dawn, options); _ = try buildLibAbseilCpp(b, lib_dawn, options);
_ = buildLibDawnNative(b, lib_dawn, options); _ = try buildLibDawnNative(b, lib_dawn, options);
_ = buildLibDawnWire(b, lib_dawn, options); _ = try buildLibDawnWire(b, lib_dawn, options);
_ = buildLibDawnUtils(b, lib_dawn, options); _ = try buildLibDawnUtils(b, lib_dawn, options);
_ = buildLibSPIRVTools(b, lib_dawn, options); _ = try buildLibSPIRVTools(b, lib_dawn, options);
_ = buildLibTint(b, lib_dawn, options); _ = try buildLibTint(b, lib_dawn, options);
if (options.d3d12.?) _ = buildLibDxcompiler(b, lib_dawn, options); if (options.d3d12.?) _ = try buildLibDxcompiler(b, lib_dawn, options);
} }
fn ensureSubmodules(allocator: std.mem.Allocator) !void { 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 target = step.target_info.target;
const binaries_available = switch (target.os.tag) { const binaries_available = switch (target.os.tag) {
.windows => target.abi.isGnu(), .windows => target.abi.isGnu(),
@ -195,7 +198,7 @@ pub fn Sdk(comptime deps: anytype) type {
else => false, else => false,
}; };
if (!binaries_available) { 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); defer b.allocator.free(zig_triple);
std.log.err("gpu-dawn binaries for {s} not available.", .{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", .{}); 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_min = .{ .none = undefined };
binary_target.os_version_max = .{ .none = undefined }; binary_target.os_version_max = .{ .none = undefined };
binary_target.glibc_version = null; 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); 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; const base_cache_dir_rel = try std.fs.path.join(b.allocator, &.{ "zig-cache", "mach", "gpu-dawn" });
std.fs.cwd().makePath(base_cache_dir_rel) catch unreachable; try std.fs.cwd().makePath(base_cache_dir_rel);
const base_cache_dir = std.fs.cwd().realpathAlloc(b.allocator, base_cache_dir_rel) catch unreachable; const base_cache_dir = try std.fs.cwd().realpathAlloc(b.allocator, base_cache_dir_rel);
const commit_cache_dir = std.fs.path.join(b.allocator, &.{ base_cache_dir, options.binary_version }) catch unreachable; 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 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 target_cache_dir = try std.fs.path.join(b.allocator, &.{ commit_cache_dir, zig_triple, release_tag });
const include_dir = std.fs.path.join(b.allocator, &.{ commit_cache_dir, "include" }) catch unreachable; const include_dir = try std.fs.path.join(b.allocator, &.{ commit_cache_dir, "include" });
defer { defer {
b.allocator.free(base_cache_dir); b.allocator.free(base_cache_dir);
b.allocator.free(commit_cache_dir); b.allocator.free(commit_cache_dir);
@ -263,7 +266,7 @@ pub fn Sdk(comptime deps: anytype) type {
is_debug: bool, is_debug: bool,
is_windows: bool, is_windows: bool,
version: []const u8, version: []const u8,
) void { ) !void {
// If zig-cache/mach/gpu-dawn/<git revision> does not exist: // If zig-cache/mach/gpu-dawn/<git revision> does not exist:
// If on a commit in the main branch => rm -r zig-cache/mach/gpu-dawn/ // If on a commit in the main branch => rm -r zig-cache/mach/gpu-dawn/
// else => noop // else => noop
@ -274,10 +277,10 @@ pub fn Sdk(comptime deps: anytype) type {
// Extract to zig-cache/mach/gpu-dawn/<git revision>/macos-aarch64/libgpu.a // Extract to zig-cache/mach/gpu-dawn/<git revision>/macos-aarch64/libgpu.a
// Remove zig-cache/mach/gpu-dawn/download // Remove zig-cache/mach/gpu-dawn/download
const base_cache_dir_rel = std.fs.path.join(allocator, &.{ "zig-cache", "mach", "gpu-dawn" }) catch unreachable; const base_cache_dir_rel = try std.fs.path.join(allocator, &.{ "zig-cache", "mach", "gpu-dawn" });
std.fs.cwd().makePath(base_cache_dir_rel) catch unreachable; try std.fs.cwd().makePath(base_cache_dir_rel);
const base_cache_dir = std.fs.cwd().realpathAlloc(allocator, base_cache_dir_rel) catch unreachable; const base_cache_dir = try std.fs.cwd().realpathAlloc(allocator, base_cache_dir_rel);
const commit_cache_dir = std.fs.path.join(allocator, &.{ base_cache_dir, version }) catch unreachable; const commit_cache_dir = try std.fs.path.join(allocator, &.{ base_cache_dir, version });
defer { defer {
allocator.free(base_cache_dir_rel); allocator.free(base_cache_dir_rel);
allocator.free(base_cache_dir); allocator.free(base_cache_dir);
@ -287,14 +290,14 @@ pub fn Sdk(comptime deps: anytype) type {
if (!dirExists(commit_cache_dir)) { if (!dirExists(commit_cache_dir)) {
// Commit cache dir does not exist. If the commit we're on is in the main branch, we're // 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. // 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) { if (gitBranchContainsCommit(allocator, "main", current_git_commit) catch false) {
std.fs.deleteTreeAbsolute(base_cache_dir) catch {}; std.fs.deleteTreeAbsolute(base_cache_dir) catch {};
} }
} }
const release_tag = if (is_debug) "debug" else "release-fast"; 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); defer allocator.free(target_cache_dir);
if (dirExists(target_cache_dir)) { if (dirExists(target_cache_dir)) {
return; // nothing to do, already have the binary 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 { fn ensureCanDownloadFiles(allocator: std.mem.Allocator) void {
const argv = &[_][]const u8{ "curl", "--version" };
const result = std.ChildProcess.exec(.{ const result = std.ChildProcess.exec(.{
.allocator = allocator, .allocator = allocator,
.argv = argv, .argv = &.{ "curl", "--version" },
.cwd = comptime thisDir(), .cwd = comptime thisDir(),
}) catch { // e.g. FileNotFound }) catch { // e.g. FileNotFound
std.log.err("mach: error: 'curl --version' failed. Is curl not installed?", .{}); 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(); 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 lib = if (!options.separate_libs) step else blk: {
const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig";
const separate_lib = b.addStaticLibrary("dawn-native-mach", main_abs); 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 // 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); var cpp_flags = std.ArrayList([]const u8).init(b.allocator);
options.appendFlags(&cpp_flags, false, true) catch unreachable; try options.appendFlags(&cpp_flags, false, true);
appendDawnEnableBackendTypeFlags(&cpp_flags, options) catch unreachable; try appendDawnEnableBackendTypeFlags(&cpp_flags, options);
cpp_flags.appendSlice(&.{ try cpp_flags.appendSlice(&.{
include(deps.glfw_include_dir), include(deps.glfw_include_dir),
include("libs/dawn/out/Debug/gen/include"), include("libs/dawn/out/Debug/gen/include"),
include("libs/dawn/out/Debug/gen/src"), include("libs/dawn/out/Debug/gen/src"),
include("libs/dawn/include"), include("libs/dawn/include"),
include("libs/dawn/src"), include("libs/dawn/src"),
}) catch unreachable; });
if (step.target_info.target.os.tag == .windows) { if (step.target_info.target.os.tag == .windows) {
cpp_flags.appendSlice(&.{ try cpp_flags.appendSlice(&.{
"-D_DEBUG", "-D_DEBUG",
"-D_MT", "-D_MT",
"-D_DLL", "-D_DLL",
}) catch unreachable; });
} }
return lib; return lib;
} }
// Builds common sources; derived from src/common/BUILD.gn // 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 lib = if (!options.separate_libs) step else blk: {
const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig";
const separate_lib = b.addStaticLibrary("dawn-common", main_abs); 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); var flags = std.ArrayList([]const u8).init(b.allocator);
flags.appendSlice(&.{ try flags.appendSlice(&.{
include("libs/dawn/src"), include("libs/dawn/src"),
include("libs/dawn/out/Debug/gen/include"), include("libs/dawn/out/Debug/gen/include"),
include("libs/dawn/out/Debug/gen/src"), include("libs/dawn/out/Debug/gen/src"),
}) catch unreachable; });
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/src/dawn/common/", "libs/dawn/src/dawn/common/",
"libs/dawn/out/Debug/gen/src/dawn/common/", "libs/dawn/out/Debug/gen/src/dawn/common/",
@ -574,7 +576,7 @@ pub fn Sdk(comptime deps: anytype) type {
"mock", "mock",
"WindowsUtils.cpp", "WindowsUtils.cpp",
}, },
}) catch unreachable; });
var cpp_sources = std.ArrayList([]const u8).init(b.allocator); var cpp_sources = std.ArrayList([]const u8).init(b.allocator);
if (step.target_info.target.os.tag == .macos) { 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, .{}); deps.system_sdk.include(b, lib, .{});
lib.linkFramework("Foundation"); lib.linkFramework("Foundation");
const abs_path = comptime thisDir() ++ "/libs/dawn/src/dawn/common/SystemUtils_mac.mm"; 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) { if (step.target_info.target.os.tag == .windows) {
const abs_path = comptime thisDir() ++ "/libs/dawn/src/dawn/common/WindowsUtils.cpp"; 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); var cpp_flags = std.ArrayList([]const u8).init(b.allocator);
cpp_flags.appendSlice(flags.items) catch unreachable; try cpp_flags.appendSlice(flags.items);
options.appendFlags(&cpp_flags, false, true) catch unreachable; try options.appendFlags(&cpp_flags, false, true);
lib.addCSourceFiles(cpp_sources.items, cpp_flags.items); lib.addCSourceFiles(cpp_sources.items, cpp_flags.items);
return lib; return lib;
} }
// Build dawn platform sources; derived from src/dawn/platform/BUILD.gn // 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 lib = if (!options.separate_libs) step else blk: {
const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig";
const separate_lib = b.addStaticLibrary("dawn-platform", main_abs); 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); var cpp_flags = std.ArrayList([]const u8).init(b.allocator);
options.appendFlags(&cpp_flags, false, true) catch unreachable; try options.appendFlags(&cpp_flags, false, true);
cpp_flags.appendSlice(&.{ try cpp_flags.appendSlice(&.{
include("libs/dawn/src"), include("libs/dawn/src"),
include("libs/dawn/include"), include("libs/dawn/include"),
include("libs/dawn/out/Debug/gen/include"), include("libs/dawn/out/Debug/gen/include"),
}) catch unreachable; });
var cpp_sources = std.ArrayList([]const u8).init(b.allocator); var cpp_sources = std.ArrayList([]const u8).init(b.allocator);
inline for ([_][]const u8{ inline for ([_][]const u8{
@ -625,7 +627,7 @@ pub fn Sdk(comptime deps: anytype) type {
"src/dawn/platform/tracing/EventTracer.cpp", "src/dawn/platform/tracing/EventTracer.cpp",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ 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); 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 // 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 lib = if (!options.separate_libs) step else blk: {
const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig";
const separate_lib = b.addStaticLibrary("dawn-native", main_abs); 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, .{}); deps.system_sdk.include(b, lib, .{});
var flags = std.ArrayList([]const u8).init(b.allocator); var flags = std.ArrayList([]const u8).init(b.allocator);
appendDawnEnableBackendTypeFlags(&flags, options) catch unreachable; try appendDawnEnableBackendTypeFlags(&flags, options);
flags.appendSlice(&.{ try flags.appendSlice(&.{
include("libs/dawn"), include("libs/dawn"),
include("libs/dawn/src"), include("libs/dawn/src"),
include("libs/dawn/include"), 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/include"),
include("libs/dawn/out/Debug/gen/src"), 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 = &.{ .rel_dirs = &.{
"libs/dawn/out/Debug/gen/src/dawn/", "libs/dawn/out/Debug/gen/src/dawn/",
"libs/dawn/src/dawn/native/", "libs/dawn/src/dawn/native/",
@ -725,16 +727,16 @@ pub fn Sdk(comptime deps: anytype) type {
"SpirvValidation.cpp", "SpirvValidation.cpp",
"XlibXcbFunctions.cpp", "XlibXcbFunctions.cpp",
}, },
}) catch unreachable; });
// dawn_native_gen // dawn_native_gen
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/out/Debug/gen/src/dawn/native/", "libs/dawn/out/Debug/gen/src/dawn/native/",
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "benchmark", "mock" }, .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): 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 // 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", "src/dawn/mingw_helpers.cpp",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/" ++ 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 = &.{ .rel_dirs = &.{
"libs/dawn/src/dawn/native/d3d12/", "libs/dawn/src/dawn/native/d3d12/",
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "benchmark", "mock" }, .excluding_contains = &.{ "test", "benchmark", "mock" },
}) catch unreachable; });
} }
if (options.metal.?) { if (options.metal.?) {
lib.linkFramework("Metal"); lib.linkFramework("Metal");
@ -768,7 +770,7 @@ pub fn Sdk(comptime deps: anytype) type {
lib.linkFramework("IOSurface"); lib.linkFramework("IOSurface");
lib.linkFramework("QuartzCore"); lib.linkFramework("QuartzCore");
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.objc = true, .objc = true,
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/src/dawn/native/metal/", "libs/dawn/src/dawn/native/metal/",
@ -776,7 +778,7 @@ pub fn Sdk(comptime deps: anytype) type {
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "benchmark", "mock" }, .excluding_contains = &.{ "test", "benchmark", "mock" },
}) catch unreachable; });
} }
if (options.linux_window_manager != null and options.linux_window_manager.? == .X11) { 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", "src/dawn/native/XlibXcbFunctions.cpp",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ 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", "src/dawn/native/null/DeviceNull.cpp",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ 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.?) { if (options.desktop_gl.? or options.vulkan.?) {
@ -801,29 +803,29 @@ pub fn Sdk(comptime deps: anytype) type {
"src/dawn/native/SpirvValidation.cpp", "src/dawn/native/SpirvValidation.cpp",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ 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.?) { if (options.desktop_gl.?) {
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/out/Debug/gen/src/dawn/native/opengl/", "libs/dawn/out/Debug/gen/src/dawn/native/opengl/",
"libs/dawn/src/dawn/native/opengl/", "libs/dawn/src/dawn/native/opengl/",
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "benchmark", "mock" }, .excluding_contains = &.{ "test", "benchmark", "mock" },
}) catch unreachable; });
} }
if (options.vulkan.?) { if (options.vulkan.?) {
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/src/dawn/native/vulkan/", "libs/dawn/src/dawn/native/vulkan/",
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "benchmark", "mock" }, .excluding_contains = &.{ "test", "benchmark", "mock" },
}) catch unreachable; });
if (isLinuxDesktopLike(step.target_info.target)) { if (isLinuxDesktopLike(step.target_info.target)) {
inline for ([_][]const u8{ inline for ([_][]const u8{
@ -831,7 +833,7 @@ pub fn Sdk(comptime deps: anytype) type {
"src/dawn/native/vulkan/external_semaphore/SemaphoreServiceFD.cpp", "src/dawn/native/vulkan/external_semaphore/SemaphoreServiceFD.cpp",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ 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) { } else if (step.target_info.target.os.tag == .fuchsia) {
inline for ([_][]const u8{ inline for ([_][]const u8{
@ -839,7 +841,7 @@ pub fn Sdk(comptime deps: anytype) type {
"src/dawn/native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp", "src/dawn/native/vulkan/external_semaphore/SemaphoreServiceZirconHandle.cpp",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path; const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ path;
cpp_sources.append(abs_path) catch unreachable; try cpp_sources.append(abs_path);
} }
} else { } else {
inline for ([_][]const u8{ inline for ([_][]const u8{
@ -847,7 +849,7 @@ pub fn Sdk(comptime deps: anytype) type {
"src/dawn/native/vulkan/external_semaphore/SemaphoreServiceNull.cpp", "src/dawn/native/vulkan/external_semaphore/SemaphoreServiceNull.cpp",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ 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", "src/dawn/native/null/NullBackend.cpp",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ 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.?) { if (options.d3d12.?) {
@ -903,7 +905,7 @@ pub fn Sdk(comptime deps: anytype) type {
"src/dawn/native/d3d12/D3D12Backend.cpp", "src/dawn/native/d3d12/D3D12Backend.cpp",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ 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.?) { if (options.desktop_gl.?) {
@ -911,7 +913,7 @@ pub fn Sdk(comptime deps: anytype) type {
"src/dawn/native/opengl/OpenGLBackend.cpp", "src/dawn/native/opengl/OpenGLBackend.cpp",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ 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.?) { if (options.vulkan.?) {
@ -919,7 +921,7 @@ pub fn Sdk(comptime deps: anytype) type {
"src/dawn/native/vulkan/VulkanBackend.cpp", "src/dawn/native/vulkan/VulkanBackend.cpp",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ 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 // TODO(build-system): vulkan
// if (enable_vulkan_validation_layers) { // 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); var cpp_flags = std.ArrayList([]const u8).init(b.allocator);
cpp_flags.appendSlice(flags.items) catch unreachable; try cpp_flags.appendSlice(flags.items);
options.appendFlags(&cpp_flags, false, true) catch unreachable; try options.appendFlags(&cpp_flags, false, true);
lib.addCSourceFiles(cpp_sources.items, cpp_flags.items); lib.addCSourceFiles(cpp_sources.items, cpp_flags.items);
return lib; return lib;
} }
// Builds tint sources; derived from src/tint/BUILD.gn // 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 lib = if (!options.separate_libs) step else blk: {
const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig";
const separate_lib = b.addStaticLibrary("tint", main_abs); 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); var flags = std.ArrayList([]const u8).init(b.allocator);
flags.appendSlice(&.{ try flags.appendSlice(&.{
// TODO(build-system): make these optional // TODO(build-system): make these optional
"-DTINT_BUILD_SPV_READER=1", "-DTINT_BUILD_SPV_READER=1",
"-DTINT_BUILD_SPV_WRITER=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("libs/dawn/out/Debug/gen/third_party/vulkan-deps/spirv-tools/src/include"), include("libs/dawn/out/Debug/gen/third_party/vulkan-deps/spirv-tools/src/include"),
include("libs/dawn/include"), include("libs/dawn/include"),
}) catch unreachable; });
// libtint_core_all_src // libtint_core_all_src
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/src/tint", "libs/dawn/src/tint",
"libs/dawn/src/tint/diagnostic/", "libs/dawn/src/tint/diagnostic/",
@ -994,101 +996,101 @@ pub fn Sdk(comptime deps: anytype) type {
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "bench", "printer_windows", "printer_linux", "printer_other", "glsl.cc" }, .excluding_contains = &.{ "test", "bench", "printer_windows", "printer_linux", "printer_other", "glsl.cc" },
}) catch unreachable; });
var cpp_sources = std.ArrayList([]const u8).init(b.allocator); var cpp_sources = std.ArrayList([]const u8).init(b.allocator);
switch (step.target_info.target.os.tag) { switch (step.target_info.target.os.tag) {
.windows => cpp_sources.append(comptime thisDir() ++ "/libs/dawn/src/tint/diagnostic/printer_windows.cc") catch unreachable, .windows => try cpp_sources.append(comptime thisDir() ++ "/libs/dawn/src/tint/diagnostic/printer_windows.cc"),
.linux => cpp_sources.append(comptime thisDir() ++ "/libs/dawn/src/tint/diagnostic/printer_linux.cc") catch unreachable, .linux => try cpp_sources.append(comptime thisDir() ++ "/libs/dawn/src/tint/diagnostic/printer_linux.cc"),
else => cpp_sources.append(comptime thisDir() ++ "/libs/dawn/src/tint/diagnostic/printer_other.cc") catch unreachable, else => try cpp_sources.append(comptime thisDir() ++ "/libs/dawn/src/tint/diagnostic/printer_other.cc"),
} }
// libtint_sem_src // libtint_sem_src
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/src/tint/sem/", "libs/dawn/src/tint/sem/",
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "benchmark" }, .excluding_contains = &.{ "test", "benchmark" },
}) catch unreachable; });
// libtint_spv_reader_src // libtint_spv_reader_src
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/src/tint/reader/spirv/", "libs/dawn/src/tint/reader/spirv/",
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "benchmark" }, .excluding_contains = &.{ "test", "benchmark" },
}) catch unreachable; });
// libtint_spv_writer_src // libtint_spv_writer_src
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/src/tint/writer/spirv/", "libs/dawn/src/tint/writer/spirv/",
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "bench" }, .excluding_contains = &.{ "test", "bench" },
}) catch unreachable; });
// TODO(build-system): make optional // TODO(build-system): make optional
// libtint_wgsl_reader_src // libtint_wgsl_reader_src
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/src/tint/reader/wgsl/", "libs/dawn/src/tint/reader/wgsl/",
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "bench" }, .excluding_contains = &.{ "test", "bench" },
}) catch unreachable; });
// TODO(build-system): make optional // TODO(build-system): make optional
// libtint_wgsl_writer_src // libtint_wgsl_writer_src
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/src/tint/writer/wgsl/", "libs/dawn/src/tint/writer/wgsl/",
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "bench" }, .excluding_contains = &.{ "test", "bench" },
}) catch unreachable; });
// TODO(build-system): make optional // TODO(build-system): make optional
// libtint_msl_writer_src // libtint_msl_writer_src
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/src/tint/writer/msl/", "libs/dawn/src/tint/writer/msl/",
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "bench" }, .excluding_contains = &.{ "test", "bench" },
}) catch unreachable; });
// TODO(build-system): make optional // TODO(build-system): make optional
// libtint_hlsl_writer_src // libtint_hlsl_writer_src
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/src/tint/writer/hlsl/", "libs/dawn/src/tint/writer/hlsl/",
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "bench" }, .excluding_contains = &.{ "test", "bench" },
}) catch unreachable; });
// TODO(build-system): make optional // TODO(build-system): make optional
// libtint_glsl_writer_src // libtint_glsl_writer_src
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/src/tint/writer/glsl/", "libs/dawn/src/tint/writer/glsl/",
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "bench" }, .excluding_contains = &.{ "test", "bench" },
}) catch unreachable; });
var cpp_flags = std.ArrayList([]const u8).init(b.allocator); var cpp_flags = std.ArrayList([]const u8).init(b.allocator);
cpp_flags.appendSlice(flags.items) catch unreachable; try cpp_flags.appendSlice(flags.items);
options.appendFlags(&cpp_flags, false, true) catch unreachable; try options.appendFlags(&cpp_flags, false, true);
lib.addCSourceFiles(cpp_sources.items, cpp_flags.items); lib.addCSourceFiles(cpp_sources.items, cpp_flags.items);
return lib; return lib;
} }
// Builds third_party/vulkan-deps/spirv-tools sources; derived from third_party/vulkan-deps/spirv-tools/src/BUILD.gn // 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 lib = if (!options.separate_libs) step else blk: {
const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig";
const separate_lib = b.addStaticLibrary("spirv-tools", main_abs); 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); var flags = std.ArrayList([]const u8).init(b.allocator);
flags.appendSlice(&.{ try flags.appendSlice(&.{
include("libs/dawn"), include("libs/dawn"),
include("libs/dawn/third_party/vulkan-deps/spirv-tools/src"), include("libs/dawn/third_party/vulkan-deps/spirv-tools/src"),
include("libs/dawn/third_party/vulkan-deps/spirv-tools/src/include"), 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("libs/dawn/out/Debug/gen/third_party/vulkan-deps/spirv-tools/src/include"), 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"), include("libs/dawn/third_party/vulkan-deps/spirv-headers/src/include/spirv/unified1"),
}) catch unreachable; });
// spvtools // spvtools
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/third_party/vulkan-deps/spirv-tools/src/source/", "libs/dawn/third_party/vulkan-deps/spirv-tools/src/source/",
"libs/dawn/third_party/vulkan-deps/spirv-tools/src/source/util/", "libs/dawn/third_party/vulkan-deps/spirv-tools/src/source/util/",
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "benchmark" }, .excluding_contains = &.{ "test", "benchmark" },
}) catch unreachable; });
// spvtools_val // spvtools_val
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/third_party/vulkan-deps/spirv-tools/src/source/val/", "libs/dawn/third_party/vulkan-deps/spirv-tools/src/source/val/",
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "benchmark" }, .excluding_contains = &.{ "test", "benchmark" },
}) catch unreachable; });
// spvtools_opt // spvtools_opt
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/third_party/vulkan-deps/spirv-tools/src/source/opt/", "libs/dawn/third_party/vulkan-deps/spirv-tools/src/source/opt/",
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "benchmark" }, .excluding_contains = &.{ "test", "benchmark" },
}) catch unreachable; });
// spvtools_link // spvtools_link
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/third_party/vulkan-deps/spirv-tools/src/source/link/", "libs/dawn/third_party/vulkan-deps/spirv-tools/src/source/link/",
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "benchmark" }, .excluding_contains = &.{ "test", "benchmark" },
}) catch unreachable; });
return lib; 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 // $ 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 lib = if (!options.separate_libs) step else blk: {
const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig";
const separate_lib = b.addStaticLibrary("abseil-cpp-common", main_abs); 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"); if (target.os.tag == .windows) lib.linkSystemLibraryName("bcrypt");
var flags = std.ArrayList([]const u8).init(b.allocator); var flags = std.ArrayList([]const u8).init(b.allocator);
flags.appendSlice(&.{ try flags.appendSlice(&.{
include("libs/dawn"), include("libs/dawn"),
include("libs/dawn/third_party/abseil-cpp"), 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", "-DABSL_FORCE_THREAD_IDENTITY_MODE=2",
"-DWIN32_LEAN_AND_MEAN", "-DWIN32_LEAN_AND_MEAN",
"-DD3D10_ARBITRARY_HEADER_ORDERING", "-DD3D10_ARBITRARY_HEADER_ORDERING",
"-D_CRT_SECURE_NO_WARNINGS", "-D_CRT_SECURE_NO_WARNINGS",
"-DNOMINMAX", "-DNOMINMAX",
include("src/dawn/zig_mingw_pthread"), include("src/dawn/zig_mingw_pthread"),
}) catch unreachable; });
// absl // absl
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/third_party/abseil-cpp/absl/strings/", "libs/dawn/third_party/abseil-cpp/absl/strings/",
"libs/dawn/third_party/abseil-cpp/absl/strings/internal/", "libs/dawn/third_party/abseil-cpp/absl/strings/internal/",
@ -1213,12 +1215,12 @@ pub fn Sdk(comptime deps: anytype) type {
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "_test", "_testing", "benchmark", "print_hash_of.cc", "gaussian_distribution_gentables.cc" }, .excluding_contains = &.{ "_test", "_testing", "benchmark", "print_hash_of.cc", "gaussian_distribution_gentables.cc" },
}) catch unreachable; });
return lib; return lib;
} }
// Buids dawn wire sources; derived from src/dawn/wire/BUILD.gn // 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 lib = if (!options.separate_libs) step else blk: {
const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig";
const separate_lib = b.addStaticLibrary("dawn-wire", main_abs); 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); var flags = std.ArrayList([]const u8).init(b.allocator);
flags.appendSlice(&.{ try flags.appendSlice(&.{
include("libs/dawn"), include("libs/dawn"),
include("libs/dawn/src"), include("libs/dawn/src"),
include("libs/dawn/include"), include("libs/dawn/include"),
include("libs/dawn/out/Debug/gen/include"), include("libs/dawn/out/Debug/gen/include"),
include("libs/dawn/out/Debug/gen/src"), include("libs/dawn/out/Debug/gen/src"),
}) catch unreachable; });
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.rel_dirs = &.{ .rel_dirs = &.{
"libs/dawn/out/Debug/gen/src/dawn/wire/", "libs/dawn/out/Debug/gen/src/dawn/wire/",
"libs/dawn/out/Debug/gen/src/dawn/wire/client/", "libs/dawn/out/Debug/gen/src/dawn/wire/client/",
@ -1250,12 +1252,12 @@ pub fn Sdk(comptime deps: anytype) type {
}, },
.flags = flags.items, .flags = flags.items,
.excluding_contains = &.{ "test", "benchmark", "mock" }, .excluding_contains = &.{ "test", "benchmark", "mock" },
}) catch unreachable; });
return lib; return lib;
} }
// Builds dawn utils sources; derived from src/dawn/utils/BUILD.gn // 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 lib = if (!options.separate_libs) step else blk: {
const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig";
const separate_lib = b.addStaticLibrary("dawn-utils", main_abs); const separate_lib = b.addStaticLibrary("dawn-utils", main_abs);
@ -1266,16 +1268,16 @@ pub fn Sdk(comptime deps: anytype) type {
separate_lib.install(); separate_lib.install();
break :blk separate_lib; 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); var flags = std.ArrayList([]const u8).init(b.allocator);
appendDawnEnableBackendTypeFlags(&flags, options) catch unreachable; try appendDawnEnableBackendTypeFlags(&flags, options);
flags.appendSlice(&.{ try flags.appendSlice(&.{
include(deps.glfw_include_dir), include(deps.glfw_include_dir),
include("libs/dawn/src"), include("libs/dawn/src"),
include("libs/dawn/include"), include("libs/dawn/include"),
include("libs/dawn/out/Debug/gen/include"), include("libs/dawn/out/Debug/gen/include"),
}) catch unreachable; });
var cpp_sources = std.ArrayList([]const u8).init(b.allocator); var cpp_sources = std.ArrayList([]const u8).init(b.allocator);
inline for ([_][]const u8{ inline for ([_][]const u8{
@ -1283,7 +1285,7 @@ pub fn Sdk(comptime deps: anytype) type {
"src/dawn/utils/NullBinding.cpp", "src/dawn/utils/NullBinding.cpp",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ 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.?) { if (options.d3d12.?) {
@ -1291,16 +1293,16 @@ pub fn Sdk(comptime deps: anytype) type {
"src/dawn/utils/D3D12Binding.cpp", "src/dawn/utils/D3D12Binding.cpp",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ 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.?) { if (options.metal.?) {
inline for ([_][]const u8{ inline for ([_][]const u8{
"src/dawn/utils/MetalBinding.mm", "src/dawn/utils/MetalBinding.mm",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ 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", "src/dawn/utils/OpenGLBinding.cpp",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ 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", "src/dawn/utils/VulkanBinding.cpp",
}) |path| { }) |path| {
const abs_path = comptime thisDir() ++ "/libs/dawn/" ++ 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); var cpp_flags = std.ArrayList([]const u8).init(b.allocator);
cpp_flags.appendSlice(flags.items) catch unreachable; try cpp_flags.appendSlice(flags.items);
options.appendFlags(&cpp_flags, false, true) catch unreachable; try options.appendFlags(&cpp_flags, false, true);
lib.addCSourceFiles(cpp_sources.items, cpp_flags.items); lib.addCSourceFiles(cpp_sources.items, cpp_flags.items);
return lib; return lib;
} }
// Buids dxcompiler sources; derived from libs/DirectXShaderCompiler/CMakeLists.txt // 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 lib = if (!options.separate_libs) step else blk: {
const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig"; const main_abs = comptime thisDir() ++ "/src/dawn/dummy.zig";
const separate_lib = b.addStaticLibrary("dxcompiler", main_abs); const separate_lib = b.addStaticLibrary("dxcompiler", main_abs);
@ -1350,7 +1352,7 @@ pub fn Sdk(comptime deps: anytype) type {
lib.linkLibCpp(); lib.linkLibCpp();
var flags = std.ArrayList([]const u8).init(b.allocator); var flags = std.ArrayList([]const u8).init(b.allocator);
flags.appendSlice(&.{ try flags.appendSlice(&.{
include("libs/"), include("libs/"),
include("libs/DirectXShaderCompiler/include/llvm/llvm_assert"), include("libs/DirectXShaderCompiler/include/llvm/llvm_assert"),
include("libs/DirectXShaderCompiler/include"), include("libs/DirectXShaderCompiler/include"),
@ -1368,9 +1370,9 @@ pub fn Sdk(comptime deps: anytype) type {
"-DHAVE_LIBPSAPI=1", "-DHAVE_LIBPSAPI=1",
"-DHAVE_LIBSHELL32=1", "-DHAVE_LIBSHELL32=1",
"-DLLVM_ON_WIN32=1", "-DLLVM_ON_WIN32=1",
}) catch unreachable; });
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.zero_debug_symbols = true, .zero_debug_symbols = true,
.rel_dirs = &.{ .rel_dirs = &.{
"libs/DirectXShaderCompiler/lib/Analysis/IPA", "libs/DirectXShaderCompiler/lib/Analysis/IPA",
@ -1401,9 +1403,9 @@ pub fn Sdk(comptime deps: anytype) type {
"libs/DirectXShaderCompiler/lib/Transforms/Vectorize", "libs/DirectXShaderCompiler/lib/Transforms/Vectorize",
}, },
.flags = flags.items, .flags = flags.items,
}) catch unreachable; });
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.zero_debug_symbols = true, .zero_debug_symbols = true,
.rel_dirs = &.{ .rel_dirs = &.{
"libs/DirectXShaderCompiler/lib/Support", "libs/DirectXShaderCompiler/lib/Support",
@ -1415,9 +1417,9 @@ pub fn Sdk(comptime deps: anytype) type {
"Path.cpp", // ignore, LLVM_INCLUDE_TESTS "Path.cpp", // ignore, LLVM_INCLUDE_TESTS
"DynamicLibrary.cpp", // ignore "DynamicLibrary.cpp", // ignore
}, },
}) catch unreachable; });
appendLangScannedSources(b, lib, options, .{ try appendLangScannedSources(b, lib, options, .{
.zero_debug_symbols = true, .zero_debug_symbols = true,
.rel_dirs = &.{ .rel_dirs = &.{
"libs/DirectXShaderCompiler/lib/Bitcode/Reader", "libs/DirectXShaderCompiler/lib/Bitcode/Reader",
@ -1426,7 +1428,7 @@ pub fn Sdk(comptime deps: anytype) type {
.excluding_contains = &.{ .excluding_contains = &.{
"BitReader.cpp", // ignore "BitReader.cpp", // ignore
}, },
}) catch unreachable; });
return lib; return lib;
} }
@ -1453,7 +1455,7 @@ pub fn Sdk(comptime deps: anytype) type {
) !void { ) !void {
var cpp_flags = std.ArrayList([]const u8).init(b.allocator); var cpp_flags = std.ArrayList([]const u8).init(b.allocator);
try cpp_flags.appendSlice(args.flags); 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" }; const cpp_extensions: []const []const u8 = if (args.objc) &.{".mm"} else &.{ ".cpp", ".cc" };
try appendScannedSources(b, step, .{ try appendScannedSources(b, step, .{
.flags = cpp_flags.items, .flags = cpp_flags.items,
@ -1465,7 +1467,7 @@ pub fn Sdk(comptime deps: anytype) type {
var flags = std.ArrayList([]const u8).init(b.allocator); var flags = std.ArrayList([]const u8).init(b.allocator);
try flags.appendSlice(args.flags); 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"}; const c_extensions: []const []const u8 = if (args.objc) &.{".m"} else &.{".c"};
try appendScannedSources(b, step, .{ try appendScannedSources(b, step, .{
.flags = flags.items, .flags = flags.items,

View file

@ -4,7 +4,7 @@ const gpu_dawn_sdk = @import("libs/mach-gpu-dawn/sdk.zig");
const gpu_sdk = @import("sdk.zig"); const gpu_sdk = @import("sdk.zig");
const system_sdk = @import("libs/mach-glfw/system_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 mode = b.standardReleaseOptions();
const target = b.standardTargetOptions(.{}); const target = b.standardTargetOptions(.{});
const gpu_dawn = gpu_dawn_sdk.Sdk(.{ 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"); 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"); const example = b.addExecutable("gpu-hello-triangle", "examples/main.zig");
example.setBuildMode(mode); example.setBuildMode(mode);
example.setTarget(target); example.setTarget(target);
example.addPackage(gpu.pkg); example.addPackage(gpu.pkg);
example.addPackage(glfw.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(); example.install();
const example_run_cmd = example.run(); const example_run_cmd = example.run();

View file

@ -2,11 +2,11 @@ const std = @import("std");
pub fn Sdk(comptime deps: anytype) type { pub fn Sdk(comptime deps: anytype) type {
return struct { 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"); const main_tests = b.addTestExe("gpu-tests", (comptime thisDir()) ++ "/src/main.zig");
main_tests.setBuildMode(mode); main_tests.setBuildMode(mode);
main_tests.setTarget(target); main_tests.setTarget(target);
link(b, main_tests, options); try link(b, main_tests, options);
main_tests.install(); main_tests.install();
return main_tests.run(); return main_tests.run();
} }
@ -22,10 +22,10 @@ pub fn Sdk(comptime deps: anytype) type {
.dependencies = &.{deps.glfw.pkg}, .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) { if (step.target.toTarget().cpu.arch != .wasm32) {
deps.glfw.link(b, step, options.glfw_options); try deps.glfw.link(b, step, options.glfw_options);
deps.gpu_dawn.link(b, step, options.gpu_dawn_options); try deps.gpu_dawn.link(b, step, options.gpu_dawn_options);
step.addCSourceFile((comptime thisDir()) ++ "/src/mach_dawn.cpp", &.{"-std=c++17"}); step.addCSourceFile((comptime thisDir()) ++ "/src/mach_dawn.cpp", &.{"-std=c++17"});
step.addIncludePath((comptime thisDir()) ++ "/src"); step.addIncludePath((comptime thisDir()) ++ "/src");
} }

View file

@ -24,16 +24,20 @@ pub const Options = struct {
listen_address: ?net.Address = null, listen_address: ?net.Address = null,
}; };
pub fn serve(step: *build.LibExeObjStep, options: Options) !*Wasmserve { pub const Error = error{CannotOpenDirectory} || mem.Allocator.Error;
const self = step.builder.allocator.create(Wasmserve) catch unreachable;
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 = 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{ self.* = Wasmserve{
.step = build.Step.init(.run, "wasmserve", step.builder.allocator, Wasmserve.make), .step = build.Step.init(.run, "wasmserve", step.builder.allocator, Wasmserve.make),
.b = step.builder, .b = step.builder,
.exe_step = step, .exe_step = step,
.install_step_name = options.install_step_name orelse step.builder.getInstallStep().name, .install_step_name = options.install_step_name orelse step.builder.getInstallStep().name,
.install_dir = install_dir, .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), .address = options.listen_address orelse net.Address.initIp4([4]u8{ 127, 0, 0, 1 }, 8080),
.subscriber = null, .subscriber = null,
.watch_paths = options.watch_paths orelse &.{"src"}, .watch_paths = options.watch_paths orelse &.{"src"},