Migrate kernel to zig build
This commit is contained in:
parent
e19165963b
commit
1b75b576ad
|
|
@ -1,41 +1,6 @@
|
||||||
ARCHES = x86_64 i386
|
.PHONY: x86_64_stivale2 clean
|
||||||
|
x86_64_stivale2:
|
||||||
ARCH ?= x86_64
|
zig build -Dtarget="$@"
|
||||||
|
|
||||||
CC = zig cc -target $(ARCH)-freestanding
|
|
||||||
LD = ld -m elf_$(ARCH)
|
|
||||||
LDSCRIPT = make/$(ARCH)/linker.ld
|
|
||||||
|
|
||||||
-include make/$(ARCH)/make.config
|
|
||||||
|
|
||||||
CFLAGS ?= -Og -g
|
|
||||||
CFLAGS := $(CFLAGS) $(ARCH_CFLAGS) \
|
|
||||||
-Wall -Wextra -pedantic -std=gnu11 -I../ext -Isrc -fPIE -mno-red-zone
|
|
||||||
LDFLAGS := $(LDFLAGS) -T $(LDSCRIPT)
|
|
||||||
|
|
||||||
|
|
||||||
TARGET := kernel
|
|
||||||
|
|
||||||
CFILES := $(shell find src -path src/arch -prune -o -type f -name '*.c' -print)
|
|
||||||
ARCHFILES := $(ARCHFILES) $(shell find src/arch/$(ARCH) -type f -name '*.c' -print)
|
|
||||||
HFILES := $(shell find src -type f -name '*.h')
|
|
||||||
OBJ := $(patsubst src/%,obj/$(ARCH)/%.o,$(CFILES) $(ARCHFILES))
|
|
||||||
|
|
||||||
.PHONY: all clean obj $(ARCHES)
|
|
||||||
|
|
||||||
default: bin/$(TARGET)-$(ARCH)
|
|
||||||
all: $(ARCHES)
|
|
||||||
|
|
||||||
$(ARCHES):
|
|
||||||
@$(MAKE) ARCH=$@
|
|
||||||
|
|
||||||
bin/$(TARGET)-$(ARCH): $(OBJ)
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
$(LD) $(LDFLAGS) $(OBJ) -o $@
|
|
||||||
|
|
||||||
obj/$(ARCH)/%.c.o: src/%.c $(HFILES) $(ARCHHEADERS)
|
|
||||||
@mkdir -p $(@D)
|
|
||||||
$(CC) $(CFLAGS) -c $< -o $@
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf bin obj zig-cache
|
rm -rf bin zig-cache
|
||||||
|
|
@ -0,0 +1,194 @@
|
||||||
|
// imports
|
||||||
|
const std = @import("std");
|
||||||
|
const Builder = std.build.Builder;
|
||||||
|
|
||||||
|
// Alloc stuff
|
||||||
|
var GPAAlloc = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
var alloc = &GPAAlloc.allocator;
|
||||||
|
|
||||||
|
// Target enumeration stuff
|
||||||
|
const Target = struct {
|
||||||
|
parent: ?*const Target = null,
|
||||||
|
cpu_arch: ?std.Target.Cpu.Arch = null,
|
||||||
|
cpu_model: ?std.build.Target.CpuModel = null,
|
||||||
|
archdir: ?[]const u8 = null,
|
||||||
|
linkscript: ?[]const u8 = null,
|
||||||
|
name: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
const x86 = Target{
|
||||||
|
.archdir = "x86",
|
||||||
|
.name = "x86-generic"
|
||||||
|
};
|
||||||
|
const x86_64 = Target {
|
||||||
|
.parent = &x86,
|
||||||
|
.cpu_arch = std.Target.Cpu.Arch.x86_64,
|
||||||
|
.archdir = "x86_64",
|
||||||
|
.name = "x86_64-generic"
|
||||||
|
};
|
||||||
|
const x86_64_stivale2 = Target {
|
||||||
|
.parent = &x86_64,
|
||||||
|
// .archdir = "x86_64/stivale2",
|
||||||
|
.linkscript = "make/x86_64/linker.ld",
|
||||||
|
.name = "x86_64-stivale2",
|
||||||
|
};
|
||||||
|
|
||||||
|
const Targets = enum {
|
||||||
|
x86_64,
|
||||||
|
x86_64_stivale2,
|
||||||
|
|
||||||
|
pub fn getTarget(self: Targets) Target {
|
||||||
|
return switch(self) {
|
||||||
|
.x86_64 => x86_64_stivale2,
|
||||||
|
.x86_64_stivale2 => x86_64_stivale2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
pub fn default() Targets {
|
||||||
|
return Targets.x86_64_stivale2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn getCpuArch(t: Target) std.Target.Cpu.Arch {
|
||||||
|
return t.cpu_arch orelse getCpuArch(t.parent.?.*);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getCpuModel(t: Target) std.build.Target.CpuModel {
|
||||||
|
if(t.cpu_model) |m| {
|
||||||
|
return m;
|
||||||
|
} else if (t.parent) |p| {
|
||||||
|
return getCpuModel(t.parent.?.*);
|
||||||
|
} else {
|
||||||
|
return std.build.Target.CpuModel.baseline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getLinkerScript(t: Target) []const u8 {
|
||||||
|
return t.linkscript orelse getLinkerScript(t.parent.?.*);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getTarget(t: Target) std.zig.CrossTarget {
|
||||||
|
return .{
|
||||||
|
.cpu_arch = getCpuArch(t),
|
||||||
|
.cpu_model = getCpuModel(t),
|
||||||
|
.os_tag = std.Target.Os.Tag.freestanding,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Directory traversal stuff
|
||||||
|
const Files = struct {
|
||||||
|
generic_c: [][]const u8,
|
||||||
|
archspecific_c: [][]const u8,
|
||||||
|
archspecific_s: [][]const u8,
|
||||||
|
nasm: [][]const u8,
|
||||||
|
};
|
||||||
|
fn strPrefix(str: []const u8, prefix: []const u8) bool {
|
||||||
|
if (str.len < prefix.len) return false;
|
||||||
|
return std.mem.eql(u8, str[0..prefix.len], prefix);
|
||||||
|
}
|
||||||
|
fn fileExtEql(name: []const u8, ext: []const u8) bool {
|
||||||
|
std.debug.assert(ext[0] == '.');
|
||||||
|
if(name.len <= ext.len) return false;
|
||||||
|
const file_ext = name[name.len - ext.len..];
|
||||||
|
return std.mem.eql(u8, file_ext, ext);
|
||||||
|
}
|
||||||
|
fn findSources(dir: []const u8, ext: []const u8, prefix: ?[]const u8) ![][] const u8 {
|
||||||
|
var files = std.ArrayList([]const u8).init(alloc);
|
||||||
|
var walker = try std.fs.walkPath(alloc, dir);
|
||||||
|
while (try walker.next()) |entry| {
|
||||||
|
if(entry.kind != std.fs.Dir.Entry.Kind.File) continue;
|
||||||
|
|
||||||
|
if(prefix != null and strPrefix(entry.path, prefix.?)) {
|
||||||
|
// std.debug.print("Ignoring {}\n", .{entry.path});
|
||||||
|
} else {
|
||||||
|
if(fileExtEql(entry.basename, ext)) {
|
||||||
|
// std.debug.print("Adding file {}\n", .{entry.path});
|
||||||
|
var p = std.ArrayList(u8).init(alloc);
|
||||||
|
try p.appendSlice(entry.path);
|
||||||
|
try files.append(p.toOwnedSlice());
|
||||||
|
} else {
|
||||||
|
// std.debug.print("wrong file extension: {}\n", .{entry.basename});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
walker.deinit();
|
||||||
|
return files.toOwnedSlice();
|
||||||
|
}
|
||||||
|
fn findArch(t: Target, ext: []const u8) ![][] const u8 {
|
||||||
|
var arch_c = std.ArrayList([]const u8).init(alloc);
|
||||||
|
if (t.parent) |parent| {
|
||||||
|
const parentfiles = findArch(parent.*, ext) catch unreachable;
|
||||||
|
try arch_c.appendSlice( parentfiles );
|
||||||
|
}
|
||||||
|
if (t.archdir) |archdir| {
|
||||||
|
const dir = try std.fmt.allocPrint(alloc, "src/arch/{}", .{archdir});
|
||||||
|
const files = try findSources(dir, ext, null);
|
||||||
|
try arch_c.appendSlice(files);
|
||||||
|
}
|
||||||
|
return arch_c.items;
|
||||||
|
}
|
||||||
|
fn findFiles(t: Target) !Files {
|
||||||
|
const generic_c = try findSources("src", ".c", "src/arch/");
|
||||||
|
const arch_c = try findArch(t, ".c");
|
||||||
|
const arch_s = try findArch(t, ".s");
|
||||||
|
const nasm = try findArch(t, ".nasm");
|
||||||
|
|
||||||
|
return Files {
|
||||||
|
.generic_c = generic_c,
|
||||||
|
.archspecific_c = arch_c,
|
||||||
|
.archspecific_s = arch_s,
|
||||||
|
.nasm = nasm
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(b: *Builder) !void {
|
||||||
|
const target_option = b.option(Targets, "target", "The kernel target") orelse Targets.default();
|
||||||
|
const ktarget = target_option.getTarget();
|
||||||
|
|
||||||
|
// Standard release options allow the person running `zig build` to select
|
||||||
|
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
|
||||||
|
const mode = b.standardReleaseOptions();
|
||||||
|
|
||||||
|
b.cache_root = "zig-cache";
|
||||||
|
|
||||||
|
const files = try findFiles(ktarget);
|
||||||
|
|
||||||
|
const cflags = [_][]const u8{"-Wall", "-Wextra", "-pedantic", "-std=gnu11", "-I../ext", "-Isrc", "-fPIE", "-mno-red-zone"};
|
||||||
|
|
||||||
|
const exename = try std.fmt.allocPrint(alloc, "kernel-{}", .{ktarget.name});
|
||||||
|
const exe = b.addExecutable(exename, "src/main.zig");
|
||||||
|
var cfiles = std.ArrayList([]const u8).init(alloc);
|
||||||
|
try cfiles.appendSlice(files.generic_c);
|
||||||
|
try cfiles.appendSlice(files.archspecific_c);
|
||||||
|
for (cfiles.items) |c_file| {
|
||||||
|
// std.debug.print("CC: {}\n", .{c_file});
|
||||||
|
exe.addCSourceFile(c_file, &cflags);
|
||||||
|
}
|
||||||
|
for(files.archspecific_s) |s_file| {
|
||||||
|
// std.debug.print("zig as: {}\n", .{s_file});
|
||||||
|
exe.addAssemblyFile(s_file);
|
||||||
|
}
|
||||||
|
for(files.nasm) |nasm_file| {
|
||||||
|
// std.debug.print("nasm: {}\n", .{nasm_file});
|
||||||
|
const output = try std.fmt.allocPrint(alloc, "zig-cache/nasm/{}.o", .{nasm_file});
|
||||||
|
const output_folder = std.fs.cwd().makePath(std.fs.path.dirname(output).?);
|
||||||
|
const assX = b.addSystemCommand(&[_][]const u8{"nasm", "-Isrc", "-felf64", nasm_file, "-o", output});
|
||||||
|
exe.step.dependOn(&assX.step);
|
||||||
|
exe.addObjectFile(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
exe.setTarget(getTarget(ktarget));
|
||||||
|
exe.setBuildMode(mode);
|
||||||
|
exe.setLinkerScriptPath(getLinkerScript(ktarget));
|
||||||
|
exe.setOutputDir("bin");
|
||||||
|
exe.install();
|
||||||
|
|
||||||
|
const run_cmd = exe.run();
|
||||||
|
run_cmd.step.dependOn(b.getInstallStep());
|
||||||
|
if (b.args) |args| {
|
||||||
|
run_cmd.addArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// const run_step = b.step("run", "Run the app");
|
||||||
|
// run_step.dependOn(&run_cmd.step);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn zigmain() anyerror!void {
|
||||||
|
std.log.info("All your codebase are belong to us.", .{});
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue