<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>