Skip to content
This repository was archived by the owner on Mar 22, 2026. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 79 additions & 60 deletions Engine/Programs/DirkBuildTool/Source/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
Expand All @@ -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{}
Expand All @@ -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
}
Expand Down
4 changes: 4 additions & 0 deletions Engine/Programs/DirkBuildTool/Source/build/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 2 additions & 7 deletions Engine/Programs/DirkBuildTool/Source/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ const (
WarningLevelMax = 3
)

type BuildConfig struct {
Target Target
Mode *BuildMode
}

type Defines map[string]string

type CompileCommands []*CompileCommand
Expand Down Expand Up @@ -69,7 +64,7 @@ type Target struct {
}

var (
BuildModes map[string]*BuildMode
BuildModes map[string]BuildMode
Platform PlatformConfig
Dirs DirsConfig
Settings BuildToolSettings
Expand Down Expand Up @@ -102,7 +97,7 @@ func LoadConfig() error {
return err
}

BuildModes = map[string]*BuildMode{
BuildModes = map[string]BuildMode{
"Development": {
Name: "Development",
Optimize: false,
Expand Down
38 changes: 20 additions & 18 deletions Engine/Programs/DirkBuildTool/Source/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,47 +37,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() {
Expand Down
24 changes: 12 additions & 12 deletions Engine/Programs/DirkBuildTool/Source/module/cpp.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand All @@ -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
Expand All @@ -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
Expand All @@ -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)

Expand Down Expand Up @@ -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:
Expand All @@ -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
}
Expand Down
6 changes: 3 additions & 3 deletions Engine/Programs/DirkBuildTool/Source/module/header.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}
Loading