[PATCH] Print tool binary names in ./configure --help

Manos Pitsidianakis posted 1 patch 8 months, 2 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20240217131934.2638382-1-manos.pitsidianakis@linaro.org
Maintainers: Paolo Bonzini <pbonzini@redhat.com>, "Alex Bennée" <alex.bennee@linaro.org>, Thomas Huth <thuth@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, John Snow <jsnow@redhat.com>, Cleber Rosa <crosa@redhat.com>
Makefile                      |  8 +++++--
meson_options.txt             |  2 +-
scripts/meson-buildoptions.py | 43 ++++++++++++++++++++++++++++++++---
scripts/meson-buildoptions.sh |  3 ++-
4 files changed, 49 insertions(+), 7 deletions(-)
[PATCH] Print tool binary names in ./configure --help
Posted by Manos Pitsidianakis 8 months, 2 weeks ago
configure --help currently outputs the following line for the tools
option:

-->8-------------------------------------------------------------------
░░tcg░░░░░░░░░░░░░TCG░support░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  tools           build support utilities that come with QEMU
░░tpm░░░░░░░░░░░░░TPM░support░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
░░u2f░░░░░░░░░░░░░U2F░emulation░support░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
---8<------------------------------------------------------------------

Which does not convey information if you don't already know what these
utilities are going to be.

This commit uses script/meson-buildoptions.py to parse the hard-coded
test binary names in meson.build and update the --help output to include
their names, like as follows:

-->8-------------------------------------------------------------------
░░tcg░░░░░░░░░░░░░TCG░support░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  tools           build utility tool binaries like qemu-edid, qemu-img,
                  qemu-io, qemu-nbd, qemu-bridge-helper, qemu-pr-helper
░░tpm░░░░░░░░░░░░░TPM░support░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
░░u2f░░░░░░░░░░░░░U2F░emulation░support░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
---8<------------------------------------------------------------------

Since it uses the meson.build AST to find those values, only hard-coded
binary names are selected and the description is non-exhaustive.

Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
---
 Makefile                      |  8 +++++--
 meson_options.txt             |  2 +-
 scripts/meson-buildoptions.py | 43 ++++++++++++++++++++++++++++++++---
 scripts/meson-buildoptions.sh |  3 ++-
 4 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/Makefile b/Makefile
index 8f36990335..79ab594c4b 100644
--- a/Makefile
+++ b/Makefile
@@ -128,8 +128,12 @@ Makefile.mtest: build.ninja scripts/mtest2make.py
 .PHONY: update-buildoptions
 all update-buildoptions: $(SRC_PATH)/scripts/meson-buildoptions.sh
 $(SRC_PATH)/scripts/meson-buildoptions.sh: $(SRC_PATH)/meson_options.txt
-	$(MESON) introspect --buildoptions $(SRC_PATH)/meson.build | $(PYTHON) \
-	  scripts/meson-buildoptions.py > $@.tmp && mv $@.tmp $@
+	{ printf '{"buildoptions":'; \
+		$(MESON) introspect --buildoptions $(SRC_PATH)/meson.build 2> >(grep -v "Unable to evaluate subdir(\[\])" >&2) \
+		&& printf ',"ast":' \
+		&& $(MESON) introspect --ast $(SRC_PATH)/meson.build 2> >(grep -v "Unable to evaluate subdir(\[\])" >&2) \
+		&& printf "}" ; } \
+		| $(PYTHON) scripts/meson-buildoptions.py > $@.tmp && mv $@.tmp $@
 endif
 
 # 4. Rules to bridge to other makefiles
diff --git a/meson_options.txt b/meson_options.txt
index 0a99a059ec..53a8b6b3e2 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -58,7 +58,7 @@ option('guest_agent', type : 'feature', value : 'auto',
 option('guest_agent_msi', type : 'feature', value : 'auto',
        description: 'Build MSI package for the QEMU Guest Agent')
 option('tools', type : 'feature', value : 'auto',
-       description: 'build support utilities that come with QEMU')
+       description: 'build utility tool binaries')
 option('qga_vss', type : 'feature', value: 'auto',
        description: 'build QGA VSS support (broken with MinGW)')
 
diff --git a/scripts/meson-buildoptions.py b/scripts/meson-buildoptions.py
index 4814a8ff61..4abdfc1d05 100644
--- a/scripts/meson-buildoptions.py
+++ b/scripts/meson-buildoptions.py
@@ -24,6 +24,7 @@
 import textwrap
 import shlex
 import sys
+from collections import deque
 
 # Options with nonstandard names (e.g. --with/--without) or OS-dependent
 # defaults.  Try not to add any.
@@ -182,7 +183,7 @@ def cli_metavar(opt):
     return "CHOICE"
 
 
-def print_help(options):
+def print_help(options, tools: list[str]):
     print("meson_options_help() {")
     feature_opts = []
     for opt in sorted(options, key=cli_help_key):
@@ -212,6 +213,8 @@ def print_help(options):
     sh_print()
     for opt in sorted(feature_opts, key=cli_option):
         key = cli_option(opt)
