const std = @import("std"); const Coverage = @import("build/Coverage.zig"); pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); // -- Engine module (the calculation library) -- const engine_mod = b.addModule("engine", .{ .root_source_file = b.path("engine/src/engine.zig"), .target = target, .optimize = optimize, }); // -- Vaxis dependency (TUI library) -- const vaxis_dep = b.dependency("vaxis", .{ .target = target, .optimize = optimize, }); // -- Engine static library (for linking into the main binary) -- const engine_lib = b.addLibrary(.{ .linkage = .static, .name = "tally-engine", .root_module = engine_mod, }); b.installArtifact(engine_lib); // -- Engine shared library (for Android JNI) -- const engine_shared = b.addLibrary(.{ .linkage = .dynamic, .name = "tally", .root_module = b.createModule(.{ .root_source_file = b.path("engine/src/c_api.zig"), .target = target, .optimize = optimize, .imports = &.{ .{ .name = "engine", .module = engine_mod }, }, }), }); b.installArtifact(engine_shared); // -- Main binary (CLI + TUI in one) -- const exe = b.addExecutable(.{ .name = "tally", .root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, .imports = &.{ .{ .name = "engine", .module = engine_mod }, .{ .name = "vaxis", .module = vaxis_dep.module("vaxis") }, }, }), }); b.installArtifact(exe); // -- Tests -- const engine_tests = b.addTest(.{ .root_module = b.createModule(.{ .root_source_file = b.path("engine/src/engine.zig"), .target = target, .optimize = optimize, }), }); const cli_tests = b.addTest(.{ .root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, .imports = &.{ .{ .name = "engine", .module = engine_mod }, .{ .name = "vaxis", .module = vaxis_dep.module("vaxis") }, }, }), }); const run_engine_tests = b.addRunArtifact(engine_tests); const run_cli_tests = b.addRunArtifact(cli_tests); // TUI tests need their own root: src/main.zig only reaches tui.zig from // main(), which is never analyzed in test mode, so its tests would be // silently skipped if we relied on the CLI test target. const tui_tests = b.addTest(.{ .root_module = b.createModule(.{ .root_source_file = b.path("src/tui.zig"), .target = target, .optimize = optimize, .imports = &.{ .{ .name = "engine", .module = engine_mod }, .{ .name = "vaxis", .module = vaxis_dep.module("vaxis") }, }, }), }); const run_tui_tests = b.addRunArtifact(tui_tests); const test_step = b.step("test", "Run unit tests"); test_step.dependOn(&run_engine_tests.step); test_step.dependOn(&run_cli_tests.step); test_step.dependOn(&run_tui_tests.step); // -- Coverage step (uses kcov, Linux x86_64/aarch64 only) -- // // One report per source tree, with disjoint include patterns so no file is // accounted for twice. The CLI test binary also compiles tui.zig (main.zig // imports it) but never runs its tests, so the CLI report is narrowed to // main.zig and src/cli; without that narrowing the TUI would appear // near-uncovered in one report and covered in another. { var cov = Coverage.init(b); const engine_cov = b.createModule(.{ .root_source_file = b.path("engine/src/engine.zig"), .target = target, .optimize = optimize, }); _ = cov.addModule(engine_cov, "tally-engine", &.{"engine/src"}); const cli_cov = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, .imports = &.{ .{ .name = "engine", .module = engine_mod }, .{ .name = "vaxis", .module = vaxis_dep.module("vaxis") }, }, }); _ = cov.addModule(cli_cov, "tally-cli", &.{ "src/main.zig", "src/cli" }); const tui_cov = b.createModule(.{ .root_source_file = b.path("src/tui.zig"), .target = target, .optimize = optimize, .imports = &.{ .{ .name = "engine", .module = engine_mod }, .{ .name = "vaxis", .module = vaxis_dep.module("vaxis") }, }, }); // tui.zig plus its views. main.zig and src/cli are deliberately excluded // even though they are not compiled into this binary, so the two app reports // stay disjoint by construction rather than by accident. _ = cov.addModule(tui_cov, "tally-tui", &.{ "src/tui.zig", "src/tui" }); } // -- Run step -- const run_step = b.step("run", "Run tally"); const run_cmd = b.addRunArtifact(exe); run_step.dependOn(&run_cmd.step); run_cmd.step.dependOn(b.getInstallStep()); if (b.args) |args| { run_cmd.addArgs(args); } }