cutekit/osdk/builder.py

127 lines
3.4 KiB
Python
Raw Normal View History

from typing import TextIO
from osdk.model import ComponentManifest, TargetManifest, Props
from osdk.ninja import Writer
from osdk.logger import Logger
from osdk.context import Context, contextFor
2023-01-31 20:09:28 +00:00
from osdk import shell, rules
logger = Logger("builder")
def gen(out: TextIO, context: Context):
writer = Writer(out)
target = context.target
writer.comment("File generated by the build system, do not edit")
writer.newline()
2023-02-08 21:41:14 +00:00
writer.variable("builddir", context.builddir())
writer.separator("Tools")
2023-02-02 22:05:45 +00:00
writer.variable("cincs", " ".join(
2023-02-06 10:14:32 +00:00
map(lambda i: f"-I{i}", context.cincls())))
writer.variable("cdefs", " ".join(context.cdefs()))
2023-02-02 22:05:45 +00:00
writer.newline()
2023-01-31 20:09:28 +00:00
for i in target.tools:
tool = target.tools[i]
2023-02-02 22:05:45 +00:00
rule = rules.rules[i]
2023-01-31 20:09:28 +00:00
writer.variable(i, tool.cmd)
writer.variable(
2023-02-02 22:05:45 +00:00
i + "flags", " ".join(rule.args + tool.args))
2023-01-31 20:09:28 +00:00
writer.rule(
2023-02-02 22:05:45 +00:00
i, f"{tool.cmd} {rule.rule.replace('$flags',f'${i}flags')}", depfile=rule.deps)
2023-01-31 20:09:28 +00:00
writer.newline()
writer.separator("Components")
for instance in context.instances:
2023-02-07 11:40:00 +00:00
objects = instance.objsfiles(context)
2023-01-31 20:09:28 +00:00
writer.comment(f"Component: {instance.manifest.id}")
writer.comment(f"Resolved: {', '.join(instance.resolved)}")
2023-01-31 20:09:28 +00:00
for obj in objects:
r = rules.byFileIn(obj[0])
if r is None:
raise Exception(f"Unknown rule for file {obj[0]}")
t = target.tools[r.id]
writer.build(obj[1], r.id, obj[0], order_only=t.files)
2023-01-31 20:09:28 +00:00
writer.newline()
if instance.isLib():
2023-02-07 11:40:00 +00:00
writer.build(instance.libfile(context), "ar",
2023-01-31 20:09:28 +00:00
list(map(lambda o: o[1], objects)))
else:
libraries: list[str] = []
for req in instance.resolved:
reqInstance = context.componentByName(req)
if reqInstance is None:
raise Exception(f"Component {req} not found")
if not reqInstance.isLib():
raise Exception(f"Component {req} is not a library")
2023-02-07 11:40:00 +00:00
libraries.append(reqInstance.outfile(context))
2023-02-07 11:40:00 +00:00
writer.build(instance.binfile(context), "ld",
list(map(lambda o: o[1], objects)) + libraries)
2023-01-31 20:09:28 +00:00
writer.newline()
def build(componentSpec: str, targetSpec: str, props: Props = {}) -> str:
context = contextFor(targetSpec, props)
target = context.target
2023-02-07 11:40:00 +00:00
shell.mkdir(context.builddir())
ninjaPath = f"{context.builddir()}/build.ninja"
with open(ninjaPath, "w") as f:
gen(f, context)
2023-02-07 11:40:00 +00:00
instance = context.componentByName(componentSpec)
2023-02-07 11:40:00 +00:00
if instance is None:
raise Exception(f"Component {componentSpec} not found")
2023-02-07 11:40:00 +00:00
shell.exec(f"ninja", "-v", "-f", ninjaPath, instance.outfile(context))
2023-02-07 11:40:00 +00:00
return instance.outfile(context)
2023-02-07 11:40:00 +00:00
class Paths:
bin: str
lib: str
obj: str
def __init__(self, bin: str, lib: str, obj: str):
self.bin = bin
self.lib = lib
self.obj = obj
2023-02-08 22:37:28 +00:00
def buildAll(targetSpec: str) -> Paths:
context = contextFor(targetSpec)
target = context.target
2023-02-07 11:40:00 +00:00
shell.mkdir(context.builddir())
ninjaPath = f"{context.builddir()}/build.ninja"
with open(ninjaPath, "w") as f:
gen(f, context)
shell.exec(f"ninja", "-v", "-f", ninjaPath)
2023-02-07 11:40:00 +00:00
return Paths(
context.builddir() + "/bin",
context.builddir() + "/lib",
context.builddir() + "/obj",
)