diff options
author | Paolo Bonzini | 2021-10-07 15:08:29 +0200 |
---|---|---|
committer | Paolo Bonzini | 2021-10-14 09:51:06 +0200 |
commit | 3b4da13293482134b81d71be656ec76beff73a76 (patch) | |
tree | a799bf5d234cc2059f91287f527e7a52d1352f5c /scripts/meson-buildoptions.py | |
parent | meson-buildoptions: include list of tracing backends (diff) | |
download | qemu-3b4da13293482134b81d71be656ec76beff73a76.tar.gz qemu-3b4da13293482134b81d71be656ec76beff73a76.tar.xz qemu-3b4da13293482134b81d71be656ec76beff73a76.zip |
configure: automatically parse command line for meson -D options
Right now meson_options.txt lists about 90 options. Each option
needs code in configure to parse it and pass the option down to Meson as
a -D command-line argument; in addition the default must be duplicated
between configure and meson_options.txt. This series tries to remove
the code duplication by generating the case statement for those --enable
and --disable options, as well as the corresponding help text.
About 80% of the options can be handled completely by the new mechanism.
Eight meson options are not of the --enable/--disable kind. Six more need
to be parsed in configure for various reasons documented in the patch,
but they still have their help automatically generated.
The advantages are:
- less code in configure
- parsing and help is more consistent (for example --enable-blobs was
not supported)
- options are described entirely in one place, meson_options.txt.
This make it more attractive to use Meson options instead of
hand-crafted configure options and config-host.mak
A few options change name: --enable-tcmalloc and --enable-jemalloc
become --enable-malloc={tcmalloc,jemalloc}; --disable-blobs becomes
--disable-install-blobs; --enable-trace-backend becomes
--enable-trace-backends. However, the old names are allowed
for backwards compatibility.
Message-Id: <20211007130829.632254-19-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'scripts/meson-buildoptions.py')
-rwxr-xr-x | scripts/meson-buildoptions.py | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/scripts/meson-buildoptions.py b/scripts/meson-buildoptions.py index d48af99aaf..256523c09d 100755 --- a/scripts/meson-buildoptions.py +++ b/scripts/meson-buildoptions.py @@ -25,10 +25,71 @@ import textwrap import shlex import sys +SKIP_OPTIONS = { + "audio_drv_list", + "default_devices", + "docdir", + "fuzzing_engine", + "qemu_firmwarepath", + "qemu_suffix", + "sphinx_build", + "trace_file", +} + +LINE_WIDTH = 76 + + +# Convert the default value of an option to the string used in +# the help message +def value_to_help(value): + if isinstance(value, list): + return ",".join(value) + if isinstance(value, bool): + return "enabled" if value else "disabled" + return str(value) + + +def wrap(left, text, indent): + spaces = " " * indent + if len(left) >= indent: + yield left + left = spaces + else: + left = (left + spaces)[0:indent] + yield from textwrap.wrap( + text, width=LINE_WIDTH, initial_indent=left, subsequent_indent=spaces + ) + + def sh_print(line=""): print(' printf "%s\\n"', shlex.quote(line)) +def help_line(left, opt, indent, long): + right = f'{opt["description"]}' + if long: + value = value_to_help(opt["value"]) + if value != "auto": + right += f" [{value}]" + if "choices" in opt and long: + choices = "/".join(sorted(opt["choices"])) + right += f" (choices: {choices})" + for x in wrap(" " + left, right, indent): + sh_print(x) + + +# Return whether the option (a dictionary) can be used with +# arguments. Booleans can never be used with arguments; +# combos allow an argument only if they accept other values +# than "auto", "enabled", and "disabled". +def allow_arg(opt): + if opt["type"] == "boolean": + return False + if opt["type"] != "combo": + return True + return not (set(opt["choices"]) <= {"auto", "disabled", "enabled"}) + + def load_options(json): json = [ x @@ -42,17 +103,48 @@ def load_options(json): def print_help(options): print("meson_options_help() {") + for opt in options: + key = opt["name"].replace("_", "-") + # The first section includes options that have an arguments, + # and booleans (i.e., only one of enable/disable makes sense) + if opt["type"] == "boolean": + left = f"--disable-{key}" if opt["value"] else f"--enable-{key}" + help_line(left, opt, 27, False) + elif allow_arg(opt): + if opt["type"] == "combo" and "enabled" in opt["choices"]: + left = f"--enable-{key}[=CHOICE]" + else: + left = f"--enable-{key}=CHOICE" + help_line(left, opt, 27, True) + sh_print() sh_print("Optional features, enabled with --enable-FEATURE and") sh_print("disabled with --disable-FEATURE, default is enabled if available") sh_print("(unless built with --without-default-features):") sh_print() + for opt in options: + key = opt["name"].replace("_", "-") + if opt["type"] != "boolean" and not allow_arg(opt): + help_line(key, opt, 18, False) print("}") def print_parse(options): print("_meson_option_parse() {") print(" case $1 in") + for opt in options: + key = opt["name"].replace("_", "-") + name = opt["name"] + if opt["type"] == "boolean": + print(f' --enable-{key}) printf "%s" -D{name}=true ;;') + print(f' --disable-{key}) printf "%s" -D{name}=false ;;') + else: + if opt["type"] == "combo" and "enabled" in opt["choices"]: + print(f' --enable-{key}) printf "%s" -D{name}=enabled ;;') + if opt["type"] == "combo" and "disabled" in opt["choices"]: + print(f' --disable-{key}) printf "%s" -D{name}=disabled ;;') + if allow_arg(opt): + print(f' --enable-{key}=*) quote_sh "-D{name}=$2" ;;') print(" *) return 1 ;;") print(" esac") print("}") |