summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlejandro Sior <aho@sior.be>2022-07-31 15:42:56 +0200
committerAlejandro Sior <aho@sior.be>2022-07-31 15:42:56 +0200
commit65f13dba60cab28c5b6cae2d72b792ade51c86c8 (patch)
treed125fc78c1c875cdcaaae2c6e627b3ace3730704
parentab4fa9d91adfc50ce3dff85b79c0ab09963f20f7 (diff)
cook: getting system compilers
-rw-r--r--.build12
-rwxr-xr-xcook.py129
-rw-r--r--test/.build5
-rw-r--r--test/test.S6
-rw-r--r--test/test.asm6
5 files changed, 111 insertions, 47 deletions
diff --git a/.build b/.build
index f7c3f1f..134b1c1 100644
--- a/.build
+++ b/.build
@@ -1,10 +1,6 @@
-global asm
-asm = Vec(
- "asm",
- "/usr/bin/nasm",
- lambda o, i, ea: "-f elf64 %s -o %s %s" % (i, o, ea),
- lambda i: (i.name + ".o"),
- desc=lambda o, i, ea: "ASM %s" % (o)
-)
+global cc
+cc = System.c_compiler()
+global ld
+ld = System.c_linker()
subdir("test") \ No newline at end of file
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
diff --git a/test/.build b/test/.build
index 8fdda48..74fa78d 100644
--- a/test/.build
+++ b/test/.build
@@ -1,5 +1,4 @@
linker_sc = CWD / "linker.sc"
-as_obj = asm("test.asm")
-obj = cc("main.c", extra_args="-T" + str(linker_sc))
-aout = ld("a.out", obj, as_obj) \ No newline at end of file
+obj = cc("main.c", "test.S")
+aout = ld("a.out", obj) \ No newline at end of file
diff --git a/test/test.S b/test/test.S
new file mode 100644
index 0000000..875ab58
--- /dev/null
+++ b/test/test.S
@@ -0,0 +1,6 @@
+.code64
+
+.global test
+test:
+ mov $69, %rax
+ ret \ No newline at end of file
diff --git a/test/test.asm b/test/test.asm
deleted file mode 100644
index bcd7d20..0000000
--- a/test/test.asm
+++ /dev/null
@@ -1,6 +0,0 @@
-[bits 64]
-
-global test
-test:
- mov eax, 69
- ret \ No newline at end of file