153 lines
4.5 KiB
Python
153 lines
4.5 KiB
Python
from typing import TextIO, Tuple
|
|
import json
|
|
import copy
|
|
|
|
from . import ninja
|
|
from . import manifests as m
|
|
from . import targets
|
|
from . import utils
|
|
|
|
|
|
def mergeToolsArgs(tool, layers):
|
|
args = []
|
|
for layer in layers:
|
|
if not layer.get("enabled", True):
|
|
continue
|
|
|
|
args.extend(layer
|
|
.get("tools", {})
|
|
.get(tool, {})
|
|
.get("args", []))
|
|
return args
|
|
|
|
|
|
def genNinja(out: TextIO, manifests: dict, target: dict) -> None:
|
|
target = copy.deepcopy(target)
|
|
target = targets.patchToolArgs(target, "cc", [m.cincludes(manifests)])
|
|
target = targets.patchToolArgs(target, "cxx", [m.cincludes(manifests)])
|
|
|
|
writer = ninja.Writer(out)
|
|
|
|
writer.comment("File generated by the build system, do not edit")
|
|
writer.newline()
|
|
|
|
writer.comment("Tools:")
|
|
for key in target["tools"]:
|
|
tool = target["tools"][key]
|
|
writer.variable(key, tool["cmd"])
|
|
writer.variable(
|
|
key + "flags", " ".join(mergeToolsArgs(key, [target] + list(manifests.values()))))
|
|
writer.newline()
|
|
|
|
writer.newline()
|
|
|
|
writer.comment("Rules:")
|
|
writer.rule(
|
|
"cc", "$cc -c -o $out $in -MD -MF $out.d $ccflags",
|
|
depfile="$out.d")
|
|
|
|
writer.rule(
|
|
"cxx", "$cxx -c -o $out $in -MD -MF $out.d $cxxflags",
|
|
depfile="$out.d")
|
|
|
|
writer.rule("ld", "$ld -o $out $in $ldflags")
|
|
|
|
writer.rule("ar", "$ar crs $out $in")
|
|
|
|
writer.rule("as", "$as -o $out $in $asflags")
|
|
|
|
writer.newline()
|
|
|
|
writer.comment("Build:")
|
|
all = []
|
|
for key in manifests:
|
|
item = manifests[key]
|
|
|
|
if not item["enabled"]:
|
|
continue
|
|
|
|
writer.comment("Project: " + item["id"])
|
|
|
|
for obj in item["objs"]:
|
|
if obj[1].endswith(".c"):
|
|
writer.build(
|
|
obj[0], "cc", obj[1], order_only=target["tools"]["cc"].get("files", ""))
|
|
elif obj[1].endswith(".cpp"):
|
|
writer.build(
|
|
obj[0], "cxx", obj[1], order_only=target["tools"]["cxx"].get("files", ""))
|
|
elif obj[1].endswith(".s") or obj[1].endswith(".asm"):
|
|
writer.build(
|
|
obj[0], "as", obj[1], order_only=target["tools"]["as"].get("files", ""))
|
|
|
|
writer.newline()
|
|
|
|
objs = [x[0] for x in item["objs"]]
|
|
|
|
if item["type"] == "lib":
|
|
writer.build(item["out"], "ar", objs,
|
|
order_only=target["tools"]["ar"].get("files", ""))
|
|
else:
|
|
objs = objs + item["libs"]
|
|
writer.build(item["out"], "ld", objs,
|
|
order_only=target["tools"]["ld"].get("files", ""))
|
|
|
|
all.append(item["out"])
|
|
|
|
writer.newline()
|
|
|
|
writer.comment("Phony:")
|
|
writer.build("all", "phony", all)
|
|
|
|
|
|
def prepare(targetId: str, props: dict) -> Tuple[dict, dict]:
|
|
target = targets.load(targetId, props)
|
|
manifests = m.loadAll("src", target)
|
|
utils.mkdirP(target["dir"])
|
|
genNinja(open(target["ninjafile"], "w"), manifests, target)
|
|
|
|
meta = {}
|
|
meta["id"] = target["key"]
|
|
meta["type"] = "artifacts"
|
|
meta["components"] = manifests
|
|
meta["target"] = target
|
|
|
|
with open(target["dir"] + "/manifest.json", "w") as f:
|
|
json.dump(meta, f, indent=4)
|
|
|
|
with open(target["dir"] + "/_key", "w") as f:
|
|
json.dump(target["key"], f, indent=4)
|
|
|
|
return target, manifests
|
|
|
|
|
|
def buildAll(targetId: str, props: dict = {}) -> None:
|
|
target, _ = prepare(targetId, props)
|
|
print(f"{utils.Colors.BOLD}Building all components for target '{targetId}{utils.Colors.RESET}'")
|
|
|
|
try:
|
|
utils.runCmd("ninja", "-v", "-j", "1", "-f", target["ninjafile"])
|
|
except:
|
|
raise utils.CliException(
|
|
"Failed to build all for " + target["key"])
|
|
|
|
|
|
def buildOne(targetId: str, componentId: str, props: dict = {}) -> str:
|
|
print(f"{utils.Colors.BOLD}Building {componentId} for target '{targetId}'{utils.Colors.RESET}")
|
|
|
|
target, manifests = prepare(targetId, props)
|
|
|
|
if not componentId in manifests:
|
|
raise utils.CliException("Unknown component: " + componentId)
|
|
|
|
if not manifests[componentId]["enabled"]:
|
|
raise utils.CliException(
|
|
f"{componentId} is not enabled for the {targetId} target")
|
|
|
|
try:
|
|
utils.runCmd("ninja", "-v", "-j", "1", "-f",
|
|
target["ninjafile"], manifests[componentId]["out"])
|
|
except:
|
|
raise utils.CliException(
|
|
f"Failed to build {componentId} for target '{target['key']}'")
|
|
|
|
return manifests[componentId]["out"]
|