spec generation complete

This commit is contained in:
Peter Li 2025-12-27 22:51:40 -08:00
parent b248573930
commit 75a9ae1b39
10 changed files with 138 additions and 32 deletions

View File

@ -14,10 +14,11 @@ backlogRoot: []const u8,
reflectShaderPathList: [][]u8 = undefined,
nwdep: *std.Build.Dependency,
apigen: *std.Build.Step.Compile,
// apigen: *std.Build.Step.Compile,
shaderEmbedGen: *std.Build.Step.Compile,
loadDynamicsGen: *std.Build.Step.Compile,
rcGen: *std.Build.Step.Compile,
specGen: *std.Build.Step.Compile,
generatedApis: std.StringHashMapUnmanaged(*std.Build.Module) = .{},
pub const BuildSystem = @This();
@ -68,8 +69,9 @@ pub fn init(b: *std.Build, initOptions: InitOptions) BuildSystem {
.cookShaders = b.option(bool, "cookShaders", "generates shaders and updates .json files before running the build. (needs to be done whenever shaders are updated, this just runs tools/scripts/cook-shaders.py)") orelse false,
.nwdep = nwdep,
.apigen = nwdep.artifact("backlog-apigen"),
// .apigen = nwdep.artifact("backlog-apigen"),
.loadDynamicsGen = nwdep.artifact("backlog-generate-loadDynamics"),
.specGen = nwdep.artifact("backlog-generate-spec"),
.rcGen = nwdep.artifact("backlog-generate-rc"),
.shaderEmbedGen = nwdep.artifact("backlog-shaderEmbedGen"),
};

View File

@ -30,12 +30,12 @@ pub fn buildGenerators(b: *std.Build, opts: bh.Options) void {
}),
});
const generateExe = b.addExecutable(.{
.name = "backlog-apigen",
const generateProgramSpecExe = b.addExecutable(.{
.name = "backlog-generate-spec",
.root_module = b.createModule(.{
.target = b.graph.host,
.optimize = .Debug,
.root_source_file = b.path("buildgen/generateApi.zig"),
.root_source_file = b.path("buildgen/generateProgramSpec.zig"),
}),
});
@ -68,7 +68,7 @@ pub fn buildGenerators(b: *std.Build, opts: bh.Options) void {
b.installArtifact(fwdGeneratorExe);
b.installArtifact(generateLoadDynamicsExe);
b.installArtifact(generateExe);
b.installArtifact(generateProgramSpecExe);
b.installArtifact(generateShaders);
b.installArtifact(generateRcExe);

View File

@ -28,6 +28,28 @@ pub const Program = struct {
self.iconPath = self.buildSystem.generateRc(self.name, path) catch return;
}
pub fn makeSpec(self: *@This()) *std.Build.Module {
const b = self.buildSystem.b;
const run = b.addRunArtifact(self.buildSystem.specGen);
const pfile = run.addOutputFileArg(b.fmt("{s}-spec.zig", .{self.name}));
run.addArg(self.name);
for (self.gameModules.items) |mod| {
if (mod.enabled)
run.addArg(mod.name);
}
const mod = b.createModule(.{
.target = self.opts.target,
.optimize = self.opts.optimize,
.root_source_file = pfile,
});
const core = self.buildSystem.nwdep.module("core");
mod.addImport("core", core);
return mod;
}
pub fn compileInstall(self: *@This()) *std.Build.Step.Compile {
const bEngine = self.buildSystem.bEngine;
const b = self.buildSystem.b;
@ -50,6 +72,9 @@ pub const Program = struct {
}),
});
// link core
const spec = self.makeSpec();
exe.root_module.addImport("gamespec", spec);
exe.root_module.addImport("core", core);
exe.root_module.addImport("trampoline", trampoline);
exe.root_module.addOptions("BacklogOptions", self.buildSystem.options);
@ -64,8 +89,6 @@ pub const Program = struct {
run_exe.dependOn(&runArtifact.step);
}
// link core
// 2. create the actual library that the loader will try to load
// 3. set up linking, if static then we will link against the loader

View File

@ -0,0 +1,64 @@
const std = @import("std");
pub fn usage() void {
std.debug.print("generate-program-spec <output file name> <spec_name> <module list>\n", .{});
}
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
// Get output filename from build system
const args = try std.process.argsAlloc(allocator);
if (args.len < 3) {
usage();
@panic("Missing output filename\n");
}
const out_path = args[1];
const programName = args[2];
const modules = args[3..];
// Generate Zig code content
var writer = std.ArrayList(u8){};
_ = try writer.appendSlice(allocator,
\\const core = @import("core").module;
\\
\\ const std = @import("std");
\\ pub fn getSpec() !*core.SpecVariantMap {
\\ const spec = try std.heap.smp_allocator.create(core.SpecVariantMap);
\\ spec.* = try core.createSpecVariant(.{
\\ .useGPA = true,
);
try writer.print(allocator, ".name = \"{s}\",\n", .{programName});
for (modules) |mod| {
try writer.print(allocator, ".{s} = true,\n", .{mod});
}
_ = try writer.appendSlice(allocator,
\\ }, std.heap.smp_allocator);
\\
\\ return spec;
\\ }
\\
);
try writer.append(allocator, 0);
// Write to specified output file
// Open or create the file for writing (overwrites if it exists)
const file = try std.fs.cwd().createFile(out_path, .{});
defer file.close();
var ast = try std.zig.Ast.parse(allocator, @as([:0]const u8, @ptrCast(writer.items[0 .. writer.items.len - 1])), .zig);
// std.debug.print("output=\n{s}", .{content.items[0 .. content.items.len - 1]});
defer ast.deinit(allocator);
const out = try ast.renderAlloc(allocator);
// Write the content to the file
try file.writeAll(out);
}

