diff --git a/osdk/context.py b/osdk/context.py index 23852ad..404942f 100644 --- a/osdk/context.py +++ b/osdk/context.py @@ -2,7 +2,7 @@ from typing import cast, Protocol from pathlib import Path -from osdk.model import TargetManifest, ComponentManifest, Props, Type, Tool +from osdk.model import TargetManifest, ComponentManifest, Props, Type, Tool, Tools from osdk.logger import Logger from osdk import const, shell, jexpr, utils, rules @@ -63,9 +63,9 @@ class ComponentInstance: class Context(IContext): target: TargetManifest instances: list[ComponentInstance] - tools: dict[str, Tool] + tools: Tools - def __init__(self, target: TargetManifest, instances: list[ComponentInstance], tools: dict[str, Tool]): + def __init__(self, target: TargetManifest, instances: list[ComponentInstance], tools: Tools): self.target = target self.instances = instances self.tools = tools @@ -188,7 +188,7 @@ def contextFor(targetSpec: str, props: Props) -> Context: target = loadTarget(targetSpec) components = loadAllComponents() - tools: dict[str, Tool] = {} + tools: Tools = {} for toolSpec in target.tools: tool = target.tools[toolSpec] diff --git a/osdk/mixins.py b/osdk/mixins.py new file mode 100644 index 0000000..77ce0d0 --- /dev/null +++ b/osdk/mixins.py @@ -0,0 +1,70 @@ +from typing import Callable +from osdk.model import TargetManifest, Tools + +Mixin = Callable[[TargetManifest, Tools], Tools] + + +def patchToolArgs(tools: Tools, toolSpec: str, args: list[str]): + tools[toolSpec].args += args + + +def prefixToolCmd(tools: Tools, toolSpec: str, prefix: str): + tools[toolSpec].cmd = prefix + " " + tools[toolSpec].cmd + + +def mixinCache(target: TargetManifest, tools: Tools) -> Tools: + prefixToolCmd(tools, "cc", "ccache") + prefixToolCmd(tools, "cxx", "ccache") + return tools + + +def makeMixinSan(san: str) -> Mixin: + def mixinSan(target: TargetManifest, tools: Tools) -> Tools: + patchToolArgs( + tools, "cc", [f"-fsanitize={san}"]) + patchToolArgs( + tools, "cxx", [f"-fsanitize={san}"]) + patchToolArgs( + tools, "ld", [f"-fsanitize={san}"]) + + return tools + + return mixinSan + + +def makeMixinOptimize(level: str) -> Mixin: + def mixinOptimize(target: TargetManifest, tools: Tools) -> Tools: + patchToolArgs(tools, "cc", [f"-O{level}"]) + patchToolArgs(tools, "cxx", [f"-O{level}"]) + + return tools + + return mixinOptimize + + +def mixinDebug(target: TargetManifest, tools: Tools) -> Tools: + patchToolArgs(tools, "cc", ["-g"]) + patchToolArgs(tools, "cxx", ["-g"]) + + return tools + + +mixins: dict[str, Mixin] = { + "cache": mixinCache, + "debug": mixinDebug, + "asan": makeMixinSan("address"), + "msan": makeMixinSan("memory"), + "tsan": makeMixinSan("thread"), + "ubsan": makeMixinSan("undefined"), + "o3": makeMixinOptimize("3"), + "o2": makeMixinOptimize("2"), + "o1": makeMixinOptimize("1"), + "o0": makeMixinOptimize("0"), +} + + +def append(mixinSpec: str, mixin: Mixin): + mixins[mixinSpec] = mixin + +def byId(id: str) -> Mixin: + return mixins[id] diff --git a/osdk/model.py b/osdk/model.py index 64fecb4..0d9ded1 100644 --- a/osdk/model.py +++ b/osdk/model.py @@ -85,9 +85,12 @@ class Tool: return f"Tool({self.cmd})" +Tools = dict[str, Tool] + + class TargetManifest(Manifest): props: Props - tools: dict[str, Tool] + tools: Tools routing: dict[str, str] def __init__(self, json: Json = None, path: str = "", strict=True, **kwargs): @@ -131,7 +134,7 @@ class TargetManifest(Manifest): class ComponentManifest(Manifest): decription: str = "(No description)" props: Props = {} - tools: dict[str, Tool] = {} + tools: Tools = {} enableIf: dict[str, list[Any]] = {} requires: list[str] = [] provides: list[str] = []