summaryrefslogtreecommitdiff
path: root/build.zig
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-03-25 17:41:18 -0400
committerFreya Murphy <freya@freyacat.org>2025-03-25 17:41:18 -0400
commitf89a4592c973a798ec47eb07b3701844d9ede54e (patch)
tree6ed2969f501aca686612700c336951c0d0f8deca /build.zig
parentinitial checkout from wrc (diff)
downloadcomus-f89a4592c973a798ec47eb07b3701844d9ede54e.tar.gz
comus-f89a4592c973a798ec47eb07b3701844d9ede54e.tar.bz2
comus-f89a4592c973a798ec47eb07b3701844d9ede54e.zip
convert build system to zig
Diffstat (limited to 'build.zig')
-rw-r--r--build.zig351
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,
+ },
+ });
+ }
+}