summaryrefslogtreecommitdiff
path: root/cook.py
diff options
context:
space:
mode:
Diffstat (limited to 'cook.py')
-rwxr-xr-xcook.py129
1 files changed, 99 insertions, 30 deletions
diff --git a/cook.py b/cook.py
index c50643e..d1057b6 100755
--- a/cook.py
+++ b/cook.py
@@ -4,7 +4,7 @@ import os
from pathlib import Path
from threading import local
import shutil
-
+import argparse
def find_program(prog, required=True):
path = shutil.which(prog)
@@ -16,6 +16,58 @@ ROOT = Path.cwd()
BUILD = Path("bld").resolve().relative_to(ROOT)
DEFDESC = lambda o, i, cmd: "%s" % (cmd)
+C_COMPILERS = {
+ 'gcc': lambda: Vec(
+ "gcc",
+ find_program("gcc"),
+ lambda o, i, ea: "-o %s -c %s %s" % (o, i, ea),
+ lambda i: i.name + ".o",
+ lambda o, i, cmd: "CC %s" % (o)
+ ),
+ 'clang': lambda: Vec(
+ "clang",
+ find_program("clang"),
+ lambda o, i, ea: "-o %s -c %s %s" % (o, i, ea),
+ lambda i: i.name + ".o",
+ lambda o, i, cmd: "CC %s" % (o)
+ ),
+ 'cc': lambda: Vec(
+ "cc",
+ find_program("cc"),
+ lambda o, i, ea: "-o %s -c %s %s" % (o, i, ea),
+ lambda i: i.name + ".o",
+ lambda o, i, cmd: "CC %s" % (o)
+ ),
+}
+
+C_LINKERS = {
+ 'gcc': lambda: Machine(
+ "ld-gcc",
+ find_program("gcc"),
+ lambda o, i, ea: "-o %s %s %s" % (o, i, ea),
+ lambda o, i, cmd: "LD %s" % (o)
+ ),
+ 'clang': lambda: Machine(
+ "ld-clang",
+ find_program("clang"),
+ lambda o, i, ea: "-o %s %s %s" % (o, i, ea),
+ lambda o, i, cmd: "LD %s" % (o)
+ ),
+ 'cc': lambda: Machine(
+ "ld-cc",
+ find_program("cc"),
+ lambda o, i, ea: "-o %s %s %s" % (o, i, ea),
+ lambda o, i, cmd: "LD %s" % (o)
+ )
+}
+
+def wrap_lambda(s):
+ if callable(s):
+ return s
+ else:
+ return lambda *args: s
+
+
class FileMeta(type):
def __call__(cls, path, *rest, **krest):
# If none, return none
@@ -91,7 +143,7 @@ class Process(File):
out = "%s: %s\n" % (self.path, inputs)
out += "\t@$(%s) %s\n" % (self.machine.name, self.machine.mkargs("$@", "$^", extra_args))
- out += "\t@echo '%s'" % (self.machine.desc(self, inputs, extra_args))
+ out += "\t@echo '%s'" % (self.machine.desc("$@", "$^", extra_args))
return out
@@ -129,14 +181,20 @@ class Machine(metaclass = MachineMeta):
self.exe = File(exe)
# The arguments that is used to launch the process
- self.mkargs = mkargs
+ self.mkargs = wrap_lambda(mkargs)
# The description
- self.desc = desc
+ self.desc = wrap_lambda(desc)
def __call__(self, name, *args, extra_args=None):
return self.gen(name, *args, extra_args=extra_args)
+ def fork(self, name, mkargs, desc=None):
+ if not desc:
+ desc = self.desc
+ args = lambda o, i, ea: self.mkargs(o, i, ea) + " " + mkargs(o, i, ea)
+ return Machine(name, self.exe, args, desc)
+
def gen(self, name, *args, extra_args=None):
inputs = File.resolve(args)
path = BUILD / Path.cwd().relative_to(ROOT) / name
@@ -156,13 +214,19 @@ class Machine(metaclass = MachineMeta):
return out
class Vec(Machine):
- def __init__(self, name, exe, args, mkout, desc=DEFDESC):
- super().__init__(name, exe, args, desc=desc)
- self.mkout = mkout
+ def __init__(self, name, exe, mkargs, mkout, desc=DEFDESC):
+ super().__init__(name, exe, mkargs, desc=desc)
+ self.mkout = wrap_lambda(mkout)
def __call__(self, *args, extra_args=None):
return self.gen(*args, extra_args=extra_args)
+ def fork(self, name, mkargs, desc=None):
+ if not desc:
+ desc = self.desc
+ args = lambda o, i, ea: self.mkargs(o, i, ea) + " " + wrap_lambda(mkargs)(o, i, ea)
+ return Vec(name, self.exe, args, self.mkout, desc)
+
def gen(self, *args, extra_args=None):
procs = []
inputs = File.resolve(args)
@@ -173,28 +237,21 @@ class Vec(Machine):
return procs
-def find_compiler(compilers):
- for c in compilers:
- cc = find_program(c, required=False)
- if cc:
- return cc
+def find_one(names):
+ for name in names:
+ program = find_program(name, required=False)
+ if program:
+ return name
return None
-c_compiler = find_compiler(["cc", "gcc", "clang", "clang.exe", "clang-cl.exe", "cl.exe"])
-
-cc = Vec(
- "cc",
- c_compiler,
- lambda o, i, ea: "-o %s -c %s %s" % (o, i, ea),
- lambda i: i.name + ".o",
- desc=lambda o, i, ea: "CC %s" % (o),
-)
-ld = Machine(
- "ld",
- c_compiler,
- lambda o, i, ea: "-o %s %s %s" % (o, i, ea),
- desc=lambda o, i, ea: "LD %s" % (o)
-)
+class System:
+ def c_compiler(c_compilers=C_COMPILERS.keys()):
+ c_compiler = find_one(c_compilers)
+ return C_COMPILERS[c_compiler]()
+
+ def c_linker(c_linkers=C_LINKERS.keys()):
+ c_linker = find_one(c_linkers)
+ return C_LINKERS[c_linker]()
def subdir(dir):
# Save the previous location
@@ -255,8 +312,20 @@ def gen_ninja():
out += "\n"
return out
-
-# Generate everything
+
+parser = argparse.ArgumentParser(description="cook build system")
+parser.add_argument("-G", type=str, metavar="backend", help="Backend to generate for: ninja or makefile")
+args = parser.parse_args()
+
+backend = "ninja"
+if args.G:
+ backend = args.G
+
gen_bld()
open(ROOT / BUILD / ".gitignore", "w").write("*")
-open(ROOT / 'build.ninja', 'w').write(gen_ninja()) \ No newline at end of file
+if backend == "ninja":
+ open(ROOT / 'build.ninja', 'w').write(gen_ninja())
+elif backend == "makefile":
+ open(ROOT / 'makefile', 'w').write(gen_makefile())
+else:
+ print("No such backend %s" % (backend)) \ No newline at end of file