+        if key == "tools":
+            opt["description"] += " like " + ", ".join(tools)
         help_line(key, opt, 18, False)
     print("}")
 
@@ -242,7 +245,41 @@ def print_parse(options):
     print("}")
 
 
-options = load_options(json.load(sys.stdin))
+# Returns hard-coded executables from meson.build AST
+def tool_executables(d: dict) -> list[str]:
+    def is_executable_fn_call(i: dict) -> bool:
+        if not (
+            "name" in i
+            and i["name"] == "executable"
+            and "node" in i
+            and i["node"] == "FunctionNode"
+            and "positional" in i["args"]
+            and len(i["args"]) > 0
+        ):
+            return False
+        first_arg = i["args"]["positional"][0]
+        return first_arg["node"] == "StringNode"
+
+    stack = deque([d])
+    while len(stack) > 0:
+        item = stack.popleft()
+        if isinstance(item, dict):
+            # Check if this is an `executable(....)` function call.
+            if is_executable_fn_call(item):
+                name = item["args"]["positional"][0]["value"]
+                if name not in ("qemu-keymap",):
+                    yield name
+            else:
+                stack.extend(item.values())
+            continue
+        if isinstance(item, list):
+            stack.extend(item)
+            continue
+
+
+input_string = json.load(sys.stdin)
+options = load_options(input_string["buildoptions"])
+bins = list(tool_executables(input_string["ast"]))
 print("# This file is generated by meson-buildoptions.py, do not edit!")
