pluto/build.zig

156 lines
5.9 KiB
Zig
Raw Normal View History

const std = @import("std");
const builtin = @import("builtin");
const rt = @import("test/runtime_test.zig");
const RuntimeStep = rt.RuntimeStep;
const Builder = std.build.Builder;
const LibExeObjStep = std.build.LibExeObjStep;
const Step = std.build.Step;
const Target = std.Target;
const CrossTarget = std.zig.CrossTarget;
const fs = std.fs;
const Mode = builtin.Mode;
const TestMode = rt.TestMode;
const ArrayList = std.ArrayList;
2020-06-02 19:54:41 +02:00
const x86_i686 = CrossTarget{
.cpu_arch = .i386,
.os_tag = .freestanding,
.cpu_model = .{ .explicit = &Target.x86.cpu._i686 },
};
2020-06-02 19:54:41 +02:00
pub fn build(b: *Builder) !void {
const arch = b.option([]const u8, "arch", "Architecture to build for: x86") orelse "x86";
const target: CrossTarget = if (std.mem.eql(u8, "x86", arch))
x86_i686
else {
std.debug.warn("Unsupported or unknown architecture '{}'\n", .{arch});
unreachable;
};
2020-01-15 17:30:30 +01:00
const fmt_step = b.addFmt(&[_][]const u8{
"build.zig",
"src",
"test",
});
b.default_step.dependOn(&fmt_step.step);
const main_src = "src/kernel/kmain.zig";
2020-06-02 19:41:54 +02:00
const arch_root = "src/kernel/arch";
const constants_path = try fs.path.join(b.allocator, &[_][]const u8{ arch_root, arch, "constants.zig" });
const linker_script_path = try fs.path.join(b.allocator, &[_][]const u8{ arch_root, arch, "link.ld" });
const output_iso = try fs.path.join(b.allocator, &[_][]const u8{ b.exe_dir, "pluto.iso" });
const iso_dir_path = try fs.path.join(b.allocator, &[_][]const u8{ b.exe_dir, "iso" });
const boot_path = try fs.path.join(b.allocator, &[_][]const u8{ b.exe_dir, "iso", "boot" });
const modules_path = try fs.path.join(b.allocator, &[_][]const u8{ b.exe_dir, "iso", "modules" });
2019-09-17 20:00:33 +02:00
const build_mode = b.standardReleaseOptions();
comptime var test_mode_desc: []const u8 = "\n ";
inline for (@typeInfo(TestMode).Enum.fields) |field| {
const tm = @field(TestMode, field.name);
test_mode_desc = test_mode_desc ++ field.name ++ " (" ++ TestMode.getDescription(tm) ++ ")";
test_mode_desc = test_mode_desc ++ "\n ";
}
const test_mode = b.option(TestMode, "test-mode", "Run a specific runtime test. This option is for the rt-test step. Available options: " ++ test_mode_desc) orelse .None;
const disable_display = b.option(bool, "disable-display", "Disable the qemu window") orelse false;
2020-06-02 19:54:41 +02:00
const exec = b.addExecutable("pluto.elf", main_src);
exec.addPackagePath("constants", constants_path);
exec.setOutputDir(b.cache_root);
exec.addBuildOption(TestMode, "test_mode", test_mode);
exec.setBuildMode(build_mode);
2020-06-02 19:41:54 +02:00
exec.setLinkerScriptPath(linker_script_path);
exec.setTarget(target);
2020-06-02 19:54:41 +02:00
const make_iso = switch (target.getCpuArch()) {
.i386 => b.addSystemCommand(&[_][]const u8{ "./makeiso.sh", boot_path, modules_path, iso_dir_path, exec.getOutputPath(), output_iso }),
else => unreachable,
};
make_iso.step.dependOn(&exec.step);
b.default_step.dependOn(&make_iso.step);
const test_step = b.step("test", "Run tests");
const mock_path = "\"../../test/mock/kernel/\"";
const arch_mock_path = "\"../../../../test/mock/kernel/\"";
const unit_tests = b.addTest(main_src);
unit_tests.setBuildMode(build_mode);
unit_tests.setMainPkgPath(".");
unit_tests.addPackagePath("constants", constants_path);
unit_tests.addBuildOption(TestMode, "test_mode", test_mode);
unit_tests.addBuildOption([]const u8, "mock_path", mock_path);
unit_tests.addBuildOption([]const u8, "arch_mock_path", arch_mock_path);
if (builtin.os.tag != .windows) {
unit_tests.enable_qemu = true;
}
unit_tests.setTarget(.{ .cpu_arch = target.cpu_arch });
test_step.dependOn(&unit_tests.step);
2019-10-01 18:35:15 +02:00
const rt_test_step = b.step("rt-test", "Run runtime tests");
const build_mode_str = switch (build_mode) {
.Debug => "",
.ReleaseSafe => "-Drelease-safe",
.ReleaseFast => "-Drelease-fast",
.ReleaseSmall => "-Drelease-small",
};
var qemu_args_al = ArrayList([]const u8).init(b.allocator);
defer qemu_args_al.deinit();
switch (target.getCpuArch()) {
.i386 => try qemu_args_al.append("qemu-system-i386"),
else => unreachable,
}
try qemu_args_al.append("-serial");
try qemu_args_al.append("stdio");
switch (target.getCpuArch()) {
.i386 => {
try qemu_args_al.append("-boot");
try qemu_args_al.append("d");
try qemu_args_al.append("-cdrom");
try qemu_args_al.append(output_iso);
2020-06-02 19:54:41 +02:00
},
else => unreachable,
}
if (disable_display) {
try qemu_args_al.append("-display");
try qemu_args_al.append("none");
}
var qemu_args = qemu_args_al.toOwnedSlice();
const rt_step = RuntimeStep.create(b, test_mode, qemu_args);
rt_step.step.dependOn(&make_iso.step);
rt_test_step.dependOn(&rt_step.step);
const run_step = b.step("run", "Run with qemu");
const run_debug_step = b.step("debug-run", "Run with qemu and wait for a gdb connection");
2019-10-01 18:35:15 +02:00
const qemu_cmd = b.addSystemCommand(qemu_args);
const qemu_debug_cmd = b.addSystemCommand(qemu_args);
2020-01-01 20:12:36 +01:00
qemu_debug_cmd.addArgs(&[_][]const u8{ "-s", "-S" });
qemu_cmd.step.dependOn(&make_iso.step);
qemu_debug_cmd.step.dependOn(&make_iso.step);
2019-10-01 18:35:15 +02:00
run_step.dependOn(&qemu_cmd.step);
run_debug_step.dependOn(&qemu_debug_cmd.step);
2019-10-01 18:35:15 +02:00
const debug_step = b.step("debug", "Debug with gdb and connect to a running qemu instance");
const symbol_file_arg = try std.mem.join(b.allocator, " ", &[_][]const u8{ "symbol-file", exec.getOutputPath() });
2020-01-01 20:12:36 +01:00
const debug_cmd = b.addSystemCommand(&[_][]const u8{
2020-06-02 19:54:41 +02:00
"gdb-multiarch",
"-ex",
2019-09-12 00:25:34 +02:00
symbol_file_arg,
2020-06-02 19:54:41 +02:00
"-ex",
"set architecture auto",
});
2020-01-01 20:12:36 +01:00
debug_cmd.addArgs(&[_][]const u8{
"-ex",
"target remote localhost:1234",
});
debug_step.dependOn(&debug_cmd.step);
}