const std = @import("std"); const build_helpers = @import("build_helpers"); pub fn build(b: *std.Build) void { const arch = b.option(build_helpers.Architecture, "arch", "The target ukernel architecture") orelse .amd64; // set CPU features based on the architecture var target_query: std.Target.Query = .{ .cpu_arch = arch.get(), .os_tag = .freestanding, .abi = .none, }; const arch_root_path, const linker_script_path, const code_model: std.builtin.CodeModel = blk: { switch (arch) { .amd64 => { const Feature = std.Target.x86.Feature; target_query.cpu_features_add.addFeature(@intFromEnum(Feature.soft_float)); target_query.cpu_features_sub.addFeature(@intFromEnum(Feature.mmx)); target_query.cpu_features_sub.addFeature(@intFromEnum(Feature.sse)); target_query.cpu_features_sub.addFeature(@intFromEnum(Feature.sse2)); target_query.cpu_features_sub.addFeature(@intFromEnum(Feature.avx)); target_query.cpu_features_sub.addFeature(@intFromEnum(Feature.avx2)); break :blk .{ "arch/amd64/root.zig", "arch/amd64/linker.ld", .kernel }; }, .aarch64 => { const Feature = std.Target.aarch64.Feature; target_query.cpu_features_sub.addFeature(@intFromEnum(Feature.fp_armv8)); target_query.cpu_features_sub.addFeature(@intFromEnum(Feature.crypto)); target_query.cpu_features_sub.addFeature(@intFromEnum(Feature.neon)); break :blk .{ "arch/aarch64/root.zig", "arch/aarch64/linker.ld", .default }; }, .riscv64 => { const Feature = std.Target.riscv.Feature; target_query.cpu_features_sub.addFeature(@intFromEnum(Feature.d)); break :blk .{ "arch/riscv64/root.zig", "arch/riscv64/linker.ld", .default }; }, } }; const target = b.resolveTargetQuery(target_query); const optimize = b.standardOptimizeOption(.{ .preferred_optimize_mode = .ReleaseSafe }); const arch_module = b.createModule(.{ .root_source_file = b.path(arch_root_path), .target = target, .optimize = optimize, .code_model = code_model, }); switch (arch) { .amd64 => { arch_module.addAssemblyFile(b.path("arch/amd64/asm/traps.S")); }, else => {}, } const limine_dep = b.dependency("limine", .{ .api_revision = 3, }); const spinlock_dep = b.dependency("spinlock", .{}); const flanterm_dep = b.dependency("flanterm", .{}); const limine_mod = limine_dep.module("limine"); const spinlock_mod = spinlock_dep.module("spinlock"); const flanterm_mod = b.createModule(.{ .root_source_file = b.path("common/aux/flanterm.zig"), }); flanterm_mod.addIncludePath(flanterm_dep.path("src")); flanterm_mod.addCSourceFile(.{ .file = flanterm_dep.path("src/flanterm.c") }); flanterm_mod.addCSourceFile(.{ .file = flanterm_dep.path("src/flanterm_backends/fb.c") }); const common_mod = b.createModule(.{ .root_source_file = b.path("common/root.zig"), }); arch_module.addImport("limine", limine_mod); arch_module.addImport("flanterm", flanterm_mod); arch_module.addImport("common", common_mod); common_mod.addImport("arch", arch_module); common_mod.addImport("spinlock", spinlock_mod); common_mod.addImport("flanterm", flanterm_mod); common_mod.addImport("limine", limine_mod); const kernel = b.addExecutable(.{ .name = "ukernel", .root_module = arch_module, // TODO: remove when x86 backend is less broken with removing CPU features .use_llvm = true, }); kernel.pie = false; kernel.want_lto = true; kernel.setLinkerScript(b.path(linker_script_path)); b.installArtifact(kernel); }