From 7d42b09bc8629c9d031add7dd1f01f86f198be14 Mon Sep 17 00:00:00 2001 From: PiquelChips Date: Mon, 12 Jan 2026 20:03:28 +0100 Subject: [PATCH 1/2] refactor main build pipeline --- .../DirkBuildTool/Source/build/build.go | 139 ++++++++++-------- .../DirkBuildTool/Source/build/graph.go | 4 + .../DirkBuildTool/Source/config/config.go | 9 +- Engine/Programs/DirkBuildTool/Source/main.go | 38 ++--- .../DirkBuildTool/Source/module/cpp.go | 24 +-- .../DirkBuildTool/Source/module/header.go | 6 +- .../DirkBuildTool/Source/module/module.go | 24 +-- .../DirkBuildTool/Source/module/shaders.go | 2 +- 8 files changed, 133 insertions(+), 113 deletions(-) diff --git a/Engine/Programs/DirkBuildTool/Source/build/build.go b/Engine/Programs/DirkBuildTool/Source/build/build.go index 5c5438b5..01c3dc87 100644 --- a/Engine/Programs/DirkBuildTool/Source/build/build.go +++ b/Engine/Programs/DirkBuildTool/Source/build/build.go @@ -11,48 +11,103 @@ import ( "os/exec" ) -func Build(buildConfig *config.BuildConfig) error { - modules, err := searchDir(config.Dirs.Source, buildConfig, 0) +type BuildConfig struct { + target config.Target + mode config.BuildMode + + graph Graph + defines config.Defines +} + +func (c *BuildConfig) getModules() map[string]module.Module { + return c.graph.getNodes() +} + +func (c *BuildConfig) GenerateCompileCommands() error { + log.Printf("Generating compile commands\n") + compileCommands := config.CompileCommands{} + for _, buildMod := range c.getModules() { + mod, ok := buildMod.(*module.CppModule) + if !ok { + continue + } + + commands, err := mod.GenerateCompileCommands(c.defines) + if err != nil { + return err + } + + compileCommands = append(compileCommands, commands...) + } + + data, err := json.Marshal(compileCommands) if err != nil { return err } + if err := config.SaveFile("compile_commands.json", data, true); err != nil { + return err + } + os.Symlink(fmt.Sprintf("%s/compile_commands.json", config.Dirs.DBTSaved), fmt.Sprintf("%s/compile_commands.json", config.Dirs.Work)) + return nil +} - modules["Shaders"], err = module.Load(config.Dirs.Engine, "Shaders", buildConfig) +func (c *BuildConfig) Build() error { + log.Printf("Building target %s with %s configuration\n", c.target.Name, c.mode.Name) + buildModules, err := c.graph.flatten() if err != nil { return err } + for _, mod := range buildModules { + if err := mod.Build(&c.target, c.defines); err != nil { + if _, ok := err.(*exec.ExitError); ok { + fmt.Printf("An error occured in the build process\n") + return nil + } + return err + } + } + + return nil +} + +func SetupBuildConfig(target config.Target, mode config.BuildMode) (*BuildConfig, error) { + modules, err := searchDir(config.Dirs.Source, &mode, 0) + if err != nil { + return nil, err + } + + modules["Shaders"], err = module.Load(config.Dirs.Engine, "Shaders", &mode) + if err != nil { + return nil, err + } + graph, err := buildDependencyGraph(modules) if err != nil { - return err + return nil, err } targets := []module.Module{} - for _, targetName := range buildConfig.Target.Modules { - target, ok := modules[targetName] + for _, targetName := range target.Modules { + targetMod, ok := modules[targetName] if !ok { - return fmt.Errorf("module %s required by target %s does not exist", targetName, buildConfig.Target.Name) + return nil, fmt.Errorf("module %s required by target %s does not exist", targetName, target.Name) } - targets = append(targets, target) + targets = append(targets, targetMod) } graph, err = graph.strip(targets) if err != nil { - return err - } - - buildModules, err := graph.flatten() - if err != nil { - return err + return nil, err } - defines := buildConfig.Target.Defines + defines := target.Defines if defines == nil { defines = config.Defines{} } - for _, mod := range buildModules { + for _, mod := range graph.getNodes() { if mod.GetDefines() != nil { maps.Copy(defines, mod.GetDefines()) } @@ -62,61 +117,25 @@ func Build(buildConfig *config.BuildConfig) error { maps.Copy(defines, config.Platform.Defines) } - if buildConfig.Mode.Defines != nil { - maps.Copy(defines, buildConfig.Mode.Defines) + if mode.Defines != nil { + maps.Copy(defines, mode.Defines) } - defines["SAVED_DIR"] = fmt.Sprintf("%s/%s/%s", config.Dirs.Saved, buildConfig.Target.Name, buildConfig.Mode.Name) + defines["SAVED_DIR"] = fmt.Sprintf("%s/%s/%s", config.Dirs.Saved, target.Name, mode.Name) defines["SHADERS_DIR"] = fmt.Sprintf("%s/Shaders", config.Dirs.Intermediate) defines["ASSETS_DIR"] = config.Dirs.Assets - log.Printf("Generating compile commands\n") - compileCommands := config.CompileCommands{} - for _, buildMod := range buildModules { - mod, ok := buildMod.(*module.CppModule) - if !ok { - continue - } - - commands, err := mod.GenerateCompileCommands(defines) - if err != nil { - return err - } - - compileCommands = append(compileCommands, commands...) - } - - data, err := json.Marshal(compileCommands) - if err != nil { - return err - } - if err := config.SaveFile("compile_commands.json", data, true); err != nil { - return err - } - os.Symlink(fmt.Sprintf("%s/compile_commands.json", config.Dirs.DBTSaved), fmt.Sprintf("%s/compile_commands.json", config.Dirs.Work)) - - log.Printf("Building target %s with %s configuration\n", buildConfig.Target.Name, buildConfig.Mode.Name) - for _, mod := range buildModules { - if err := mod.Build(defines); err != nil { - if _, ok := err.(*exec.ExitError); ok { - fmt.Printf("An error occured in the build process\n") - return nil - } - return err - } - } - - return nil + return &BuildConfig{target, mode, graph, defines}, nil } -func searchDir(path string, buildConfig *config.BuildConfig, count int) (map[string]module.Module, error) { +func searchDir(path string, buildMode *config.BuildMode, count int) (map[string]module.Module, error) { entries, err := os.ReadDir(path) if err != nil { return nil, err } if count >= 10 { - log.Printf("Module search has reached %d recursions. Current dir: %s.\n", count, path) + log.Printf("Module search has reached %d recursions. Currently searching: %s.\n", count, path) } modules := map[string]module.Module{} @@ -130,13 +149,13 @@ func searchDir(path string, buildConfig *config.BuildConfig, count int) (map[str return nil, err } - config, err := module.Load(path, info.Name(), buildConfig) + config, err := module.Load(path, info.Name(), buildMode) if err != nil { return nil, err } if config == nil { - newMods, err := searchDir(fmt.Sprintf("%s/%s", path, entry.Name()), buildConfig, count+1) + newMods, err := searchDir(fmt.Sprintf("%s/%s", path, entry.Name()), buildMode, count+1) if err != nil { return nil, err } diff --git a/Engine/Programs/DirkBuildTool/Source/build/graph.go b/Engine/Programs/DirkBuildTool/Source/build/graph.go index a0b5b620..ee2f276b 100644 --- a/Engine/Programs/DirkBuildTool/Source/build/graph.go +++ b/Engine/Programs/DirkBuildTool/Source/build/graph.go @@ -14,6 +14,10 @@ type Graph struct { nodes map[string]module.Module } +func (g *Graph) getNodes() map[string]module.Module { + return g.nodes +} + func (g *Graph) addDependency(task, dep module.Module) { g.nodes[task.GetName()] = task g.nodes[dep.GetName()] = dep diff --git a/Engine/Programs/DirkBuildTool/Source/config/config.go b/Engine/Programs/DirkBuildTool/Source/config/config.go index 60a1d157..83e0b4d9 100644 --- a/Engine/Programs/DirkBuildTool/Source/config/config.go +++ b/Engine/Programs/DirkBuildTool/Source/config/config.go @@ -20,11 +20,6 @@ const ( WarningLevelMax = 3 ) -type BuildConfig struct { - Target Target - Mode *BuildMode -} - type Defines map[string]string type CompileCommands []*CompileCommand @@ -69,7 +64,7 @@ type Target struct { } var ( - BuildModes map[string]*BuildMode + BuildModes map[string]BuildMode Platform PlatformConfig Dirs DirsConfig Settings BuildToolSettings @@ -102,7 +97,7 @@ func LoadConfig() error { return err } - BuildModes = map[string]*BuildMode{ + BuildModes = map[string]BuildMode{ "Development": { Name: "Development", Optimize: false, diff --git a/Engine/Programs/DirkBuildTool/Source/main.go b/Engine/Programs/DirkBuildTool/Source/main.go index ca580553..6d1a452b 100644 --- a/Engine/Programs/DirkBuildTool/Source/main.go +++ b/Engine/Programs/DirkBuildTool/Source/main.go @@ -31,47 +31,49 @@ func main() { } } + if err := buildTarget(os.Args); err != nil { + panic(err) + } +} + +func buildTarget(args []string) error { targetName := "" buildModeName := "" - switch len(os.Args) { + switch len(args) { case 1: targetName = defaultTarget buildModeName = defaultBuildType case 2: - targetName = os.Args[1] + targetName = args[1] buildModeName = defaultBuildType case 3: - targetName = os.Args[1] - buildModeName = os.Args[2] + targetName = args[1] + buildModeName = args[2] default: - fmt.Printf("Invalid number of arguments.\n") usage() - os.Exit(1) - return + return fmt.Errorf("Invalid number of arguments.") } buildMode, ok := config.BuildModes[buildModeName] if !ok { - fmt.Printf("Build type %s does not exist\n", buildModeName) - os.Exit(1) - return + return fmt.Errorf("Build type %s does not exist\n", buildModeName) } target, ok := config.Targets[targetName] if !ok { - fmt.Printf("Target %s does not exist\n", targetName) - os.Exit(1) - return + return fmt.Errorf("Target %s does not exist\n", targetName) } - buildConfig := &config.BuildConfig{ - Target: target, - Mode: buildMode, + buildConfig, err := build.SetupBuildConfig(target, buildMode) + if err != nil { + return err } - if err := build.Build(buildConfig); err != nil { - panic(err) + if err := buildConfig.GenerateCompileCommands(); err != nil { + return err } + + return buildConfig.Build() } func clean() { diff --git a/Engine/Programs/DirkBuildTool/Source/module/cpp.go b/Engine/Programs/DirkBuildTool/Source/module/cpp.go index bc3d6d25..1f48a103 100644 --- a/Engine/Programs/DirkBuildTool/Source/module/cpp.go +++ b/Engine/Programs/DirkBuildTool/Source/module/cpp.go @@ -20,7 +20,7 @@ type CppModule struct { Config *moduleConfig External []string IncludeDirs []string - build *config.BuildConfig + buildMode *config.BuildMode allDeps []Module // all the dependencies, detected recursively (populated by getDeps) } @@ -32,12 +32,12 @@ func (m *CppModule) GetLibs() []string { return append(m.External, m.Na func (m *CppModule) GetDependencies() []string { return m.Config.Deps } func (m *CppModule) AddDependency(module Module) { m.Dependencies = append(m.Dependencies, module) } -func (m *CppModule) Build(defines config.Defines) error { +func (m *CppModule) Build(target *config.Target, defines config.Defines) error { log.Printf("Generating Makefile for %s\n", m.Name) - target := m.Name + targetName := m.Name if m.Config.HasEntrypoint { - target = m.build.Target.Name + targetName = target.Name } libs := m.External @@ -47,17 +47,17 @@ func (m *CppModule) Build(defines config.Defines) error { err := make.RunMakefile(&make.CppMakefile{ Name: m.Name, - Target: target, + Target: targetName, Path: m.Path, - BuildMode: m.build.Mode, + BuildMode: m.buildMode, IncDirs: m.getAllIncludeDirs(), Libs: libs, Defines: defines, IsLib: !m.Config.HasEntrypoint, - IsStatic: m.build.Mode.Compact, - Optimize: m.build.Mode.Optimize, + IsStatic: m.buildMode.Compact, + Optimize: m.buildMode.Optimize, CFlags: m.getCFlags(), - LdFlags: m.build.Mode.LinkerFlags, + LdFlags: m.buildMode.LinkerFlags, }) return err @@ -78,7 +78,7 @@ func (m *CppModule) GenerateCompileCommands(defines config.Defines) (config.Comp in = strings.Trim(in, "/") intDir := fmt.Sprintf("%s/%s", config.Dirs.Intermediate, m.Name) - out := fmt.Sprintf("%s/%s/%s", intDir, m.build.Mode.Name, in) + out := fmt.Sprintf("%s/%s/%s", intDir, m.buildMode.Name, in) out = strings.Replace(out, "/src/", "/obj/", 1) out = strings.Replace(out, ".cpp", ".o", 1) @@ -116,7 +116,7 @@ func (m *CppModule) GenerateCompileCommands(defines config.Defines) (config.Comp func (m *CppModule) getCFlags() []string { var warningFlags []string - switch m.build.Mode.WarningLevel { + switch m.buildMode.WarningLevel { case config.WarningLevelNone: warningFlags = []string{"-w"} case config.WarningLevelLow: @@ -137,7 +137,7 @@ func (m *CppModule) getCFlags() []string { } } - cFlags := append(m.build.Mode.CompileFlags, warningFlags...) + cFlags := append(m.buildMode.CompileFlags, warningFlags...) cFlags = append(cFlags, "-fPIC", fmt.Sprintf("-std=%s", m.Std)) return cFlags } diff --git a/Engine/Programs/DirkBuildTool/Source/module/header.go b/Engine/Programs/DirkBuildTool/Source/module/header.go index 173db69a..b85c1437 100644 --- a/Engine/Programs/DirkBuildTool/Source/module/header.go +++ b/Engine/Programs/DirkBuildTool/Source/module/header.go @@ -16,6 +16,6 @@ func (m *HeaderModule) GetIncludeDirs() []string { return m.IncludeDirs } func (m *HeaderModule) GetDefines() config.Defines { return m.Defines } func (m *HeaderModule) GetLibs() []string { return m.External } -func (m *HeaderModule) Build(config.Defines) error { return nil } -func (m *HeaderModule) GetDependencies() []string { return nil } -func (m *HeaderModule) AddDependency(Module) {} +func (m *HeaderModule) Build(*config.Target, config.Defines) error { return nil } +func (m *HeaderModule) GetDependencies() []string { return nil } +func (m *HeaderModule) AddDependency(Module) {} diff --git a/Engine/Programs/DirkBuildTool/Source/module/module.go b/Engine/Programs/DirkBuildTool/Source/module/module.go index 5de7085e..8d0a09fe 100644 --- a/Engine/Programs/DirkBuildTool/Source/module/module.go +++ b/Engine/Programs/DirkBuildTool/Source/module/module.go @@ -16,12 +16,12 @@ type Module interface { GetDefines() config.Defines GetLibs() []string - Build(config.Defines) error + Build(*config.Target, config.Defines) error AddDependency(Module) GetDependencies() []string } -func Load(path, name string, buildConfig *config.BuildConfig) (Module, error) { +func Load(path, name string, buildMode *config.BuildMode) (Module, error) { path = fmt.Sprintf("%s/%s", path, name) modFile := fmt.Sprintf("%s/%s.dirkmod", path, name) data, err := os.ReadFile(modFile) @@ -46,20 +46,20 @@ func Load(path, name string, buildConfig *config.BuildConfig) (Module, error) { return nil, fmt.Errorf("module name does not match folder name. module at %s has name %s but should be %s", path, mod.Name, name) } - return mod.toModule(buildConfig), nil + return mod.toModule(buildMode), nil } type NullModule struct { Name string } -func (m *NullModule) GetName() string { return m.Name } -func (m *NullModule) GetIncludeDirs() []string { return nil } -func (m *NullModule) GetDefines() config.Defines { return nil } -func (m *NullModule) GetLibs() []string { return nil } -func (m *NullModule) Build(config.Defines) error { return nil } -func (m *NullModule) GetDependencies() []string { return nil } -func (m *NullModule) AddDependency(Module) {} +func (m *NullModule) GetName() string { return m.Name } +func (m *NullModule) GetIncludeDirs() []string { return nil } +func (m *NullModule) GetDefines() config.Defines { return nil } +func (m *NullModule) GetLibs() []string { return nil } +func (m *NullModule) Build(*config.Target, config.Defines) error { return nil } +func (m *NullModule) GetDependencies() []string { return nil } +func (m *NullModule) AddDependency(Module) {} // read from .dirkmod files type moduleConfig struct { @@ -75,7 +75,7 @@ type moduleConfig struct { IncludeDirs []string `json:"include_dirs"` } -func (c *moduleConfig) toModule(buildConfig *config.BuildConfig) Module { +func (c *moduleConfig) toModule(buildMode *config.BuildMode) Module { if c.Type == "" { c.Type = "cpp" } @@ -109,7 +109,7 @@ func (c *moduleConfig) toModule(buildConfig *config.BuildConfig) Module { Config: c, External: c.External, IncludeDirs: c.IncludeDirs, - build: buildConfig, + buildMode: buildMode, allDeps: nil, } case "header-only": diff --git a/Engine/Programs/DirkBuildTool/Source/module/shaders.go b/Engine/Programs/DirkBuildTool/Source/module/shaders.go index cc1fddf7..28edcb8f 100644 --- a/Engine/Programs/DirkBuildTool/Source/module/shaders.go +++ b/Engine/Programs/DirkBuildTool/Source/module/shaders.go @@ -14,7 +14,7 @@ func (m *ShaderModule) GetIncludeDirs() []string { return nil } func (m *ShaderModule) GetDefines() config.Defines { return nil } func (m *ShaderModule) GetLibs() []string { return nil } -func (m *ShaderModule) Build(config.Defines) error { +func (m *ShaderModule) Build(*config.Target, config.Defines) error { err := make.RunMakefile(&make.ShaderMakefile{ Name: m.Name, Path: m.Path, From 39f932d38cea9c11a2cf487d0e84cfbb6ccc3c10 Mon Sep 17 00:00:00 2001 From: Piquel Date: Sat, 14 Feb 2026 10:45:37 +0100 Subject: [PATCH 2/2] Update shaders.go --- Engine/Programs/DirkBuildTool/Source/module/shaders.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Engine/Programs/DirkBuildTool/Source/module/shaders.go b/Engine/Programs/DirkBuildTool/Source/module/shaders.go index 28edcb8f..af385309 100644 --- a/Engine/Programs/DirkBuildTool/Source/module/shaders.go +++ b/Engine/Programs/DirkBuildTool/Source/module/shaders.go @@ -15,12 +15,10 @@ func (m *ShaderModule) GetDefines() config.Defines { return nil } func (m *ShaderModule) GetLibs() []string { return nil } func (m *ShaderModule) Build(*config.Target, config.Defines) error { - err := make.RunMakefile(&make.ShaderMakefile{ + return make.RunMakefile(&make.ShaderMakefile{ Name: m.Name, Path: m.Path, }) - - return err } // shader modules dont have dependencies