Skip to content

Commit f6721ec

Browse files
committed
A more structured build.zig for building user apps
1 parent c7761da commit f6721ec

File tree

4 files changed

+107
-65
lines changed

4 files changed

+107
-65
lines changed

cmake/x86/userflags.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ set(MOS_USER_GCC_INCLUDE_DIRS
1616
)
1717

1818
set(MOS_USER_LINKER_SCRIPT_FILE ${PROJECT_SOURCE_DIR}/src/kernel/x86/process.ld)
19+
set(MOS_USER_APP_ENTRY_POINT proc_main)

src/apps/zapps/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ set(ZIG_BUILD_DEFINES
1010
-DLibCMPath=$<TARGET_FILE_DIR:cm>
1111
-DCRTPath=$<TARGET_OBJECTS:crta>
1212
-DCInludePath=${MOS_USER_GCC_INCLUDE_DIRS}
13+
-DEntryPoint=${MOS_USER_APP_ENTRY_POINT}
1314
)
1415

1516
add_custom_command(
@@ -21,7 +22,7 @@ add_custom_command(
2122
${CMAKE_CURRENT_LIST_DIR}/zig-out/hello.flt
2223
COMMAND ${ZIG_EXECUTABLE} build ${ZIG_BUILD_OPTIONS} ${ZIG_BUILD_DEFINES}
2324
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/zig-out/bin/hello ${MOS_OBJ_DIR}
24-
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/zig-out/hello.flt ${MOS_BIN_DIR}
25+
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/zig-out/bin/hello.flt ${MOS_BIN_DIR}
2526
DEPENDS
2627
${CMAKE_CURRENT_LIST_DIR}/hello.zig
2728
${CMAKE_CURRENT_LIST_DIR}/build.zig

src/apps/zapps/MosBuild.zig

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
const std = @import("std");
2+
const Build = std.Build;
3+
const Step = Build.Step;
4+
5+
const Self = @This();
6+
7+
const BuildOptions = struct {
8+
linker_script_rel_path: []const u8,
9+
libcm_rel_path: []const u8,
10+
crta_rel_path: []const u8,
11+
include_rel_path: []const u8,
12+
entry_point: []const u8,
13+
};
14+
15+
const i686_cpu_model = std.Target.Cpu.Model{
16+
.name = "i686",
17+
.llvm_name = "",
18+
.features = .empty,
19+
};
20+
21+
options: BuildOptions,
22+
b: *Build,
23+
optimize: std.builtin.OptimizeMode,
24+
target: std.Build.ResolvedTarget,
25+
26+
pub fn init(b: *std.Build) !Self {
27+
return .{
28+
.target = b.resolveTargetQuery(.{
29+
.abi = .none,
30+
.cpu_arch = .x86,
31+
.cpu_model = .{ .explicit = &i686_cpu_model },
32+
.os_tag = .freestanding,
33+
}),
34+
.optimize = b.standardOptimizeOption(.{}),
35+
.b = b,
36+
.options = try getMosBuildOptions(b),
37+
};
38+
}
39+
40+
fn getMosBuildOptions(b: *Build) !BuildOptions {
41+
const linker_script_path = b.option([]const u8, "LinkerScriptPath", "Absolute path to linker script") orelse ""; // Must provide 'LinkerScriptPath'
42+
const libcm_path = b.option([]const u8, "LibCMPath", "Absolute path to libcm library") orelse ""; // Must provide 'LibCMPath'
43+
const crt_path = b.option([]const u8, "CRTPath", "Absolute path to crt.o") orelse ""; // Must provide 'CRTPath'
44+
const include_path = b.option([]const u8, "CInludePath", "Absolute path to C include root dir") orelse ""; // Must provide 'CInludePath'
45+
const entry_point = b.option([]const u8, "EntryPoint", "Entry point of user application") orelse ""; // Must provide 'EntryPoint'
46+
47+
return .{
48+
.crta_rel_path = try std.fs.path.relative(b.allocator, ".", crt_path),
49+
.include_rel_path = try std.fs.path.relative(b.allocator, ".", include_path),
50+
.libcm_rel_path = try std.fs.path.relative(b.allocator, ".", libcm_path),
51+
.linker_script_rel_path = try std.fs.path.relative(b.allocator, ".", linker_script_path),
52+
.entry_point = entry_point,
53+
};
54+
}
55+
56+
pub fn addExecutable(self: Self, comptime name: []const u8, comptime root_src_file: []const u8) *Step {
57+
const b = self.b;
58+
const exe = self.elf_compilation(name, root_src_file);
59+
const exe_install = b.addInstallArtifact(exe, .{});
60+
61+
const flatten_output_file = name ++ ".flt";
62+
const objcopy_run = b.addSystemCommand(&.{ "objcopy", "-O", "binary" });
63+
objcopy_run.addArg(b.getInstallPath(.bin, exe.name));
64+
const flatten_output_path = objcopy_run.addOutputFileArg(flatten_output_file);
65+
66+
const flatten_install = b.addInstallFileWithDir(flatten_output_path, .bin, flatten_output_file);
67+
68+
objcopy_run.step.dependOn(&exe_install.step);
69+
return &flatten_install.step;
70+
}
71+
72+
fn elf_compilation(self: Self, name: []const u8, root_src_file: []const u8) *Step.Compile {
73+
const b = self.b;
74+
const exe = b.addExecutable(.{
75+
.name = name,
76+
.root_module = b.createModule(.{
77+
.root_source_file = b.path(root_src_file),
78+
.target = self.target,
79+
.optimize = self.optimize,
80+
.omit_frame_pointer = false,
81+
.red_zone = false,
82+
.unwind_tables = .none,
83+
.stack_protector = false,
84+
.single_threaded = true,
85+
.pic = false,
86+
}),
87+
});
88+
89+
exe.root_module.addLibraryPath(b.path(self.options.libcm_rel_path));
90+
exe.root_module.linkSystemLibrary("cm", .{});
91+
exe.addObjectFile(b.path(self.options.crta_rel_path));
92+
exe.addIncludePath(b.path(self.options.include_rel_path));
93+
94+
exe.linker_script = b.path(self.options.linker_script_rel_path);
95+
exe.link_gc_sections = true;
96+
exe.link_eh_frame_hdr = false;
97+
exe.entry = .{ .symbol_name = self.options.entry_point };
98+
99+
return exe;
100+
}

src/apps/zapps/build.zig

Lines changed: 4 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,8 @@
11
const std = @import("std");
2-
const Model = std.Target.Cpu.Model;
2+
const MosBuild = @import("MosBuild.zig");
33

44
pub fn build(b: *std.Build) !void {
5-
const linker_script_path = b.option([]const u8, "LinkerScriptPath", "Absolute path to linker script") orelse ""; // Must provide 'LinkerScriptPath'
6-
const libcm_path = b.option([]const u8, "LibCMPath", "Absolute path to libcm library") orelse ""; // Must provide 'LibCMPath'
7-
const crt_path = b.option([]const u8, "CRTPath", "Absolute path to crt.o") orelse ""; // Must provide 'CRTPath'
8-
const include_path = b.option([]const u8, "CInludePath", "Absolute path to C include root dir") orelse ""; // Must provide 'CInludePath'
9-
10-
// TODO: Check if the options were provided. If not fail the build.
11-
12-
const linker_script_rel_path = try std.fs.path.relative(b.allocator, ".", linker_script_path);
13-
const libcm_rel_path = try std.fs.path.relative(b.allocator, ".", libcm_path);
14-
const crt_rel_path = try std.fs.path.relative(b.allocator, ".", crt_path);
15-
const include_rel_path = try std.fs.path.relative(b.allocator, ".", include_path);
16-
17-
const i686_cpu_model = Model{
18-
.name = "i686",
19-
.llvm_name = "",
20-
.features = .empty,
21-
};
22-
23-
const target = b.resolveTargetQuery(.{
24-
.abi = .none,
25-
.cpu_arch = .x86,
26-
.cpu_model = .{ .explicit = &i686_cpu_model },
27-
.os_tag = .freestanding,
28-
});
29-
30-
const hello_exe = b.addExecutable(.{
31-
.name = "hello",
32-
.root_module = b.createModule(.{
33-
.root_source_file = b.path("hello.zig"),
34-
.target = target,
35-
.optimize = b.standardOptimizeOption(.{}),
36-
.omit_frame_pointer = false,
37-
.red_zone = false,
38-
.unwind_tables = .none,
39-
.stack_protector = false,
40-
.single_threaded = true,
41-
.pic = false,
42-
}),
43-
});
44-
45-
hello_exe.root_module.addLibraryPath(b.path(libcm_rel_path));
46-
hello_exe.root_module.linkSystemLibrary("cm", .{});
47-
hello_exe.addObjectFile(b.path(crt_rel_path));
48-
hello_exe.addIncludePath(b.path(include_rel_path));
49-
50-
hello_exe.linker_script = b.path(linker_script_rel_path);
51-
hello_exe.link_gc_sections = true;
52-
hello_exe.link_eh_frame_hdr = false;
53-
hello_exe.entry = .{ .symbol_name = "proc_start" };
54-
55-
b.installArtifact(hello_exe);
56-
57-
const output_path = try std.fs.path.join(b.allocator, &.{ b.install_path, "hello.flt" });
58-
defer b.allocator.free(output_path);
59-
60-
const objcopy_run = b.addSystemCommand(&.{"objcopy"});
61-
objcopy_run.addArg("-O");
62-
objcopy_run.addArg("binary");
63-
objcopy_run.addArg(b.getInstallPath(.bin, hello_exe.name));
64-
objcopy_run.addArg(output_path);
65-
66-
objcopy_run.step.dependOn(b.getInstallStep());
67-
b.default_step = &objcopy_run.step;
5+
const mos_build = try MosBuild.init(b);
6+
const hello_install = mos_build.addExecutable("hello", "./hello.zig");
7+
b.getInstallStep().dependOn(hello_install);
688
}

0 commit comments

Comments
 (0)