<div dir="ltr"><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, May 3, 2023 at 11:12 AM Sebastian Huber <<a href="mailto:sebastian.huber@embedded-brains.de" target="_blank">sebastian.huber@embedded-brains.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello Philip,<br>
<br>
On 28.04.23 11:27, Philip Kirkpatrick wrote:<br>
> I don't know if anyone else will find this useful or if it already <br>
> exists and I duplicated some effort, but I find it difficult to just <br>
> read the files in the spec folder and understand how they are connected <br>
> and what files are used in BSPs I'm interested in. I looked through the <br>
> wscript and didn't see an existing way to dump the item tree for a given <br>
> configuration, so I added it. The patch is as follows:<br>
<br>
this looks like a useful addition. I would make it a new command, for <br>
example "./waf viewspec".<br>
<br></blockquote><div> </div><div>I originally didn't do it that way because I was having a hard time figuring out how to add a new command that could get the build context for the correct variant and I needed to move on. I had some time today to look into it again today and got it figured out. <br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> <br>
> ---<br>
> diff --git a/wscript b/wscript<br>
> index 567f42db2f..4e59188188 100755<br>
> --- a/wscript<br>
> +++ b/wscript<br>
> @@ -151,6 +151,61 @@ def _is_enabled(enabled, enabled_by):<br>
> return _IS_ENABLED_OP[key](enabled, value)<br>
> return enabled_by in enabled<br>
> <br>
> +color_true = '\x1b[32m'<br>
> +color_false = '\x1b[31m'<br>
> +color_clear = '\x1b[0m'<br>
> +<br>
> +def _get_enabler_op_and(enabled, enabled_by):<br>
> + and_str = "{ "<br>
> + first = True<br>
> + for next_enabled_by in enabled_by:<br>
> + if first:<br>
> + first = False<br>
> + else:<br>
> + and_str = and_str + " and "<br>
> + and_str = and_str + _get_enabler(enabled, next_enabled_by)<br>
> + return and_str + " }"<br>
<br>
Can this be simplified to<br>
<br>
" and ".join(_get_enabler(enabled, next_enabled_by) for next_enabled_by <br>
in enabled_by)<br>
<br>
?<br></blockquote><div> </div><div>Yes, it can! Thinking as a C programmer, I had no idea python could do that. "_get_enabler_op_or" can (and has been) also be reduced.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
> +<br>
> +<br>
> +def _get_enabler_op_not(enabled, enabled_by):<br>
> + return "{ " + color_true + "not " + color_false + <br>
> _get_enabler(enabled, enabled_by) + color_clear + " }"<br>
> +<br>
> +<br>
> +def _get_enabler_op_or(enabled, enabled_by):<br>
> + or_str = "{ "<br>
> + first = True<br>
> + for next_enabled_by in enabled_by:<br>
> + if first:<br>
> + first = False<br>
> + else:<br>
> + or_str = or_str + " or "<br>
> + if _is_enabled(enabled, next_enabled_by):<br>
> + color_start = color_true<br>
> + color_end = color_clear<br>
> + else:<br>
> + color_start = color_false<br>
> + color_end = color_clear<br>
> + or_str = or_str + color_start + _get_enabler(enabled, <br>
> next_enabled_by) + color_end<br>
> + return or_str + " }"<br>
> +<br>
> +<br>
> +_GET_ENABLER_OP = {<br>
> + "and": _get_enabler_op_and,<br>
> + "not": _get_enabler_op_not,<br>
> + "or": _get_enabler_op_or,<br>
> +}<br>
> +<br>
> +<br>
> +def _get_enabler(enabled, enabled_by):<br>
> + if isinstance(enabled_by, bool):<br>
> + return color_true + str(enabled_by) + color_clear<br>
> + if isinstance(enabled_by, list):<br>
> + return _get_enabler_op_or(enabled, enabled_by)<br>
> + if isinstance(enabled_by, dict):<br>
> + key, value = next(iter(enabled_by.items()))<br>
> + return _GET_ENABLER_OP[key](enabled, value)<br>
> + return enabled_by<br>
> +<br>
> <br>
> def _asm_explicit_target(self, node):<br>
> task = self.create_task("asm", node,<br>
> @@ -233,6 +288,14 @@ class Item(object):<br>
> "Build error related to item spec:{}: {}".format(<br>
> self.uid, str(e)))<br>
> <br>
> +<br>
> + def dump_spec(self, bld, bic, depth):<br>
> + if _is_enabled(bld.env.ENABLE, self.get_enabled_by()):<br>
> + enabler = _get_enabler(bld.env.ENABLE, self.get_enabled_by())<br>
> + print("│ " * depth + "├──" + self.uid + " # enabled-by: " <br>
> + enabler)<br>
> + for p in self.links():<br>
> + p.dump_spec(bld, bic, depth + 1)<br>
> +<br>
> def do_defaults(self, enabled):<br>
> return<br>
> <br>
> @@ -1320,6 +1383,14 @@ def options(ctx):<br>
> help=<br>
> "sets the option identified by KEY to the VALUE in the build <br>
> specification; it is intended for RTEMS maintainers and may be used in <br>
> the bspdefaults and configure commands",<br>
> )<br>
> + rg.add_option(<br>
> + "--rtems-dumpspec",<br>
> + action="store_true",<br>
> + dest="rtems_dump_spec",<br>
> + default=False,<br>
> + help=<br>
> + "dumps the currently enable spec yaml files and the links tree; <br>
> it is intended for RTEMS maintainers and may be used in the build commands",<br>
> + )<br>
> <br>
> <br>
> def check_environment(conf):<br>
> @@ -1587,8 +1658,14 @@ def build(bld):<br>
> long_command_line_workaround(bld)<br>
> bic = BuildItemContext(bld.env.ARCH_INCLUDES.split(), [], [], [], <br>
> [], [],<br>
> [])<br>
> - bsps[bld.env.ARCH][bld.env.BSP_BASE].build(bld, bic)<br>
> - items[bld.env.TOPGROUP].build(bld, bic)<br>
> + if(bld.options.rtems_dump_spec):<br>
> + print("BSPS:")<br>
> + bsps[bld.env.ARCH][bld.env.BSP_BASE].dump_spec(bld, bic, 0)<br>
> + print("items:")<br>
> + items[bld.env.TOPGROUP].dump_spec(bld, bic, 0)<br>
> + else:<br>
> + bsps[bld.env.ARCH][bld.env.BSP_BASE].build(bld, bic)<br>
> + items[bld.env.TOPGROUP].build(bld, bic)<br>
> <br>
> <br>
> def add_log_filter(name):<br>
> ---<br>
> <br>
> <br>
> _______________________________________________<br>
> devel mailing list<br>
> <a href="mailto:devel@rtems.org" target="_blank">devel@rtems.org</a><br>
> <a href="http://lists.rtems.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a><br>
<br>
-- <br>
embedded brains GmbH<br>
Herr Sebastian HUBER<br>
Dornierstr. 4<br>
82178 Puchheim<br>
Germany<br>
email: <a href="mailto:sebastian.huber@embedded-brains.de" target="_blank">sebastian.huber@embedded-brains.de</a><br>
phone: +49-89-18 94 741 - 16<br>
fax: +49-89-18 94 741 - 08<br>
<br>
Registergericht: Amtsgericht München<br>
Registernummer: HRB 157899<br>
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler<br>
Unsere Datenschutzerklärung finden Sie hier:<br>
<a href="https://embedded-brains.de/datenschutzerklaerung/" rel="noreferrer" target="_blank">https://embedded-brains.de/datenschutzerklaerung/</a></blockquote><div><br></div><div>---</div><div>--- /home/phil-k/RTEMS/TMP/rtems/wscript<br>+++ /home/phil-k/RTEMS/rtems-tools/rtems/wscript<br>@@ -151,6 +151,40 @@<br> return _IS_ENABLED_OP[key](enabled, value)<br> return enabled_by in enabled<br> <br>+color_true = '\x1b[32m'<br>+color_false = '\x1b[31m'<br>+color_clear = '\x1b[0m'<br>+<br>+def _get_enabler_op_and(enabled, enabled_by):<br>+ return "{ " + " and ".join(_get_enabler(enabled, next_enabled_by) for next_enabled_by in enabled_by) + " }"<br>+<br>+<br>+def _get_enabler_op_not(enabled, enabled_by):<br>+ return "{ " + color_true + "not " + color_false + _get_enabler(enabled, enabled_by) + color_clear + " }"<br>+<br>+<br>+def _get_enabler_op_or(enabled, enabled_by):<br>+ return "{ " + " or ".join((color_true if _is_enabled(enabled, next_enabled_by) else color_false) + \<br>+ _get_enabler(enabled, next_enabled_by) + color_clear for next_enabled_by in enabled_by) + " }"<br>+<br>+<br>+_GET_ENABLER_OP = {<br>+ "and": _get_enabler_op_and,<br>+ "not": _get_enabler_op_not,<br>+ "or": _get_enabler_op_or,<br>+}<br>+<br>+<br>+def _get_enabler(enabled, enabled_by):<br>+ if isinstance(enabled_by, bool):<br>+ return color_true + str(enabled_by) + color_clear<br>+ if isinstance(enabled_by, list):<br>+ return _get_enabler_op_or(enabled, enabled_by)<br>+ if isinstance(enabled_by, dict):<br>+ key, value = next(iter(enabled_by.items()))<br>+ return _GET_ENABLER_OP[key](enabled, value)<br>+ return enabled_by<br>+<br> <br> def _asm_explicit_target(self, node):<br> task = self.create_task("asm", node,<br>@@ -232,6 +266,14 @@<br> raise type(e)(<br> "Build error related to item spec:{}: {}".format(<br> self.uid, str(e)))<br>+<br>+<br>+ def dump_spec(self, bld, bic, depth):<br>+ if _is_enabled(bld.env.ENABLE, self.get_enabled_by()):<br>+ enabler = _get_enabler(bld.env.ENABLE, self.get_enabled_by())<br>+ print("│ "*depth + "├──" + self.uid + " # enabled-by: " + enabler)<br>+ for p in self.links():<br>+ p.dump_spec(bld, bic, depth + 1)<br> <br> def do_defaults(self, enabled):<br> return<br>@@ -1683,3 +1725,47 @@<br> print(variant)<br> if first:<br> no_matches_error(ctx, white_list)<br>+<br>+<br>+def append_variant_viewspec(bld):<br>+ import waflib.Options<br>+ from waflib.Build import BuildContext<br>+<br>+ for var in bld.env["VARIANTS"]:<br>+ class magic(BuildContext):<br>+ cmd = "viewspec_" + var<br>+ fun = "viewspec"<br>+ variant = var<br>+<br>+ waflib.Options.commands.append(bld.cmd + "_" + var)<br>+<br>+def viewspec(bld):<br>+ if not bld.variant:<br>+ check_forbidden_options(<br>+ bld,<br>+ [<br>+ "compiler",<br>+ "config",<br>+ "options",<br>+ "specs",<br>+ "tools",<br>+ "top_group",<br>+ "version",<br>+ ],<br>+ )<br>+ load_items(bld, bld.env.SPECS)<br>+ append_variant_viewspec(bld)<br>+ return<br>+ long_command_line_workaround(bld)<br>+ bic = BuildItemContext([], [], [], [], [], [],<br>+ [])<br>+<br>+ print("BSPS:")<br>+ bsps[bld.env.ARCH][bld.env.BSP_BASE].dump_spec(bld, bic, 0)<br>+ print("items:")<br>+ items[bld.env.TOPGROUP].dump_spec(bld, bic, 0)<br>+<br>+from waflib.Build import BuildContext<br>+class viewspec_magic(BuildContext):<br>+ cmd = 'viewspec'<br>+ fun = 'viewspec'<br></div><div>---<br></div><div> </div></div></div>