cutekit/osdk/builder.py

108 lines
3 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()
writer.separator("Tools")
2023-01-31 20:09:28 +00:00
for i in target.tools:
tool = target.tools[i]
writer.variable(i, tool.cmd)
writer.variable(
2023-01-31 20:09:28 +00:00
i + "flags", " ".join(tool.args))
writer.newline()
writer.separator("Rules")
2023-01-31 20:09:28 +00:00
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')}", deps=rule.deps)
2023-01-31 20:09:28 +00:00
writer.newline()
writer.separator("Components")
for instance in context.instances:
objects = instance.objsfiles()
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():
writer.build(instance.libfile(), "ar",
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")
libraries.append(reqInstance.outfile())
2023-01-31 20:09:28 +00:00
writer.build(instance.binfile(), "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
shell.mkdir(target.builddir())
ninjaPath = f"{target.builddir()}/build.ninja"
with open(ninjaPath, "w") as f:
gen(f, context)
component = context.componentByName(componentSpec)
if component is None:
raise Exception(f"Component {componentSpec} not found")
shell.exec(f"ninja", "-v", "-f", ninjaPath, component.outfile())
return component.outfile()
def buildAll(targetSpec: str, props: Props = {}) -> str:
context = contextFor(targetSpec, props)
target = context.target
shell.mkdir(target.builddir())
ninjaPath = f"{target.builddir()}/build.ninja"
with open(ninjaPath, "w") as f:
gen(f, context)
shell.exec(f"ninja", "-v", "-f", ninjaPath)
return target.builddir()