Skip to content

[Developer] QEMU build options

Brany edited this page Feb 5, 2024 · 1 revision

How to add a build option

To add a build option to QEMU as of version 8.2.50 is very straight forward. This requires three distinct steps:

  1. Adding a build option
  2. Creating a build logic
  3. Adding build dependant code

Adding an option

To add an option to the build system and its documentation, the following files needs 1-2 specific lines to be inserted.

meson_options.txt

It's a simple file configuration which add your configuration to other files. The auto field can be wither true/false or auto, which describe the feature's default compilation state.

option('libqflex', type : 'feature', value : 'auto', description: 'QFlex support')

After adding this one or multiple lines, you may call make update-buildoptions. This should append new lines to scripts/meson-buildoptions.sh.

scripts/meson-buildoptions.sh

The first block adds the command documentation when calling ./configure --help. The second line, create the switch in the configure system. You should verify that these lines were correctly created using the make command.

printf "%s\n" '  libpmem         libpmem support'
printf "%s\n" '  libqflex        QFlex support'                // <----  
printf "%s\n" '  libssh          ssh block device support'

--enable-libqflex) printf "%s" -Dlibqflex=enabled ;;           // <----
--disable-libqflex) printf "%s" -Dlibqflex=disabled ;;         // <----

Build logic

Once the option enabled, this allows for new possible specific configuration. Most of it happens in the meson.build file.

meson.build

In this file lies a crucial invocation. The next lines create a new preprocessor variable, which is then parsed with all file compiled.

config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
config_host_data.set('CONFIG_LIBQFLEX', libqflex.found())     # <----
config_host_data.set('CONFIG_MODULES', enable_modules)

To create the libqflex dependency object, meson has a vast dependency resolving mechanism. Here is a simple example that test the existence of a file before resolving the dependency

libqflex = not_found
if get_option('libqflex').enabled()
  if fs.is_dir('backends/libqflex')
    libqflex = declare_dependency()
  else
    error('libqflex was not found in "./backends/libqflex"')
  endif
endif

Finally, useful for debugging, maybe also adding your object to the summary.

summary_info = {}
summary_info += {'libqflex':          libqflex}
summary(summary_info, bool_yn: true, section: 'PARSA')

**/meson.build

Once the dependency object created, it is passed implicitly to any sub-meson.build files. This could be used to extend the build logic. In general, this could be where .c files are added to the build tree.

arm_ss.add(when: libqflex, if_true: files(
        'libqflex-module.c',
        'libqflex.c'
    ))

Build dependant code

Now that a preprocessor variable is enable to add our specific code to the existing source code. It's possible to do so using the #ifdef preprocessor logic

system/vl.c

#ifdef CONFIG_LIBQFLEX
    qemu_add_opts(&qemu_libqflex_opts);
#endif

Don't forget to also add the manpage documentation

qemu-options.hx

#ifdef CONFIG_LIBQFLEX

DEFHEADING()

DEFHEADING(Simulation backend:)

DEF("libqflex", 0, QEMU_OPTION_libqflex,
    "-libqflex	Start custom tracing toward libqflex\n",
    QEMU_ARCH_ARM)
SRST
`` -libqflex	Start custom tracing toward libqflex``
ERST
#endif