// Targets: // - default: ml (ReleaseSmall) // - dev: ml-dev (Debug) // - prod: ml (ReleaseSmall) -> zig-out/prod // - release: ml-release (ReleaseFast) -> zig-out/release // - cross: ml-* per platform -> zig-out/cross const std = @import("std"); pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{ .preferred_optimize_mode = .ReleaseSmall }); // Common executable configuration // Default build optimizes for small binary size (~200KB after strip) const exe = b.addExecutable(.{ .name = "ml", .root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, }), }); // Embed rsync binary if available const embed_rsync = b.option(bool, "embed-rsync", "Embed rsync binary in CLI") orelse false; if (embed_rsync) { // This would embed the actual rsync binary // For now, we'll use the wrapper approach exe.root_module.addCMacro("EMBED_RSYNC", "1"); } b.installArtifact(exe); // Default run command 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); // === Development Build === // Fast build with debug info for development const dev_exe = b.addExecutable(.{ .name = "ml-dev", .root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = b.resolveTargetQuery(.{}), // Use host target .optimize = .Debug, }), }); const dev_install = b.addInstallArtifact(dev_exe, .{ .dest_dir = .{ .override = .{ .custom = "dev" } }, }); const dev_step = b.step("dev", "Build development version (fast compilation, debug info)"); dev_step.dependOn(&dev_install.step); // === Production Build === // Optimized for size and speed const prod_exe = b.addExecutable(.{ .name = "ml", .root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = target, .optimize = .ReleaseSmall, // Optimize for small binary size }), }); const prod_install = b.addInstallArtifact(prod_exe, .{ .dest_dir = .{ .override = .{ .custom = "prod" } }, }); const prod_step = b.step("prod", "Build production version (optimized for size and speed)"); prod_step.dependOn(&prod_install.step); // === Release Build === // Fully optimized for performance const release_exe = b.addExecutable(.{ .name = "ml-release", .root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = target, .optimize = .ReleaseFast, // Optimize for speed }), }); const release_install = b.addInstallArtifact(release_exe, .{ .dest_dir = .{ .override = .{ .custom = "release" } }, }); const release_step = b.step("release", "Build release version (optimized for performance)"); release_step.dependOn(&release_install.step); // === Cross-Platform Builds === // Build for common platforms with descriptive binary names const cross_targets = [_]struct { query: std.Target.Query, name: []const u8, }{ .{ .query = .{ .cpu_arch = .x86_64, .os_tag = .linux }, .name = "ml-linux-x86_64" }, .{ .query = .{ .cpu_arch = .x86_64, .os_tag = .linux, .abi = .musl }, .name = "ml-linux-musl-x86_64" }, .{ .query = .{ .cpu_arch = .x86_64, .os_tag = .macos }, .name = "ml-macos-x86_64" }, .{ .query = .{ .cpu_arch = .aarch64, .os_tag = .macos }, .name = "ml-macos-aarch64" }, }; const cross_step = b.step("cross", "Build cross-platform binaries"); for (cross_targets) |ct| { const cross_target = b.resolveTargetQuery(ct.query); const cross_exe = b.addExecutable(.{ .name = ct.name, .root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = cross_target, .optimize = .ReleaseSmall, }), }); const cross_install = b.addInstallArtifact(cross_exe, .{ .dest_dir = .{ .override = .{ .custom = "cross" } }, }); cross_step.dependOn(&cross_install.step); } // === Clean Step === const clean_step = b.step("clean", "Clean build artifacts"); const clean_cmd = b.addSystemCommand(&[_][]const u8{ "rm", "-rf", "zig-out", ".zig-cache", }); clean_step.dependOn(&clean_cmd.step); // === Install Step === // Install binary to system PATH const install_step = b.step("install-system", "Install binary to /usr/local/bin"); const install_cmd = b.addSystemCommand(&[_][]const u8{ "sudo", "cp", "zig-out/bin/ml", "/usr/local/bin/", }); install_step.dependOn(&install_cmd.step); // === Size Check === // Show binary sizes for different builds const size_step = b.step("size", "Show binary sizes"); const size_cmd = b.addSystemCommand(&[_][]const u8{ "sh", "-c", "if [ -d zig-out/bin ]; then echo 'zig-out/bin contents:'; ls -lh zig-out/bin/; fi; " ++ "if [ -d zig-out/prod ]; then echo '\nzig-out/prod contents:'; ls -lh zig-out/prod/; fi; " ++ "if [ -d zig-out/release ]; then echo '\nzig-out/release contents:'; ls -lh zig-out/release/; fi; " ++ "if [ -d zig-out/cross ]; then echo '\nzig-out/cross contents:'; ls -lh zig-out/cross/; fi; " ++ "if [ ! -d zig-out/bin ] && [ ! -d zig-out/prod ] && [ ! -d zig-out/release ] && [ ! -d zig-out/cross ]; then " ++ "echo 'No CLI binaries found. Run zig build (default), zig build dev, zig build prod, or zig build release first.'; fi", }); size_step.dependOn(&size_cmd.step); // Test step const source_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, }); const test_module = b.createModule(.{ .root_source_file = b.path("tests/main_test.zig"), .target = target, .optimize = optimize, }); test_module.addImport("src", source_module); const exe_tests = b.addTest(.{ .root_module = test_module, }); const run_exe_tests = b.addRunArtifact(exe_tests); const test_step = b.step("test", "Run unit tests"); test_step.dependOn(&run_exe_tests.step); }