Working on ninja file generation.
This commit is contained in:
parent
a3ae84fde9
commit
e7b93db95f
|
@ -4,7 +4,7 @@ from osdk.model import ComponentManifest, TargetManifest, Props
|
|||
from osdk.ninja import Writer
|
||||
from osdk.logger import Logger
|
||||
from osdk.context import Context, contextFor
|
||||
from osdk import shell
|
||||
from osdk import shell, rules
|
||||
|
||||
logger = Logger("builder")
|
||||
|
||||
|
@ -18,14 +18,45 @@ def gen(out: TextIO, context: Context):
|
|||
writer.newline()
|
||||
|
||||
writer.separator("Tools")
|
||||
for key in target.tools:
|
||||
tool = target.tools[key]
|
||||
writer.variable(key, tool.cmd)
|
||||
for i in target.tools:
|
||||
tool = target.tools[i]
|
||||
writer.variable(i, tool.cmd)
|
||||
writer.variable(
|
||||
key + "flags", " ".join(tool.args))
|
||||
i + "flags", " ".join(tool.args))
|
||||
writer.newline()
|
||||
|
||||
writer.separator("Rules")
|
||||
for i in rules.rules:
|
||||
tool = target.tools[i]
|
||||
rule = rules.rules[i]
|
||||
writer.rule(
|
||||
i, f"{tool.cmd} {rule.rule.replace('$flags',f'${i}flags')}")
|
||||
writer.newline()
|
||||
|
||||
writer.separator("Components")
|
||||
|
||||
for instance in context.instances:
|
||||
objects = instance.objsfiles()
|
||||
writer.comment(f"Component: {instance.manifest.id}")
|
||||
|
||||
writer.newline()
|
||||
|
||||
for obj in objects:
|
||||
r = rules.byFileIn(obj[0])
|
||||
if r is None:
|
||||
raise Exception(f"Unknown rule for file {obj[0]}")
|
||||
writer.build(obj[1], r.id, obj[0])
|
||||
|
||||
writer.newline()
|
||||
|
||||
if instance.isLib():
|
||||
writer.build(instance.libfile(), "ar",
|
||||
list(map(lambda o: o[1], objects)))
|
||||
else:
|
||||
writer.build(instance.binfile(), "ld",
|
||||
list(map(lambda o: o[1], objects)))
|
||||
|
||||
writer.newline()
|
||||
|
||||
|
||||
def build(componentSpec: str, targetSpec: str = "default", props: Props = {}) -> str:
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from typing import cast
|
||||
|
||||
from osdk.model import TargetManifest, ComponentManifest, Props
|
||||
from osdk.logger import Logger
|
||||
from osdk import const, shell, jexpr
|
||||
|
@ -22,17 +24,21 @@ class ComponentInstance:
|
|||
self.sources = sources
|
||||
self.resolved = resolved
|
||||
|
||||
def isLib(self):
|
||||
return self.manifest.type == "lib"
|
||||
|
||||
def binfile(self) -> str:
|
||||
return f"{self.target.builddir()}/bin/{self.manifest.id}.out"
|
||||
|
||||
def objdir(self) -> str:
|
||||
return f"{self.target.builddir()}/obj/{self.manifest.id}"
|
||||
|
||||
def objsfiles(self) -> list[str]:
|
||||
def objsfiles(self) -> list[tuple[str, str]]:
|
||||
return list(
|
||||
map(
|
||||
lambda s: f"{self.objdir()}/{s}.o",
|
||||
self.sources.remplace(self.manifest.dirname(), "")))
|
||||
lambda s: (
|
||||
s, f"{self.objdir()}/{s.replace(self.manifest.dirname() + '/', '')}.o"),
|
||||
self.sources))
|
||||
|
||||
def libfile(self) -> str:
|
||||
return f"{self.target.builddir()}/lib/{self.manifest.id}.a"
|
||||
|
@ -124,12 +130,15 @@ def resolveDeps(componentSpec: str, components: list[ComponentManifest], target:
|
|||
return enabled, resolved[1:]
|
||||
|
||||
|
||||
def instanciate(componentSpec: str, components: list[ComponentManifest], target: TargetManifest) -> ComponentInstance:
|
||||
def instanciate(componentSpec: str, components: list[ComponentManifest], target: TargetManifest) -> ComponentInstance | None:
|
||||
manifest = next(filter(lambda c: c.id == componentSpec, components))
|
||||
sources = shell.find(
|
||||
manifest.path, ["*.c", "*.cpp", "*.s", "*.asm"])
|
||||
manifest.dirname(), ["*.c", "*.cpp", "*.s", "*.asm"])
|
||||
enabled, resolved = resolveDeps(componentSpec, components, target)
|
||||
|
||||
if not enabled:
|
||||
return None
|
||||
|
||||
return ComponentInstance(target, manifest, sources, resolved)
|
||||
|
||||
|
||||
|
@ -140,8 +149,8 @@ def contextFor(targetSpec: str, props: Props) -> Context:
|
|||
components = loadAllComponents()
|
||||
|
||||
components = filterDisabled(components, target)
|
||||
instances = list(map(lambda c: instanciate(
|
||||
c.id, components, target), components))
|
||||
instances = cast(list[ComponentInstance], list(filter(lambda e: e != None, map(lambda c: instanciate(
|
||||
c.id, components, target), components))))
|
||||
|
||||
return Context(
|
||||
target,
|
||||
|
|
|
@ -141,10 +141,17 @@ class ComponentManifest(Manifest):
|
|||
|
||||
def isEnabled(self, target: TargetManifest):
|
||||
for k, v in self.enableIf.items():
|
||||
if k in target.props and target.props[k] in v:
|
||||
return True
|
||||
if not k in target.props:
|
||||
logger.log(
|
||||
f"Component {self.id} disabled by missing {k} in target")
|
||||
return False
|
||||
|
||||
return False
|
||||
if not target.props[k] in v:
|
||||
logger.log(
|
||||
f"Component {self.id} disabled by {k}={target.props[k]} not in {v}")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class ModelEncoder(JSONEncoder):
|
||||
|
|
|
@ -1,7 +1,37 @@
|
|||
rules = {
|
||||
"cc": "-c -o $out $in -MD -MF $out.d $flags",
|
||||
"cxx": "-c -o $out $in -MD -MF $out.d $flags",
|
||||
"as": "-o $out $in $flags",
|
||||
"ar": "$flags $out $in",
|
||||
"ld": "-o $out $in $flags",
|
||||
class Rule:
|
||||
id: str
|
||||
fileIn: list[str]
|
||||
fileOut: list[str]
|
||||
rule: str
|
||||
|
||||
def __init__(self, id: str, fileIn: list[str], fileOut: list[str], rule: str):
|
||||
self.id = id
|
||||
self.fileIn = fileIn
|
||||
self.fileOut = fileOut
|
||||
self.rule = rule
|
||||
|
||||
|
||||
rules: dict[str, Rule] = {
|
||||
"cc": Rule("cc", ["c"], ["o"], "-c -o $out $in -MD -MF $out.d $flags"),
|
||||
"cxx": Rule("cxx", ["cpp", "cc", "cxx"], ["o"], "-c -o $out $in -MD -MF $out.d $flags"),
|
||||
"as": Rule("as", ["s", "asm", "S"], ["o"], "-o $out $in $flags"),
|
||||
"ar": Rule("ar", ["o"], ["a"], "$flags $out $in"),
|
||||
"ld": Rule("ld", ["o", "a"], ["out"], "$flags $out $in"),
|
||||
}
|
||||
|
||||
|
||||
def append(rule: Rule):
|
||||
rules[rule.id] = rule
|
||||
|
||||
|
||||
def byFileIn(fileIn: str) -> Rule | None:
|
||||
for key in rules:
|
||||
rule = rules[key]
|
||||
for ext in rule.fileIn:
|
||||
if fileIn.endswith("." + ext):
|
||||
return rule
|
||||
return None
|
||||
|
||||
|
||||
def byId(id: str) -> Rule | None:
|
||||
return rules.get(id, None)
|
||||
|
|
|
@ -2,6 +2,8 @@ from typing import Any, TypeVar, cast
|
|||
import json
|
||||
import hashlib
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
|
||||
def uniq(l: list[str]) -> list[str]:
|
||||
result: list[str] = []
|
||||
|
@ -48,9 +50,6 @@ def key(obj: Any, keys: list[str] = []) -> str:
|
|||
return "-".join(k)
|
||||
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
|
||||
def asList(i: T | list[T] | None) -> list[T]:
|
||||
if i is None:
|
||||
return []
|
||||
|
|
Loading…
Reference in a new issue