The last commit was a bandaid, but this needed a real fix. Now we create a .parse_deps.phony file in every module build dir that implicitly depends on that module's dependencies' .parse_deps.phony files, as well as order-only depends on any cog-parsed output for that module. This causes the cog files to get generated first if they never have been, but still leaves real header dependency tracking to clang's depfile generation.
86 lines
2.0 KiB
Python
86 lines
2.0 KiB
Python
class Action:
|
|
name = property(lambda self: self.__name)
|
|
implicit = property(lambda self: False)
|
|
rule = property(lambda self: None)
|
|
deps = property(lambda self: tuple())
|
|
|
|
def __init__(self, name):
|
|
self.__name = name
|
|
|
|
def output_of(self, path):
|
|
return None
|
|
|
|
|
|
class Compile(Action):
|
|
rule = property(lambda self: f'compile_{self.name}')
|
|
deps = property(lambda self: ("${module_dir}/.parse_dep.phony",))
|
|
|
|
def __init__(self, name, suffix = ".o"):
|
|
super().__init__(name)
|
|
self.__suffix = suffix
|
|
|
|
def output_of(self, path):
|
|
return str(path) + self.__suffix
|
|
|
|
|
|
class Parse(Action):
|
|
rule = property(lambda self: f'parse_{self.name}')
|
|
|
|
def output_of(self, path):
|
|
suffix = "." + self.name
|
|
if path.suffix == suffix:
|
|
return path.with_suffix('')
|
|
return path
|
|
|
|
|
|
class Link(Action): pass
|
|
|
|
|
|
class Header(Action):
|
|
implicit = property(lambda self: True)
|
|
|
|
|
|
class Source:
|
|
Actions = {
|
|
'.c': Compile('c'),
|
|
'.cpp': Compile('cxx'),
|
|
'.s': Compile('asm'),
|
|
'.cog': Parse('cog'),
|
|
'.o': Link('o'),
|
|
'.h': Header('h'),
|
|
'.inc': Header('inc'),
|
|
}
|
|
|
|
def __init__(self, root, path, output=None, deps=tuple()):
|
|
from pathlib import Path
|
|
self.__root = Path(root)
|
|
self.__path = Path(path)
|
|
self.__output = output
|
|
self.__deps = tuple(deps)
|
|
|
|
def __str__(self):
|
|
return self.input
|
|
|
|
def add_deps(self, deps):
|
|
self.__deps += tuple(deps)
|
|
|
|
@property
|
|
def action(self):
|
|
suffix = self.__path.suffix
|
|
return self.Actions.get(suffix)
|
|
|
|
@property
|
|
def output(self):
|
|
if not self.action:
|
|
return None
|
|
|
|
path = self.__output
|
|
if path is None:
|
|
path = self.action.output_of(self.__path)
|
|
|
|
return path and Source("${module_dir}", path)
|
|
|
|
deps = property(lambda self: self.__deps)
|
|
name = property(lambda self: str(self.__path))
|
|
input = property(lambda self: str(self.__root / self.__path))
|