-print_help(options)
+print_help(options, bins)
 print_parse(options)
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
index 680fa3f581..ac1fad55df 100644
--- a/scripts/meson-buildoptions.sh
+++ b/scripts/meson-buildoptions.sh
@@ -185,7 +185,8 @@ meson_options_help() {
   printf "%s\n" '  spice-protocol  Spice protocol support'
   printf "%s\n" '  stack-protector compiler-provided stack protection'
   printf "%s\n" '  tcg             TCG support'
-  printf "%s\n" '  tools           build support utilities that come with QEMU'
+  printf "%s\n" '  tools           build utility tool binaries like qemu-edid, qemu-img,'
+  printf "%s\n" '                  qemu-io, qemu-nbd, qemu-bridge-helper, qemu-pr-helper'
   printf "%s\n" '  tpm             TPM support'
   printf "%s\n" '  u2f             U2F emulation support'
   printf "%s\n" '  usb-redir       libusbredir support'

base-commit: da96ad4a6a2ef26c83b15fa95e7fceef5147269c
-- 
γαῖα πυρί μιχθήτω


Re: [PATCH] Print tool binary names in ./configure --help
Posted by Stefan Hajnoczi 8 months, 1 week ago
On Sat, 17 Feb 2024 at 08:21, Manos Pitsidianakis
<manos.pitsidianakis@linaro.org> wrote:
>
> configure --help currently outputs the following line for the tools
> option:
>
> -->8-------------------------------------------------------------------
> ░░tcg░░░░░░░░░░░░░TCG░support░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
>   tools           build support utilities that come with QEMU
> ░░tpm░░░░░░░░░░░░░TPM░support░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
> ░░u2f░░░░░░░░░░░░░U2F░emulation░support░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
> ---8<------------------------------------------------------------------
>
> Which does not convey information if you don't already know what these
> utilities are going to be.
>
> This commit uses script/meson-buildoptions.py to parse the hard-coded
> test binary names in meson.build and update the --help output to include
> their names, like as follows:
>
> -->8-------------------------------------------------------------------
> ░░tcg░░░░░░░░░░░░░TCG░support░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
>   tools           build utility tool binaries like qemu-edid, qemu-img,
>                   qemu-io, qemu-nbd, qemu-bridge-helper, qemu-pr-helper
> ░░tpm░░░░░░░░░░░░░TPM░support░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
> ░░u2f░░░░░░░░░░░░░U2F░emulation░support░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
> ---8<------------------------------------------------------------------
>
> Since it uses the meson.build AST to find those values, only hard-coded
> binary names are selected and the description is non-exhaustive.

How about updating the description in meson_options.txt to what's
shown above and dropping the meson introspect part?

I think the complexity is a little high given that the generated list
is incomplete. Less custom build system code makes it easier to
understand and reduces the chance of breakage.

>
> Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
> ---
>  Makefile                      |  8 +++++--
>  meson_options.txt             |  2 +-
>  scripts/meson-buildoptions.py | 43 ++++++++++++++++++++++++++++++++---
>  scripts/meson-buildoptions.sh |  3 ++-
>  4 files changed, 49 insertions(+), 7 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index 8f36990335..79ab594c4b 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -128,8 +128,12 @@ Makefile.mtest: build.ninja scripts/mtest2make.py
>  .PHONY: update-buildoptions
>  all update-buildoptions: $(SRC_PATH)/scripts/meson-buildoptions.sh
>  $(SRC_PATH)/scripts/meson-buildoptions.sh: $(SRC_PATH)/meson_options.txt
> -       $(MESON) introspect --buildoptions $(SRC_PATH)/meson.build | $(PYTHON) \
> -         scripts/meson-buildoptions.py > $@.tmp && mv $@.tmp $@
> +       { printf '{"buildoptions":'; \
> +               $(MESON) introspect --buildoptions $(SRC_PATH)/meson.build 2> >(grep -v "Unable to evaluate subdir(\[\])" >&2) \
> +               && printf ',"ast":' \
> +               && $(MESON) introspect --ast $(SRC_PATH)/meson.build 2> >(grep -v "Unable to evaluate subdir(\[\])" >&2) \
> +               && printf "}" ; } \
> +               | $(PYTHON) scripts/meson-buildoptions.py > $@.tmp && mv $@.tmp $@
>  endif
>
>  # 4. Rules to bridge to other makefiles
> diff --git a/meson_options.txt b/meson_options.txt
> index 0a99a059ec..53a8b6b3e2 100644
> --- a/meson_options.txt
> +++ b/meson_options.txt
> @@ -58,7 +58,7 @@ option('guest_agent', type : 'feature', value : 'auto',
>  option('guest_agent_msi', type : 'feature', value : 'auto',
>         description: 'Build MSI package for the QEMU Guest Agent')
>  option('tools', type : 'feature', value : 'auto',
> -       description: 'build support utilities that come with QEMU')
> +       description: 'build utility tool binaries')
>  option('qga_vss', type : 'feature', value: 'auto',
>         description: 'build QGA VSS support (broken with MinGW)')
>
> diff --git a/scripts/meson-buildoptions.py b/scripts/meson-buildoptions.py
> index 4814a8ff61..4abdfc1d05 100644
> --- a/scripts/meson-buildoptions.py
> +++ b/scripts/meson-buildoptions.py
> @@ -24,6 +24,7 @@
>  import textwrap
>  import shlex
>  import sys
> +from collections import deque
>
>  # Options with nonstandard names (e.g. --with/--without) or OS-dependent
>  # defaults.  Try not to add any.
> @@ -182,7 +183,7 @@ def cli_metavar(opt):
>      return "CHOICE"
>
>
> -def print_help(options):
> +def print_help(options, tools: list[str]):
>      print("meson_options_help() {")
>      feature_opts = []
>      for opt in sorted(options, key=cli_help_key):
> @@ -212,6 +213,8 @@ def print_help(options):
>      sh_print()
>      for opt in sorted(feature_opts, key=cli_option):
>          key = cli_option(opt)
> +        if key == "tools":
> +            opt["description"] += " like " + ", ".join(tools)
>          help_line(key, opt, 18, False)
>      print("}")
>
> @@ -242,7 +245,41 @@ def print_parse(options):
>      print("}")
>
>
> -options = load_options(json.load(sys.stdin))
> +# Returns hard-coded executables from meson.build AST
> +def tool_executables(d: dict) -> list[str]:
> +    def is_executable_fn_call(i: dict) -> bool:
> +        if not (
> +            "name" in i
> +            and i["name"] == "executable"
> +            and "node" in i
> +            and i["node"] == "FunctionNode"
> +            and "positional" in i["args"]
> +            and len(i["args"]) > 0
> +        ):
> +            return False
> +        first_arg = i["args"]["positional"][0]
> +        return first_arg["node"] == "StringNode"
> +
> +    stack = deque([d])
> +    while len(stack) > 0:
> +        item = stack.popleft()
> +        if isinstance(item, dict):
> +            # Check if this is an `executable(....)` function call.
> +            if is_executable_fn_call(item):
> +                name = item["args"]["positional"][0]["value"]
> +                if name not in ("qemu-keymap",):
> +                    yield name
> +            else:
> +                stack.extend(item.values())
> +            continue
> +        if isinstance(item, list):
> +            stack.extend(item)
> +            continue
> +
> +
> +input_string = json.load(sys.stdin)
> +options = load_options(input_string["buildoptions"])
> +bins = list(tool_executables(input_string["ast"]))
>  print("# This file is generated by meson-buildoptions.py, do not edit!")
> -print_help(options)
> +print_help(options, bins)
>  print_parse(options)
> diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
> index 680fa3f581..ac1fad55df 100644
> --- a/scripts/meson-buildoptions.sh
> +++ b/scripts/meson-buildoptions.sh
> @@ -185,7 +185,8 @@ meson_options_help() {
>    printf "%s\n" '  spice-protocol  Spice protocol support'
>    printf "%s\n" '  stack-protector compiler-provided stack protection'
>    printf "%s\n" '  tcg             TCG support'
> -  printf "%s\n" '  tools           build support utilities that come with QEMU'
> +  printf "%s\n" '  tools           build utility tool binaries like qemu-edid, qemu-img,'
> +  printf "%s\n" '                  qemu-io, qemu-nbd, qemu-bridge-helper, qemu-pr-helper'
>    printf "%s\n" '  tpm             TPM support'
>    printf "%s\n" '  u2f             U2F emulation support'
>    printf "%s\n" '  usb-redir       libusbredir support'
>
> base-commit: da96ad4a6a2ef26c83b15fa95e7fceef5147269c
> --
> γαῖα πυρί μιχθήτω
>
>