cutekit/osdk/builder.py

162 lines
4.3 KiB
Python
Raw Normal View History

2023-02-21 16:33:38 +00:00
import os
from typing import TextIO
2023-03-11 14:29:31 +00:00
from osdk.model import Props
from osdk.ninja import Writer
from osdk.logger import Logger
2023-04-15 23:03:06 +00:00
from osdk.context import ComponentInstance, 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-04-15 23:03:06 +00:00
writer.rule("cp", "cp $in $out")
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")
2023-02-10 20:40:57 +00:00
all: list[str] = []
2023-02-10 20:40:57 +00:00
for instance in context.enabledInstances():
2023-04-15 23:03:06 +00:00
objects = instance.objsfiles()
assets = instance.resfiles()
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
2023-04-15 23:03:06 +00:00
for asset in assets:
writer.build(asset[1], "cp", asset[0])
2023-01-31 20:09:28 +00:00
writer.newline()
if instance.isLib():
2023-04-15 23:03:06 +00:00
writer.build(instance.outfile(), "ar",
list(map(lambda o: o[1], objects)), implicit=list(map(lambda o: o[1], assets)))
2023-01-31 20:09:28 +00:00
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-04-15 23:03:06 +00:00
libraries.append(reqInstance.outfile())
2023-04-15 23:03:06 +00:00
writer.build(instance.outfile(), "ld", list(
map(lambda o: o[1], objects)) + libraries, implicit=list(map(lambda o: o[1], assets)))
2023-01-31 20:09:28 +00:00
2023-04-15 23:03:06 +00:00
all.append(instance.outfile())
2023-02-10 20:40:57 +00:00
2023-01-31 20:09:28 +00:00
writer.newline()
2023-02-10 20:40:57 +00:00
writer.separator("Phony targets")
writer.build("all", "phony", all)
2023-02-10 20:51:42 +00:00
writer.default("all")
2023-02-10 20:40:57 +00:00
2023-04-15 23:03:06 +00:00
def build(componentSpec: str, targetSpec: str, props: Props = {}) -> ComponentInstance:
context = contextFor(targetSpec, props)
2023-02-07 11:40:00 +00:00
shell.mkdir(context.builddir())
2023-02-21 16:33:38 +00:00
ninjaPath = os.path.join(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")
if not instance.enabled:
raise Exception(
f"Component {componentSpec} is disabled: {instance.disableReason}")
2023-04-15 23:03:06 +00:00
shell.exec(f"ninja", "-v", "-f", ninjaPath, instance.outfile())
2023-04-15 23:03:06 +00:00
return instance
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-04-15 23:03:06 +00:00
def buildAll(targetSpec: str) -> Context:
2023-02-08 22:37:28 +00:00
context = contextFor(targetSpec)
2023-02-07 11:40:00 +00:00
shell.mkdir(context.builddir())
2023-02-21 16:33:38 +00:00
ninjaPath = os.path.join(context.builddir(), "build.ninja")
with open(ninjaPath, "w") as f:
gen(f, context)
shell.exec(f"ninja", "-v", "-f", ninjaPath)
2023-04-15 23:03:06 +00:00
return context
2023-03-11 14:29:31 +00:00
def testAll(targetSpec: str):
context = contextFor(targetSpec)
shell.mkdir(context.builddir())
ninjaPath = os.path.join(context.builddir(), "build.ninja")
with open(ninjaPath, "w") as f:
gen(f, context)
shell.exec(f"ninja", "-v", "-f", ninjaPath, "all")
for instance in context.enabledInstances():
if instance.isLib():
continue
if instance.id().endswith("-tests"):
print(f"Running {instance.id()}")
2023-04-15 23:03:06 +00:00
shell.exec(instance.outfile())