View File

@ -0,0 +1,11 @@
// templated file
//
// should still be a formattable zig file
// even if it is not compile-able
//
// definitions marked with // TEMPLATE_DEFINITION
// are removed during the templating step
const programName = "__program_name"; // TEMPLATE_DEFINITION
export fn loadModule() void {}

View File

@ -0,0 +1,26 @@
// templated file
//
// should still be a formattable zig file
// even if it is not compile-able
//
// definitions marked with // TEMPLATE_DEFINITION
// are removed during the templating step
const core = @import("core");
const programName = "__program_name"; // TEMPLATE_DEFINITION
pub export fn startup_module(p_allocator: *anyopaque, p_a: ?*anyopaque) bool {
const allocator = core.modulePreamble(p_allocator, p_a) catch return false;
_ = allocator;
// imgui.setupFromModule();
// platform.setupFromModule();
// sys.setupFromModule();
// rend.setupFromModule();
// backlog.physics.setupFromModule();
core.engine_logs("creating externgame");
// start_module(core.startup_getArgs(p_a.?)) catch return false;
return true;
}

View File

View File

@ -4,9 +4,7 @@ const panickers = core.panickers;
// const realMain = @import("main");
// pub const gametree = @import("gametree");
pub const trampoline = @import("trampoline");
pub const gamespec = @import("gamespec");
pub const options = @import("BacklogOptions");
pub const std_options = std.Options{
.enable_segfault_handler = true,
@ -40,21 +38,6 @@ fn fileExists(path: []const u8) bool {
return true;
}
// this should be provided by gametree,
pub fn getSpec(comptime name: []const u8) !*core.SpecVariantMap {
const spec = try std.heap.smp_allocator.create(core.SpecVariantMap);
spec.* = try core.createSpecVariant(.{
.useGPA = true,
.name = name,
// placeholder module list.
.core = true,
.platform = true,
.assets = true,
}, std.heap.smp_allocator);
return spec;
}
pub fn run() !void {
core.engine_logs("calling gEngine.run");
@ -144,7 +127,7 @@ pub fn main() !void {
core.engine_log("Working Dir set: {s}", .{try std.fs.cwd().realpath(".", &BUFFER)});
}
const spec = try getSpec("sampleGame");
const spec = try gamespec.getSpec();
_ = startEngine(spec);
// panickers.attachSegfaultHandler();

View File

@ -1,7 +1,4 @@
What is thisthis
this is going to be an exercise in craftsmanship
1. start with a simple main program that starts the core's loop.
1. create generate-launcher.zig
2. create generate-landing.zig