diff options
author | Freya Murphy <freya@freyacat.org> | 2025-03-25 17:41:18 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2025-03-25 17:41:18 -0400 |
commit | f89a4592c973a798ec47eb07b3701844d9ede54e (patch) | |
tree | 6ed2969f501aca686612700c336951c0d0f8deca /build.zig | |
parent | initial checkout from wrc (diff) | |
download | comus-f89a4592c973a798ec47eb07b3701844d9ede54e.tar.gz comus-f89a4592c973a798ec47eb07b3701844d9ede54e.tar.bz2 comus-f89a4592c973a798ec47eb07b3701844d9ede54e.zip |
convert build system to zig
Diffstat (limited to 'build.zig')
-rw-r--r-- | build.zig | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/build.zig b/build.zig new file mode 100644 index 0000000..0485259 --- /dev/null +++ b/build.zig @@ -0,0 +1,351 @@ +const std = @import("std"); +const builtin = @import("builtin"); + +const c_flags = &[_][]const u8{ + // lang + "-std=c99", + // warnings + "-Wall", + "-Wextra", + "-pedantic", + // flags + "-fno-pie", + "-fno-stack-protector", + "-fno-omit-frame-pointer", + "-ffreestanding", + "-fno-builtin", +}; + +const ld_flags = &[_][]const u8{ + "-nmagic", + "-nostdlib", + "--no-warn-rwx-segments", +}; + +const boot_src = &[_][]const u8{"boot/boot.S"}; + +const kernel_src = &[_][]const u8{ + "kernel/cio.c", + "kernel/clock.c", + "kernel/isrs.S", + "kernel/kernel.c", + "kernel/kmem.c", + "kernel/list.c", + "kernel/procs.c", + "kernel/sio.c", + "kernel/startup.S", + "kernel/support.c", + "kernel/syscalls.c", + "kernel/user.c", + "kernel/vm.c", + "kernel/vmtables.c", + "lib/klibc.c", +}; + +const lib_src = &[_][]const u8{ + "lib/bound.c", + "lib/cvtdec0.c", + "lib/cvtdec.c", + "lib/cvthex.c", + "lib/cvtoct.c", + "lib/cvtuns0.c", + "lib/cvtuns.c", + "lib/memclr.c", + "lib/memcpy.c", + "lib/memset.c", + "lib/pad.c", + "lib/padstr.c", + "lib/sprint.c", + "lib/str2int.c", + "lib/strcat.c", + "lib/strcmp.c", + "lib/strcpy.c", + "lib/strlen.c", +}; + +const ulib_src = &[_][]const u8{ + "lib/entry.S", + "lib/ulibc.c", + "lib/ulibs.S", +}; + +const Prog = struct { + name: []const u8, + source: []const []const u8, +}; + +const util_progs = &[_]Prog{ + // mkblob + Prog{ + .name = "mkblob", + .source = &[_][]const u8{"util/mkblob.c"}, + }, + // listblob + Prog{ + .name = "listblob", + .source = &[_][]const u8{"util/listblob.c"}, + }, + // BuildImage + Prog{ + .name = "BuildImage", + .source = &[_][]const u8{"util/BuildImage.c"}, + }, +}; + +const user_progs = &[_]Prog{ + // idle + Prog{ + .name = "idle", + .source = &[_][]const u8{"user/idle.c"}, + }, + // init + Prog{ + .name = "init", + .source = &[_][]const u8{"user/init.c"}, + }, + // progABC + Prog{ + .name = "progABC", + .source = &[_][]const u8{"user/progABC.c"}, + }, + // progDE + Prog{ + .name = "progDE", + .source = &[_][]const u8{"user/progDE.c"}, + }, + // progFG + Prog{ + .name = "progFG", + .source = &[_][]const u8{"user/progFG.c"}, + }, + // progH + Prog{ + .name = "progH", + .source = &[_][]const u8{"user/progH.c"}, + }, + // progI + Prog{ + .name = "progI", + .source = &[_][]const u8{"user/progI.c"}, + }, + // progJ + Prog{ + .name = "progJ", + .source = &[_][]const u8{"user/progJ.c"}, + }, + // progKL + Prog{ + .name = "progKL", + .source = &[_][]const u8{"user/progKL.c"}, + }, + // progKL + Prog{ + .name = "progKL", + .source = &[_][]const u8{"user/progKL.c"}, + }, + // progMN + Prog{ + .name = "progMN", + .source = &[_][]const u8{"user/progMN.c"}, + }, + // progP + Prog{ + .name = "progP", + .source = &[_][]const u8{"user/progP.c"}, + }, + // progQ + Prog{ + .name = "progQ", + .source = &[_][]const u8{"user/progQ.c"}, + }, + // progR + Prog{ + .name = "progR", + .source = &[_][]const u8{"user/progR.c"}, + }, + // progS + Prog{ + .name = "progS", + .source = &[_][]const u8{"user/progS.c"}, + }, + // progTUV + Prog{ + .name = "progTUV", + .source = &[_][]const u8{"user/progTUV.c"}, + }, + // progW + Prog{ + .name = "progW", + .source = &[_][]const u8{"user/progW.c"}, + }, + // progX + Prog{ + .name = "progX", + .source = &[_][]const u8{"user/progX.c"}, + }, + // progY + Prog{ + .name = "progY", + .source = &[_][]const u8{"user/progY.c"}, + }, + // progZ + Prog{ + .name = "progZ", + .source = &[_][]const u8{"user/progZ.c"}, + }, + // shell + Prog{ + .name = "shell", + .source = &[_][]const u8{"user/shell.c"}, + }, +}; + +const AddSourcesOpts = struct { exe: *std.Build.Step.Compile, sources: []const []const []const u8, c_flags: []const []const u8 }; + +fn add_sources(b: *std.Build, opts: AddSourcesOpts) void { + // add asm and c source files + for (opts.sources) |source| { + for (source) |file| { + if (std.mem.endsWith(u8, file, ".c")) { + // c file + opts.exe.addCSourceFile(.{ .file = b.path(file), .flags = opts.c_flags }); + } else { + // assembly file + opts.exe.addAssemblyFile(b.path(file)); + } + } + } +} + +const BuildKernBinaryOpts = struct { + name: []const u8, + target: std.Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, + sources: []const []const []const u8, + linker: ?[]const u8 = null, + entry: []const u8 = "_start", +}; + +fn build_kern_binary(b: *std.Build, opts: BuildKernBinaryOpts) void { + // create compile step + const exe = b.addExecutable(.{ + .name = opts.name, + .target = opts.target, + .optimize = opts.optimize, + .strip = true, + }); + + // add include path + exe.addIncludePath(b.path("include/")); + exe.entry = .{ .symbol_name = opts.entry }; + + // add asm and c source files + add_sources(b, .{ + .exe = exe, + .sources = opts.sources, + .c_flags = c_flags, + }); + + if (opts.linker != null) { + exe.setLinkerScript(b.path(opts.linker.?)); + } + + const step = b.addInstallArtifact(exe, .{ .dest_dir = .{ + .override = .{ .custom = "../bin" }, + } }); + b.getInstallStep().dependOn(&step.step); +} + +const BuildNativeBinaryOpts = struct { + name: []const u8, + optimize: std.builtin.OptimizeMode, + sources: []const []const []const u8, +}; + +fn build_native_binary(b: *std.Build, opts: BuildNativeBinaryOpts) void { + // create compile step + const exe = b.addExecutable(.{ + .name = opts.name, + .target = b.graph.host, + .optimize = opts.optimize, + .strip = true, + }); + + // include libc + exe.linkLibC(); + + // add asm and c source files + add_sources(b, .{ + .exe = exe, + .sources = opts.sources, + .c_flags = &.{}, + }); + + const step = b.addInstallArtifact(exe, .{ .dest_dir = .{ + .override = .{ .custom = "../bin" }, + } }); + b.getInstallStep().dependOn(&step.step); +} + +pub fn build(b: *std.Build) !void { + + // context + const target = b.standardTargetOptions(.{ + .default_target = .{ + .cpu_arch = std.Target.Cpu.Arch.x86, + .os_tag = std.Target.Os.Tag.freestanding, + .abi = std.Target.Abi.gnu, + .ofmt = std.Target.ObjectFormat.elf, + }, + }); + const optimize = std.builtin.OptimizeMode.ReleaseSmall; + + // boot + build_kern_binary(b, .{ + .name = "boot", + .target = target, + .optimize = optimize, + .sources = &.{ + boot_src, + }, + .linker = "boot/boot.ld", + .entry = "bootentry", + }); + + // kernel + build_kern_binary(b, .{ + .name = "kernel", + .target = target, + .optimize = optimize, + .sources = &.{ + kernel_src, + lib_src, + }, + .linker = "kernel/kernel.ld", + }); + + // user_progs + for (user_progs) |prog| { + build_kern_binary(b, .{ + .name = prog.name, + .target = target, + .optimize = optimize, + .sources = &.{ + prog.source, + lib_src, + ulib_src, + }, + }); + } + + // util_progs + for (util_progs) |prog| { + build_native_binary(b, .{ + .name = prog.name, + .optimize = optimize, + .sources = &.{ + prog.source, + }, + }); + } +} |