const std = @import("std"); const Build = std.Build; fn addLinuxAssembly(b: *Build, filename: []const u8) !std.Build.LazyPath { const obj_basename = try std.mem.concat(b.allocator, u8, &.{ std.fs.path.stem(filename), ".o" }); const obj = b.addSystemCommand(&.{ "nasm", "-g", "-f", "elf64", "-o" }); const output_obj = obj.addOutputFileArg(obj_basename); obj.addFileArg(.{ .path = filename }); return output_obj; } fn addAllLinuxAssmeblies(b: *Build, path: []const u8) !std.ArrayList(std.Build.LazyPath) { const allocator = b.allocator; var linux_assemblies = std.ArrayList(std.Build.LazyPath).init(allocator); errdefer linux_assemblies.deinit(); var dir = try std.fs.cwd().openDir(path, .{ .iterate = true }); var it = dir.iterate(); while (try it.next()) |file| { if (file.kind != .file) continue; const ext = std.fs.path.extension(file.name); if (!std.mem.eql(u8, ext, ".asm")) continue; const assembly_path = try std.fs.path.join(allocator, &.{ path, file.name }); defer allocator.free(assembly_path); try linux_assemblies.append(try addLinuxAssembly(b, assembly_path)); } return linux_assemblies; } pub fn build(b: *Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const allocator = b.allocator; var dir = try std.fs.cwd().openDir("src", .{ .iterate = true }); var it = dir.iterate(); while (try it.next()) |entry| { if (entry.kind != .directory) continue; const program_dir = try std.fs.path.join(allocator, &.{ "src", entry.name }); defer allocator.free(program_dir); const main_c = try std.fs.path.join(allocator, &.{ program_dir, "main.c" }); defer allocator.free(main_c); const exe = b.addExecutable(.{ .name = entry.name, .optimize = optimize, .target = target }); exe.addIncludePath(.{ .path = program_dir }); exe.addIncludePath(.{ .path = "src" }); exe.addCSourceFile(.{ .file = b.path(main_c) }); exe.linkLibC(); var assemblies = try addAllLinuxAssmeblies(b, program_dir); defer assemblies.deinit(); for (assemblies.items) |obj| { exe.addObjectFile(obj); } b.installArtifact(exe); const run_exe = b.addRunArtifact(exe); if (b.args) |args| { run_exe.addArgs(args); } const step_description = try std.fmt.allocPrint(b.allocator, "Run '{s}' test", .{ entry.name }); defer b.allocator.free(step_description); const run_step = b.step(entry.name, step_description); run_step.dependOn(&run_exe.step); } }