1
Fork 0
glsl_analyzer/build.zig
2025-03-19 17:50:59 -07:00

168 lines
5.4 KiB
Zig

const std = @import("std");
pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// Executable
{
const exe = try addExecutable(b, .{ .target = target, .optimize = optimize });
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}
// Tests
{
const unit_tests = b.addTest(.{
.name = "unit-tests",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
try attachModules(unit_tests);
if (b.option(bool, "install-tests", "Install the unit tests in the `bin` folder") orelse false) {
b.installArtifact(unit_tests);
}
const run_unit_tests = b.addRunArtifact(unit_tests);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_unit_tests.step);
}
// Release
{
const target_triples = [_][]const u8{
"x86_64-linux-musl",
"aarch64-linux-musl",
"x86_64-macos",
"aarch64-macos",
"x86_64-windows",
"aarch64-windows",
};
const release_step = b.step("release", "Produce executables for targeted platforms");
for (&target_triples) |triple| {
const release_target = b.resolveTargetQuery(try std.Target.Query.parse(.{
.arch_os_abi = triple,
.cpu_features = "baseline",
}));
const exe = try addExecutable(b, .{ .target = release_target, .optimize = optimize });
const install = b.addInstallArtifact(exe, .{
.dest_dir = .{ .override = .{
.custom = b.pathJoin(&.{ triple, "bin" }),
} },
});
release_step.dependOn(&install.step);
}
}
}
fn addExecutable(b: *std.Build, options: struct {
target: std.Build.ResolvedTarget,
optimize: std.builtin.OptimizeMode,
}) !*std.Build.Step.Compile {
const exe = b.addExecutable(.{
.name = "glsl_analyzer",
.root_source_file = b.path("src/main.zig"),
.target = options.target,
.optimize = options.optimize,
});
try attachModules(exe);
return exe;
}
fn attachModules(step: *std.Build.Step.Compile) !void {
const b = step.step.owner;
step.linkLibC();
const compressed_spec = try CompressStep.create(b, "spec.json.zlib", b.path("spec/spec.json"));
step.root_module.addAnonymousImport("glsl_spec.json.zlib", .{ .root_source_file = compressed_spec.getOutput() });
const options = b.addOptions();
const build_root_path = try std.fs.path.resolve(
b.allocator,
&.{b.build_root.path orelse "."},
);
options.addOption([]const u8, "build_root", build_root_path);
options.addOption([]const u8, "version", b.run(&.{ "git", "describe", "--tags", "--always" }));
step.root_module.addOptions("build_options", options);
}
const CompressStep = struct {
step: std.Build.Step,
generated_file: std.Build.GeneratedFile,
input: std.Build.LazyPath,
pub fn create(b: *std.Build, name: []const u8, path: std.Build.LazyPath) !*@This() {
const self = try b.allocator.create(@This());
self.* = .{
.step = std.Build.Step.init(.{
.id = .custom,
.name = name,
.owner = b,
.makeFn = &make,
}),
.generated_file = .{ .step = &self.step },
.input = path,
};
path.addStepDependencies(&self.step);
return self;
}
pub fn getOutput(self: *@This()) std.Build.LazyPath {
return .{ .generated = .{ .file = &self.generated_file } };
}
fn make(step: *std.Build.Step, _: std.Build.Step.MakeOptions) anyerror!void {
const b = step.owner;
const self: *@This() = @fieldParentPtr("step", step);
const input_path = self.input.getPath(b);
var man = b.graph.cache.obtain();
defer man.deinit();
man.hash.add(@as(u32, 0x00000002));
const input_index = try man.addFile(input_path, 16 << 20);
const is_hit = try step.cacheHit(&man);
const digest = man.final();
const output_path = try b.cache_root.join(b.allocator, &.{ "o", &digest, step.name });
self.generated_file.path = output_path;
if (is_hit) return;
const input_contents = man.files.keys()[input_index].contents.?;
if (std.fs.path.dirname(output_path)) |dir| try b.cache_root.handle.makePath(dir);
var output_file = b.cache_root.handle.createFile(output_path, .{}) catch |err| {
std.log.err("could not open {s}: {s}", .{ output_path, @errorName(err) });
return err;
};
defer output_file.close();
var output_buffered = std.io.bufferedWriter(output_file.writer());
{
var compress_stream = try std.compress.zlib.compressor(output_buffered.writer(), .{});
try compress_stream.writer().writeAll(input_contents);
try compress_stream.finish();
}
try output_buffered.flush();
try step.writeManifest(&man);
}
};