diff options
| -rwxr-xr-x | cook.py | 201 | ||||
| -rw-r--r-- | test/.build | 8 | ||||
| -rw-r--r-- | test/hai.c | 8 | ||||
| -rw-r--r-- | test/hai.h | 3 | ||||
| -rw-r--r-- | test/main.c | 78 |
5 files changed, 160 insertions, 138 deletions
@@ -39,11 +39,11 @@ class FileMeta(type): # If none, return none if path == None: return None - + # If already a file, return it if issubclass(type(path), File): return path - + # Adjust name to be a path if type(path) == str: p = Path(path).resolve() @@ -51,12 +51,12 @@ class FileMeta(type): path = p.relative_to(ROOT) else: path = p - + idx = str(path) + cls.__name__ - + if idx in cls.fdb: return cls.fdb[idx] - + obj = cls.__new__(cls, path, *rest, **krest) cls.__init__(obj, path, *rest, **krest) cls.fdb[idx] = obj @@ -70,7 +70,7 @@ class File(metaclass = FileMeta): # the target: this can be # a path or an abstract name self.path = path - + def __str__(self): return str(self.path) @@ -80,16 +80,16 @@ class File(metaclass = FileMeta): class Target(File): def __init__(self, path, processor, inputs, extra_args = []): super().__init__(path) - + # The generator that created this process self.processor = processor - + # The inputs self.inputs = File.resolve(inputs) - + # The extra arguments taken self.extra_args = extra_args - + def gen_makefile(self): inputs = " ".join([str(x) for x in self.inputs]) extra_args = " ".join([x for x in self.extra_args]) @@ -97,13 +97,13 @@ class Target(File): out = "%s: %s\n" % (self.path, inputs) out += "\t@$(%s) %s\n" % (self.processor.name, self.processor.mkargs("$@", inputs, extra_args)) out += "\t@echo '%s'" % (self.processor.mkdesc("$@", inputs, extra_args)) - + return out - + def gen_ninja(self): inputs = " ".join([str(x) for x in self.inputs]) extra_args = " ".join(self.extra_args) - + out = "build %s: %s %s" % (self.path, self.processor.name, inputs) if self.extra_args != []: out += "\n extra = %s" % (extra_args) @@ -115,10 +115,10 @@ class ProcessorMeta(type): # If already a file, return it if issubclass(type(name), Processor): return name - + if name in cls.mdb: return cls.mdb[name] - + obj = cls.__new__(cls, name, *rest, **krest) cls.__init__(obj, name, *rest, **krest) cls.mdb[name] = obj @@ -127,29 +127,38 @@ class ProcessorMeta(type): class Processor(metaclass = ProcessorMeta): mdb = dict() - def __init__(self, name, exe, mkargs, mkout=DEFMKOUT, mkdesc=DEFMKDESC): + def __init__(self, name, exe, mkargs, mkextra=[], mkout=DEFMKOUT, mkdesc=DEFMKDESC): # The name of the processor self.name = name - + # Executable used in the process self.exe = File(exe) - + # The arguments that is used to launch the process self.mkargs = wrap_lambda(mkargs) - + + # A list of functions indicating how to build extra arguments + # XXX: TODO: mkextra is a horrible hack + self.mkextra = mkextra + # The way to generate output path self.mkout = wrap_lambda(mkout) - + # The description self.mkdesc = wrap_lambda(mkdesc) def __call__(self, name, *args, extra_args = []): return self.gen(name, *args, extra_args = extra_args) - + def gen(self, name, *args, extra_args = []): inputs = File.resolve(args) path = BUILD / Path(".").resolve().relative_to(ROOT) / self.mkout(name) - + + # XXX: consider passing the arrays of files to handlers directly + i = " ".join([str(inp) for inp in inputs]) + for mk in self.mkextra: + extra_args += [mk(name)] + return Target(path, self, inputs, extra_args) def gen_makefile(self): @@ -157,27 +166,32 @@ class Processor(metaclass = ProcessorMeta): def gen_ninja(self): out = "rule %s\n" % (self.name) - + cmd = "%s %s" % (self.exe, self.mkargs("$out", "$in", "$extra")) - + out += " command = %s\n" % (cmd) out += " description = %s\n" % (self.mkdesc("$out", "$in", cmd)) return out class Vec(Processor): - def __init__(self, name, exe, mkargs, mkout, mkdesc=DEFMKDESC): - super().__init__(name, exe, mkargs, mkout = mkout, mkdesc = mkdesc) - + def __init__(self, name, exe, mkargs, mkout, mkextra=[], mkdesc=DEFMKDESC): + super().__init__(name, exe, mkargs, mkextra = mkextra, mkout = mkout, mkdesc = mkdesc) + def __call__(self, *args, extra_args = []): return self.gen(*args, extra_args = extra_args) - + def gen(self, *args, extra_args = []): args = File.resolve(args) extra_args = flatten(extra_args) - + targets = [] for i in args: path = BUILD / i.path.parent / self.mkout(i.path) + extra_p = extra_args + + # XXX: consider passing the i File directly to mk + for mk in self.mkextra: + extra_p += [mk(path)] targets.append(Target(path, self, [i], extra_args)) @@ -187,74 +201,88 @@ class CTarget(Target): def __init__(self, path, processor, inputs, header_depends, extra_args = []): super().__init__(path, processor, inputs, extra_args = extra_args) self.header_depends = File.resolve(header_depends) - + def gen_makefile(self): out = [] if self.header_depends != []: out += ["-include %s\n" % hdep for hdep in self.header_depends] - + out += super().gen_makefile() return "".join(out) class CC(Vec): - def __init__(self, name, exe, mkargs, mkout, mkinc, mkdep=None, depstyle=None, mkdesc=DEFMKDESC): - super().__init__(name, exe, mkargs, mkout, mkdesc=mkdesc) + def __init__(self, name, exe, mkargs, mkout, mkinc, mkextra=[], mkdep=None, depstyle=None, mkdesc=DEFMKDESC): + super().__init__(name, exe, mkargs, mkout, mkextra=mkextra, mkdesc=mkdesc) self.mkinc = mkinc self.mkdep = mkdep self.depstyle = depstyle - + def __call__(self, *args, extra_args = [], include_dirs = []): return self.gen(*args, extra_args = extra_args, include_dirs = include_dirs) - + def gen(self, *args, extra_args = [], include_dirs = []): inputs = File.resolve(args) - + extra_args = flatten(extra_args) include_dirs = File.resolve(include_dirs) include_args = [self.mkinc(str(x)) for x in include_dirs] extra_args += include_args - + targets = [] for input in inputs: out = self.mkout(input.path) path = BUILD / out - hdep = BUILD / self.mkdep(out) - targets.append(CTarget(path, self, input, header_depends = hdep, extra_args = extra_args)) + header_depends = [] + if self.mkdep: + hdep += BUILD / self.mkdep(out) + + extra_p = extra_args + # XXX: consider passing the i File directly to mk + for mk in self.mkextra: + extra_p += [mk(path)] + + targets.append(CTarget(path, self, input, header_depends = header_depends, extra_args = extra_p)) return targets - + def gen_ninja(self): out = super().gen_ninja() - - if self.mkdep and self.depstyle == "gcc": + + if self.depstyle == "gcc": out += " deps = gcc\n" + elif self.depstyle == "msvc": + out += " deps = msvc\n" + else: + raise Exception("ninja dependencies for selected depstyle is unimplemented") + + if self.mkdep and self.depstyle == "gcc": out += " depfile = %s\n" % (self.mkdep("$out")) elif self.mkdep: raise Exception("ninja dependencies for selected depstyle is unimplemented") - + return out class CExe(Processor): - def __init__(self, name, exe, mkargs, mklib, mkout = DEFMKOUT, mkdesc=DEFMKDESC): - super().__init__(name, exe, mkargs, mkout = mkout, mkdesc = mkdesc) - + def __init__(self, name, exe, mkargs, mklib, mkextra = [], mkout = DEFMKOUT, mkdesc=DEFMKDESC): + super().__init__(name, exe, mkargs, mkextra = mkextra, mkout = mkout, mkdesc = mkdesc) + self.mklib = mklib - + def __call__(self, name, *args, libs = [], extra_args = []): return self.gen(name, *args, libs = libs, extra_args = extra_args) - + def gen(self, name, *args, libs, extra_args = []): extra_args = flatten(extra_args) libs = flatten(libs) - + # Note: this is bad, perhaps take a "depends" also/instead # XXX Handling of libraries is temporary libs_args = [self.mklib(lib) for lib in libs] extra_args += libs_args - + return super().gen(name, *args, extra_args = extra_args) def CCStyleToolchain(name, gccname, arname, suffix="", c_args=[], ld_args=[]): @@ -262,10 +290,10 @@ def CCStyleToolchain(name, gccname, arname, suffix="", c_args=[], ld_args=[]): exename = name + "exe" + suffix libname = name + "lib" + suffix shlibname = name + "shlib" + suffix - + c_args = " ".join(flatten(c_args)) ld_args = " ".join(flatten(ld_args)) - + gcc = find_program(gccname) ar = find_program(arname) @@ -313,7 +341,59 @@ def ClangToolchain(suffix="", c_args=[], ld_args=[]): def CCToolchain(suffix="", c_args=[], ld_args=[]): return CCStyleToolchain("cc", "cc", "ar", suffix, c_args, ld_args) +def MSVCToolchain(suffix="", c_args=[], ld_args=[]): + ccname = "msvc" + suffix + exename = "msvcexe" + suffix + libname = "msvclib" + suffix + shlibname = "msvcshlib" + suffix + + c_args = " ".join(flatten(c_args)) + ld_args = " ".join(flatten(ld_args)) + + cl = find_program("cl") + lib = find_program("lib") + link = find_program("link") + + cc = CC( + name=ccname, + exe=cl, + mkargs=lambda o, i, ea: "/showIncludes /nologo /D_USRDLL /D_WINDLL /Fo%s /c %s /MT %s %s" % (o, i, c_args, ea), + mkout=lambda i: "%s.obj" % (i), + mkinc=lambda inc: "/I%s" % (inc), + mkdesc=lambda o, i, cmd: "CC %s" % (o), + depstyle="msvc" + ) + exe = CExe( + name=exename, + exe=link, + mkargs=lambda o, i, ea: "/OUT:%s %s %s %s" % (o, i, ld_args, ea), + mklib=lambda l: l, + mkdesc=lambda o, i, cmd: "LD %s" % (o), + mkout=lambda n: "%s.exe" % (n), + ) + lib = CExe( + name=libname, + exe=lib, + mkargs=lambda o, i, ea: "/OUT:%s %s %s" % (o, i, ea), + mklib=lambda l: "", # TODO: this should not be needed + mkdesc=lambda o, i, cmd: "AR %s" % (o), + mkout=lambda n: "lib%s.lib" % (n) + ) + shlib = CExe( + name=shlibname, + exe=cl, + mkargs=lambda o, i, ea: "/D_USRDLL /D_WINDLL %s /MT /link /DLL %s %s" % (i, ld_args, ea), + mklib=lambda l: "", # TODO: make this not needed + mkdesc=lambda o, i, cmd: "SO %s" % (o), + mkout=lambda n: "%s.lib" % (n), + # XXX: TODO: mkextra is very bad, do this properly + # perhaps, by specializing CTarget or injecting data into it + mkextra=[lambda n: "/OUT:" + str(BUILD / CWD / ("%s.dll" % (n)))] + ) + return cc, exe, lib, shlib + CTOOLCHAINS = { + 'msvc': MSVCToolchain, 'cc': CCToolchain, 'clang': ClangToolchain, 'gcc': GccToolchain @@ -328,7 +408,7 @@ def CToolchain(name="system", suffix="", c_args=[], ld_args=[]): if name != "system": if not name in CTOOLCHAINS: raise Exception("No such C toolchain available") - + return CTOOLCHAINS[name](suffix, c_args, ld_args) for t in CTOOLCHAINS.values(): @@ -336,7 +416,7 @@ def CToolchain(name="system", suffix="", c_args=[], ld_args=[]): return t(suffix, c_args, ld_args) except: pass - + raise Exception("No C toolchain found on system") global cc, exe, lib, shlib @@ -352,15 +432,16 @@ def find_one(names): def subdir(dir): # Save the previous location PWD = Path.cwd() - + # Go into subdir sub = PWD / dir os.chdir(sub) - + # Set helper path + global CWD CWD = Path.cwd().relative_to(ROOT) exec(open('.build').read()) - + # Revert the current directory; os.chdir(PWD) @@ -374,13 +455,13 @@ def gen_bld(): def gen_makefile(): out = [mach.gen_makefile() + "\n" for mach in Processor.mdb.values()] out += ["\n\n" + target.gen_makefile() for target in File.fdb.values() if issubclass(type(target), Target)] - + return "".join(out) - + def gen_ninja(): out = [mach.gen_ninja() + "\n" for mach in Processor.mdb.values()] out += [target.gen_ninja() + "\n" for target in File.fdb.values() if issubclass(type(target), Target)] - + return "".join(out) parser = argparse.ArgumentParser(description="cook build system") diff --git a/test/.build b/test/.build index 96b8226..61983a3 100644 --- a/test/.build +++ b/test/.build @@ -1,3 +1,5 @@ -obj = cc("main.c") -l = lib("vol", obj) -aout = exe("vol", l, libs=["Xm", "Xt"])
\ No newline at end of file +maino = cc("main.c") +haio = cc("hai.c") +hailib = shlib("hai", haio) + +aout = exe("vol", maino, hailib)
\ No newline at end of file diff --git a/test/hai.c b/test/hai.c new file mode 100644 index 0000000..263a8de --- /dev/null +++ b/test/hai.c @@ -0,0 +1,8 @@ +#include "hai.h" + +#include <stdio.h> + +__declspec(dllexport) +void hai() { + printf("lol\n"); +}
\ No newline at end of file diff --git a/test/hai.h b/test/hai.h new file mode 100644 index 0000000..5da3133 --- /dev/null +++ b/test/hai.h @@ -0,0 +1,3 @@ +__declspec(dllexport) +void hai(); +// test
\ No newline at end of file diff --git a/test/main.c b/test/main.c index 25c49da..3763706 100644 --- a/test/main.c +++ b/test/main.c @@ -1,81 +1,9 @@ - #include <stdio.h> -#include <Xm/Xm.h> -#include <Xm/MainW.h> -#include <Xm/PushB.h> -#include <Xm/ArrowB.h> -#include <Xm/RowColumn.h> -#include <Xm/Form.h> - -int lol() { - printf("yes!\n"); - return 0; -} +#include "hai.h" int main(int argc, char **argv) { - XtAppContext app; - Widget toplevel = XtVaAppInitialize(&app, "Demo", NULL, 0, &argc, argv, NULL, NULL); - - /*Widget mainw = XtVaCreateManagedWidget("main_window", - xmMainWindowWidgetClass, toplevel, - XmNscrollBarDisplayPolicy, XmAS_NEEDED, - XmNscrollingPolicy, XmAUTOMATIC, - NULL); - - XmString file = XmStringCreateLocalized("File"); - XmString edit = XmStringCreateLocalized("Edit"); - Widget menu = XmVaCreateSimpleMenuBar(mainw, "menubar", - XmVaCASCADEBUTTON, file, 'F', - XmVaCASCADEBUTTON, edit, 'E', - NULL); - XmStringFree(edit); - XmStringFree(file); - - XtManageChild(menu); */ - - Widget form = XmVaCreateForm(toplevel, "form", - XmNfractionBase, 90, - NULL); - XtManageChild(form); - - Widget left = XmVaCreateArrowButton(form, "voldown", - XmNarrowDirection, XmARROW_LEFT, - XmNtopAttachment, XmATTACH_FORM, - XmNleftAttachment, XmATTACH_FORM, - XmNbottomAttachment, XmATTACH_FORM, - XmNrightAttachment, XmATTACH_POSITION, - XmNrightPosition, 30, - NULL); - XtAddCallback(left, XmNactivateCallback, (XtCallbackProc)lol, NULL); - XtAddCallback(left, XmNdisarmCallback, (XtCallbackProc)lol, NULL); - XtManageChild(left); - - - Widget pb = XmVaCreatePushButton(form, "Volume", - XmNleftAttachment, XmATTACH_WIDGET, - XmNleftWidget, left, - XmNtopAttachment, XmATTACH_FORM, - XmNbottomAttachment, XmATTACH_FORM, - XmNrightAttachment, XmATTACH_POSITION, - XmNrightPosition, 60, - NULL); - XtAddCallback(pb, XmNactivateCallback, (XtCallbackProc)lol, NULL); - XtManageChild(pb); - - Widget right = XmVaCreateArrowButton(form, "volup", - XmNarrowDirection, XmARROW_RIGHT, - XmNleftAttachment, XmATTACH_WIDGET, - XmNleftWidget, pb, - XmNrightAttachment, XmATTACH_FORM, - XmNtopAttachment, XmATTACH_FORM, - XmNbottomAttachment, XmATTACH_FORM, - NULL); - XtAddCallback(right, XmNactivateCallback, (XtCallbackProc)lol, NULL); - XtAddCallback(right, XmNdisarmCallback, (XtCallbackProc)lol, NULL); - XtManageChild(right); - - XtRealizeWidget(toplevel); - XtAppMainLoop(app); + printf("Hello world\n"); + hai(); return 0; } |
