cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

meson.build (117520B)


      1project('qemu', ['c'], meson_version: '>=0.58.2',
      2        default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
      3                          'b_staticpic=false'],
      4        version: files('VERSION'))
      5
      6not_found = dependency('', required: false)
      7keyval = import('keyval')
      8ss = import('sourceset')
      9fs = import('fs')
     10
     11sh = find_program('sh')
     12cc = meson.get_compiler('c')
     13config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
     14enable_modules = 'CONFIG_MODULES' in config_host
     15enable_static = 'CONFIG_STATIC' in config_host
     16
     17# Allow both shared and static libraries unless --enable-static
     18static_kwargs = enable_static ? {'static': true} : {}
     19
     20# Temporary directory used for files created while
     21# configure runs. Since it is in the build directory
     22# we can safely blow away any previous version of it
     23# (and we need not jump through hoops to try to delete
     24# it when configure exits.)
     25tmpdir = meson.current_build_dir() / 'meson-private/temp'
     26
     27if get_option('qemu_suffix').startswith('/')
     28  error('qemu_suffix cannot start with a /')
     29endif
     30
     31qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
     32qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
     33qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
     34qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
     35
     36qemu_desktopdir = get_option('datadir') / 'applications'
     37qemu_icondir = get_option('datadir') / 'icons'
     38
     39config_host_data = configuration_data()
     40genh = []
     41
     42target_dirs = config_host['TARGET_DIRS'].split()
     43have_user = false
     44have_system = false
     45foreach target : target_dirs
     46  have_user = have_user or target.endswith('-user')
     47  have_system = have_system or target.endswith('-softmmu')
     48endforeach
     49have_tools = 'CONFIG_TOOLS' in config_host
     50have_block = have_system or have_tools
     51
     52python = import('python').find_installation()
     53
     54supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
     55supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
     56  'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
     57
     58cpu = host_machine.cpu_family()
     59targetos = host_machine.system()
     60
     61if cpu in ['x86', 'x86_64']
     62  kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
     63elif cpu == 'aarch64'
     64  kvm_targets = ['aarch64-softmmu']
     65elif cpu == 's390x'
     66  kvm_targets = ['s390x-softmmu']
     67elif cpu in ['ppc', 'ppc64']
     68  kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
     69elif cpu in ['mips', 'mips64']
     70  kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
     71else
     72  kvm_targets = []
     73endif
     74
     75accelerator_targets = { 'CONFIG_KVM': kvm_targets }
     76
     77if cpu in ['aarch64']
     78  accelerator_targets += {
     79    'CONFIG_HVF': ['aarch64-softmmu']
     80  }
     81endif
     82
     83if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
     84  # i386 emulator provides xenpv machine type for multiple architectures
     85  accelerator_targets += {
     86    'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
     87  }
     88endif
     89if cpu in ['x86', 'x86_64']
     90  accelerator_targets += {
     91    'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
     92    'CONFIG_HVF': ['x86_64-softmmu'],
     93    'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
     94    'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
     95  }
     96endif
     97
     98modular_tcg = []
     99# Darwin does not support references to thread-local variables in modules
    100if targetos != 'darwin'
    101  modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
    102endif
    103
    104edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
    105unpack_edk2_blobs = false
    106foreach target : edk2_targets
    107  if target in target_dirs
    108    bzip2 = find_program('bzip2', required: get_option('install_blobs'))
    109    unpack_edk2_blobs = bzip2.found()
    110    break
    111  endif
    112endforeach
    113
    114##################
    115# Compiler flags #
    116##################
    117
    118# Specify linker-script with add_project_link_arguments so that it is not placed
    119# within a linker --start-group/--end-group pair
    120if 'CONFIG_FUZZ' in config_host
    121   add_project_link_arguments(['-Wl,-T,',
    122                               (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
    123                              native: false, language: ['c', 'cpp', 'objc'])
    124endif
    125
    126add_global_arguments(config_host['QEMU_CFLAGS'].split(),
    127                     native: false, language: ['c', 'objc'])
    128add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
    129                     native: false, language: 'cpp')
    130add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
    131                          native: false, language: ['c', 'cpp', 'objc'])
    132
    133if targetos == 'linux'
    134  add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
    135                        '-isystem', 'linux-headers',
    136                        language: ['c', 'cpp'])
    137endif
    138
    139add_project_arguments('-iquote', '.',
    140                      '-iquote', meson.current_source_dir(),
    141                      '-iquote', meson.current_source_dir() / 'include',
    142                      '-iquote', meson.current_source_dir() / 'disas/libvixl',
    143                      language: ['c', 'cpp', 'objc'])
    144
    145link_language = meson.get_external_property('link_language', 'cpp')
    146if link_language == 'cpp'
    147  add_languages('cpp', required: true, native: false)
    148endif
    149if host_machine.system() == 'darwin'
    150  add_languages('objc', required: false, native: false)
    151endif
    152
    153sparse = find_program('cgcc', required: get_option('sparse'))
    154if sparse.found()
    155  run_target('sparse',
    156             command: [find_program('scripts/check_sparse.py'),
    157                       'compile_commands.json', sparse.full_path(), '-Wbitwise',
    158                       '-Wno-transparent-union', '-Wno-old-initializer',
    159                       '-Wno-non-pointer-null'])
    160endif
    161
    162###########################################
    163# Target-specific checks and dependencies #
    164###########################################
    165
    166if targetos != 'linux' and get_option('mpath').enabled()
    167  error('Multipath is supported only on Linux')
    168endif
    169
    170if targetos != 'linux' and get_option('multiprocess').enabled()
    171  error('Multiprocess QEMU is supported only on Linux')
    172endif
    173multiprocess_allowed = targetos == 'linux' and not get_option('multiprocess').disabled()
    174
    175libm = cc.find_library('m', required: false)
    176threads = dependency('threads')
    177util = cc.find_library('util', required: false)
    178winmm = []
    179socket = []
    180version_res = []
    181coref = []
    182iokit = []
    183emulator_link_args = []
    184nvmm =not_found
    185hvf = not_found
    186if targetos == 'windows'
    187  socket = cc.find_library('ws2_32')
    188  winmm = cc.find_library('winmm')
    189
    190  win = import('windows')
    191  version_res = win.compile_resources('version.rc',
    192                                      depend_files: files('pc-bios/qemu-nsis.ico'),
    193                                      include_directories: include_directories('.'))
    194elif targetos == 'darwin'
    195  coref = dependency('appleframeworks', modules: 'CoreFoundation')
    196  iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
    197elif targetos == 'sunos'
    198  socket = [cc.find_library('socket'),
    199            cc.find_library('nsl'),
    200            cc.find_library('resolv')]
    201elif targetos == 'haiku'
    202  socket = [cc.find_library('posix_error_mapper'),
    203            cc.find_library('network'),
    204            cc.find_library('bsd')]
    205elif targetos == 'openbsd'
    206  if not get_option('tcg').disabled() and target_dirs.length() > 0
    207    # Disable OpenBSD W^X if available
    208    emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
    209  endif
    210endif
    211
    212accelerators = []
    213if not get_option('kvm').disabled() and targetos == 'linux'
    214  accelerators += 'CONFIG_KVM'
    215endif
    216if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
    217  accelerators += 'CONFIG_XEN'
    218  have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
    219else
    220  have_xen_pci_passthrough = false
    221endif
    222if not get_option('whpx').disabled() and targetos == 'windows'
    223  if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
    224    error('WHPX requires 64-bit host')
    225  elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
    226       cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
    227    accelerators += 'CONFIG_WHPX'
    228  endif
    229endif
    230if not get_option('hvf').disabled()
    231  hvf = dependency('appleframeworks', modules: 'Hypervisor',
    232                   required: get_option('hvf'))
    233  if hvf.found()
    234    accelerators += 'CONFIG_HVF'
    235  endif
    236endif
    237if not get_option('hax').disabled()
    238  if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
    239    accelerators += 'CONFIG_HAX'
    240  endif
    241endif
    242if targetos == 'netbsd'
    243  if cc.has_header_symbol('nvmm.h', 'nvmm_cpu_stop', required: get_option('nvmm'))
    244    nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
    245  endif
    246  if nvmm.found()
    247    accelerators += 'CONFIG_NVMM'
    248  endif
    249endif
    250
    251tcg_arch = config_host['ARCH']
    252if not get_option('tcg').disabled()
    253  if cpu not in supported_cpus
    254    if get_option('tcg_interpreter')
    255      warning('Unsupported CPU @0@, will use TCG with TCI (experimental and slow)'.format(cpu))
    256    else
    257      error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
    258    endif
    259  elif get_option('tcg_interpreter')
    260    warning('Use of the TCG interpretor is not recommended on this host')
    261    warning('architecture. There is a native TCG execution backend available')
    262    warning('which provides substantially better performance and reliability.')
    263    warning('It is strongly recommended to remove the --enable-tcg-interpreter')
    264    warning('configuration option on this architecture to use the native')
    265    warning('backend.')
    266  endif
    267  if get_option('tcg_interpreter')
    268    tcg_arch = 'tci'
    269  elif config_host['ARCH'] == 'sparc64'
    270    tcg_arch = 'sparc'
    271  elif config_host['ARCH'] in ['x86_64', 'x32']
    272    tcg_arch = 'i386'
    273  elif config_host['ARCH'] == 'ppc64'
    274    tcg_arch = 'ppc'
    275  elif config_host['ARCH'] in ['riscv32', 'riscv64']
    276    tcg_arch = 'riscv'
    277  endif
    278  add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
    279                        language: ['c', 'cpp', 'objc'])
    280
    281  accelerators += 'CONFIG_TCG'
    282  config_host += { 'CONFIG_TCG': 'y' }
    283endif
    284
    285if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
    286  error('KVM not available on this platform')
    287endif
    288if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
    289  error('HVF not available on this platform')
    290endif
    291if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
    292  error('NVMM not available on this platform')
    293endif
    294if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
    295  error('WHPX not available on this platform')
    296endif
    297if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
    298  if 'CONFIG_XEN' in accelerators
    299    error('Xen PCI passthrough not available on this platform')
    300  else
    301    error('Xen PCI passthrough requested but Xen not enabled')
    302  endif
    303endif
    304
    305################
    306# Dependencies #
    307################
    308
    309# The path to glib.h is added to all compilation commands.  This was
    310# grandfathered in from the QEMU Makefiles.
    311add_project_arguments(config_host['GLIB_CFLAGS'].split(),
    312                      native: false, language: ['c', 'cpp', 'objc'])
    313glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
    314                          link_args: config_host['GLIB_LIBS'].split())
    315# override glib dep with the configure results (for subprojects)
    316meson.override_dependency('glib-2.0', glib)
    317
    318gio = not_found
    319if 'CONFIG_GIO' in config_host
    320  gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
    321                           link_args: config_host['GIO_LIBS'].split())
    322endif
    323lttng = not_found
    324if 'CONFIG_TRACE_UST' in config_host
    325  lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
    326endif
    327pixman = not_found
    328if have_system or have_tools
    329  pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
    330                      method: 'pkg-config', kwargs: static_kwargs)
    331endif
    332libaio = cc.find_library('aio', required: false)
    333zlib = dependency('zlib', required: true, kwargs: static_kwargs)
    334
    335linux_io_uring = not_found
    336if not get_option('linux_io_uring').auto() or have_block
    337  linux_io_uring = dependency('liburing', required: get_option('linux_io_uring'),
    338                              method: 'pkg-config', kwargs: static_kwargs)
    339endif
    340libxml2 = not_found
    341if not get_option('libxml2').auto() or have_block
    342  libxml2 = dependency('libxml-2.0', required: get_option('libxml2'),
    343                       method: 'pkg-config', kwargs: static_kwargs)
    344endif
    345libnfs = not_found
    346if not get_option('libnfs').auto() or have_block
    347  libnfs = dependency('libnfs', version: '>=1.9.3',
    348                      required: get_option('libnfs'),
    349                      method: 'pkg-config', kwargs: static_kwargs)
    350endif
    351
    352libattr_test = '''
    353  #include <stddef.h>
    354  #include <sys/types.h>
    355  #ifdef CONFIG_LIBATTR
    356  #include <attr/xattr.h>
    357  #else
    358  #include <sys/xattr.h>
    359  #endif
    360  int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
    361
    362libattr = not_found
    363have_old_libattr = false
    364if not get_option('attr').disabled()
    365  if cc.links(libattr_test)
    366    libattr = declare_dependency()
    367  else
    368    libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
    369                              required: get_option('attr'),
    370                              kwargs: static_kwargs)
    371    if libattr.found() and not \
    372      cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
    373      libattr = not_found
    374      if get_option('attr').enabled()
    375        error('could not link libattr')
    376      else
    377        warning('could not link libattr, disabling')
    378      endif
    379    else
    380      have_old_libattr = libattr.found()
    381    endif
    382  endif
    383endif
    384
    385cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
    386if cocoa.found() and get_option('sdl').enabled()
    387  error('Cocoa and SDL cannot be enabled at the same time')
    388endif
    389if cocoa.found() and get_option('gtk').enabled()
    390  error('Cocoa and GTK+ cannot be enabled at the same time')
    391endif
    392
    393seccomp = not_found
    394if not get_option('seccomp').auto() or have_system or have_tools
    395  seccomp = dependency('libseccomp', version: '>=2.3.0',
    396                       required: get_option('seccomp'),
    397                       method: 'pkg-config', kwargs: static_kwargs)
    398endif
    399
    400libcap_ng = not_found
    401if not get_option('cap_ng').auto() or have_system or have_tools
    402  libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
    403                              required: get_option('cap_ng'),
    404                              kwargs: static_kwargs)
    405endif
    406if libcap_ng.found() and not cc.links('''
    407   #include <cap-ng.h>
    408   int main(void)
    409   {
    410     capng_capability_to_name(CAPNG_EFFECTIVE);
    411     return 0;
    412   }''', dependencies: libcap_ng)
    413  libcap_ng = not_found
    414  if get_option('cap_ng').enabled()
    415    error('could not link libcap-ng')
    416  else
    417    warning('could not link libcap-ng, disabling')
    418  endif
    419endif
    420
    421if get_option('xkbcommon').auto() and not have_system and not have_tools
    422  xkbcommon = not_found
    423else
    424  xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
    425                         method: 'pkg-config', kwargs: static_kwargs)
    426endif
    427vde = not_found
    428if config_host.has_key('CONFIG_VDE')
    429  vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
    430endif
    431pulse = not_found
    432if 'CONFIG_LIBPULSE' in config_host
    433  pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
    434                             link_args: config_host['PULSE_LIBS'].split())
    435endif
    436alsa = not_found
    437if 'CONFIG_ALSA' in config_host
    438  alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
    439                            link_args: config_host['ALSA_LIBS'].split())
    440endif
    441jack = not_found
    442if 'CONFIG_LIBJACK' in config_host
    443  jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
    444endif
    445spice = not_found
    446spice_headers = not_found
    447spice_protocol = not_found
    448if 'CONFIG_SPICE' in config_host
    449  spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
    450                             link_args: config_host['SPICE_LIBS'].split())
    451  spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
    452endif
    453if 'CONFIG_SPICE_PROTOCOL' in config_host
    454  spice_protocol = declare_dependency(compile_args: config_host['SPICE_PROTOCOL_CFLAGS'].split())
    455endif
    456rt = cc.find_library('rt', required: false)
    457libdl = not_found
    458if 'CONFIG_PLUGIN' in config_host
    459  libdl = cc.find_library('dl', required: false)
    460  if not cc.has_function('dlopen', dependencies: libdl)
    461    error('dlopen not found')
    462  endif
    463endif
    464libiscsi = not_found
    465if not get_option('libiscsi').auto() or have_block
    466  libiscsi = dependency('libiscsi', version: '>=1.9.0',
    467                         required: get_option('libiscsi'),
    468                         method: 'pkg-config', kwargs: static_kwargs)
    469endif
    470zstd = not_found
    471if not get_option('zstd').auto() or have_block
    472  zstd = dependency('libzstd', version: '>=1.4.0',
    473                    required: get_option('zstd'),
    474                    method: 'pkg-config', kwargs: static_kwargs)
    475endif
    476virgl = not_found
    477if not get_option('virglrenderer').auto() or have_system
    478  virgl = dependency('virglrenderer',
    479                     method: 'pkg-config',
    480                     required: get_option('virglrenderer'),
    481                     kwargs: static_kwargs)
    482endif
    483curl = not_found
    484if not get_option('curl').auto() or have_block
    485  curl = dependency('libcurl', version: '>=7.29.0',
    486                    method: 'pkg-config',
    487                    required: get_option('curl'),
    488                    kwargs: static_kwargs)
    489endif
    490libudev = not_found
    491if targetos == 'linux' and (have_system or have_tools)
    492  libudev = dependency('libudev',
    493                       method: 'pkg-config',
    494                       required: get_option('libudev'),
    495                       kwargs: static_kwargs)
    496endif
    497
    498mpathlibs = [libudev]
    499mpathpersist = not_found
    500mpathpersist_new_api = false
    501if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
    502  mpath_test_source_new = '''
    503    #include <libudev.h>
    504    #include <mpath_persist.h>
    505    unsigned mpath_mx_alloc_len = 1024;
    506    int logsink;
    507    static struct config *multipath_conf;
    508    extern struct udev *udev;
    509    extern struct config *get_multipath_config(void);
    510    extern void put_multipath_config(struct config *conf);
    511    struct udev *udev;
    512    struct config *get_multipath_config(void) { return multipath_conf; }
    513    void put_multipath_config(struct config *conf) { }
    514    int main(void) {
    515        udev = udev_new();
    516        multipath_conf = mpath_lib_init();
    517        return 0;
    518    }'''
    519  mpath_test_source_old = '''
    520      #include <libudev.h>
    521      #include <mpath_persist.h>
    522      unsigned mpath_mx_alloc_len = 1024;
    523      int logsink;
    524      int main(void) {
    525          struct udev *udev = udev_new();
    526          mpath_lib_init(udev);
    527          return 0;
    528      }'''
    529  libmpathpersist = cc.find_library('mpathpersist',
    530                                    required: get_option('mpath'),
    531                                    kwargs: static_kwargs)
    532  if libmpathpersist.found()
    533    mpathlibs += libmpathpersist
    534    if enable_static
    535      mpathlibs += cc.find_library('devmapper',
    536                                     required: get_option('mpath'),
    537                                     kwargs: static_kwargs)
    538    endif
    539    mpathlibs += cc.find_library('multipath',
    540                                 required: get_option('mpath'),
    541                                 kwargs: static_kwargs)
    542    foreach lib: mpathlibs
    543      if not lib.found()
    544        mpathlibs = []
    545        break
    546      endif
    547    endforeach
    548    if mpathlibs.length() == 0
    549      msg = 'Dependencies missing for libmpathpersist'
    550    elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
    551      mpathpersist = declare_dependency(dependencies: mpathlibs)
    552      mpathpersist_new_api = true
    553    elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
    554      mpathpersist = declare_dependency(dependencies: mpathlibs)
    555    else
    556      msg = 'Cannot detect libmpathpersist API'
    557    endif
    558    if not mpathpersist.found()
    559      if get_option('mpath').enabled()
    560        error(msg)
    561      else
    562        warning(msg + ', disabling')
    563      endif
    564    endif
    565  endif
    566endif
    567
    568iconv = not_found
    569curses = not_found
    570if have_system and not get_option('curses').disabled()
    571  curses_test = '''
    572    #include <locale.h>
    573    #include <curses.h>
    574    #include <wchar.h>
    575    int main(void) {
    576      wchar_t wch = L'w';
    577      setlocale(LC_ALL, "");
    578      resize_term(0, 0);
    579      addwstr(L"wide chars\n");
    580      addnwstr(&wch, 1);
    581      add_wch(WACS_DEGREE);
    582      return 0;
    583    }'''
    584
    585  curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
    586  foreach curses_dep : curses_dep_list
    587    if not curses.found()
    588      curses = dependency(curses_dep,
    589                          required: false,
    590                          method: 'pkg-config',
    591                          kwargs: static_kwargs)
    592    endif
    593  endforeach
    594  msg = get_option('curses').enabled() ? 'curses library not found' : ''
    595  curses_compile_args = ['-DNCURSES_WIDECHAR']
    596  if curses.found()
    597    if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
    598      curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
    599    else
    600      msg = 'curses package not usable'
    601      curses = not_found
    602    endif
    603  endif
    604  if not curses.found()
    605    has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
    606    if targetos != 'windows' and not has_curses_h
    607      message('Trying with /usr/include/ncursesw')
    608      curses_compile_args += ['-I/usr/include/ncursesw']
    609      has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
    610    endif
    611    if has_curses_h
    612      curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
    613      foreach curses_libname : curses_libname_list
    614        libcurses = cc.find_library(curses_libname,
    615                                    required: false,
    616                                    kwargs: static_kwargs)
    617        if libcurses.found()
    618          if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
    619            curses = declare_dependency(compile_args: curses_compile_args,
    620                                        dependencies: [libcurses])
    621            break
    622          else
    623            msg = 'curses library not usable'
    624          endif
    625        endif
    626      endforeach
    627    endif
    628  endif
    629  if not get_option('iconv').disabled()
    630    foreach link_args : [ ['-liconv'], [] ]
    631      # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
    632      # We need to use libiconv if available because mixing libiconv's headers with
    633      # the system libc does not work.
    634      # However, without adding glib to the dependencies -L/usr/local/lib will not be
    635      # included in the command line and libiconv will not be found.
    636      if cc.links('''
    637        #include <iconv.h>
    638        int main(void) {
    639          iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
    640          return conv != (iconv_t) -1;
    641        }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
    642        iconv = declare_dependency(link_args: link_args, dependencies: glib)
    643        break
    644      endif
    645    endforeach
    646  endif
    647  if curses.found() and not iconv.found()
    648    if get_option('iconv').enabled()
    649      error('iconv not available')
    650    endif
    651    msg = 'iconv required for curses UI but not available'
    652    curses = not_found
    653  endif
    654  if not curses.found() and msg != ''
    655    if get_option('curses').enabled()
    656      error(msg)
    657    else
    658      warning(msg + ', disabling')
    659    endif
    660  endif
    661endif
    662
    663brlapi = not_found
    664if not get_option('brlapi').auto() or have_system
    665  brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
    666                         required: get_option('brlapi'),
    667                         kwargs: static_kwargs)
    668  if brlapi.found() and not cc.links('''
    669     #include <brlapi.h>
    670     #include <stddef.h>
    671     int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
    672    brlapi = not_found
    673    if get_option('brlapi').enabled()
    674      error('could not link brlapi')
    675    else
    676      warning('could not link brlapi, disabling')
    677    endif
    678  endif
    679endif
    680
    681sdl = not_found
    682if not get_option('sdl').auto() or (have_system and not cocoa.found())
    683  sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
    684  sdl_image = not_found
    685endif
    686if sdl.found()
    687  # work around 2.0.8 bug
    688  sdl = declare_dependency(compile_args: '-Wno-undef',
    689                           dependencies: sdl)
    690  sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
    691                         method: 'pkg-config', kwargs: static_kwargs)
    692else
    693  if get_option('sdl_image').enabled()
    694    error('sdl-image required, but SDL was @0@'.format(
    695          get_option('sdl').disabled() ? 'disabled' : 'not found'))
    696  endif
    697  sdl_image = not_found
    698endif
    699
    700rbd = not_found
    701if not get_option('rbd').auto() or have_block
    702  librados = cc.find_library('rados', required: get_option('rbd'),
    703                             kwargs: static_kwargs)
    704  librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
    705                           required: get_option('rbd'),
    706                           kwargs: static_kwargs)
    707  if librados.found() and librbd.found()
    708    if cc.links('''
    709      #include <stdio.h>
    710      #include <rbd/librbd.h>
    711      int main(void) {
    712        rados_t cluster;
    713        rados_create(&cluster, NULL);
    714        #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
    715        #error
    716        #endif
    717        return 0;
    718      }''', dependencies: [librbd, librados])
    719      rbd = declare_dependency(dependencies: [librbd, librados])
    720    elif get_option('rbd').enabled()
    721      error('librbd >= 1.12.0 required')
    722    else
    723      warning('librbd >= 1.12.0 not found, disabling')
    724    endif
    725  endif
    726endif
    727
    728glusterfs = not_found
    729glusterfs_ftruncate_has_stat = false
    730glusterfs_iocb_has_stat = false
    731if not get_option('glusterfs').auto() or have_block
    732  glusterfs = dependency('glusterfs-api', version: '>=3',
    733                         required: get_option('glusterfs'),
    734                         method: 'pkg-config', kwargs: static_kwargs)
    735  if glusterfs.found()
    736    glusterfs_ftruncate_has_stat = cc.links('''
    737      #include <glusterfs/api/glfs.h>
    738
    739      int
    740      main(void)
    741      {
    742          /* new glfs_ftruncate() passes two additional args */
    743          return glfs_ftruncate(NULL, 0, NULL, NULL);
    744      }
    745    ''', dependencies: glusterfs)
    746    glusterfs_iocb_has_stat = cc.links('''
    747      #include <glusterfs/api/glfs.h>
    748
    749      /* new glfs_io_cbk() passes two additional glfs_stat structs */
    750      static void
    751      glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
    752      {}
    753
    754      int
    755      main(void)
    756      {
    757          glfs_io_cbk iocb = &glusterfs_iocb;
    758          iocb(NULL, 0 , NULL, NULL, NULL);
    759          return 0;
    760      }
    761    ''', dependencies: glusterfs)
    762  endif
    763endif
    764libssh = not_found
    765if 'CONFIG_LIBSSH' in config_host
    766  libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
    767                              link_args: config_host['LIBSSH_LIBS'].split())
    768endif
    769libbzip2 = not_found
    770if not get_option('bzip2').auto() or have_block
    771  libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
    772                             required: get_option('bzip2'),
    773                             kwargs: static_kwargs)
    774  if libbzip2.found() and not cc.links('''
    775     #include <bzlib.h>
    776     int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
    777    libbzip2 = not_found
    778    if get_option('bzip2').enabled()
    779      error('could not link libbzip2')
    780    else
    781      warning('could not link libbzip2, disabling')
    782    endif
    783  endif
    784endif
    785
    786liblzfse = not_found
    787if not get_option('lzfse').auto() or have_block
    788  liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
    789                             required: get_option('lzfse'),
    790                             kwargs: static_kwargs)
    791endif
    792if liblzfse.found() and not cc.links('''
    793   #include <lzfse.h>
    794   int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
    795  liblzfse = not_found
    796  if get_option('lzfse').enabled()
    797    error('could not link liblzfse')
    798  else
    799    warning('could not link liblzfse, disabling')
    800  endif
    801endif
    802
    803oss = not_found
    804if 'CONFIG_AUDIO_OSS' in config_host
    805  oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
    806endif
    807dsound = not_found
    808if 'CONFIG_AUDIO_DSOUND' in config_host
    809  dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
    810endif
    811coreaudio = not_found
    812if 'CONFIG_AUDIO_COREAUDIO' in config_host
    813  coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
    814endif
    815
    816opengl = not_found
    817if 'CONFIG_OPENGL' in config_host
    818  opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
    819                              link_args: config_host['OPENGL_LIBS'].split())
    820endif
    821gbm = not_found
    822if (have_system or have_tools) and (virgl.found() or opengl.found())
    823  gbm = dependency('gbm', method: 'pkg-config', required: false,
    824                   kwargs: static_kwargs)
    825endif
    826
    827gnutls = not_found
    828gnutls_crypto = not_found
    829if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
    830  # For general TLS support our min gnutls matches
    831  # that implied by our platform support matrix
    832  #
    833  # For the crypto backends, we look for a newer
    834  # gnutls:
    835  #
    836  #   Version 3.6.8  is needed to get XTS
    837  #   Version 3.6.13 is needed to get PBKDF
    838  #   Version 3.6.14 is needed to get HW accelerated XTS
    839  #
    840  # If newer enough gnutls isn't available, we can
    841  # still use a different crypto backend to satisfy
    842  # the platform support requirements
    843  gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
    844                             method: 'pkg-config',
    845                             required: false,
    846                             kwargs: static_kwargs)
    847  if gnutls_crypto.found()
    848    gnutls = gnutls_crypto
    849  else
    850    # Our min version if all we need is TLS
    851    gnutls = dependency('gnutls', version: '>=3.5.18',
    852                        method: 'pkg-config',
    853                        required: get_option('gnutls'),
    854                        kwargs: static_kwargs)
    855  endif
    856endif
    857
    858# We prefer use of gnutls for crypto, unless the options
    859# explicitly asked for nettle or gcrypt.
    860#
    861# If gnutls isn't available for crypto, then we'll prefer
    862# gcrypt over nettle for performance reasons.
    863gcrypt = not_found
    864nettle = not_found
    865xts = 'none'
    866
    867if get_option('nettle').enabled() and get_option('gcrypt').enabled()
    868  error('Only one of gcrypt & nettle can be enabled')
    869endif
    870
    871# Explicit nettle/gcrypt request, so ignore gnutls for crypto
    872if get_option('nettle').enabled() or get_option('gcrypt').enabled()
    873  gnutls_crypto = not_found
    874endif
    875
    876if not gnutls_crypto.found()
    877  if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
    878    gcrypt = dependency('libgcrypt', version: '>=1.8',
    879                        method: 'config-tool',
    880                        required: get_option('gcrypt'),
    881                        kwargs: static_kwargs)
    882    # Debian has removed -lgpg-error from libgcrypt-config
    883    # as it "spreads unnecessary dependencies" which in
    884    # turn breaks static builds...
    885    if gcrypt.found() and enable_static
    886      gcrypt = declare_dependency(dependencies: [
    887        gcrypt,
    888        cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
    889    endif
    890  endif
    891  if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
    892    nettle = dependency('nettle', version: '>=3.4',
    893                        method: 'pkg-config',
    894                        required: get_option('nettle'),
    895                        kwargs: static_kwargs)
    896    if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
    897      xts = 'private'
    898    endif
    899  endif
    900endif
    901
    902gtk = not_found
    903gtkx11 = not_found
    904vte = not_found
    905if not get_option('gtk').auto() or (have_system and not cocoa.found())
    906  gtk = dependency('gtk+-3.0', version: '>=3.22.0',
    907                   method: 'pkg-config',
    908                   required: get_option('gtk'),
    909                   kwargs: static_kwargs)
    910  if gtk.found()
    911    gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
    912                        method: 'pkg-config',
    913                        required: false,
    914                        kwargs: static_kwargs)
    915    gtk = declare_dependency(dependencies: [gtk, gtkx11])
    916
    917    if not get_option('vte').auto() or have_system
    918      vte = dependency('vte-2.91',
    919                       method: 'pkg-config',
    920                       required: get_option('vte'),
    921                       kwargs: static_kwargs)
    922    endif
    923  endif
    924endif
    925
    926x11 = not_found
    927if gtkx11.found()
    928  x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
    929                   kwargs: static_kwargs)
    930endif
    931vnc = not_found
    932png = not_found
    933jpeg = not_found
    934sasl = not_found
    935if have_system and not get_option('vnc').disabled()
    936  vnc = declare_dependency() # dummy dependency
    937  png = dependency('libpng', required: get_option('vnc_png'),
    938                   method: 'pkg-config', kwargs: static_kwargs)
    939  jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
    940                    method: 'pkg-config', kwargs: static_kwargs)
    941  sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
    942                         required: get_option('vnc_sasl'),
    943                         kwargs: static_kwargs)
    944  if sasl.found()
    945    sasl = declare_dependency(dependencies: sasl,
    946                              compile_args: '-DSTRUCT_IOVEC_DEFINED')
    947  endif
    948endif
    949
    950pam = not_found
    951if not get_option('auth_pam').auto() or have_system
    952  pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
    953                        required: get_option('auth_pam'),
    954                        kwargs: static_kwargs)
    955endif
    956if pam.found() and not cc.links('''
    957   #include <stddef.h>
    958   #include <security/pam_appl.h>
    959   int main(void) {
    960     const char *service_name = "qemu";
    961     const char *user = "frank";
    962     const struct pam_conv pam_conv = { 0 };
    963     pam_handle_t *pamh = NULL;
    964     pam_start(service_name, user, &pam_conv, &pamh);
    965     return 0;
    966   }''', dependencies: pam)
    967  pam = not_found
    968  if get_option('auth_pam').enabled()
    969    error('could not link libpam')
    970  else
    971    warning('could not link libpam, disabling')
    972  endif
    973endif
    974
    975snappy = not_found
    976if not get_option('snappy').auto() or have_system
    977  snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
    978                           required: get_option('snappy'),
    979                           kwargs: static_kwargs)
    980endif
    981if snappy.found() and not cc.links('''
    982   #include <snappy-c.h>
    983   int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
    984  snappy = not_found
    985  if get_option('snappy').enabled()
    986    error('could not link libsnappy')
    987  else
    988    warning('could not link libsnappy, disabling')
    989  endif
    990endif
    991
    992lzo = not_found
    993if not get_option('lzo').auto() or have_system
    994  lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
    995                        required: get_option('lzo'),
    996                        kwargs: static_kwargs)
    997endif
    998if lzo.found() and not cc.links('''
    999   #include <lzo/lzo1x.h>
   1000   int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
   1001  lzo = not_found
   1002  if get_option('lzo').enabled()
   1003    error('could not link liblzo2')
   1004  else
   1005    warning('could not link liblzo2, disabling')
   1006  endif
   1007endif
   1008
   1009rdma = not_found
   1010if 'CONFIG_RDMA' in config_host
   1011  rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
   1012endif
   1013numa = not_found
   1014if 'CONFIG_NUMA' in config_host
   1015  numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
   1016endif
   1017xen = not_found
   1018if 'CONFIG_XEN_BACKEND' in config_host
   1019  xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
   1020                           link_args: config_host['XEN_LIBS'].split())
   1021endif
   1022cacard = not_found
   1023if not get_option('smartcard').auto() or have_system
   1024  cacard = dependency('libcacard', required: get_option('smartcard'),
   1025                      version: '>=2.5.1', method: 'pkg-config',
   1026                      kwargs: static_kwargs)
   1027endif
   1028u2f = not_found
   1029if have_system
   1030  u2f = dependency('u2f-emu', required: get_option('u2f'),
   1031                   method: 'pkg-config',
   1032                   kwargs: static_kwargs)
   1033endif
   1034usbredir = not_found
   1035if not get_option('usb_redir').auto() or have_system
   1036  usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
   1037                        version: '>=0.6', method: 'pkg-config',
   1038                        kwargs: static_kwargs)
   1039endif
   1040libusb = not_found
   1041if not get_option('libusb').auto() or have_system
   1042  libusb = dependency('libusb-1.0', required: get_option('libusb'),
   1043                      version: '>=1.0.13', method: 'pkg-config',
   1044                      kwargs: static_kwargs)
   1045endif
   1046
   1047libpmem = not_found
   1048if not get_option('libpmem').auto() or have_system
   1049  libpmem = dependency('libpmem', required: get_option('libpmem'),
   1050                       method: 'pkg-config', kwargs: static_kwargs)
   1051endif
   1052libdaxctl = not_found
   1053if not get_option('libdaxctl').auto() or have_system
   1054  libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
   1055                         version: '>=57', method: 'pkg-config',
   1056                         kwargs: static_kwargs)
   1057endif
   1058tasn1 = not_found
   1059if gnutls.found()
   1060  tasn1 = dependency('libtasn1',
   1061                     method: 'pkg-config',
   1062                     kwargs: static_kwargs)
   1063endif
   1064keyutils = dependency('libkeyutils', required: false,
   1065                      method: 'pkg-config', kwargs: static_kwargs)
   1066
   1067has_gettid = cc.has_function('gettid')
   1068
   1069# Malloc tests
   1070
   1071malloc = []
   1072if get_option('malloc') == 'system'
   1073  has_malloc_trim = \
   1074    not get_option('malloc_trim').disabled() and \
   1075    cc.links('''#include <malloc.h>
   1076                int main(void) { malloc_trim(0); return 0; }''')
   1077else
   1078  has_malloc_trim = false
   1079  malloc = cc.find_library(get_option('malloc'), required: true)
   1080endif
   1081if not has_malloc_trim and get_option('malloc_trim').enabled()
   1082  if get_option('malloc') == 'system'
   1083    error('malloc_trim not available on this platform.')
   1084  else
   1085    error('malloc_trim not available with non-libc memory allocator')
   1086  endif
   1087endif
   1088
   1089# Check whether the glibc provides statx()
   1090
   1091gnu_source_prefix = '''
   1092  #ifndef _GNU_SOURCE
   1093  #define _GNU_SOURCE
   1094  #endif
   1095'''
   1096statx_test = gnu_source_prefix + '''
   1097  #include <sys/stat.h>
   1098  int main(void) {
   1099    struct statx statxbuf;
   1100    statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
   1101    return 0;
   1102  }'''
   1103
   1104has_statx = cc.links(statx_test)
   1105
   1106have_vhost_user_blk_server = (targetos == 'linux' and
   1107    'CONFIG_VHOST_USER' in config_host)
   1108
   1109if get_option('vhost_user_blk_server').enabled()
   1110    if targetos != 'linux'
   1111        error('vhost_user_blk_server requires linux')
   1112    elif 'CONFIG_VHOST_USER' not in config_host
   1113        error('vhost_user_blk_server requires vhost-user support')
   1114    endif
   1115elif get_option('vhost_user_blk_server').disabled() or not have_system
   1116    have_vhost_user_blk_server = false
   1117endif
   1118
   1119
   1120if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
   1121  error('Cannot enable fuse-lseek while fuse is disabled')
   1122endif
   1123
   1124fuse = dependency('fuse3', required: get_option('fuse'),
   1125                  version: '>=3.1', method: 'pkg-config',
   1126                  kwargs: static_kwargs)
   1127
   1128fuse_lseek = not_found
   1129if not get_option('fuse_lseek').disabled()
   1130  if fuse.version().version_compare('>=3.8')
   1131    # Dummy dependency
   1132    fuse_lseek = declare_dependency()
   1133  elif get_option('fuse_lseek').enabled()
   1134    if fuse.found()
   1135      error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
   1136    else
   1137      error('fuse-lseek requires libfuse, which was not found')
   1138    endif
   1139  endif
   1140endif
   1141
   1142# libbpf
   1143libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
   1144if libbpf.found() and not cc.links('''
   1145   #include <bpf/libbpf.h>
   1146   int main(void)
   1147   {
   1148     bpf_object__destroy_skeleton(NULL);
   1149     return 0;
   1150   }''', dependencies: libbpf)
   1151  libbpf = not_found
   1152  if get_option('bpf').enabled()
   1153    error('libbpf skeleton test failed')
   1154  else
   1155    warning('libbpf skeleton test failed, disabling')
   1156  endif
   1157endif
   1158
   1159if get_option('cfi')
   1160  cfi_flags=[]
   1161  # Check for dependency on LTO
   1162  if not get_option('b_lto')
   1163    error('Selected Control-Flow Integrity but LTO is disabled')
   1164  endif
   1165  if config_host.has_key('CONFIG_MODULES')
   1166    error('Selected Control-Flow Integrity is not compatible with modules')
   1167  endif
   1168  # Check for cfi flags. CFI requires LTO so we can't use
   1169  # get_supported_arguments, but need a more complex "compiles" which allows
   1170  # custom arguments
   1171  if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
   1172                 args: ['-flto', '-fsanitize=cfi-icall'] )
   1173    cfi_flags += '-fsanitize=cfi-icall'
   1174  else
   1175    error('-fsanitize=cfi-icall is not supported by the compiler')
   1176  endif
   1177  if cc.compiles('int main () { return 0; }',
   1178                 name: '-fsanitize-cfi-icall-generalize-pointers',
   1179                 args: ['-flto', '-fsanitize=cfi-icall',
   1180                        '-fsanitize-cfi-icall-generalize-pointers'] )
   1181    cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
   1182  else
   1183    error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
   1184  endif
   1185  if get_option('cfi_debug')
   1186    if cc.compiles('int main () { return 0; }',
   1187                   name: '-fno-sanitize-trap=cfi-icall',
   1188                   args: ['-flto', '-fsanitize=cfi-icall',
   1189                          '-fno-sanitize-trap=cfi-icall'] )
   1190      cfi_flags += '-fno-sanitize-trap=cfi-icall'
   1191    else
   1192      error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
   1193    endif
   1194  endif
   1195  add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
   1196  add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
   1197endif
   1198
   1199have_host_block_device = (targetos != 'darwin' or
   1200    cc.has_header('IOKit/storage/IOMedia.h'))
   1201
   1202#################
   1203# config-host.h #
   1204#################
   1205
   1206have_virtfs = (targetos == 'linux' and
   1207    have_system and
   1208    libattr.found() and
   1209    libcap_ng.found())
   1210
   1211have_virtfs_proxy_helper = have_virtfs and have_tools
   1212
   1213if get_option('virtfs').enabled()
   1214  if not have_virtfs
   1215    if targetos != 'linux'
   1216      error('virtio-9p (virtfs) requires Linux')
   1217    elif not libcap_ng.found() or not libattr.found()
   1218      error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
   1219    elif not have_system
   1220      error('virtio-9p (virtfs) needs system emulation support')
   1221    endif
   1222  endif
   1223elif get_option('virtfs').disabled()
   1224  have_virtfs = false
   1225endif
   1226
   1227config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
   1228config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
   1229config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
   1230config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
   1231config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
   1232config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
   1233config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
   1234config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
   1235config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
   1236config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
   1237config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
   1238config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
   1239
   1240config_host_data.set('CONFIG_ATTR', libattr.found())
   1241config_host_data.set('CONFIG_BRLAPI', brlapi.found())
   1242config_host_data.set('CONFIG_COCOA', cocoa.found())
   1243config_host_data.set('CONFIG_LIBUDEV', libudev.found())
   1244config_host_data.set('CONFIG_LZO', lzo.found())
   1245config_host_data.set('CONFIG_MPATH', mpathpersist.found())
   1246config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
   1247config_host_data.set('CONFIG_CURL', curl.found())
   1248config_host_data.set('CONFIG_CURSES', curses.found())
   1249config_host_data.set('CONFIG_GBM', gbm.found())
   1250config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
   1251if glusterfs.found()
   1252  config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
   1253  config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
   1254  config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
   1255  config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
   1256  config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
   1257  config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
   1258endif
   1259config_host_data.set('CONFIG_GTK', gtk.found())
   1260config_host_data.set('CONFIG_VTE', vte.found())
   1261config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
   1262config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
   1263config_host_data.set('CONFIG_EBPF', libbpf.found())
   1264config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
   1265config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
   1266config_host_data.set('CONFIG_LIBNFS', libnfs.found())
   1267config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
   1268config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
   1269config_host_data.set('CONFIG_RBD', rbd.found())
   1270config_host_data.set('CONFIG_SDL', sdl.found())
   1271config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
   1272config_host_data.set('CONFIG_SECCOMP', seccomp.found())
   1273config_host_data.set('CONFIG_SNAPPY', snappy.found())
   1274config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
   1275config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
   1276config_host_data.set('CONFIG_VNC', vnc.found())
   1277config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
   1278config_host_data.set('CONFIG_VNC_PNG', png.found())
   1279config_host_data.set('CONFIG_VNC_SASL', sasl.found())
   1280config_host_data.set('CONFIG_VIRTFS', have_virtfs)
   1281config_host_data.set('CONFIG_VTE', vte.found())
   1282config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
   1283config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
   1284config_host_data.set('CONFIG_GETTID', has_gettid)
   1285config_host_data.set('CONFIG_GNUTLS', gnutls.found())
   1286config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
   1287config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
   1288config_host_data.set('CONFIG_NETTLE', nettle.found())
   1289config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
   1290config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
   1291config_host_data.set('CONFIG_STATX', has_statx)
   1292config_host_data.set('CONFIG_ZSTD', zstd.found())
   1293config_host_data.set('CONFIG_FUSE', fuse.found())
   1294config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
   1295config_host_data.set('CONFIG_X11', x11.found())
   1296config_host_data.set('CONFIG_CFI', get_option('cfi'))
   1297config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
   1298config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
   1299config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
   1300config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
   1301
   1302config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
   1303
   1304# has_header
   1305config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
   1306config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
   1307config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
   1308config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
   1309config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
   1310config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
   1311config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
   1312config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
   1313config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
   1314
   1315# has_function
   1316config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
   1317config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
   1318config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
   1319config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
   1320config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
   1321config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
   1322config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
   1323config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
   1324config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
   1325config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
   1326config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
   1327config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
   1328config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
   1329config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
   1330config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
   1331config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
   1332config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
   1333config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
   1334
   1335# has_header_symbol
   1336config_host_data.set('CONFIG_BYTESWAP_H',
   1337                     cc.has_header_symbol('byteswap.h', 'bswap_32'))
   1338config_host_data.set('CONFIG_EPOLL_CREATE1',
   1339                     cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
   1340config_host_data.set('CONFIG_HAS_ENVIRON',
   1341                     cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix))
   1342config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
   1343                     cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
   1344                     cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
   1345config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
   1346                     cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
   1347config_host_data.set('CONFIG_FIEMAP',
   1348                     cc.has_header('linux/fiemap.h') and
   1349                     cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
   1350config_host_data.set('CONFIG_GETRANDOM',
   1351                     cc.has_function('getrandom') and
   1352                     cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
   1353config_host_data.set('CONFIG_INOTIFY',
   1354                     cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
   1355config_host_data.set('CONFIG_INOTIFY1',
   1356                     cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
   1357config_host_data.set('CONFIG_MACHINE_BSWAP_H',
   1358                     cc.has_header_symbol('machine/bswap.h', 'bswap32',
   1359                                          prefix: '''#include <sys/endian.h>
   1360                                                     #include <sys/types.h>'''))
   1361config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
   1362                     cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
   1363config_host_data.set('CONFIG_RTNETLINK',
   1364                     cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
   1365config_host_data.set('CONFIG_SYSMACROS',
   1366                     cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
   1367config_host_data.set('HAVE_OPTRESET',
   1368                     cc.has_header_symbol('getopt.h', 'optreset'))
   1369config_host_data.set('HAVE_UTMPX',
   1370                     cc.has_header_symbol('utmpx.h', 'struct utmpx'))
   1371config_host_data.set('HAVE_IPPROTO_MPTCP',
   1372                     cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
   1373
   1374# has_member
   1375config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
   1376                     cc.has_member('struct sigevent', 'sigev_notify_thread_id',
   1377                                   prefix: '#include <signal.h>'))
   1378config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
   1379                     cc.has_member('struct stat', 'st_atim',
   1380                                   prefix: '#include <sys/stat.h>'))
   1381
   1382config_host_data.set('CONFIG_EVENTFD', cc.links('''
   1383  #include <sys/eventfd.h>
   1384  int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
   1385config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
   1386  #include <unistd.h>
   1387  int main(void) {
   1388  #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
   1389  return fdatasync(0);
   1390  #else
   1391  #error Not supported
   1392  #endif
   1393  }'''))
   1394config_host_data.set('CONFIG_MADVISE', cc.links(gnu_source_prefix + '''
   1395  #include <sys/types.h>
   1396  #include <sys/mman.h>
   1397  #include <stddef.h>
   1398  int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }'''))
   1399config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
   1400  #include <sys/mman.h>
   1401  int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
   1402config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
   1403  #include <fcntl.h>
   1404  #if !defined(AT_EMPTY_PATH)
   1405  # error missing definition
   1406  #else
   1407  int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
   1408  #endif'''))
   1409config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
   1410  #include <unistd.h>
   1411  #include <fcntl.h>
   1412
   1413  int main(void)
   1414  {
   1415      int pipefd[2];
   1416      return pipe2(pipefd, O_CLOEXEC);
   1417  }'''))
   1418config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
   1419  #include <sys/mman.h>
   1420  #include <stddef.h>
   1421  int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
   1422config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
   1423  #include <unistd.h>
   1424  #include <sys/syscall.h>
   1425  #include <signal.h>
   1426  int main(void) { return syscall(SYS_signalfd, -1, NULL, _NSIG / 8); }'''))
   1427config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
   1428  #include <unistd.h>
   1429  #include <fcntl.h>
   1430  #include <limits.h>
   1431
   1432  int main(void)
   1433  {
   1434    int len, fd = 0;
   1435    len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
   1436    splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
   1437    return 0;
   1438  }'''))
   1439
   1440# Some versions of Mac OS X incorrectly define SIZE_MAX
   1441config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
   1442    #include <stdint.h>
   1443    #include <stdio.h>
   1444    int main(int argc, char *argv[]) {
   1445        return printf("%zu", SIZE_MAX);
   1446    }''', args: ['-Werror']))
   1447
   1448
   1449ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
   1450arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
   1451strings = ['HOST_DSOSUF', 'CONFIG_IASL']
   1452foreach k, v: config_host
   1453  if ignored.contains(k)
   1454    # do nothing
   1455  elif arrays.contains(k)
   1456    if v != ''
   1457      v = '"' + '", "'.join(v.split()) + '", '
   1458    endif
   1459    config_host_data.set(k, v)
   1460  elif k == 'ARCH'
   1461    config_host_data.set('HOST_' + v.to_upper(), 1)
   1462  elif strings.contains(k)
   1463    if not k.startswith('CONFIG_')
   1464      k = 'CONFIG_' + k.to_upper()
   1465    endif
   1466    config_host_data.set_quoted(k, v)
   1467  elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
   1468    config_host_data.set(k, v == 'y' ? 1 : v)
   1469  endif
   1470endforeach
   1471
   1472########################
   1473# Target configuration #
   1474########################
   1475
   1476minikconf = find_program('scripts/minikconf.py')
   1477config_all = {}
   1478config_all_devices = {}
   1479config_all_disas = {}
   1480config_devices_mak_list = []
   1481config_devices_h = {}
   1482config_target_h = {}
   1483config_target_mak = {}
   1484
   1485disassemblers = {
   1486  'alpha' : ['CONFIG_ALPHA_DIS'],
   1487  'arm' : ['CONFIG_ARM_DIS'],
   1488  'avr' : ['CONFIG_AVR_DIS'],
   1489  'cris' : ['CONFIG_CRIS_DIS'],
   1490  'hexagon' : ['CONFIG_HEXAGON_DIS'],
   1491  'hppa' : ['CONFIG_HPPA_DIS'],
   1492  'i386' : ['CONFIG_I386_DIS'],
   1493  'x86_64' : ['CONFIG_I386_DIS'],
   1494  'x32' : ['CONFIG_I386_DIS'],
   1495  'm68k' : ['CONFIG_M68K_DIS'],
   1496  'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
   1497  'mips' : ['CONFIG_MIPS_DIS'],
   1498  'nios2' : ['CONFIG_NIOS2_DIS'],
   1499  'or1k' : ['CONFIG_OPENRISC_DIS'],
   1500  'ppc' : ['CONFIG_PPC_DIS'],
   1501  'riscv' : ['CONFIG_RISCV_DIS'],
   1502  'rx' : ['CONFIG_RX_DIS'],
   1503  's390' : ['CONFIG_S390_DIS'],
   1504  'sh4' : ['CONFIG_SH4_DIS'],
   1505  'sparc' : ['CONFIG_SPARC_DIS'],
   1506  'xtensa' : ['CONFIG_XTENSA_DIS'],
   1507}
   1508if link_language == 'cpp'
   1509  disassemblers += {
   1510    'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
   1511    'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
   1512    'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
   1513  }
   1514endif
   1515
   1516have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
   1517host_kconfig = \
   1518  ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
   1519  ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
   1520  (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
   1521  ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
   1522  (x11.found() ? ['CONFIG_X11=y'] : []) + \
   1523  ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
   1524  ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
   1525  ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
   1526  (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
   1527  ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
   1528  ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
   1529  (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
   1530
   1531ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
   1532
   1533default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
   1534actual_target_dirs = []
   1535fdt_required = []
   1536foreach target : target_dirs
   1537  config_target = { 'TARGET_NAME': target.split('-')[0] }
   1538  if target.endswith('linux-user')
   1539    if targetos != 'linux'
   1540      if default_targets
   1541        continue
   1542      endif
   1543      error('Target @0@ is only available on a Linux host'.format(target))
   1544    endif
   1545    config_target += { 'CONFIG_LINUX_USER': 'y' }
   1546  elif target.endswith('bsd-user')
   1547    if 'CONFIG_BSD' not in config_host
   1548      if default_targets
   1549        continue
   1550      endif
   1551      error('Target @0@ is only available on a BSD host'.format(target))
   1552    endif
   1553    config_target += { 'CONFIG_BSD_USER': 'y' }
   1554  elif target.endswith('softmmu')
   1555    config_target += { 'CONFIG_SOFTMMU': 'y' }
   1556  endif
   1557  if target.endswith('-user')
   1558    config_target += {
   1559      'CONFIG_USER_ONLY': 'y',
   1560      'CONFIG_QEMU_INTERP_PREFIX':
   1561        config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
   1562    }
   1563  endif
   1564
   1565  accel_kconfig = []
   1566  foreach sym: accelerators
   1567    if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
   1568      config_target += { sym: 'y' }
   1569      config_all += { sym: 'y' }
   1570      if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
   1571        config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
   1572      elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
   1573        config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
   1574      endif
   1575      if target in modular_tcg
   1576        config_target += { 'CONFIG_TCG_MODULAR': 'y' }
   1577      else
   1578        config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
   1579      endif
   1580      accel_kconfig += [ sym + '=y' ]
   1581    endif
   1582  endforeach
   1583  if accel_kconfig.length() == 0
   1584    if default_targets
   1585      continue
   1586    endif
   1587    error('No accelerator available for target @0@'.format(target))
   1588  endif
   1589
   1590  actual_target_dirs += target
   1591  config_target += keyval.load('configs/targets' / target + '.mak')
   1592  config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
   1593
   1594  if 'TARGET_NEED_FDT' in config_target
   1595    fdt_required += target
   1596  endif
   1597
   1598  # Add default keys
   1599  if 'TARGET_BASE_ARCH' not in config_target
   1600    config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
   1601  endif
   1602  if 'TARGET_ABI_DIR' not in config_target
   1603    config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
   1604  endif
   1605
   1606  foreach k, v: disassemblers
   1607    if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
   1608      foreach sym: v
   1609        config_target += { sym: 'y' }
   1610        config_all_disas += { sym: 'y' }
   1611      endforeach
   1612    endif
   1613  endforeach
   1614
   1615  config_target_data = configuration_data()
   1616  foreach k, v: config_target
   1617    if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
   1618      # do nothing
   1619    elif ignored.contains(k)
   1620      # do nothing
   1621    elif k == 'TARGET_BASE_ARCH'
   1622      # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
   1623      # not used to select files from sourcesets.
   1624      config_target_data.set('TARGET_' + v.to_upper(), 1)
   1625    elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
   1626      config_target_data.set_quoted(k, v)
   1627    elif v == 'y'
   1628      config_target_data.set(k, 1)
   1629    else
   1630      config_target_data.set(k, v)
   1631    endif
   1632  endforeach
   1633  config_target_data.set('QEMU_ARCH',
   1634                         'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
   1635  config_target_h += {target: configure_file(output: target + '-config-target.h',
   1636                                               configuration: config_target_data)}
   1637
   1638  if target.endswith('-softmmu')
   1639    config_input = meson.get_external_property(target, 'default')
   1640    config_devices_mak = target + '-config-devices.mak'
   1641    config_devices_mak = configure_file(
   1642      input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
   1643      output: config_devices_mak,
   1644      depfile: config_devices_mak + '.d',
   1645      capture: true,
   1646      command: [minikconf,
   1647                get_option('default_devices') ? '--defconfig' : '--allnoconfig',
   1648                config_devices_mak, '@DEPFILE@', '@INPUT@',
   1649                host_kconfig, accel_kconfig,
   1650                'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
   1651
   1652    config_devices_data = configuration_data()
   1653    config_devices = keyval.load(config_devices_mak)
   1654    foreach k, v: config_devices
   1655      config_devices_data.set(k, 1)
   1656    endforeach
   1657    config_devices_mak_list += config_devices_mak
   1658    config_devices_h += {target: configure_file(output: target + '-config-devices.h',
   1659                                                configuration: config_devices_data)}
   1660    config_target += config_devices
   1661    config_all_devices += config_devices
   1662  endif
   1663  config_target_mak += {target: config_target}
   1664endforeach
   1665target_dirs = actual_target_dirs
   1666
   1667# This configuration is used to build files that are shared by
   1668# multiple binaries, and then extracted out of the "common"
   1669# static_library target.
   1670#
   1671# We do not use all_sources()/all_dependencies(), because it would
   1672# build literally all source files, including devices only used by
   1673# targets that are not built for this compilation.  The CONFIG_ALL
   1674# pseudo symbol replaces it.
   1675
   1676config_all += config_all_devices
   1677config_all += config_host
   1678config_all += config_all_disas
   1679config_all += {
   1680  'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
   1681  'CONFIG_SOFTMMU': have_system,
   1682  'CONFIG_USER_ONLY': have_user,
   1683  'CONFIG_ALL': true,
   1684}
   1685
   1686##############
   1687# Submodules #
   1688##############
   1689
   1690capstone = not_found
   1691capstone_opt = get_option('capstone')
   1692if capstone_opt in ['enabled', 'auto', 'system']
   1693  have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
   1694  capstone = dependency('capstone', version: '>=4.0',
   1695                        kwargs: static_kwargs, method: 'pkg-config',
   1696                        required: capstone_opt == 'system' or
   1697                                  capstone_opt == 'enabled' and not have_internal)
   1698
   1699  # Some versions of capstone have broken pkg-config file
   1700  # that reports a wrong -I path, causing the #include to
   1701  # fail later. If the system has such a broken version
   1702  # do not use it.
   1703  if capstone.found() and not cc.compiles('#include <capstone.h>',
   1704                                          dependencies: [capstone])
   1705    capstone = not_found
   1706    if capstone_opt == 'system'
   1707      error('system capstone requested, it does not appear to work')
   1708    endif
   1709  endif
   1710
   1711  if capstone.found()
   1712    capstone_opt = 'system'
   1713  elif have_internal
   1714    capstone_opt = 'internal'
   1715  else
   1716    capstone_opt = 'disabled'
   1717  endif
   1718endif
   1719if capstone_opt == 'internal'
   1720  capstone_data = configuration_data()
   1721  capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
   1722
   1723  capstone_files = files(
   1724    'capstone/cs.c',
   1725    'capstone/MCInst.c',
   1726    'capstone/MCInstrDesc.c',
   1727    'capstone/MCRegisterInfo.c',
   1728    'capstone/SStream.c',
   1729    'capstone/utils.c'
   1730  )
   1731
   1732  if 'CONFIG_ARM_DIS' in config_all_disas
   1733    capstone_data.set('CAPSTONE_HAS_ARM', '1')
   1734    capstone_files += files(
   1735      'capstone/arch/ARM/ARMDisassembler.c',
   1736      'capstone/arch/ARM/ARMInstPrinter.c',
   1737      'capstone/arch/ARM/ARMMapping.c',
   1738      'capstone/arch/ARM/ARMModule.c'
   1739    )
   1740  endif
   1741
   1742  # FIXME: This config entry currently depends on a c++ compiler.
   1743  # Which is needed for building libvixl, but not for capstone.
   1744  if 'CONFIG_ARM_A64_DIS' in config_all_disas
   1745    capstone_data.set('CAPSTONE_HAS_ARM64', '1')
   1746    capstone_files += files(
   1747      'capstone/arch/AArch64/AArch64BaseInfo.c',
   1748      'capstone/arch/AArch64/AArch64Disassembler.c',
   1749      'capstone/arch/AArch64/AArch64InstPrinter.c',
   1750      'capstone/arch/AArch64/AArch64Mapping.c',
   1751      'capstone/arch/AArch64/AArch64Module.c'
   1752    )
   1753  endif
   1754
   1755  if 'CONFIG_PPC_DIS' in config_all_disas
   1756    capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
   1757    capstone_files += files(
   1758      'capstone/arch/PowerPC/PPCDisassembler.c',
   1759      'capstone/arch/PowerPC/PPCInstPrinter.c',
   1760      'capstone/arch/PowerPC/PPCMapping.c',
   1761      'capstone/arch/PowerPC/PPCModule.c'
   1762    )
   1763  endif
   1764
   1765  if 'CONFIG_S390_DIS' in config_all_disas
   1766    capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
   1767    capstone_files += files(
   1768      'capstone/arch/SystemZ/SystemZDisassembler.c',
   1769      'capstone/arch/SystemZ/SystemZInstPrinter.c',
   1770      'capstone/arch/SystemZ/SystemZMapping.c',
   1771      'capstone/arch/SystemZ/SystemZModule.c',
   1772      'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
   1773    )
   1774  endif
   1775
   1776  if 'CONFIG_I386_DIS' in config_all_disas
   1777    capstone_data.set('CAPSTONE_HAS_X86', 1)
   1778    capstone_files += files(
   1779      'capstone/arch/X86/X86Disassembler.c',
   1780      'capstone/arch/X86/X86DisassemblerDecoder.c',
   1781      'capstone/arch/X86/X86ATTInstPrinter.c',
   1782      'capstone/arch/X86/X86IntelInstPrinter.c',
   1783      'capstone/arch/X86/X86InstPrinterCommon.c',
   1784      'capstone/arch/X86/X86Mapping.c',
   1785      'capstone/arch/X86/X86Module.c'
   1786    )
   1787  endif
   1788
   1789  configure_file(output: 'capstone-defs.h', configuration: capstone_data)
   1790
   1791  capstone_cargs = [
   1792    # FIXME: There does not seem to be a way to completely replace the c_args
   1793    # that come from add_project_arguments() -- we can only add to them.
   1794    # So: disable all warnings with a big hammer.
   1795    '-Wno-error', '-w',
   1796
   1797    # Include all configuration defines via a header file, which will wind up
   1798    # as a dependency on the object file, and thus changes here will result
   1799    # in a rebuild.
   1800    '-include', 'capstone-defs.h'
   1801  ]
   1802
   1803  libcapstone = static_library('capstone',
   1804                               build_by_default: false,
   1805                               sources: capstone_files,
   1806                               c_args: capstone_cargs,
   1807                               include_directories: 'capstone/include')
   1808  capstone = declare_dependency(link_with: libcapstone,
   1809                                include_directories: 'capstone/include/capstone')
   1810endif
   1811
   1812slirp = not_found
   1813slirp_opt = 'disabled'
   1814if have_system
   1815  slirp_opt = get_option('slirp')
   1816  if slirp_opt in ['enabled', 'auto', 'system']
   1817    have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
   1818    slirp = dependency('slirp', kwargs: static_kwargs,
   1819                       method: 'pkg-config',
   1820                       required: slirp_opt == 'system' or
   1821                                 slirp_opt == 'enabled' and not have_internal)
   1822    if slirp.found()
   1823      slirp_opt = 'system'
   1824    elif have_internal
   1825      slirp_opt = 'internal'
   1826    else
   1827      slirp_opt = 'disabled'
   1828    endif
   1829  endif
   1830  if slirp_opt == 'internal'
   1831    slirp_deps = []
   1832    if targetos == 'windows'
   1833      slirp_deps = cc.find_library('iphlpapi')
   1834    elif targetos == 'darwin'
   1835      slirp_deps = cc.find_library('resolv')
   1836    endif
   1837    slirp_conf = configuration_data()
   1838    slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
   1839    slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
   1840    slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
   1841    slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
   1842    slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
   1843    slirp_files = [
   1844      'slirp/src/arp_table.c',
   1845      'slirp/src/bootp.c',
   1846      'slirp/src/cksum.c',
   1847      'slirp/src/dhcpv6.c',
   1848      'slirp/src/dnssearch.c',
   1849      'slirp/src/if.c',
   1850      'slirp/src/ip6_icmp.c',
   1851      'slirp/src/ip6_input.c',
   1852      'slirp/src/ip6_output.c',
   1853      'slirp/src/ip_icmp.c',
   1854      'slirp/src/ip_input.c',
   1855      'slirp/src/ip_output.c',
   1856      'slirp/src/mbuf.c',
   1857      'slirp/src/misc.c',
   1858      'slirp/src/ncsi.c',
   1859      'slirp/src/ndp_table.c',
   1860      'slirp/src/sbuf.c',
   1861      'slirp/src/slirp.c',
   1862      'slirp/src/socket.c',
   1863      'slirp/src/state.c',
   1864      'slirp/src/stream.c',
   1865      'slirp/src/tcp_input.c',
   1866      'slirp/src/tcp_output.c',
   1867      'slirp/src/tcp_subr.c',
   1868      'slirp/src/tcp_timer.c',
   1869      'slirp/src/tftp.c',
   1870      'slirp/src/udp.c',
   1871      'slirp/src/udp6.c',
   1872      'slirp/src/util.c',
   1873      'slirp/src/version.c',
   1874      'slirp/src/vmstate.c',
   1875    ]
   1876
   1877    configure_file(
   1878      input : 'slirp/src/libslirp-version.h.in',
   1879      output : 'libslirp-version.h',
   1880      configuration: slirp_conf)
   1881
   1882    slirp_inc = include_directories('slirp', 'slirp/src')
   1883    libslirp = static_library('slirp',
   1884                              build_by_default: false,
   1885                              sources: slirp_files,
   1886                              c_args: slirp_cargs,
   1887                              include_directories: slirp_inc)
   1888    slirp = declare_dependency(link_with: libslirp,
   1889                               dependencies: slirp_deps,
   1890                               include_directories: slirp_inc)
   1891  endif
   1892endif
   1893
   1894# For CFI, we need to compile slirp as a static library together with qemu.
   1895# This is because we register slirp functions as callbacks for QEMU Timers.
   1896# When using a system-wide shared libslirp, the type information for the
   1897# callback is missing and the timer call produces a false positive with CFI.
   1898#
   1899# Now that slirp_opt has been defined, check if the selected slirp is compatible
   1900# with control-flow integrity.
   1901if get_option('cfi') and slirp_opt == 'system'
   1902  error('Control-Flow Integrity is not compatible with system-wide slirp.' \
   1903         + ' Please configure with --enable-slirp=git')
   1904endif
   1905
   1906fdt = not_found
   1907fdt_opt = get_option('fdt')
   1908if have_system
   1909  if fdt_opt in ['enabled', 'auto', 'system']
   1910    have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
   1911    fdt = cc.find_library('fdt', kwargs: static_kwargs,
   1912                          required: fdt_opt == 'system' or
   1913                                    fdt_opt == 'enabled' and not have_internal)
   1914    if fdt.found() and cc.links('''
   1915       #include <libfdt.h>
   1916       #include <libfdt_env.h>
   1917       int main(void) { fdt_check_full(NULL, 0); return 0; }''',
   1918         dependencies: fdt)
   1919      fdt_opt = 'system'
   1920    elif fdt_opt == 'system'
   1921       error('system libfdt requested, but it is too old (1.5.1 or newer required)')
   1922    elif have_internal
   1923      fdt_opt = 'internal'
   1924    else
   1925      fdt_opt = 'disabled'
   1926      fdt = not_found
   1927    endif
   1928  endif
   1929  if fdt_opt == 'internal'
   1930    fdt_files = files(
   1931      'dtc/libfdt/fdt.c',
   1932      'dtc/libfdt/fdt_ro.c',
   1933      'dtc/libfdt/fdt_wip.c',
   1934      'dtc/libfdt/fdt_sw.c',
   1935      'dtc/libfdt/fdt_rw.c',
   1936      'dtc/libfdt/fdt_strerror.c',
   1937      'dtc/libfdt/fdt_empty_tree.c',
   1938      'dtc/libfdt/fdt_addresses.c',
   1939      'dtc/libfdt/fdt_overlay.c',
   1940      'dtc/libfdt/fdt_check.c',
   1941    )
   1942
   1943    fdt_inc = include_directories('dtc/libfdt')
   1944    libfdt = static_library('fdt',
   1945                            build_by_default: false,
   1946                            sources: fdt_files,
   1947                            include_directories: fdt_inc)
   1948    fdt = declare_dependency(link_with: libfdt,
   1949                             include_directories: fdt_inc)
   1950  endif
   1951endif
   1952if not fdt.found() and fdt_required.length() > 0
   1953  error('fdt not available but required by targets ' + ', '.join(fdt_required))
   1954endif
   1955
   1956config_host_data.set('CONFIG_CAPSTONE', capstone.found())
   1957config_host_data.set('CONFIG_FDT', fdt.found())
   1958config_host_data.set('CONFIG_SLIRP', slirp.found())
   1959
   1960#####################
   1961# Generated sources #
   1962#####################
   1963
   1964genh += configure_file(output: 'config-host.h', configuration: config_host_data)
   1965
   1966hxtool = find_program('scripts/hxtool')
   1967shaderinclude = find_program('scripts/shaderinclude.pl')
   1968qapi_gen = find_program('scripts/qapi-gen.py')
   1969qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
   1970                     meson.current_source_dir() / 'scripts/qapi/commands.py',
   1971                     meson.current_source_dir() / 'scripts/qapi/common.py',
   1972                     meson.current_source_dir() / 'scripts/qapi/error.py',
   1973                     meson.current_source_dir() / 'scripts/qapi/events.py',
   1974                     meson.current_source_dir() / 'scripts/qapi/expr.py',
   1975                     meson.current_source_dir() / 'scripts/qapi/gen.py',
   1976                     meson.current_source_dir() / 'scripts/qapi/introspect.py',
   1977                     meson.current_source_dir() / 'scripts/qapi/parser.py',
   1978                     meson.current_source_dir() / 'scripts/qapi/schema.py',
   1979                     meson.current_source_dir() / 'scripts/qapi/source.py',
   1980                     meson.current_source_dir() / 'scripts/qapi/types.py',
   1981                     meson.current_source_dir() / 'scripts/qapi/visit.py',
   1982                     meson.current_source_dir() / 'scripts/qapi/common.py',
   1983                     meson.current_source_dir() / 'scripts/qapi-gen.py'
   1984]
   1985
   1986tracetool = [
   1987  python, files('scripts/tracetool.py'),
   1988   '--backend=' + config_host['TRACE_BACKENDS']
   1989]
   1990tracetool_depends = files(
   1991  'scripts/tracetool/backend/log.py',
   1992  'scripts/tracetool/backend/__init__.py',
   1993  'scripts/tracetool/backend/dtrace.py',
   1994  'scripts/tracetool/backend/ftrace.py',
   1995  'scripts/tracetool/backend/simple.py',
   1996  'scripts/tracetool/backend/syslog.py',
   1997  'scripts/tracetool/backend/ust.py',
   1998  'scripts/tracetool/format/tcg_h.py',
   1999  'scripts/tracetool/format/ust_events_c.py',
   2000  'scripts/tracetool/format/ust_events_h.py',
   2001  'scripts/tracetool/format/__init__.py',
   2002  'scripts/tracetool/format/d.py',
   2003  'scripts/tracetool/format/tcg_helper_c.py',
   2004  'scripts/tracetool/format/simpletrace_stap.py',
   2005  'scripts/tracetool/format/c.py',
   2006  'scripts/tracetool/format/h.py',
   2007  'scripts/tracetool/format/tcg_helper_h.py',
   2008  'scripts/tracetool/format/log_stap.py',
   2009  'scripts/tracetool/format/stap.py',
   2010  'scripts/tracetool/format/tcg_helper_wrapper_h.py',
   2011  'scripts/tracetool/__init__.py',
   2012  'scripts/tracetool/transform.py',
   2013  'scripts/tracetool/vcpu.py'
   2014)
   2015
   2016qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
   2017                    meson.current_source_dir(),
   2018                    config_host['PKGVERSION'], meson.project_version()]
   2019qemu_version = custom_target('qemu-version.h',
   2020                             output: 'qemu-version.h',
   2021                             command: qemu_version_cmd,
   2022                             capture: true,
   2023                             build_by_default: true,
   2024                             build_always_stale: true)
   2025genh += qemu_version
   2026
   2027hxdep = []
   2028hx_headers = [
   2029  ['qemu-options.hx', 'qemu-options.def'],
   2030  ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
   2031]
   2032if have_system
   2033  hx_headers += [
   2034    ['hmp-commands.hx', 'hmp-commands.h'],
   2035    ['hmp-commands-info.hx', 'hmp-commands-info.h'],
   2036  ]
   2037endif
   2038foreach d : hx_headers
   2039  hxdep += custom_target(d[1],
   2040                input: files(d[0]),
   2041                output: d[1],
   2042                capture: true,
   2043                build_by_default: true, # to be removed when added to a target
   2044                command: [hxtool, '-h', '@INPUT0@'])
   2045endforeach
   2046genh += hxdep
   2047
   2048###################
   2049# Collect sources #
   2050###################
   2051
   2052authz_ss = ss.source_set()
   2053blockdev_ss = ss.source_set()
   2054block_ss = ss.source_set()
   2055bsd_user_ss = ss.source_set()
   2056chardev_ss = ss.source_set()
   2057common_ss = ss.source_set()
   2058crypto_ss = ss.source_set()
   2059io_ss = ss.source_set()
   2060linux_user_ss = ss.source_set()
   2061qmp_ss = ss.source_set()
   2062qom_ss = ss.source_set()
   2063softmmu_ss = ss.source_set()
   2064specific_fuzz_ss = ss.source_set()
   2065specific_ss = ss.source_set()
   2066stub_ss = ss.source_set()
   2067trace_ss = ss.source_set()
   2068user_ss = ss.source_set()
   2069util_ss = ss.source_set()
   2070
   2071# accel modules
   2072qtest_module_ss = ss.source_set()
   2073tcg_module_ss = ss.source_set()
   2074
   2075modules = {}
   2076target_modules = {}
   2077hw_arch = {}
   2078target_arch = {}
   2079target_softmmu_arch = {}
   2080target_user_arch = {}
   2081
   2082###############
   2083# Trace files #
   2084###############
   2085
   2086# TODO: add each directory to the subdirs from its own meson.build, once
   2087# we have those
   2088trace_events_subdirs = [
   2089  'crypto',
   2090  'qapi',
   2091  'qom',
   2092  'monitor',
   2093  'util',
   2094]
   2095if have_user
   2096  trace_events_subdirs += [ 'linux-user' ]
   2097endif
   2098if have_block
   2099  trace_events_subdirs += [
   2100    'authz',
   2101    'block',
   2102    'io',
   2103    'nbd',
   2104    'scsi',
   2105  ]
   2106endif
   2107if have_system
   2108  trace_events_subdirs += [
   2109    'accel/kvm',
   2110    'audio',
   2111    'backends',
   2112    'backends/tpm',
   2113    'chardev',
   2114    'ebpf',
   2115    'hw/9pfs',
   2116    'hw/acpi',
   2117    'hw/adc',
   2118    'hw/alpha',
   2119    'hw/arm',
   2120    'hw/audio',
   2121    'hw/block',
   2122    'hw/block/dataplane',
   2123    'hw/char',
   2124    'hw/display',
   2125    'hw/dma',
   2126    'hw/hppa',
   2127    'hw/hyperv',
   2128    'hw/i2c',
   2129    'hw/i386',
   2130    'hw/i386/xen',
   2131    'hw/ide',
   2132    'hw/input',
   2133    'hw/intc',
   2134    'hw/isa',
   2135    'hw/mem',
   2136    'hw/mips',
   2137    'hw/misc',
   2138    'hw/misc/macio',
   2139    'hw/net',
   2140    'hw/net/can',
   2141    'hw/nubus',
   2142    'hw/nvme',
   2143    'hw/nvram',
   2144    'hw/pci',
   2145    'hw/pci-host',
   2146    'hw/ppc',
   2147    'hw/rdma',
   2148    'hw/rdma/vmw',
   2149    'hw/rtc',
   2150    'hw/s390x',
   2151    'hw/scsi',
   2152    'hw/sd',
   2153    'hw/sparc',
   2154    'hw/sparc64',
   2155    'hw/ssi',
   2156    'hw/timer',
   2157    'hw/tpm',
   2158    'hw/usb',
   2159    'hw/vfio',
   2160    'hw/virtio',
   2161    'hw/watchdog',
   2162    'hw/xen',
   2163    'hw/gpio',
   2164    'migration',
   2165    'net',
   2166    'softmmu',
   2167    'ui',
   2168    'hw/remote',
   2169  ]
   2170endif
   2171if have_system or have_user
   2172  trace_events_subdirs += [
   2173    'accel/tcg',
   2174    'hw/core',
   2175    'target/arm',
   2176    'target/arm/hvf',
   2177    'target/hppa',
   2178    'target/i386',
   2179    'target/i386/kvm',
   2180    'target/mips/tcg',
   2181    'target/ppc',
   2182    'target/riscv',
   2183    'target/s390x',
   2184    'target/s390x/kvm',
   2185    'target/sparc',
   2186  ]
   2187endif
   2188
   2189vhost_user = not_found
   2190if 'CONFIG_VHOST_USER' in config_host
   2191  libvhost_user = subproject('libvhost-user')
   2192  vhost_user = libvhost_user.get_variable('vhost_user_dep')
   2193endif
   2194
   2195subdir('qapi')
   2196subdir('qobject')
   2197subdir('stubs')
   2198subdir('trace')
   2199subdir('util')
   2200subdir('qom')
   2201subdir('authz')
   2202subdir('crypto')
   2203subdir('ui')
   2204
   2205
   2206if enable_modules
   2207  libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
   2208  modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
   2209endif
   2210
   2211stub_ss = stub_ss.apply(config_all, strict: false)
   2212
   2213util_ss.add_all(trace_ss)
   2214util_ss = util_ss.apply(config_all, strict: false)
   2215libqemuutil = static_library('qemuutil',
   2216                             sources: util_ss.sources() + stub_ss.sources() + genh,
   2217                             dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
   2218qemuutil = declare_dependency(link_with: libqemuutil,
   2219                              sources: genh + version_res)
   2220
   2221if have_system or have_user
   2222  decodetree = generator(find_program('scripts/decodetree.py'),
   2223                         output: 'decode-@BASENAME@.c.inc',
   2224                         arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
   2225  subdir('libdecnumber')
   2226  subdir('target')
   2227endif
   2228
   2229subdir('audio')
   2230subdir('io')
   2231subdir('chardev')
   2232subdir('fsdev')
   2233subdir('dump')
   2234
   2235if have_block
   2236  block_ss.add(files(
   2237    'block.c',
   2238    'blockjob.c',
   2239    'job.c',
   2240    'qemu-io-cmds.c',
   2241  ))
   2242  block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
   2243
   2244  subdir('nbd')
   2245  subdir('scsi')
   2246  subdir('block')
   2247
   2248  blockdev_ss.add(files(
   2249    'blockdev.c',
   2250    'blockdev-nbd.c',
   2251    'iothread.c',
   2252    'job-qmp.c',
   2253  ), gnutls)
   2254
   2255  # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
   2256  # os-win32.c does not
   2257  blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
   2258  softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
   2259endif
   2260
   2261common_ss.add(files('cpus-common.c'))
   2262
   2263subdir('softmmu')
   2264
   2265common_ss.add(capstone)
   2266specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
   2267
   2268# Work around a gcc bug/misfeature wherein constant propagation looks
   2269# through an alias:
   2270#   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
   2271# to guess that a const variable is always zero.  Without lto, this is
   2272# impossible, as the alias is restricted to page-vary-common.c.  Indeed,
   2273# without lto, not even the alias is required -- we simply use different
   2274# declarations in different compilation units.
   2275pagevary = files('page-vary-common.c')
   2276if get_option('b_lto')
   2277  pagevary_flags = ['-fno-lto']
   2278  if get_option('cfi')
   2279    pagevary_flags += '-fno-sanitize=cfi-icall'
   2280  endif
   2281  pagevary = static_library('page-vary-common', sources: pagevary,
   2282                            c_args: pagevary_flags)
   2283  pagevary = declare_dependency(link_with: pagevary)
   2284endif
   2285common_ss.add(pagevary)
   2286specific_ss.add(files('page-vary.c'))
   2287
   2288subdir('backends')
   2289subdir('disas')
   2290subdir('migration')
   2291subdir('monitor')
   2292subdir('net')
   2293subdir('replay')
   2294subdir('semihosting')
   2295subdir('hw')
   2296subdir('tcg')
   2297subdir('fpu')
   2298subdir('accel')
   2299subdir('plugins')
   2300subdir('bsd-user')
   2301subdir('linux-user')
   2302subdir('ebpf')
   2303
   2304common_ss.add(libbpf)
   2305
   2306bsd_user_ss.add(files('gdbstub.c'))
   2307specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
   2308
   2309linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
   2310specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
   2311
   2312# needed for fuzzing binaries
   2313subdir('tests/qtest/libqos')
   2314subdir('tests/qtest/fuzz')
   2315
   2316# accel modules
   2317tcg_real_module_ss = ss.source_set()
   2318tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
   2319specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
   2320target_modules += { 'accel' : { 'qtest': qtest_module_ss,
   2321                                'tcg': tcg_real_module_ss }}
   2322
   2323########################
   2324# Library dependencies #
   2325########################
   2326
   2327modinfo_collect = find_program('scripts/modinfo-collect.py')
   2328modinfo_generate = find_program('scripts/modinfo-generate.py')
   2329modinfo_files = []
   2330
   2331block_mods = []
   2332softmmu_mods = []
   2333foreach d, list : modules
   2334  foreach m, module_ss : list
   2335    if enable_modules and targetos != 'windows'
   2336      module_ss = module_ss.apply(config_all, strict: false)
   2337      sl = static_library(d + '-' + m, [genh, module_ss.sources()],
   2338                          dependencies: [modulecommon, module_ss.dependencies()], pic: true)
   2339      if d == 'block'
   2340        block_mods += sl
   2341      else
   2342        softmmu_mods += sl
   2343      endif
   2344      if module_ss.sources() != []
   2345        # FIXME: Should use sl.extract_all_objects(recursive: true) as
   2346        # input. Sources can be used multiple times but objects are
   2347        # unique when it comes to lookup in compile_commands.json.
   2348        # Depnds on a mesion version with
   2349        # https://github.com/mesonbuild/meson/pull/8900
   2350        modinfo_files += custom_target(d + '-' + m + '.modinfo',
   2351                                       output: d + '-' + m + '.modinfo',
   2352                                       input: module_ss.sources() + genh,
   2353                                       capture: true,
   2354                                       command: [modinfo_collect, module_ss.sources()])
   2355      endif
   2356    else
   2357      if d == 'block'
   2358        block_ss.add_all(module_ss)
   2359      else
   2360        softmmu_ss.add_all(module_ss)
   2361      endif
   2362    endif
   2363  endforeach
   2364endforeach
   2365
   2366foreach d, list : target_modules
   2367  foreach m, module_ss : list
   2368    if enable_modules and targetos != 'windows'
   2369      foreach target : target_dirs
   2370        if target.endswith('-softmmu')
   2371          config_target = config_target_mak[target]
   2372          config_target += config_host
   2373          target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
   2374          c_args = ['-DNEED_CPU_H',
   2375                    '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
   2376                    '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
   2377          target_module_ss = module_ss.apply(config_target, strict: false)
   2378          if target_module_ss.sources() != []
   2379            module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
   2380            sl = static_library(module_name,
   2381                                [genh, target_module_ss.sources()],
   2382                                dependencies: [modulecommon, target_module_ss.dependencies()],
   2383                                include_directories: target_inc,
   2384                                c_args: c_args,
   2385                                pic: true)
   2386            softmmu_mods += sl
   2387            # FIXME: Should use sl.extract_all_objects(recursive: true) too.
   2388            modinfo_files += custom_target(module_name + '.modinfo',
   2389                                           output: module_name + '.modinfo',
   2390                                           input: target_module_ss.sources() + genh,
   2391                                           capture: true,
   2392                                           command: [modinfo_collect, '--target', target, target_module_ss.sources()])
   2393          endif
   2394        endif
   2395      endforeach
   2396    else
   2397      specific_ss.add_all(module_ss)
   2398    endif
   2399  endforeach
   2400endforeach
   2401
   2402if enable_modules
   2403  modinfo_src = custom_target('modinfo.c',
   2404                              output: 'modinfo.c',
   2405                              input: modinfo_files,
   2406                              command: [modinfo_generate, '@INPUT@'],
   2407                              capture: true)
   2408  modinfo_lib = static_library('modinfo', modinfo_src)
   2409  modinfo_dep = declare_dependency(link_whole: modinfo_lib)
   2410  softmmu_ss.add(modinfo_dep)
   2411endif
   2412
   2413nm = find_program('nm')
   2414undefsym = find_program('scripts/undefsym.py')
   2415block_syms = custom_target('block.syms', output: 'block.syms',
   2416                             input: [libqemuutil, block_mods],
   2417                             capture: true,
   2418                             command: [undefsym, nm, '@INPUT@'])
   2419qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
   2420                             input: [libqemuutil, softmmu_mods],
   2421                             capture: true,
   2422                             command: [undefsym, nm, '@INPUT@'])
   2423
   2424qom_ss = qom_ss.apply(config_host, strict: false)
   2425libqom = static_library('qom', qom_ss.sources() + genh,
   2426                        dependencies: [qom_ss.dependencies()],
   2427                        name_suffix: 'fa')
   2428
   2429qom = declare_dependency(link_whole: libqom)
   2430
   2431authz_ss = authz_ss.apply(config_host, strict: false)
   2432libauthz = static_library('authz', authz_ss.sources() + genh,
   2433                          dependencies: [authz_ss.dependencies()],
   2434                          name_suffix: 'fa',
   2435                          build_by_default: false)
   2436
   2437authz = declare_dependency(link_whole: libauthz,
   2438                           dependencies: qom)
   2439
   2440crypto_ss = crypto_ss.apply(config_host, strict: false)
   2441libcrypto = static_library('crypto', crypto_ss.sources() + genh,
   2442                           dependencies: [crypto_ss.dependencies()],
   2443                           name_suffix: 'fa',
   2444                           build_by_default: false)
   2445
   2446crypto = declare_dependency(link_whole: libcrypto,
   2447                            dependencies: [authz, qom])
   2448
   2449io_ss = io_ss.apply(config_host, strict: false)
   2450libio = static_library('io', io_ss.sources() + genh,
   2451                       dependencies: [io_ss.dependencies()],
   2452                       link_with: libqemuutil,
   2453                       name_suffix: 'fa',
   2454                       build_by_default: false)
   2455
   2456io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
   2457
   2458libmigration = static_library('migration', sources: migration_files + genh,
   2459                              name_suffix: 'fa',
   2460                              build_by_default: false)
   2461migration = declare_dependency(link_with: libmigration,
   2462                               dependencies: [zlib, qom, io])
   2463softmmu_ss.add(migration)
   2464
   2465block_ss = block_ss.apply(config_host, strict: false)
   2466libblock = static_library('block', block_ss.sources() + genh,
   2467                          dependencies: block_ss.dependencies(),
   2468                          link_depends: block_syms,
   2469                          name_suffix: 'fa',
   2470                          build_by_default: false)
   2471
   2472block = declare_dependency(link_whole: [libblock],
   2473                           link_args: '@block.syms',
   2474                           dependencies: [crypto, io])
   2475
   2476blockdev_ss = blockdev_ss.apply(config_host, strict: false)
   2477libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
   2478                             dependencies: blockdev_ss.dependencies(),
   2479                             name_suffix: 'fa',
   2480                             build_by_default: false)
   2481
   2482blockdev = declare_dependency(link_whole: [libblockdev],
   2483                              dependencies: [block])
   2484
   2485qmp_ss = qmp_ss.apply(config_host, strict: false)
   2486libqmp = static_library('qmp', qmp_ss.sources() + genh,
   2487                        dependencies: qmp_ss.dependencies(),
   2488                        name_suffix: 'fa',
   2489                        build_by_default: false)
   2490
   2491qmp = declare_dependency(link_whole: [libqmp])
   2492
   2493libchardev = static_library('chardev', chardev_ss.sources() + genh,
   2494                            name_suffix: 'fa',
   2495                            dependencies: [gnutls],
   2496                            build_by_default: false)
   2497
   2498chardev = declare_dependency(link_whole: libchardev)
   2499
   2500libhwcore = static_library('hwcore', sources: hwcore_files + genh,
   2501                           name_suffix: 'fa',
   2502                           build_by_default: false)
   2503hwcore = declare_dependency(link_whole: libhwcore)
   2504common_ss.add(hwcore)
   2505
   2506###########
   2507# Targets #
   2508###########
   2509
   2510foreach m : block_mods + softmmu_mods
   2511  shared_module(m.name(),
   2512                name_prefix: '',
   2513                link_whole: m,
   2514                install: true,
   2515                install_dir: qemu_moddir)
   2516endforeach
   2517
   2518softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
   2519common_ss.add(qom, qemuutil)
   2520
   2521common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
   2522common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
   2523
   2524common_all = common_ss.apply(config_all, strict: false)
   2525common_all = static_library('common',
   2526                            build_by_default: false,
   2527                            sources: common_all.sources() + genh,
   2528                            implicit_include_directories: false,
   2529                            dependencies: common_all.dependencies(),
   2530                            name_suffix: 'fa')
   2531
   2532feature_to_c = find_program('scripts/feature_to_c.sh')
   2533
   2534emulators = {}
   2535foreach target : target_dirs
   2536  config_target = config_target_mak[target]
   2537  target_name = config_target['TARGET_NAME']
   2538  arch = config_target['TARGET_BASE_ARCH']
   2539  arch_srcs = [config_target_h[target]]
   2540  arch_deps = []
   2541  c_args = ['-DNEED_CPU_H',
   2542            '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
   2543            '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
   2544  link_args = emulator_link_args
   2545
   2546  config_target += config_host
   2547  target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
   2548  if targetos == 'linux'
   2549    target_inc += include_directories('linux-headers', is_system: true)
   2550  endif
   2551  if target.endswith('-softmmu')
   2552    qemu_target_name = 'qemu-system-' + target_name
   2553    target_type='system'
   2554    t = target_softmmu_arch[arch].apply(config_target, strict: false)
   2555    arch_srcs += t.sources()
   2556    arch_deps += t.dependencies()
   2557
   2558    hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
   2559    hw = hw_arch[hw_dir].apply(config_target, strict: false)
   2560    arch_srcs += hw.sources()
   2561    arch_deps += hw.dependencies()
   2562
   2563    arch_srcs += config_devices_h[target]
   2564    link_args += ['@block.syms', '@qemu.syms']
   2565  else
   2566    abi = config_target['TARGET_ABI_DIR']
   2567    target_type='user'
   2568    qemu_target_name = 'qemu-' + target_name
   2569    if arch in target_user_arch
   2570      t = target_user_arch[arch].apply(config_target, strict: false)
   2571      arch_srcs += t.sources()
   2572      arch_deps += t.dependencies()
   2573    endif
   2574    if 'CONFIG_LINUX_USER' in config_target
   2575      base_dir = 'linux-user'
   2576      target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
   2577    endif
   2578    if 'CONFIG_BSD_USER' in config_target
   2579      base_dir = 'bsd-user'
   2580      target_inc += include_directories('bsd-user/' / targetos)
   2581      dir = base_dir / abi
   2582      arch_srcs += files(dir / 'target_arch_cpu.c')
   2583    endif
   2584    target_inc += include_directories(
   2585      base_dir,
   2586      base_dir / abi,
   2587    )
   2588    if 'CONFIG_LINUX_USER' in config_target
   2589      dir = base_dir / abi
   2590      arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
   2591      if config_target.has_key('TARGET_SYSTBL_ABI')
   2592        arch_srcs += \
   2593          syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
   2594                                             extra_args : config_target['TARGET_SYSTBL_ABI'])
   2595      endif
   2596    endif
   2597  endif
   2598
   2599  if 'TARGET_XML_FILES' in config_target
   2600    gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
   2601                                output: target + '-gdbstub-xml.c',
   2602                                input: files(config_target['TARGET_XML_FILES'].split()),
   2603                                command: [feature_to_c, '@INPUT@'],
   2604                                capture: true)
   2605    arch_srcs += gdbstub_xml
   2606  endif
   2607
   2608  t = target_arch[arch].apply(config_target, strict: false)
   2609  arch_srcs += t.sources()
   2610  arch_deps += t.dependencies()
   2611
   2612  target_common = common_ss.apply(config_target, strict: false)
   2613  objects = common_all.extract_objects(target_common.sources())
   2614  deps = target_common.dependencies()
   2615
   2616  target_specific = specific_ss.apply(config_target, strict: false)
   2617  arch_srcs += target_specific.sources()
   2618  arch_deps += target_specific.dependencies()
   2619
   2620  lib = static_library('qemu-' + target,
   2621                 sources: arch_srcs + genh,
   2622                 dependencies: arch_deps,
   2623                 objects: objects,
   2624                 include_directories: target_inc,
   2625                 c_args: c_args,
   2626                 build_by_default: false,
   2627                 name_suffix: 'fa')
   2628
   2629  if target.endswith('-softmmu')
   2630    execs = [{
   2631      'name': 'qemu-system-' + target_name,
   2632      'win_subsystem': 'console',
   2633      'sources': files('softmmu/main.c'),
   2634      'dependencies': []
   2635    }]
   2636    if targetos == 'windows' and (sdl.found() or gtk.found())
   2637      execs += [{
   2638        'name': 'qemu-system-' + target_name + 'w',
   2639        'win_subsystem': 'windows',
   2640        'sources': files('softmmu/main.c'),
   2641        'dependencies': []
   2642      }]
   2643    endif
   2644    if config_host.has_key('CONFIG_FUZZ')
   2645      specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
   2646      execs += [{
   2647        'name': 'qemu-fuzz-' + target_name,
   2648        'win_subsystem': 'console',
   2649        'sources': specific_fuzz.sources(),
   2650        'dependencies': specific_fuzz.dependencies(),
   2651      }]
   2652    endif
   2653  else
   2654    execs = [{
   2655      'name': 'qemu-' + target_name,
   2656      'win_subsystem': 'console',
   2657      'sources': [],
   2658      'dependencies': []
   2659    }]
   2660  endif
   2661  foreach exe: execs
   2662    exe_name = exe['name']
   2663    if targetos == 'darwin'
   2664      exe_name += '-unsigned'
   2665    endif
   2666
   2667    emulator = executable(exe_name, exe['sources'],
   2668               install: true,
   2669               c_args: c_args,
   2670               dependencies: arch_deps + deps + exe['dependencies'],
   2671               objects: lib.extract_all_objects(recursive: true),
   2672               link_language: link_language,
   2673               link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
   2674               link_args: link_args,
   2675               win_subsystem: exe['win_subsystem'])
   2676
   2677    if targetos == 'darwin'
   2678      icon = 'pc-bios/qemu.rsrc'
   2679      build_input = [emulator, files(icon)]
   2680      install_input = [
   2681        get_option('bindir') / exe_name,
   2682        meson.current_source_dir() / icon
   2683      ]
   2684      if 'CONFIG_HVF' in config_target
   2685        entitlements = 'accel/hvf/entitlements.plist'
   2686        build_input += files(entitlements)
   2687        install_input += meson.current_source_dir() / entitlements
   2688      endif
   2689
   2690      emulators += {exe['name'] : custom_target(exe['name'],
   2691                   input: build_input,
   2692                   output: exe['name'],
   2693                   command: [
   2694                     files('scripts/entitlement.sh'),
   2695                     '@OUTPUT@',
   2696                     '@INPUT@'
   2697                   ])
   2698      }
   2699
   2700      meson.add_install_script('scripts/entitlement.sh', '--install',
   2701                               get_option('bindir') / exe['name'],
   2702                               install_input)
   2703    else
   2704      emulators += {exe['name']: emulator}
   2705    endif
   2706
   2707    if 'CONFIG_TRACE_SYSTEMTAP' in config_host
   2708      foreach stp: [
   2709        {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
   2710        {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
   2711        {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
   2712        {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
   2713      ]
   2714        custom_target(exe['name'] + stp['ext'],
   2715                      input: trace_events_all,
   2716                      output: exe['name'] + stp['ext'],
   2717                      install: stp['install'],
   2718                      install_dir: get_option('datadir') / 'systemtap/tapset',
   2719                      command: [
   2720                        tracetool, '--group=all', '--format=' + stp['fmt'],
   2721                        '--binary=' + stp['bin'],
   2722                        '--target-name=' + target_name,
   2723                        '--target-type=' + target_type,
   2724                        '--probe-prefix=qemu.' + target_type + '.' + target_name,
   2725                        '@INPUT@', '@OUTPUT@'
   2726                      ],
   2727                      depend_files: tracetool_depends)
   2728      endforeach
   2729    endif
   2730  endforeach
   2731endforeach
   2732
   2733# Other build targets
   2734
   2735if 'CONFIG_PLUGIN' in config_host
   2736  install_headers('include/qemu/qemu-plugin.h')
   2737endif
   2738
   2739if 'CONFIG_GUEST_AGENT' in config_host
   2740  subdir('qga')
   2741elif get_option('guest_agent_msi').enabled()
   2742  error('Guest agent MSI requested, but the guest agent is not being built')
   2743endif
   2744
   2745# Don't build qemu-keymap if xkbcommon is not explicitly enabled
   2746# when we don't build tools or system
   2747if xkbcommon.found()
   2748  # used for the update-keymaps target, so include rules even if !have_tools
   2749  qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
   2750                           dependencies: [qemuutil, xkbcommon], install: have_tools)
   2751endif
   2752
   2753if have_tools
   2754  qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
   2755             dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
   2756  qemu_io = executable('qemu-io', files('qemu-io.c'),
   2757             dependencies: [block, qemuutil], install: true)
   2758  qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
   2759               dependencies: [blockdev, qemuutil, gnutls], install: true)
   2760
   2761  subdir('storage-daemon')
   2762  subdir('contrib/rdmacm-mux')
   2763  subdir('contrib/elf2dmp')
   2764
   2765  executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
   2766             dependencies: qemuutil,
   2767             install: true)
   2768
   2769  if 'CONFIG_VHOST_USER' in config_host
   2770    subdir('contrib/vhost-user-blk')
   2771    subdir('contrib/vhost-user-gpu')
   2772    subdir('contrib/vhost-user-input')
   2773    subdir('contrib/vhost-user-scsi')
   2774  endif
   2775
   2776  if targetos == 'linux'
   2777    executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
   2778               dependencies: [qemuutil, libcap_ng],
   2779               install: true,
   2780               install_dir: get_option('libexecdir'))
   2781
   2782    executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
   2783               dependencies: [authz, crypto, io, qom, qemuutil,
   2784                              libcap_ng, mpathpersist],
   2785               install: true)
   2786  endif
   2787
   2788  if have_ivshmem
   2789    subdir('contrib/ivshmem-client')
   2790    subdir('contrib/ivshmem-server')
   2791  endif
   2792endif
   2793
   2794subdir('scripts')
   2795subdir('tools')
   2796subdir('pc-bios')
   2797subdir('docs')
   2798subdir('tests')
   2799if gtk.found()
   2800  subdir('po')
   2801endif
   2802
   2803if host_machine.system() == 'windows'
   2804  nsis_cmd = [
   2805    find_program('scripts/nsis.py'),
   2806    '@OUTPUT@',
   2807    get_option('prefix'),
   2808    meson.current_source_dir(),
   2809    host_machine.cpu(),
   2810    '--',
   2811    '-DDISPLAYVERSION=' + meson.project_version(),
   2812  ]
   2813  if build_docs
   2814    nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
   2815  endif
   2816  if gtk.found()
   2817    nsis_cmd += '-DCONFIG_GTK=y'
   2818  endif
   2819
   2820  nsis = custom_target('nsis',
   2821                       output: 'qemu-setup-' + meson.project_version() + '.exe',
   2822                       input: files('qemu.nsi'),
   2823                       build_always_stale: true,
   2824                       command: nsis_cmd + ['@INPUT@'])
   2825  alias_target('installer', nsis)
   2826endif
   2827
   2828#########################
   2829# Configuration summary #
   2830#########################
   2831
   2832# Directories
   2833summary_info = {}
   2834summary_info += {'Install prefix':    get_option('prefix')}
   2835summary_info += {'BIOS directory':    qemu_datadir}
   2836summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
   2837summary_info += {'binary directory':  get_option('bindir')}
   2838summary_info += {'library directory': get_option('libdir')}
   2839summary_info += {'module directory':  qemu_moddir}
   2840summary_info += {'libexec directory': get_option('libexecdir')}
   2841summary_info += {'include directory': get_option('includedir')}
   2842summary_info += {'config directory':  get_option('sysconfdir')}
   2843if targetos != 'windows'
   2844  summary_info += {'local state directory': get_option('localstatedir')}
   2845  summary_info += {'Manual directory':      get_option('mandir')}
   2846else
   2847  summary_info += {'local state directory': 'queried at runtime'}
   2848endif
   2849summary_info += {'Doc directory':     get_option('docdir')}
   2850summary_info += {'Build directory':   meson.current_build_dir()}
   2851summary_info += {'Source path':       meson.current_source_dir()}
   2852summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
   2853summary(summary_info, bool_yn: true, section: 'Directories')
   2854
   2855# Host binaries
   2856summary_info = {}
   2857summary_info += {'git':               config_host['GIT']}
   2858summary_info += {'make':              config_host['MAKE']}
   2859summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
   2860summary_info += {'sphinx-build':      sphinx_build}
   2861if config_host.has_key('HAVE_GDB_BIN')
   2862  summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
   2863endif
   2864summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
   2865if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
   2866  summary_info += {'wixl':            wixl}
   2867endif
   2868if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
   2869  summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
   2870endif
   2871summary(summary_info, bool_yn: true, section: 'Host binaries')
   2872
   2873# Configurable features
   2874summary_info = {}
   2875summary_info += {'Documentation':     build_docs}
   2876summary_info += {'system-mode emulation': have_system}
   2877summary_info += {'user-mode emulation': have_user}
   2878summary_info += {'block layer':       have_block}
   2879summary_info += {'Install blobs':     get_option('install_blobs')}
   2880summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
   2881if config_host.has_key('CONFIG_MODULES')
   2882  summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
   2883endif
   2884summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
   2885if have_system
   2886  summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
   2887endif
   2888summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
   2889if config_host['TRACE_BACKENDS'].split().contains('simple')
   2890  summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
   2891endif
   2892summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
   2893summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
   2894summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
   2895summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
   2896summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
   2897summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
   2898summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
   2899summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
   2900summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
   2901summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
   2902summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
   2903summary(summary_info, bool_yn: true, section: 'Configurable features')
   2904
   2905# Compilation information
   2906summary_info = {}
   2907summary_info += {'host CPU':          cpu}
   2908summary_info += {'host endianness':   build_machine.endian()}
   2909summary_info += {'C compiler':        ' '.join(meson.get_compiler('c').cmd_array())}
   2910summary_info += {'Host C compiler':   ' '.join(meson.get_compiler('c', native: true).cmd_array())}
   2911if link_language == 'cpp'
   2912  summary_info += {'C++ compiler':    ' '.join(meson.get_compiler('cpp').cmd_array())}
   2913else
   2914  summary_info += {'C++ compiler':      false}
   2915endif
   2916if targetos == 'darwin'
   2917  summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
   2918endif
   2919if targetos == 'windows'
   2920  if 'WIN_SDK' in config_host
   2921    summary_info += {'Windows SDK':   config_host['WIN_SDK']}
   2922  endif
   2923endif
   2924summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
   2925                                               + ['-O' + get_option('optimization')]
   2926                                               + (get_option('debug') ? ['-g'] : []))}
   2927if link_language == 'cpp'
   2928  summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
   2929                                               + ['-O' + get_option('optimization')]
   2930                                               + (get_option('debug') ? ['-g'] : []))}
   2931endif
   2932link_args = get_option(link_language + '_link_args')
   2933if link_args.length() > 0
   2934  summary_info += {'LDFLAGS':         ' '.join(link_args)}
   2935endif
   2936summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
   2937summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
   2938summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
   2939summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
   2940summary_info += {'PIE':               get_option('b_pie')}
   2941summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
   2942summary_info += {'malloc trim support': has_malloc_trim}
   2943summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
   2944summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
   2945summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
   2946summary_info += {'memory allocator':  get_option('malloc')}
   2947summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
   2948summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
   2949summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
   2950summary_info += {'gcov':              get_option('b_coverage')}
   2951summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
   2952summary_info += {'CFI support':       get_option('cfi')}
   2953if get_option('cfi')
   2954  summary_info += {'CFI debug support': get_option('cfi_debug')}
   2955endif
   2956summary_info += {'strip binaries':    get_option('strip')}
   2957summary_info += {'sparse':            sparse}
   2958summary_info += {'mingw32 support':   targetos == 'windows'}
   2959
   2960# snarf the cross-compilation information for tests
   2961foreach target: target_dirs
   2962  tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
   2963  if fs.exists(tcg_mak)
   2964    config_cross_tcg = keyval.load(tcg_mak)
   2965    target = config_cross_tcg['TARGET_NAME']
   2966    compiler = ''
   2967    if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
   2968      summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
   2969                                          ' via ' + config_cross_tcg['DOCKER_IMAGE']}
   2970    elif 'CROSS_CC_GUEST' in config_cross_tcg
   2971      summary_info += {target + ' tests'
   2972                                : config_cross_tcg['CROSS_CC_GUEST'] }
   2973    endif
   2974   endif
   2975endforeach
   2976
   2977summary(summary_info, bool_yn: true, section: 'Compilation')
   2978
   2979# Targets and accelerators
   2980summary_info = {}
   2981if have_system
   2982  summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
   2983  summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
   2984  summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
   2985  summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
   2986  summary_info += {'NVMM support':      config_all.has_key('CONFIG_NVMM')}
   2987  summary_info += {'Xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
   2988  if config_host.has_key('CONFIG_XEN_BACKEND')
   2989    summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
   2990  endif
   2991endif
   2992summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
   2993if config_all.has_key('CONFIG_TCG')
   2994  if get_option('tcg_interpreter')
   2995    summary_info += {'TCG backend':   'TCI (TCG with bytecode interpreter, experimental and slow)'}
   2996  else
   2997    summary_info += {'TCG backend':   'native (@0@)'.format(cpu)}
   2998  endif
   2999  summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
   3000  summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
   3001endif
   3002summary_info += {'target list':       ' '.join(target_dirs)}
   3003if have_system
   3004  summary_info += {'default devices':   get_option('default_devices')}
   3005  summary_info += {'out of process emulation': multiprocess_allowed}
   3006endif
   3007summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
   3008
   3009# Block layer
   3010summary_info = {}
   3011summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
   3012summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
   3013if have_block
   3014  summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
   3015  summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
   3016  summary_info += {'Use block whitelist in tools': config_host.has_key('CONFIG_BDRV_WHITELIST_TOOLS')}
   3017  summary_info += {'VirtFS support':    have_virtfs}
   3018  summary_info += {'build virtiofs daemon': have_virtiofsd}
   3019  summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
   3020  summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
   3021  summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
   3022  summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
   3023  summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
   3024  summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
   3025  summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
   3026  summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
   3027  summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
   3028  summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
   3029  summary_info += {'FUSE exports':      fuse}
   3030endif
   3031summary(summary_info, bool_yn: true, section: 'Block layer support')
   3032
   3033# Crypto
   3034summary_info = {}
   3035summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
   3036summary_info += {'GNUTLS support':    gnutls}
   3037if gnutls.found()
   3038  summary_info += {'  GNUTLS crypto':   gnutls_crypto.found()}
   3039endif
   3040summary_info += {'libgcrypt':         gcrypt}
   3041summary_info += {'nettle':            nettle}
   3042if nettle.found()
   3043   summary_info += {'  XTS':             xts != 'private'}
   3044endif
   3045summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
   3046summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
   3047summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
   3048summary(summary_info, bool_yn: true, section: 'Crypto')
   3049
   3050# Libraries
   3051summary_info = {}
   3052if targetos == 'darwin'
   3053  summary_info += {'Cocoa support':   cocoa}
   3054endif
   3055summary_info += {'SDL support':       sdl}
   3056summary_info += {'SDL image support': sdl_image}
   3057summary_info += {'GTK support':       gtk}
   3058summary_info += {'pixman':            pixman}
   3059summary_info += {'VTE support':       vte}
   3060summary_info += {'slirp support':     slirp_opt == 'internal' ? slirp_opt : slirp}
   3061summary_info += {'libtasn1':          tasn1}
   3062summary_info += {'PAM':               pam}
   3063summary_info += {'iconv support':     iconv}
   3064summary_info += {'curses support':    curses}
   3065summary_info += {'virgl support':     virgl}
   3066summary_info += {'curl support':      curl}
   3067summary_info += {'Multipath support': mpathpersist}
   3068summary_info += {'VNC support':       vnc}
   3069if vnc.found()
   3070  summary_info += {'VNC SASL support':  sasl}
   3071  summary_info += {'VNC JPEG support':  jpeg}
   3072  summary_info += {'VNC PNG support':   png}
   3073endif
   3074summary_info += {'brlapi support':    brlapi}
   3075summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
   3076summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
   3077summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
   3078summary_info += {'Linux io_uring support': linux_io_uring}
   3079summary_info += {'ATTR/XATTR support': libattr}
   3080summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
   3081summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
   3082summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
   3083summary_info += {'libcap-ng support': libcap_ng}
   3084summary_info += {'bpf support':       libbpf}
   3085# TODO: add back protocol and server version
   3086summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
   3087summary_info += {'rbd support':       rbd}
   3088summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
   3089summary_info += {'smartcard support': cacard}
   3090summary_info += {'U2F support':       u2f}
   3091summary_info += {'libusb':            libusb}
   3092summary_info += {'usb net redir':     usbredir}
   3093summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
   3094summary_info += {'GBM':               gbm}
   3095summary_info += {'libiscsi support':  libiscsi}
   3096summary_info += {'libnfs support':    libnfs}
   3097if targetos == 'windows'
   3098  if config_host.has_key('CONFIG_GUEST_AGENT')
   3099    summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
   3100    summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
   3101  endif
   3102endif
   3103summary_info += {'seccomp support':   seccomp}
   3104summary_info += {'GlusterFS support': glusterfs}
   3105summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
   3106summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
   3107summary_info += {'lzo support':       lzo}
   3108summary_info += {'snappy support':    snappy}
   3109summary_info += {'bzip2 support':     libbzip2}
   3110summary_info += {'lzfse support':     liblzfse}
   3111summary_info += {'zstd support':      zstd}
   3112summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
   3113summary_info += {'libxml2':           libxml2}
   3114summary_info += {'capstone':          capstone_opt == 'internal' ? capstone_opt : capstone}
   3115summary_info += {'libpmem support':   libpmem}
   3116summary_info += {'libdaxctl support': libdaxctl}
   3117summary_info += {'libudev':           libudev}
   3118# Dummy dependency, keep .found()
   3119summary_info += {'FUSE lseek':        fuse_lseek.found()}
   3120summary(summary_info, bool_yn: true, section: 'Dependencies')
   3121
   3122if not supported_cpus.contains(cpu)
   3123  message()
   3124  warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
   3125  message()
   3126  message('CPU host architecture ' + cpu + ' support is not currently maintained.')
   3127  message('The QEMU project intends to remove support for this host CPU in')
   3128  message('a future release if nobody volunteers to maintain it and to')
   3129  message('provide a build host for our continuous integration setup.')
   3130  message('configure has succeeded and you can continue to build, but')
   3131  message('if you care about QEMU on this platform you should contact')
   3132  message('us upstream at qemu-devel@nongnu.org.')
   3133endif
   3134
   3135if not supported_oses.contains(targetos)
   3136  message()
   3137  warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
   3138  message()
   3139  message('Host OS ' + targetos + 'support is not currently maintained.')
   3140  message('The QEMU project intends to remove support for this host OS in')
   3141  message('a future release if nobody volunteers to maintain it and to')
   3142  message('provide a build host for our continuous integration setup.')
   3143  message('configure has succeeded and you can continue to build, but')
   3144  message('if you care about QEMU on this platform you should contact')
   3145  message('us upstream at qemu-devel@nongnu.org.')
   3146endif