aboutsummaryrefslogtreecommitdiff
path: root/tools/makefile.go
diff options
context:
space:
mode:
Diffstat (limited to 'tools/makefile.go')
-rw-r--r--tools/makefile.go115
1 files changed, 115 insertions, 0 deletions
diff --git a/tools/makefile.go b/tools/makefile.go
new file mode 100644
index 0000000..968b6d1
--- /dev/null
+++ b/tools/makefile.go
@@ -0,0 +1,115 @@
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "io/fs"
+ "os"
+ "path"
+ "strings"
+)
+
+var (
+ outputExe = "game"
+ compilerExe = "g++"
+ compilerOptions = []string{
+ "-m64",
+ "-fno-strict-aliasing",
+ "-pedantic",
+ "-Wall",
+ "-Wextra",
+ "-Wno-unused-parameter",
+ "-Wno-format-truncation",
+ "-std=c++11",
+ "-DOS_LINUX=1",
+ "-DARCH_X64=1",
+ }
+ linkerOptions = []string{
+ "-Wl,-t",
+ }
+)
+
+func main() {
+ if len(os.Args) < 2 {
+ fmt.Println("USAGE: makefile.exe SRCDIR")
+ os.Exit(1)
+ }
+
+ sourceDir := os.Args[1]
+ buildDir := path.Join(path.Dir(sourceDir), "build")
+
+ type Object struct{ obj, src string }
+ objectFiles := []Object{}
+ headerFiles := []string{}
+
+ fs.WalkDir(os.DirFS(sourceDir), ".",
+ func(rel string, d fs.DirEntry, err error) error {
+ if err == nil && !d.IsDir() {
+ ext := path.Ext(rel)
+ switch ext {
+ case ".cpp", ".cxx", ".cc", ".c":
+ src := rel
+ obj := rel[:len(src)-len(ext)] + ".obj"
+ objectFiles = append(objectFiles, Object{obj, src})
+ case ".hpp", ".hxx", ".hh", ".h":
+ hdr := rel
+ headerFiles = append(headerFiles, hdr)
+ }
+ }
+ return nil
+ })
+
+ output := bytes.Buffer{}
+
+ // VARIABLES
+ fmt.Fprintf(&output, "SRCDIR = %v\n", sourceDir)
+ fmt.Fprintf(&output, "BUILDDIR = %v\n", buildDir)
+ fmt.Fprintf(&output, "OUTPUTEXE = %v\n", outputExe)
+ fmt.Fprint(&output, "\n")
+
+ fmt.Fprintf(&output, "CC = %v\n", compilerExe)
+ fmt.Fprintf(&output, "CFLAGS = %v\n", strings.Join(compilerOptions, " "))
+ fmt.Fprintf(&output, "LFLAGS = %v\n", strings.Join(linkerOptions, " "))
+ fmt.Fprint(&output, "\n")
+
+ // DEBUG SWITCH
+ fmt.Fprint(&output, "DEBUG ?= 0\n")
+ fmt.Fprint(&output, "ifneq ($(DEBUG), 0)\n")
+ fmt.Fprint(&output, "\tCFLAGS += -g -O0\n")
+ fmt.Fprint(&output, "else\n")
+ fmt.Fprint(&output, "\tCFLAGS += -O2\n")
+ fmt.Fprint(&output, "endif\n")
+
+ // HEADERS
+ fmt.Fprint(&output, "HEADERS =")
+ for _, header := range headerFiles {
+ fmt.Fprintf(&output, " $(SRCDIR)/%v", header)
+ }
+ fmt.Fprint(&output, "\n\n")
+
+ // EXECUTABLE
+ fmt.Fprint(&output, "$(BUILDDIR)/$(OUTPUTEXE):")
+ for _, object := range objectFiles {
+ fmt.Fprintf(&output, " $(BUILDDIR)/%v", object.obj)
+ }
+ fmt.Fprint(&output, "\n")
+ fmt.Fprint(&output, "\t$(CC) $(CFLAGS) $(LFLAGS) -o $@ $^\n\n")
+
+ // OBJECTS
+ for _, object := range objectFiles {
+ fmt.Fprintf(&output, "$(BUILDDIR)/%v: $(SRCDIR)/%v $(HEADERS)\n", object.obj, object.src)
+ fmt.Fprint(&output, "\t@mkdir -p $(@D)\n")
+ fmt.Fprint(&output, "\t$(CC) -c $(CFLAGS) -o $@ $<\n\n")
+ }
+
+ // PHONY
+ fmt.Fprint(&output, ".PHONY: clean\n\n")
+ fmt.Fprint(&output, "clean:\n\t@rm -r $(BUILDDIR)\n\n")
+
+ if err := os.WriteFile("Makefile", output.Bytes(), 0644); err != nil {
+ fmt.Printf("failed to write Makefile: %v\n", err)
+ os.Exit(1)
+ }
+
+ return
+}