From ddedac846b0788e3cff90a24b2c8109308b1e840 Mon Sep 17 00:00:00 2001 From: Alejandro Sior Date: Tue, 13 Sep 2022 15:27:35 +0200 Subject: cook: simplified the module system --- cook.py | 203 +++++++++++++++++++++++++++++----------------------------------- 1 file changed, 93 insertions(+), 110 deletions(-) (limited to 'cook.py') diff --git a/cook.py b/cook.py index db409ba..002ab04 100755 --- a/cook.py +++ b/cook.py @@ -224,11 +224,15 @@ class CC(Vec): def __call__(self, *args, **kwargs): return self.gen(*args, **kwargs) - def gen(self, *args, extra_args = [], include_dirs = [], **kwargs): + def gen(self, *args, extra_args = [], include_dirs = [], deps = [], **kwargs): inputs = File.resolve(args) + + deps = flatten(deps) + include_dirs += [d.include_dirs for d in deps if d.include_dirs] include_dirs = File.resolve(include_dirs) include_args = [self.mkinc(str(x)) for x in include_dirs] + extra_args += [d.cc_args for d in deps if d.cc_args] extra_args += include_args targets = [] @@ -270,9 +274,13 @@ class CExe(Processor): def __call__(self, *args, **kwargs): return self.gen(*args, **kwargs) - def gen(self, name, *args, libs=[], extra_args = [], **kwargs): + def gen(self, name, *args, libs=[], deps = [], extra_args = [], **kwargs): libs = flatten(libs) - + deps = flatten(deps) + + libs += [d.libs for d in deps if d.libs] + extra_args += [d.ld_args for d in deps if d.ld_args] + # 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] @@ -442,112 +450,86 @@ def CToolchain(name="system", suffix="", c_args=[], ld_args=[], tdb=CTOOLCHAINS) def CppToolchain(*args, tdb=CXXTOOLCHAINS, **kwargs): return CToolchain(*args, tdb = tdb, **kwargs) -# NOTE: this implementation is very simple and bad but does what -# i need -class CModule: - def __init__(self, name, cc, exe, lib, shlib, root = None): +class CMod: + def __init__(self, parent, name): + self.path = parent.path / name if parent else ROOT + self.name = name - - # The toolchain that the module uses - self.cc = cc - self.exe = exe - self.lib = lib - self.shlib = shlib - - # The root module. Is this needed? - self.root = root - - # Executables instanciated by the module. Add shared libraries when applicable - self.exes = dict() - # Submodules instanciated by the module - self.submodules = dict() - - # Objects accumulator - self.objects = [] - - # Private includes, libs and args - self.includes = [] - self.libs = [] - self.ld_args = [] - self.cc_args = [] - - # Shared includes, libs and args - self.shared_includes = [] - self.shared_libs = [] - self.bcast_includes = [] - self.shared_ld_args = [] - self.shared_cc_args = [] - - def eval(self): - subdir(self.name) + self.parent = parent + if self.parent: + self.parent.children[name] = self + self.children = dict() + self.objects = dict() - def submodule(self, name, toolchain = None): - global mod - prev = mod - - root = self.root if self.root else self - cc = prev.cc - exe = prev.exe - lib = prev.lib - shlib = prev.shlib - if toolchain: - cc, exe, lib, shlib = toolchain - root = None - - mod = CModule(name, cc, exe, lib, shlib, root) - #if root == None: - # pass - # XXX: FIX this "if", temporary and put this elsewhere - mod.includes += self.bcast_includes - mod.eval() + def __call__(self, path): + components = path.split("/") - # Perhaps store everything the object created - self.link(mod) + resolved = self - mod, prev = prev, mod + for i, component in enumerate(components): + if i == 0 and component == "": + resolved = _root + elif component == "" or component == ".": + resolved = resolved + elif component == "..": + resolved = resolved.parent + elif component in resolved.children: + resolved = resolved.children[component] + else: + m = CMod(resolved, component) + m.dive() + resolved = m - mod.submodules[name] = prev - - return prev + return resolved + + def __getitem__(self, key): + if key in self.objects: + return self.objects[key] + elif self.parent: + return self.parent[key] + else: + return None - def set_toolchain(self, toolchain): - self.cc, self.exe, self.lib, self.shlib = toolchain + def __setitem__(self, key, val): + self.objects[key] = val - def mklib(self): - if self.objects == [] or self.lib == None: - return None - return self.lib(self.name, self.objects) + def __delitem__(self, key): + if key in self.objects: + del self.objects[key] + + def __getattr__(self, attr): + return self[attr] - def link(self, *mods): - mods = flatten(mods) - - for mod in mods: - if type(mod) == str: - mod = CDependency(mod) - - obj = mod.mklib() - if obj: - self.objects += [obj] - self.shared_includes += mod.shared_includes - self.shared_libs += mod.shared_libs - self.bcast_includes += mod.bcast_includes - self.shared_ld_args += mod.shared_ld_args - self.shared_cc_args += mod.shared_cc_args + def dive(self): + global mod + # Save the previous location + PWD = Path.cwd() + pmod = mod + mod = self - def src(self, *args, extra_args = [], include_dirs = [], **kwargs): - obj = self.cc(*args, extra_args = [extra_args, self.cc_args, self.shared_cc_args], include_dirs = [include_dirs, self.includes, self.bcast_includes, self.shared_includes], **kwargs) - self.objects += obj + # Go into subdir + sub = self.path + os.chdir(sub) - def mkdep(self, shared_includes = [], shared_libs = [], bcast_includes = [], shared_ld_args = [], shared_cc_args = []): - self.shared_includes += flatten(shared_includes) - self.shared_libs += flatten(shared_libs) - self.shared_ld_args += flatten(shared_ld_args) - self.shared_cc_args += flatten(shared_cc_args) - self.bcast_includes += flatten(bcast_includes) + exec(open('.build').read(), globals()) - def mkexe(self, name, extra_args = [], libs = [], **kwargs): - self.exes[name] = self.exe(name, self.objects, extra_args = [extra_args, self.ld_args, self.shared_ld_args], libs = [libs, self.libs, self.shared_libs], **kwargs) - return self.exes[name] + # Revert the current directory; + os.chdir(PWD) + mod = pmod + +global _root +_root = CMod(None, "") + +global mod +mod = _root + +def set_toolchain(t): + mod(".")["cc"] = t[0] + mod(".")["exe"] = t[1] + mod(".")["lib"] = t[2] + mod(".")["shlib"] = t[3] + +set_toolchain(CToolchain()) pkgconfig = find_program("pkg-config", False) @@ -556,18 +538,19 @@ def subproc(*args, **kwargs): # XXX: make name a variadic def CDependency(name): - #if type(name) == list or type(name) is tuple: - # return [CDependency(n) for n in name] + if type(name) == list or type(name) is tuple: + return [CDependency(n) for n in name] - module = CModule(name, None, None, None, None, None) + module = CMod(None, name) if pkgconfig: try: inc = subproc([pkgconfig.path, "--cflags", name]).strip().decode("utf-8") lib = subproc([pkgconfig.path, "--libs", name]).strip().decode("utf-8") - inc = inc if inc != "" else [] - lib = lib if lib != "" else [] - module.mkdep(shared_ld_args = lib, shared_cc_args = inc) + + module["cc_args"] = inc if inc != "" else [] + module["ld_args"] = lib if lib != "" else [] + return module except subprocess.CalledProcessError: pass @@ -577,15 +560,15 @@ def CDependency(name): # XXX: windows stuff # Use the system way of getting to know libraries (no includes specified) - module.mkdep(shared_libs = name) + module["libs"] = name return module -cc, exe, lib, shlib = CToolchain() +# cc, exe, lib, shlib = CToolchain() -global root, mod -root = CModule("root", cc, exe, lib, shlib) -mod = root +# #global root, mod +# root = CModule("root", cc, exe, lib, shlib) +# mod = root def find_one(names): for name in names: @@ -610,7 +593,7 @@ def subdir(dir): # Revert the current directory; os.chdir(PWD) -subdir(".") +mod.dive() def gen_bld(): return [target.path.parent.mkdir(parents=True, exist_ok=True) -- cgit v1.2.3