meson.build | 15 +++++++- qemu-options.hx | 14 ++++++++ scripts/build_info_gen.py | 91 +++++++++++++++++++++++++++++++++++++++++++++++ system/vl.c | 41 +++++++++++++++++++++ 4 files changed, 160 insertions(+), 1 deletion(-)
Add -build-info and -build-info-json CLI arguments for human and machine
readable output of build/compile-time configuration data. The source for
this data is the meson generated config-host.h.
This information is mainly of interest to developers and other folk who
deal with many different builds of QEMU and need a way to properly
differentiate them.
Because there's always the chance someone will want to consume an
interface programmatically, also add a -json option that does the same
but outputs a machine-readable JSON object.
Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
---
Notes:
Sample output:
$ ./qemu-system-aarch64 -build-info
./qemu-system-aarch64 version 9.1.50 (v9.0.0-3444-g8d988656d8) build information
configuration key key value
----------------- ---------
accept4
af_vsock
asan_iface_fiber
atomic64
attr
audio_alsa
audio_drivers pa,sndio,oss
audio_oss
audio_pa
audio_pipewire
audio_sdl
audio_sndio
avx2_opt
avx512bw_opt
bdrv_ro_whitelist
bdrv_rw_whitelist
bindir /usr/local/bin
blkzoned
brlapi
capstone
clock_adjtime
close_range
coroutine_pool
cpuid_h
curl
curses
dbus_display
debug_graph_lock
debug_mutex
debug_tcg
dup3
ebpf
epoll
epoll_create1
eventfd
fallocate
fallocate_punch_hole
fallocate_zero_range
fdatasync
fdt
fiemap
fsfreeze
fstrim
fuse
fuse_lseek
gbm
getauxval
getcpu
getrandom
gettid
gio
gnutls
gnutls_crypto
gtk
hexagon_idef_parser
host_dsosuf .so
iasl /bin/iasl
inotify
inotify1
int128
int128_type
iovec
keyutils
kvm_targets i386-softmmu,x86_64-softmmu
l2tpv3
libdw
libudev
linux
linux_io_uring
linux_magic_h
madvise
malloc_trim
memalign
memfd
opengl
open_by_handle
pixman
plugin
png
posix
posix_fallocate
posix_madvise
posix_memalign
ppoll
prctl_pr_set_timerslack
preadv
prefix /usr/local
pthread_affinity_np
pthread_setname_np_w_tid
qemu_confdir /usr/local/etc/qemu
qemu_datadir /usr/local/share/qemu
qemu_desktopdir /usr/local/share/applications
qemu_firmwarepath /usr/local/share/qemu-firmware
qemu_helperdir /usr/local/libexec
qemu_icondir /usr/local/share/icons
qemu_localedir /usr/local/share/locale
qemu_localstatedir /var/local
qemu_moddir /usr/local/lib/x86_64-linux-gnu/qemu
qom_cast_debug
relocatable
replication
rtnetlink
sdl
seccomp
seccomp_sysrawrc
secret_keyring
selinux
sendfile
setns
signalfd
slirp
smbd_command /usr/sbin/smbd
splice
statx
statx_mnt_id
syncfs
sync_file_range
sysconfdir /usr/local/etc
sysmacros
tasn1
tcg 1
timerfd
tls_priority NORMAL
tpm
trace_file trace
trace_log
usbfs
usb_libusb
valgrind_h
valloc
vduse_blk_export
vhost
vhost_crypto
vhost_kernel
vhost_net
vhost_net_user
vhost_net_vdpa
vhost_user
vhost_user_blk_server
vhost_vdpa
virtfs
vnc
vnc_jpeg
vte
x11
xen_backend
xen_ctrl_interface_version 41700
xkbcommon
zstd
blk_zone_rep_capacity
btrfs_h
copy_file_range
drm_h
fsxattr
getifaddrs
host_block_device
ipproto_mptcp
mlockall
openpty
pty_h
strchrnul
struct_stat_st_atim
system_function
utmpx
virgl_d3d_info_ext
host_x86_64 1
qemu_version 9.1.50
qemu_version_major 9
qemu_version_micro 50
qemu_version_minor 1
---
meson.build | 15 +++++++-
qemu-options.hx | 14 ++++++++
scripts/build_info_gen.py | 91 +++++++++++++++++++++++++++++++++++++++++++++++
system/vl.c | 41 +++++++++++++++++++++
4 files changed, 160 insertions(+), 1 deletion(-)
diff --git a/meson.build b/meson.build
index 10464466ff..eff2ee323a 100644
--- a/meson.build
+++ b/meson.build
@@ -3292,7 +3292,20 @@ endif
# Generated sources #
#####################
-genh += configure_file(output: 'config-host.h', configuration: config_host_data)
+config_host_h = configure_file(output: 'config-host.h', configuration: config_host_data)
+genh += config_host_h
+
+build_info_h = custom_target('build-info.h',
+ output: 'build-info.h',
+ command: [
+ find_program('scripts/build_info_gen.py'),
+ '--config-headers',
+ config_host_h
+ ],
+ capture: true,
+ build_by_default: true,
+ build_always_stale: true)
+genh += build_info_h
hxtool = find_program('scripts/hxtool')
shaderinclude = find_program('scripts/shaderinclude.py')
diff --git a/qemu-options.hx b/qemu-options.hx
index d94e2cbbae..3f17b7371b 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -24,6 +24,20 @@ SRST
Display version information and exit
ERST
+DEF("build-info", 0, QEMU_OPTION_build_info,
+ "-build-info display build information of executable and exit\n", QEMU_ARCH_ALL)
+SRST
+``-build-info``
+ Display build information of executable and exit
+ERST
+
+DEF("build-info-json", 0, QEMU_OPTION_build_info_json,
+ "-build-info-json dump build information of executable in JSON format and exit\n", QEMU_ARCH_ALL)
+SRST
+``-build-info-json``
+ Dump build information of executable in JSON format and exit
+ERST
+
DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
"-machine [type=]name[,prop[=value][,...]]\n"
" selects emulated machine ('-machine help' for list)\n"
diff --git a/scripts/build_info_gen.py b/scripts/build_info_gen.py
new file mode 100755
index 0000000000..37a9421651
--- /dev/null
+++ b/scripts/build_info_gen.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python3
+
+"""
+Generate build information header, build-info.h,
+for output of -build-info* command line arguments.
+
+SPDX-FileContributor: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+SPDX-FileCopyrightText: 2024 Linaro Ltd.
+SPDX-License-Identifier: GPL-2.0-or-later
+"""
+
+# Formatted with black --line-length 80 scripts/build-info-gen.py
+
+import argparse
+import logging
+
+
+def generate_key_val(header: str) -> str:
+ # pylint: disable=missing-function-docstring
+
+ with open(header, encoding="utf-8") as cfg:
+ config = [l.split()[1:] for l in cfg if l.startswith("#define")]
+
+ for cfg in config:
+ if cfg[0].startswith("HAVE_"):
+ yield (cfg[0].removeprefix("HAVE_").lower(), None)
+ continue
+ yield (
+ cfg[0].removeprefix("CONFIG_").lower(),
+ (
+ cfg[1]
+ if len(cfg) == 2
+ else "".join(cfg[1:]).replace('"', "") if len(cfg) > 2 else None
+ ),
+ )
+
+
+def main() -> None:
+ # pylint: disable=missing-function-docstring
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-v", "--verbose", action="store_true")
+ parser.add_argument(
+ "--config-headers",
+ metavar="CONFIG_HEADER",
+ action="append",
+ dest="config_headers",
+ help="paths to configuration host C headers (*.h files)",
+ required=False,
+ default=[],
+ )
+ args = parser.parse_args()
+ if args.verbose:
+ logging.basicConfig(level=logging.ERROR)
+ logging.debug("args: %s", args)
+ print(
+ """// @generated by scripts/build-info-gen.py
+
+#include <stddef.h>"""
+ )
+ print(
+ """static struct build_info_t {
+ const char *key;
+ const char *value;
+} BUILD_INFO[] = {"""
+ )
+ total = 0
+ header_width = 0
+ for header in args.config_headers:
+ for key, val in generate_key_val(header):
+ total += 1
+ header_width = max(header_width, len(key))
+ print(
+ '{"',
+ key,
+ '", "',
+ val.strip('"').strip(",").strip('"') if val else "",
+ '"},',
+ sep="",
+ )
+ print("};")
+ print("\nstatic size_t BUILD_INFO_SIZE = ", total, ";", sep="")
+ print(
+ "static unsigned int BUILD_INFO_HEADER_WIDTH = ",
+ header_width,
+ ";",
+ sep="",
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/system/vl.c b/system/vl.c
index fe547ca47c..5266b85d22 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -908,6 +908,41 @@ static void help(int exitcode)
exit(exitcode);
}
+static void build_info(const char *execname, bool as_json)
+{
+#include "build-info.h"
+ if (as_json) {
+ printf("{\n");
+ for (size_t i = 0; i + 1 < BUILD_INFO_SIZE ; i++) {
+ printf("\"%s\":\"%s\",\n",
+ BUILD_INFO[i].key,
+ BUILD_INFO[i].value);
+ }
+ if (BUILD_INFO_SIZE > 0) {
+ printf("\"%s\":\"%s\"\n",
+ BUILD_INFO[BUILD_INFO_SIZE - 1].key,
+ BUILD_INFO[BUILD_INFO_SIZE - 1].value);
+ }
+ printf("}\n");
+ } else {
+ printf("%s version "
+ QEMU_FULL_VERSION
+ " build information\n\n", execname ?:"QEMU");
+ printf(" %-*s key value\n",
+ BUILD_INFO_HEADER_WIDTH,
+ "configuration key");
+ printf(" %-*s ---------\n",
+ BUILD_INFO_HEADER_WIDTH,
+ "-----------------");
+ for (size_t i = 0; i < BUILD_INFO_SIZE ; i++) {
+ printf(" %-*s %s\n",
+ BUILD_INFO_HEADER_WIDTH,
+ BUILD_INFO[i].key,
+ BUILD_INFO[i].value);
+ }
+ }
+}
+
enum {
#define DEF(option, opt_arg, opt_enum, opt_help, arch_mask) \
@@ -3019,6 +3054,12 @@ void qemu_init(int argc, char **argv)
version();
exit(0);
break;
+ case QEMU_OPTION_build_info:
+ /* fallthrough */
+ case QEMU_OPTION_build_info_json:
+ build_info(argv[0], popt->index != QEMU_OPTION_build_info);
+ exit(0);
+ break;
case QEMU_OPTION_m:
opts = qemu_opts_parse_noisily(qemu_find_opts("memory"), optarg, true);
if (opts == NULL) {
---
base-commit: 01dc65a3bc262ab1bec8fe89775e9bbfa627becb
change-id: 20240922-feature-build-info-cli-c9e08e34c34b
--
γαῖα πυρί μιχθήτω
© 2016 - 2024 Red Hat, Inc.