2019-04-30 11:43:40 +02:00
|
|
|
const std = @import("std");
|
2019-09-03 20:13:26 +02:00
|
|
|
const builtin = @import("builtin");
|
|
|
|
const Builder = std.build.Builder;
|
2019-09-16 23:19:21 +02:00
|
|
|
const LibExeObjStep = std.build.LibExeObjStep;
|
2019-09-03 20:13:26 +02:00
|
|
|
const Step = std.build.Step;
|
2020-04-12 23:26:34 +02:00
|
|
|
const Target = std.Target;
|
|
|
|
const CrossTarget = std.zig.CrossTarget;
|
2019-09-03 20:13:26 +02:00
|
|
|
const fs = std.fs;
|
2019-09-08 21:48:23 +02:00
|
|
|
const Mode = builtin.Mode;
|
2019-09-03 20:13:26 +02:00
|
|
|
|
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 },
|
|
|
|
};
|
2019-09-08 21:48:23 +02:00
|
|
|
|
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;
|
2019-09-08 21:48:23 +02:00
|
|
|
};
|
2019-09-16 23:19:21 +02:00
|
|
|
|
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);
|
|
|
|
|
2020-01-09 14:08:00 +01:00
|
|
|
const main_src = "src/kernel/kmain.zig";
|
2020-06-02 19:54:41 +02:00
|
|
|
const constants_path = try fs.path.join(b.allocator, &[_][]const u8{ "src/kernel/arch", arch, "constants.zig" });
|
2020-01-09 14:08:00 +01:00
|
|
|
|
2019-09-17 20:00:33 +02:00
|
|
|
const build_mode = b.standardReleaseOptions();
|
2019-06-30 00:50:44 +02:00
|
|
|
const rt_test = b.option(bool, "rt-test", "enable/disable runtime testing") orelse false;
|
2019-04-17 18:40:26 +02:00
|
|
|
|
2020-06-02 19:54:41 +02:00
|
|
|
const exec = b.addExecutable("pluto.elf", main_src);
|
2019-09-16 23:19:21 +02:00
|
|
|
exec.addPackagePath("constants", constants_path);
|
2020-01-09 14:08:00 +01:00
|
|
|
exec.setOutputDir(b.cache_root);
|
2019-09-03 20:13:26 +02:00
|
|
|
exec.addBuildOption(bool, "rt_test", rt_test);
|
2020-01-09 14:08:00 +01:00
|
|
|
exec.setBuildMode(build_mode);
|
2019-09-03 20:13:26 +02:00
|
|
|
exec.setLinkerScriptPath("link.ld");
|
2020-04-12 23:26:34 +02:00
|
|
|
exec.setTarget(target);
|
2019-05-31 08:41:28 +02:00
|
|
|
|
2020-01-09 14:08:00 +01:00
|
|
|
const output_iso = try fs.path.join(b.allocator, &[_][]const u8{ b.exe_dir, "pluto.iso" });
|
2020-01-01 20:12:36 +01:00
|
|
|
const iso_dir_path = try fs.path.join(b.allocator, &[_][]const u8{ b.exe_dir, "iso" });
|
2020-01-09 14:08:00 +01:00
|
|
|
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-05-13 00:31:38 +02:00
|
|
|
|
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,
|
|
|
|
};
|
2019-04-17 18:40:26 +02:00
|
|
|
|
2020-01-09 14:08:00 +01:00
|
|
|
make_iso.step.dependOn(&exec.step);
|
|
|
|
b.default_step.dependOn(&make_iso.step);
|
2019-04-17 18:40:26 +02:00
|
|
|
|
2020-01-09 14:08:00 +01:00
|
|
|
const test_step = b.step("test", "Run tests");
|
|
|
|
if (rt_test) {
|
2020-06-02 19:54:41 +02:00
|
|
|
const script = b.addSystemCommand(&[_][]const u8{ "python3", "test/rt-test.py", arch, b.zig_exe });
|
2020-01-09 14:08:00 +01:00
|
|
|
test_step.dependOn(&script.step);
|
|
|
|
} else {
|
|
|
|
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(bool, "rt_test", rt_test);
|
|
|
|
unit_tests.addBuildOption([]const u8, "mock_path", mock_path);
|
|
|
|
unit_tests.addBuildOption([]const u8, "arch_mock_path", arch_mock_path);
|
2019-04-17 18:40:26 +02:00
|
|
|
|
2020-04-12 23:26:34 +02:00
|
|
|
if (builtin.os.tag != .windows) unit_tests.enable_qemu = true;
|
2019-11-02 03:18:02 +01:00
|
|
|
|
2020-06-02 19:54:41 +02:00
|
|
|
unit_tests.setTarget(.{ .cpu_arch = target.cpu_arch });
|
2019-11-02 03:18:02 +01:00
|
|
|
|
2020-01-09 14:08:00 +01:00
|
|
|
test_step.dependOn(&unit_tests.step);
|
|
|
|
}
|
2019-04-17 18:40:26 +02:00
|
|
|
|
2019-09-03 20:13:26 +02:00
|
|
|
const run_step = b.step("run", "Run with qemu");
|
2019-10-01 18:35:15 +02:00
|
|
|
const run_debug_step = b.step("debug-run", "Run with qemu and wait for a gdb connection");
|
|
|
|
|
2020-04-12 23:26:34 +02:00
|
|
|
const qemu_bin = switch (target.getCpuArch()) {
|
2019-09-16 23:19:21 +02:00
|
|
|
.i386 => "qemu-system-i386",
|
|
|
|
else => unreachable,
|
|
|
|
};
|
2020-01-01 20:12:36 +01:00
|
|
|
const qemu_args = &[_][]const u8{
|
2019-09-03 20:13:26 +02:00
|
|
|
qemu_bin,
|
2019-04-30 11:43:40 +02:00
|
|
|
"-serial",
|
|
|
|
"stdio",
|
2019-10-01 18:35:15 +02:00
|
|
|
};
|
2020-06-02 19:54:41 +02:00
|
|
|
const qemu_machine_args = switch (target.getCpuArch()) {
|
|
|
|
.i386 => &[_][]const u8{
|
|
|
|
"-boot",
|
|
|
|
"d",
|
|
|
|
"-cdrom",
|
|
|
|
output_iso,
|
|
|
|
},
|
|
|
|
else => null,
|
|
|
|
};
|
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" });
|
2020-06-02 19:54:41 +02:00
|
|
|
if (qemu_machine_args) |machine_args| {
|
|
|
|
qemu_cmd.addArgs(machine_args);
|
|
|
|
qemu_debug_cmd.addArgs(machine_args);
|
|
|
|
}
|
2019-09-16 23:19:21 +02:00
|
|
|
|
|
|
|
if (rt_test) {
|
2020-01-01 20:12:36 +01:00
|
|
|
const qemu_rt_test_args = &[_][]const u8{ "-display", "none" };
|
2019-10-01 18:35:15 +02:00
|
|
|
qemu_cmd.addArgs(qemu_rt_test_args);
|
|
|
|
qemu_debug_cmd.addArgs(qemu_rt_test_args);
|
2019-09-16 23:19:21 +02:00
|
|
|
}
|
|
|
|
|
2020-01-09 14:08:00 +01:00
|
|
|
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-04-30 11:43:40 +02:00
|
|
|
|
2019-10-01 18:35:15 +02:00
|
|
|
const debug_step = b.step("debug", "Debug with gdb and connect to a running qemu instance");
|
2020-01-09 14:08:00 +01:00
|
|
|
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",
|
2019-09-03 20:13:26 +02:00
|
|
|
"-ex",
|
2019-09-12 00:25:34 +02:00
|
|
|
symbol_file_arg,
|
2020-06-02 19:54:41 +02:00
|
|
|
"-ex",
|
|
|
|
"set architecture auto",
|
2019-09-03 20:13:26 +02:00
|
|
|
});
|
2020-01-01 20:12:36 +01:00
|
|
|
debug_cmd.addArgs(&[_][]const u8{
|
2019-09-03 20:13:26 +02:00
|
|
|
"-ex",
|
|
|
|
"target remote localhost:1234",
|
|
|
|
});
|
|
|
|
debug_step.dependOn(&debug_cmd.step);
|
2019-04-30 11:43:40 +02:00
|
|
|
}
|