xref: /openbmc/qemu/meson.build (revision 3b9bd3f4)
1project('qemu', ['c'], meson_version: '>=0.55.0',
2        default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11', 'b_colorout=auto'] +
3                         (meson.version().version_compare('>=0.56.0') ? [ 'b_staticpic=false' ] : []),
4        version: run_command('head', meson.source_root() / 'VERSION').stdout().strip())
5
6not_found = dependency('', required: false)
7if meson.version().version_compare('>=0.56.0')
8  keyval = import('keyval')
9else
10  keyval = import('unstable-keyval')
11endif
12ss = import('sourceset')
13fs = import('fs')
14
15sh = find_program('sh')
16cc = meson.get_compiler('c')
17config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
18enable_modules = 'CONFIG_MODULES' in config_host
19enable_static = 'CONFIG_STATIC' in config_host
20
21# Temporary directory used for files created while
22# configure runs. Since it is in the build directory
23# we can safely blow away any previous version of it
24# (and we need not jump through hoops to try to delete
25# it when configure exits.)
26tmpdir = meson.current_build_dir() / 'meson-private/temp'
27
28if get_option('qemu_suffix').startswith('/')
29  error('qemu_suffix cannot start with a /')
30endif
31
32qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
33qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
34qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
35qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
36
37qemu_desktopdir = get_option('datadir') / 'applications'
38qemu_icondir = get_option('datadir') / 'icons'
39
40config_host_data = configuration_data()
41genh = []
42
43target_dirs = config_host['TARGET_DIRS'].split()
44have_user = false
45have_system = false
46foreach target : target_dirs
47  have_user = have_user or target.endswith('-user')
48  have_system = have_system or target.endswith('-softmmu')
49endforeach
50have_tools = 'CONFIG_TOOLS' in config_host
51have_block = have_system or have_tools
52
53python = import('python').find_installation()
54
55supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
56supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
57  'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
58
59cpu = host_machine.cpu_family()
60targetos = host_machine.system()
61
62if cpu in ['x86', 'x86_64']
63  kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
64elif cpu == 'aarch64'
65  kvm_targets = ['aarch64-softmmu']
66elif cpu == 's390x'
67  kvm_targets = ['s390x-softmmu']
68elif cpu in ['ppc', 'ppc64']
69  kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
70elif cpu in ['mips', 'mips64']
71  kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
72else
73  kvm_targets = []
74endif
75
76accelerator_targets = { 'CONFIG_KVM': kvm_targets }
77if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
78  # i368 emulator provides xenpv machine type for multiple architectures
79  accelerator_targets += {
80    'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
81  }
82endif
83if cpu in ['x86', 'x86_64']
84  accelerator_targets += {
85    'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
86    'CONFIG_HVF': ['x86_64-softmmu'],
87    'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
88  }
89endif
90
91##################
92# Compiler flags #
93##################
94
95# Specify linker-script with add_project_link_arguments so that it is not placed
96# within a linker --start-group/--end-group pair
97if 'CONFIG_FUZZ' in config_host
98   add_project_link_arguments(['-Wl,-T,',
99                               (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
100                              native: false, language: ['c', 'cpp', 'objc'])
101endif
102
103add_project_arguments(config_host['QEMU_CFLAGS'].split(),
104                      native: false, language: ['c', 'objc'])
105add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
106                      native: false, language: 'cpp')
107add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
108                           native: false, language: ['c', 'cpp', 'objc'])
109
110if targetos == 'linux'
111  add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
112                        '-isystem', 'linux-headers',
113                        language: ['c', 'cpp'])
114endif
115
116if 'CONFIG_TCG_INTERPRETER' in config_host
117  tcg_arch = 'tci'
118elif config_host['ARCH'] == 'sparc64'
119  tcg_arch = 'sparc'
120elif config_host['ARCH'] == 's390x'
121  tcg_arch = 's390'
122elif config_host['ARCH'] in ['x86_64', 'x32']
123  tcg_arch = 'i386'
124elif config_host['ARCH'] == 'ppc64'
125  tcg_arch = 'ppc'
126elif config_host['ARCH'] in ['riscv32', 'riscv64']
127  tcg_arch = 'riscv'
128else
129  tcg_arch = config_host['ARCH']
130endif
131add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
132                      '-iquote', '.',
133                      '-iquote', meson.current_source_dir(),
134                      '-iquote', meson.current_source_dir() / 'accel/tcg',
135                      '-iquote', meson.current_source_dir() / 'include',
136                      '-iquote', meson.current_source_dir() / 'disas/libvixl',
137                      language: ['c', 'cpp', 'objc'])
138
139link_language = meson.get_external_property('link_language', 'cpp')
140if link_language == 'cpp'
141  add_languages('cpp', required: true, native: false)
142endif
143if host_machine.system() == 'darwin'
144  add_languages('objc', required: false, native: false)
145endif
146
147sparse = find_program('cgcc', required: get_option('sparse'))
148if sparse.found()
149  run_target('sparse',
150             command: [find_program('scripts/check_sparse.py'),
151                       'compile_commands.json', sparse.full_path(), '-Wbitwise',
152                       '-Wno-transparent-union', '-Wno-old-initializer',
153                       '-Wno-non-pointer-null'])
154endif
155
156###########################################
157# Target-specific checks and dependencies #
158###########################################
159
160if targetos != 'linux' and get_option('mpath').enabled()
161  error('Multipath is supported only on Linux')
162endif
163
164m = cc.find_library('m', required: false)
165util = cc.find_library('util', required: false)
166winmm = []
167socket = []
168version_res = []
169coref = []
170iokit = []
171emulator_link_args = []
172cocoa = not_found
173hvf = not_found
174if targetos == 'windows'
175  socket = cc.find_library('ws2_32')
176  winmm = cc.find_library('winmm')
177
178  win = import('windows')
179  version_res = win.compile_resources('version.rc',
180                                      depend_files: files('pc-bios/qemu-nsis.ico'),
181                                      include_directories: include_directories('.'))
182elif targetos == 'darwin'
183  coref = dependency('appleframeworks', modules: 'CoreFoundation')
184  iokit = dependency('appleframeworks', modules: 'IOKit')
185  cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
186elif targetos == 'sunos'
187  socket = [cc.find_library('socket'),
188            cc.find_library('nsl'),
189            cc.find_library('resolv')]
190elif targetos == 'haiku'
191  socket = [cc.find_library('posix_error_mapper'),
192            cc.find_library('network'),
193            cc.find_library('bsd')]
194elif targetos == 'openbsd'
195  if not get_option('tcg').disabled() and target_dirs.length() > 0
196    # Disable OpenBSD W^X if available
197    emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
198  endif
199endif
200
201accelerators = []
202if not get_option('kvm').disabled() and targetos == 'linux'
203  accelerators += 'CONFIG_KVM'
204endif
205if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
206  accelerators += 'CONFIG_XEN'
207  have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
208else
209  have_xen_pci_passthrough = false
210endif
211if not get_option('whpx').disabled() and targetos == 'windows'
212  if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
213    error('WHPX requires 64-bit host')
214  elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
215       cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
216    accelerators += 'CONFIG_WHPX'
217  endif
218endif
219if not get_option('hvf').disabled()
220  hvf = dependency('appleframeworks', modules: 'Hypervisor',
221                   required: get_option('hvf'))
222  if hvf.found()
223    accelerators += 'CONFIG_HVF'
224  endif
225endif
226if not get_option('hax').disabled()
227  if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
228    accelerators += 'CONFIG_HAX'
229  endif
230endif
231if not get_option('tcg').disabled()
232  if cpu not in supported_cpus
233    if 'CONFIG_TCG_INTERPRETER' in config_host
234      warning('Unsupported CPU @0@, will use TCG with TCI (experimental)'.format(cpu))
235    else
236      error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
237    endif
238  endif
239  accelerators += 'CONFIG_TCG'
240  config_host += { 'CONFIG_TCG': 'y' }
241endif
242
243if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
244  error('KVM not available on this platform')
245endif
246if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
247  error('HVF not available on this platform')
248endif
249if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
250  error('WHPX not available on this platform')
251endif
252if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
253  if 'CONFIG_XEN' in accelerators
254    error('Xen PCI passthrough not available on this platform')
255  else
256    error('Xen PCI passthrough requested but Xen not enabled')
257  endif
258endif
259if not cocoa.found() and get_option('cocoa').enabled()
260  error('Cocoa not available on this platform')
261endif
262
263################
264# Dependencies #
265################
266
267# The path to glib.h is added to all compilation commands.  This was
268# grandfathered in from the QEMU Makefiles.
269add_project_arguments(config_host['GLIB_CFLAGS'].split(),
270                      native: false, language: ['c', 'cpp', 'objc'])
271glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
272                          link_args: config_host['GLIB_LIBS'].split())
273# override glib dep with the configure results (for subprojects)
274meson.override_dependency('glib-2.0', glib)
275
276gio = not_found
277if 'CONFIG_GIO' in config_host
278  gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
279                           link_args: config_host['GIO_LIBS'].split())
280endif
281lttng = not_found
282if 'CONFIG_TRACE_UST' in config_host
283  lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
284endif
285urcubp = not_found
286if 'CONFIG_TRACE_UST' in config_host
287  urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
288endif
289gcrypt = not_found
290if 'CONFIG_GCRYPT' in config_host
291  gcrypt = declare_dependency(compile_args: config_host['GCRYPT_CFLAGS'].split(),
292                              link_args: config_host['GCRYPT_LIBS'].split())
293endif
294nettle = not_found
295if 'CONFIG_NETTLE' in config_host
296  nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
297                              link_args: config_host['NETTLE_LIBS'].split())
298endif
299gnutls = not_found
300if 'CONFIG_GNUTLS' in config_host
301  gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
302                              link_args: config_host['GNUTLS_LIBS'].split())
303endif
304pixman = not_found
305if have_system or have_tools
306  pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
307                      method: 'pkg-config', static: enable_static)
308endif
309pam = not_found
310if 'CONFIG_AUTH_PAM' in config_host
311  pam = cc.find_library('pam')
312endif
313libaio = cc.find_library('aio', required: false)
314zlib = dependency('zlib', required: true, static: enable_static)
315linux_io_uring = not_found
316if 'CONFIG_LINUX_IO_URING' in config_host
317  linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
318                                      link_args: config_host['LINUX_IO_URING_LIBS'].split())
319endif
320libxml2 = not_found
321if 'CONFIG_LIBXML2' in config_host
322  libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
323                               link_args: config_host['LIBXML2_LIBS'].split())
324endif
325libnfs = not_found
326if 'CONFIG_LIBNFS' in config_host
327  libnfs = declare_dependency(link_args: config_host['LIBNFS_LIBS'].split())
328endif
329libattr = not_found
330if 'CONFIG_ATTR' in config_host
331  libattr = declare_dependency(link_args: config_host['LIBATTR_LIBS'].split())
332endif
333seccomp = not_found
334if 'CONFIG_SECCOMP' in config_host
335  seccomp = declare_dependency(compile_args: config_host['SECCOMP_CFLAGS'].split(),
336                               link_args: config_host['SECCOMP_LIBS'].split())
337endif
338libcap_ng = not_found
339if 'CONFIG_LIBCAP_NG' in config_host
340  libcap_ng = declare_dependency(link_args: config_host['LIBCAP_NG_LIBS'].split())
341endif
342if get_option('xkbcommon').auto() and not have_system and not have_tools
343  xkbcommon = not_found
344else
345  xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
346                         method: 'pkg-config', static: enable_static)
347endif
348vde = not_found
349if config_host.has_key('CONFIG_VDE')
350  vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
351endif
352pulse = not_found
353if 'CONFIG_LIBPULSE' in config_host
354  pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
355                             link_args: config_host['PULSE_LIBS'].split())
356endif
357alsa = not_found
358if 'CONFIG_ALSA' in config_host
359  alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
360                            link_args: config_host['ALSA_LIBS'].split())
361endif
362jack = not_found
363if 'CONFIG_LIBJACK' in config_host
364  jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
365endif
366spice = not_found
367spice_headers = not_found
368if 'CONFIG_SPICE' in config_host
369  spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
370                             link_args: config_host['SPICE_LIBS'].split())
371  spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
372endif
373rt = cc.find_library('rt', required: false)
374libdl = not_found
375if 'CONFIG_PLUGIN' in config_host
376  libdl = cc.find_library('dl', required: true)
377endif
378libiscsi = not_found
379if 'CONFIG_LIBISCSI' in config_host
380  libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(),
381                                link_args: config_host['LIBISCSI_LIBS'].split())
382endif
383zstd = not_found
384if 'CONFIG_ZSTD' in config_host
385  zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(),
386                            link_args: config_host['ZSTD_LIBS'].split())
387endif
388gbm = not_found
389if 'CONFIG_GBM' in config_host
390  gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
391                           link_args: config_host['GBM_LIBS'].split())
392endif
393virgl = not_found
394if 'CONFIG_VIRGL' in config_host
395  virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
396                             link_args: config_host['VIRGL_LIBS'].split())
397endif
398curl = not_found
399if 'CONFIG_CURL' in config_host
400  curl = declare_dependency(compile_args: config_host['CURL_CFLAGS'].split(),
401                            link_args: config_host['CURL_LIBS'].split())
402endif
403libudev = not_found
404if targetos == 'linux' and (have_system or have_tools)
405  libudev = dependency('libudev',
406                       required: get_option('libudev'),
407                       static: enable_static)
408endif
409
410mpathlibs = [libudev]
411mpathpersist = not_found
412mpathpersist_new_api = false
413if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
414  mpath_test_source_new = '''
415    #include <libudev.h>
416    #include <mpath_persist.h>
417    unsigned mpath_mx_alloc_len = 1024;
418    int logsink;
419    static struct config *multipath_conf;
420    extern struct udev *udev;
421    extern struct config *get_multipath_config(void);
422    extern void put_multipath_config(struct config *conf);
423    struct udev *udev;
424    struct config *get_multipath_config(void) { return multipath_conf; }
425    void put_multipath_config(struct config *conf) { }
426    int main(void) {
427        udev = udev_new();
428        multipath_conf = mpath_lib_init();
429        return 0;
430    }'''
431  mpath_test_source_old = '''
432      #include <libudev.h>
433      #include <mpath_persist.h>
434      unsigned mpath_mx_alloc_len = 1024;
435      int logsink;
436      int main(void) {
437          struct udev *udev = udev_new();
438          mpath_lib_init(udev);
439          return 0;
440      }'''
441  libmpathpersist = cc.find_library('mpathpersist',
442                                    required: get_option('mpath'),
443                                    static: enable_static)
444  if libmpathpersist.found()
445    mpathlibs += libmpathpersist
446    if enable_static
447      mpathlibs += cc.find_library('devmapper',
448                                     required: get_option('mpath'),
449                                     static: enable_static)
450    endif
451    mpathlibs += cc.find_library('multipath',
452                                 required: get_option('mpath'),
453                                 static: enable_static)
454    foreach lib: mpathlibs
455      if not lib.found()
456        mpathlibs = []
457        break
458      endif
459    endforeach
460    if mpathlibs.length() == 0
461      msg = 'Dependencies missing for libmpathpersist'
462    elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
463      mpathpersist = declare_dependency(dependencies: mpathlibs)
464      mpathpersist_new_api = true
465    elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
466      mpathpersist = declare_dependency(dependencies: mpathlibs)
467    else
468      msg = 'Cannot detect libmpathpersist API'
469    endif
470    if not mpathpersist.found()
471      if get_option('mpath').enabled()
472        error(msg)
473      else
474        warning(msg + ', disabling')
475      endif
476    endif
477  endif
478endif
479
480iconv = not_found
481curses = not_found
482if have_system and not get_option('curses').disabled()
483  curses_test = '''
484    #include <locale.h>
485    #include <curses.h>
486    #include <wchar.h>
487    int main(void) {
488      wchar_t wch = L'w';
489      setlocale(LC_ALL, "");
490      resize_term(0, 0);
491      addwstr(L"wide chars\n");
492      addnwstr(&wch, 1);
493      add_wch(WACS_DEGREE);
494      return 0;
495    }'''
496
497  curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
498  foreach curses_dep : curses_dep_list
499    if not curses.found()
500      curses = dependency(curses_dep,
501                          required: false,
502                          method: 'pkg-config',
503                          static: enable_static)
504    endif
505  endforeach
506  msg = get_option('curses').enabled() ? 'curses library not found' : ''
507  if curses.found()
508    if cc.links(curses_test, dependencies: [curses])
509      curses = declare_dependency(compile_args: '-DNCURSES_WIDECHAR', dependencies: [curses])
510    else
511      msg = 'curses package not usable'
512      curses = not_found
513    endif
514  endif
515  if not curses.found()
516    curses_compile_args = ['-DNCURSES_WIDECHAR']
517    has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
518    if targetos != 'windows' and not has_curses_h
519      message('Trying with /usr/include/ncursesw')
520      curses_compile_args += ['-I/usr/include/ncursesw']
521      has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
522    endif
523    if has_curses_h
524      curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
525      foreach curses_libname : curses_libname_list
526        libcurses = cc.find_library(curses_libname,
527                                    required: false,
528                                    static: enable_static)
529        if libcurses.found()
530          if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
531            curses = declare_dependency(compile_args: curses_compile_args,
532                                        dependencies: [libcurses])
533            break
534          else
535            msg = 'curses library not usable'
536          endif
537        endif
538      endforeach
539    endif
540  endif
541  if not get_option('iconv').disabled()
542    foreach link_args : [ ['-liconv'], [] ]
543      # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
544      # We need to use libiconv if available because mixing libiconv's headers with
545      # the system libc does not work.
546      # However, without adding glib to the dependencies -L/usr/local/lib will not be
547      # included in the command line and libiconv will not be found.
548      if cc.links('''
549        #include <iconv.h>
550        int main(void) {
551          iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
552          return conv != (iconv_t) -1;
553        }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
554        iconv = declare_dependency(link_args: link_args, dependencies: glib)
555        break
556      endif
557    endforeach
558  endif
559  if curses.found() and not iconv.found()
560    if get_option('iconv').enabled()
561      error('iconv not available')
562    endif
563    msg = 'iconv required for curses UI but not available'
564    curses = not_found
565  endif
566  if not curses.found() and msg != ''
567    if get_option('curses').enabled()
568      error(msg)
569    else
570      warning(msg + ', disabling')
571    endif
572  endif
573endif
574
575brlapi = not_found
576if 'CONFIG_BRLAPI' in config_host
577  brlapi = declare_dependency(link_args: config_host['BRLAPI_LIBS'].split())
578endif
579
580sdl = not_found
581if have_system
582  sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
583  sdl_image = not_found
584endif
585if sdl.found()
586  # work around 2.0.8 bug
587  sdl = declare_dependency(compile_args: '-Wno-undef',
588                           dependencies: sdl)
589  sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
590                         method: 'pkg-config', static: enable_static)
591else
592  if get_option('sdl_image').enabled()
593    error('sdl-image required, but SDL was @0@'.format(
594          get_option('sdl').disabled() ? 'disabled' : 'not found'))
595  endif
596  sdl_image = not_found
597endif
598
599rbd = not_found
600if 'CONFIG_RBD' in config_host
601  rbd = declare_dependency(link_args: config_host['RBD_LIBS'].split())
602endif
603glusterfs = not_found
604if 'CONFIG_GLUSTERFS' in config_host
605  glusterfs = declare_dependency(compile_args: config_host['GLUSTERFS_CFLAGS'].split(),
606                                 link_args: config_host['GLUSTERFS_LIBS'].split())
607endif
608libssh = not_found
609if 'CONFIG_LIBSSH' in config_host
610  libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
611                              link_args: config_host['LIBSSH_LIBS'].split())
612endif
613libbzip2 = not_found
614if 'CONFIG_BZIP2' in config_host
615  libbzip2 = declare_dependency(link_args: config_host['BZIP2_LIBS'].split())
616endif
617liblzfse = not_found
618if 'CONFIG_LZFSE' in config_host
619  liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split())
620endif
621oss = not_found
622if 'CONFIG_AUDIO_OSS' in config_host
623  oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
624endif
625dsound = not_found
626if 'CONFIG_AUDIO_DSOUND' in config_host
627  dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
628endif
629coreaudio = not_found
630if 'CONFIG_AUDIO_COREAUDIO' in config_host
631  coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
632endif
633opengl = not_found
634if 'CONFIG_OPENGL' in config_host
635  opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
636                              link_args: config_host['OPENGL_LIBS'].split())
637endif
638gtk = not_found
639if 'CONFIG_GTK' in config_host
640  gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
641                              link_args: config_host['GTK_LIBS'].split())
642endif
643vte = not_found
644if 'CONFIG_VTE' in config_host
645  vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
646                           link_args: config_host['VTE_LIBS'].split())
647endif
648x11 = not_found
649if 'CONFIG_X11' in config_host
650  x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
651                           link_args: config_host['X11_LIBS'].split())
652endif
653vnc = not_found
654png = not_found
655jpeg = not_found
656sasl = not_found
657if get_option('vnc').enabled()
658  vnc = declare_dependency() # dummy dependency
659  png = dependency('libpng', required: get_option('vnc_png'),
660                   method: 'pkg-config', static: enable_static)
661  jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
662                    method: 'pkg-config', static: enable_static)
663  sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
664                         required: get_option('vnc_sasl'),
665                         static: enable_static)
666  if sasl.found()
667    sasl = declare_dependency(dependencies: sasl,
668                              compile_args: '-DSTRUCT_IOVEC_DEFINED')
669  endif
670endif
671snappy = not_found
672if 'CONFIG_SNAPPY' in config_host
673  snappy = declare_dependency(link_args: config_host['SNAPPY_LIBS'].split())
674endif
675lzo = not_found
676if 'CONFIG_LZO' in config_host
677  lzo = declare_dependency(link_args: config_host['LZO_LIBS'].split())
678endif
679rdma = not_found
680if 'CONFIG_RDMA' in config_host
681  rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
682endif
683numa = not_found
684if 'CONFIG_NUMA' in config_host
685  numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
686endif
687xen = not_found
688if 'CONFIG_XEN_BACKEND' in config_host
689  xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
690                           link_args: config_host['XEN_LIBS'].split())
691endif
692cacard = not_found
693if 'CONFIG_SMARTCARD' in config_host
694  cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
695                              link_args: config_host['SMARTCARD_LIBS'].split())
696endif
697u2f = not_found
698if have_system
699  u2f = dependency('u2f-emu', required: get_option('u2f'),
700                   method: 'pkg-config',
701                   static: enable_static)
702endif
703usbredir = not_found
704if 'CONFIG_USB_REDIR' in config_host
705  usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
706                                link_args: config_host['USB_REDIR_LIBS'].split())
707endif
708libusb = not_found
709if 'CONFIG_USB_LIBUSB' in config_host
710  libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
711                              link_args: config_host['LIBUSB_LIBS'].split())
712endif
713libpmem = not_found
714if 'CONFIG_LIBPMEM' in config_host
715  libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
716                               link_args: config_host['LIBPMEM_LIBS'].split())
717endif
718libdaxctl = not_found
719if 'CONFIG_LIBDAXCTL' in config_host
720  libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
721endif
722tasn1 = not_found
723if 'CONFIG_TASN1' in config_host
724  tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
725                             link_args: config_host['TASN1_LIBS'].split())
726endif
727keyutils = dependency('libkeyutils', required: false,
728                      method: 'pkg-config', static: enable_static)
729
730has_gettid = cc.has_function('gettid')
731
732# Malloc tests
733
734malloc = []
735if get_option('malloc') == 'system'
736  has_malloc_trim = \
737    not get_option('malloc_trim').disabled() and \
738    cc.links('''#include <malloc.h>
739                int main(void) { malloc_trim(0); return 0; }''')
740else
741  has_malloc_trim = false
742  malloc = cc.find_library(get_option('malloc'), required: true)
743endif
744if not has_malloc_trim and get_option('malloc_trim').enabled()
745  if get_option('malloc') == 'system'
746    error('malloc_trim not available on this platform.')
747  else
748    error('malloc_trim not available with non-libc memory allocator')
749  endif
750endif
751
752# Check whether the glibc provides statx()
753
754statx_test = '''
755  #ifndef _GNU_SOURCE
756  #define _GNU_SOURCE
757  #endif
758  #include <sys/stat.h>
759  int main(void) {
760    struct statx statxbuf;
761    statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
762    return 0;
763  }'''
764
765has_statx = cc.links(statx_test)
766
767have_vhost_user_blk_server = (targetos == 'linux' and
768    'CONFIG_VHOST_USER' in config_host)
769
770if get_option('vhost_user_blk_server').enabled()
771    if targetos != 'linux'
772        error('vhost_user_blk_server requires linux')
773    elif 'CONFIG_VHOST_USER' not in config_host
774        error('vhost_user_blk_server requires vhost-user support')
775    endif
776elif get_option('vhost_user_blk_server').disabled() or not have_system
777    have_vhost_user_blk_server = false
778endif
779
780
781if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
782  error('Cannot enable fuse-lseek while fuse is disabled')
783endif
784
785fuse = dependency('fuse3', required: get_option('fuse'),
786                  version: '>=3.1', method: 'pkg-config',
787                  static: enable_static)
788
789fuse_lseek = not_found
790if not get_option('fuse_lseek').disabled()
791  if fuse.version().version_compare('>=3.8')
792    # Dummy dependency
793    fuse_lseek = declare_dependency()
794  elif get_option('fuse_lseek').enabled()
795    if fuse.found()
796      error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
797    else
798      error('fuse-lseek requires libfuse, which was not found')
799    endif
800  endif
801endif
802
803if get_option('cfi')
804  cfi_flags=[]
805  # Check for dependency on LTO
806  if not get_option('b_lto')
807    error('Selected Control-Flow Integrity but LTO is disabled')
808  endif
809  if config_host.has_key('CONFIG_MODULES')
810    error('Selected Control-Flow Integrity is not compatible with modules')
811  endif
812  # Check for cfi flags. CFI requires LTO so we can't use
813  # get_supported_arguments, but need a more complex "compiles" which allows
814  # custom arguments
815  if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
816                 args: ['-flto', '-fsanitize=cfi-icall'] )
817    cfi_flags += '-fsanitize=cfi-icall'
818  else
819    error('-fsanitize=cfi-icall is not supported by the compiler')
820  endif
821  if cc.compiles('int main () { return 0; }',
822                 name: '-fsanitize-cfi-icall-generalize-pointers',
823                 args: ['-flto', '-fsanitize=cfi-icall',
824                        '-fsanitize-cfi-icall-generalize-pointers'] )
825    cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
826  else
827    error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
828  endif
829  if get_option('cfi_debug')
830    if cc.compiles('int main () { return 0; }',
831                   name: '-fno-sanitize-trap=cfi-icall',
832                   args: ['-flto', '-fsanitize=cfi-icall',
833                          '-fno-sanitize-trap=cfi-icall'] )
834      cfi_flags += '-fno-sanitize-trap=cfi-icall'
835    else
836      error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
837    endif
838  endif
839  add_project_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
840  add_project_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
841endif
842
843#################
844# config-host.h #
845#################
846
847config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
848config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
849config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
850config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
851config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
852config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
853config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
854config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
855config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
856config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
857config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
858config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
859
860config_host_data.set('CONFIG_COCOA', cocoa.found())
861config_host_data.set('CONFIG_LIBUDEV', libudev.found())
862config_host_data.set('CONFIG_MPATH', mpathpersist.found())
863config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
864config_host_data.set('CONFIG_CURSES', curses.found())
865config_host_data.set('CONFIG_SDL', sdl.found())
866config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
867config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
868config_host_data.set('CONFIG_VNC', vnc.found())
869config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
870config_host_data.set('CONFIG_VNC_PNG', png.found())
871config_host_data.set('CONFIG_VNC_SASL', sasl.found())
872config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
873config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
874config_host_data.set('CONFIG_GETTID', has_gettid)
875config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
876config_host_data.set('CONFIG_STATX', has_statx)
877config_host_data.set('CONFIG_FUSE', fuse.found())
878config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
879config_host_data.set('CONFIG_CFI', get_option('cfi'))
880config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
881config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
882config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
883config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
884
885config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
886config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
887config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
888config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
889config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
890config_host_data.set('HAVE_SYS_SIGNAL_H', cc.has_header('sys/signal.h'))
891
892ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
893arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
894strings = ['HOST_DSOSUF', 'CONFIG_IASL']
895foreach k, v: config_host
896  if ignored.contains(k)
897    # do nothing
898  elif arrays.contains(k)
899    if v != ''
900      v = '"' + '", "'.join(v.split()) + '", '
901    endif
902    config_host_data.set(k, v)
903  elif k == 'ARCH'
904    config_host_data.set('HOST_' + v.to_upper(), 1)
905  elif strings.contains(k)
906    if not k.startswith('CONFIG_')
907      k = 'CONFIG_' + k.to_upper()
908    endif
909    config_host_data.set_quoted(k, v)
910  elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
911    config_host_data.set(k, v == 'y' ? 1 : v)
912  endif
913endforeach
914
915########################
916# Target configuration #
917########################
918
919minikconf = find_program('scripts/minikconf.py')
920config_all = {}
921config_all_devices = {}
922config_all_disas = {}
923config_devices_mak_list = []
924config_devices_h = {}
925config_target_h = {}
926config_target_mak = {}
927
928disassemblers = {
929  'alpha' : ['CONFIG_ALPHA_DIS'],
930  'arm' : ['CONFIG_ARM_DIS'],
931  'avr' : ['CONFIG_AVR_DIS'],
932  'cris' : ['CONFIG_CRIS_DIS'],
933  'hppa' : ['CONFIG_HPPA_DIS'],
934  'i386' : ['CONFIG_I386_DIS'],
935  'x86_64' : ['CONFIG_I386_DIS'],
936  'x32' : ['CONFIG_I386_DIS'],
937  'lm32' : ['CONFIG_LM32_DIS'],
938  'm68k' : ['CONFIG_M68K_DIS'],
939  'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
940  'mips' : ['CONFIG_MIPS_DIS'],
941  'moxie' : ['CONFIG_MOXIE_DIS'],
942  'nios2' : ['CONFIG_NIOS2_DIS'],
943  'or1k' : ['CONFIG_OPENRISC_DIS'],
944  'ppc' : ['CONFIG_PPC_DIS'],
945  'riscv' : ['CONFIG_RISCV_DIS'],
946  'rx' : ['CONFIG_RX_DIS'],
947  's390' : ['CONFIG_S390_DIS'],
948  'sh4' : ['CONFIG_SH4_DIS'],
949  'sparc' : ['CONFIG_SPARC_DIS'],
950  'xtensa' : ['CONFIG_XTENSA_DIS'],
951}
952if link_language == 'cpp'
953  disassemblers += {
954    'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
955    'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
956    'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
957  }
958endif
959
960kconfig_external_symbols = [
961  'CONFIG_KVM',
962  'CONFIG_XEN',
963  'CONFIG_TPM',
964  'CONFIG_SPICE',
965  'CONFIG_IVSHMEM',
966  'CONFIG_OPENGL',
967  'CONFIG_X11',
968  'CONFIG_VHOST_USER',
969  'CONFIG_VHOST_VDPA',
970  'CONFIG_VHOST_KERNEL',
971  'CONFIG_VIRTFS',
972  'CONFIG_LINUX',
973  'CONFIG_PVRDMA',
974]
975ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
976
977default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
978actual_target_dirs = []
979fdt_required = []
980foreach target : target_dirs
981  config_target = { 'TARGET_NAME': target.split('-')[0] }
982  if target.endswith('linux-user')
983    if targetos != 'linux'
984      if default_targets
985        continue
986      endif
987      error('Target @0@ is only available on a Linux host'.format(target))
988    endif
989    config_target += { 'CONFIG_LINUX_USER': 'y' }
990  elif target.endswith('bsd-user')
991    if 'CONFIG_BSD' not in config_host
992      if default_targets
993        continue
994      endif
995      error('Target @0@ is only available on a BSD host'.format(target))
996    endif
997    config_target += { 'CONFIG_BSD_USER': 'y' }
998  elif target.endswith('softmmu')
999    config_target += { 'CONFIG_SOFTMMU': 'y' }
1000  endif
1001  if target.endswith('-user')
1002    config_target += {
1003      'CONFIG_USER_ONLY': 'y',
1004      'CONFIG_QEMU_INTERP_PREFIX':
1005        config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1006    }
1007  endif
1008
1009  have_accel = false
1010  foreach sym: accelerators
1011    if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1012      config_target += { sym: 'y' }
1013      config_all += { sym: 'y' }
1014      if sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1015        config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1016      endif
1017      have_accel = true
1018    endif
1019  endforeach
1020  if not have_accel
1021    if default_targets
1022      continue
1023    endif
1024    error('No accelerator available for target @0@'.format(target))
1025  endif
1026
1027  actual_target_dirs += target
1028  config_target += keyval.load('default-configs/targets' / target + '.mak')
1029  config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1030
1031  if 'TARGET_NEED_FDT' in config_target
1032    fdt_required += target
1033  endif
1034
1035  # Add default keys
1036  if 'TARGET_BASE_ARCH' not in config_target
1037    config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1038  endif
1039  if 'TARGET_ABI_DIR' not in config_target
1040    config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1041  endif
1042
1043  foreach k, v: disassemblers
1044    if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1045      foreach sym: v
1046        config_target += { sym: 'y' }
1047        config_all_disas += { sym: 'y' }
1048      endforeach
1049    endif
1050  endforeach
1051
1052  config_target_data = configuration_data()
1053  foreach k, v: config_target
1054    if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1055      # do nothing
1056    elif ignored.contains(k)
1057      # do nothing
1058    elif k == 'TARGET_BASE_ARCH'
1059      # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1060      # not used to select files from sourcesets.
1061      config_target_data.set('TARGET_' + v.to_upper(), 1)
1062    elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1063      config_target_data.set_quoted(k, v)
1064    elif v == 'y'
1065      config_target_data.set(k, 1)
1066    else
1067      config_target_data.set(k, v)
1068    endif
1069  endforeach
1070  config_target_h += {target: configure_file(output: target + '-config-target.h',
1071                                               configuration: config_target_data)}
1072
1073  if target.endswith('-softmmu')
1074    base_kconfig = []
1075    foreach sym : kconfig_external_symbols
1076      if sym in config_target or sym in config_host
1077        base_kconfig += '@0@=y'.format(sym)
1078      endif
1079    endforeach
1080
1081    config_devices_mak = target + '-config-devices.mak'
1082    config_devices_mak = configure_file(
1083      input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
1084      output: config_devices_mak,
1085      depfile: config_devices_mak + '.d',
1086      capture: true,
1087      command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
1088                config_devices_mak, '@DEPFILE@', '@INPUT@',
1089                base_kconfig])
1090
1091    config_devices_data = configuration_data()
1092    config_devices = keyval.load(config_devices_mak)
1093    foreach k, v: config_devices
1094      config_devices_data.set(k, 1)
1095    endforeach
1096    config_devices_mak_list += config_devices_mak
1097    config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1098                                                configuration: config_devices_data)}
1099    config_target += config_devices
1100    config_all_devices += config_devices
1101  endif
1102  config_target_mak += {target: config_target}
1103endforeach
1104target_dirs = actual_target_dirs
1105
1106# This configuration is used to build files that are shared by
1107# multiple binaries, and then extracted out of the "common"
1108# static_library target.
1109#
1110# We do not use all_sources()/all_dependencies(), because it would
1111# build literally all source files, including devices only used by
1112# targets that are not built for this compilation.  The CONFIG_ALL
1113# pseudo symbol replaces it.
1114
1115config_all += config_all_devices
1116config_all += config_host
1117config_all += config_all_disas
1118config_all += {
1119  'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1120  'CONFIG_SOFTMMU': have_system,
1121  'CONFIG_USER_ONLY': have_user,
1122  'CONFIG_ALL': true,
1123}
1124
1125##############
1126# Submodules #
1127##############
1128
1129capstone = not_found
1130capstone_opt = get_option('capstone')
1131if capstone_opt in ['enabled', 'auto', 'system']
1132  have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1133  capstone = dependency('capstone', version: '>=4.0',
1134                        static: enable_static, method: 'pkg-config',
1135                        required: capstone_opt == 'system' or
1136                                  capstone_opt == 'enabled' and not have_internal)
1137  if capstone.found()
1138    capstone_opt = 'system'
1139  elif have_internal
1140    capstone_opt = 'internal'
1141  else
1142    capstone_opt = 'disabled'
1143  endif
1144endif
1145if capstone_opt == 'internal'
1146  capstone_data = configuration_data()
1147  capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1148
1149  capstone_files = files(
1150    'capstone/cs.c',
1151    'capstone/MCInst.c',
1152    'capstone/MCInstrDesc.c',
1153    'capstone/MCRegisterInfo.c',
1154    'capstone/SStream.c',
1155    'capstone/utils.c'
1156  )
1157
1158  if 'CONFIG_ARM_DIS' in config_all_disas
1159    capstone_data.set('CAPSTONE_HAS_ARM', '1')
1160    capstone_files += files(
1161      'capstone/arch/ARM/ARMDisassembler.c',
1162      'capstone/arch/ARM/ARMInstPrinter.c',
1163      'capstone/arch/ARM/ARMMapping.c',
1164      'capstone/arch/ARM/ARMModule.c'
1165    )
1166  endif
1167
1168  # FIXME: This config entry currently depends on a c++ compiler.
1169  # Which is needed for building libvixl, but not for capstone.
1170  if 'CONFIG_ARM_A64_DIS' in config_all_disas
1171    capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1172    capstone_files += files(
1173      'capstone/arch/AArch64/AArch64BaseInfo.c',
1174      'capstone/arch/AArch64/AArch64Disassembler.c',
1175      'capstone/arch/AArch64/AArch64InstPrinter.c',
1176      'capstone/arch/AArch64/AArch64Mapping.c',
1177      'capstone/arch/AArch64/AArch64Module.c'
1178    )
1179  endif
1180
1181  if 'CONFIG_PPC_DIS' in config_all_disas
1182    capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1183    capstone_files += files(
1184      'capstone/arch/PowerPC/PPCDisassembler.c',
1185      'capstone/arch/PowerPC/PPCInstPrinter.c',
1186      'capstone/arch/PowerPC/PPCMapping.c',
1187      'capstone/arch/PowerPC/PPCModule.c'
1188    )
1189  endif
1190
1191  if 'CONFIG_S390_DIS' in config_all_disas
1192    capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1193    capstone_files += files(
1194      'capstone/arch/SystemZ/SystemZDisassembler.c',
1195      'capstone/arch/SystemZ/SystemZInstPrinter.c',
1196      'capstone/arch/SystemZ/SystemZMapping.c',
1197      'capstone/arch/SystemZ/SystemZModule.c',
1198      'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1199    )
1200  endif
1201
1202  if 'CONFIG_I386_DIS' in config_all_disas
1203    capstone_data.set('CAPSTONE_HAS_X86', 1)
1204    capstone_files += files(
1205      'capstone/arch/X86/X86Disassembler.c',
1206      'capstone/arch/X86/X86DisassemblerDecoder.c',
1207      'capstone/arch/X86/X86ATTInstPrinter.c',
1208      'capstone/arch/X86/X86IntelInstPrinter.c',
1209      'capstone/arch/X86/X86InstPrinterCommon.c',
1210      'capstone/arch/X86/X86Mapping.c',
1211      'capstone/arch/X86/X86Module.c'
1212    )
1213  endif
1214
1215  configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1216
1217  capstone_cargs = [
1218    # FIXME: There does not seem to be a way to completely replace the c_args
1219    # that come from add_project_arguments() -- we can only add to them.
1220    # So: disable all warnings with a big hammer.
1221    '-Wno-error', '-w',
1222
1223    # Include all configuration defines via a header file, which will wind up
1224    # as a dependency on the object file, and thus changes here will result
1225    # in a rebuild.
1226    '-include', 'capstone-defs.h'
1227  ]
1228
1229  libcapstone = static_library('capstone',
1230                               sources: capstone_files,
1231                               c_args: capstone_cargs,
1232                               include_directories: 'capstone/include')
1233  capstone = declare_dependency(link_with: libcapstone,
1234                                include_directories: 'capstone/include/capstone')
1235endif
1236
1237slirp = not_found
1238slirp_opt = 'disabled'
1239if have_system
1240  slirp_opt = get_option('slirp')
1241  if slirp_opt in ['enabled', 'auto', 'system']
1242    have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1243    slirp = dependency('slirp', static: enable_static,
1244                       method: 'pkg-config',
1245                       required: slirp_opt == 'system' or
1246                                 slirp_opt == 'enabled' and not have_internal)
1247    if slirp.found()
1248      slirp_opt = 'system'
1249    elif have_internal
1250      slirp_opt = 'internal'
1251    else
1252      slirp_opt = 'disabled'
1253    endif
1254  endif
1255  if slirp_opt == 'internal'
1256    slirp_deps = []
1257    if targetos == 'windows'
1258      slirp_deps = cc.find_library('iphlpapi')
1259    endif
1260    slirp_conf = configuration_data()
1261    slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1262    slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1263    slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1264    slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1265    slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1266    slirp_files = [
1267      'slirp/src/arp_table.c',
1268      'slirp/src/bootp.c',
1269      'slirp/src/cksum.c',
1270      'slirp/src/dhcpv6.c',
1271      'slirp/src/dnssearch.c',
1272      'slirp/src/if.c',
1273      'slirp/src/ip6_icmp.c',
1274      'slirp/src/ip6_input.c',
1275      'slirp/src/ip6_output.c',
1276      'slirp/src/ip_icmp.c',
1277      'slirp/src/ip_input.c',
1278      'slirp/src/ip_output.c',
1279      'slirp/src/mbuf.c',
1280      'slirp/src/misc.c',
1281      'slirp/src/ncsi.c',
1282      'slirp/src/ndp_table.c',
1283      'slirp/src/sbuf.c',
1284      'slirp/src/slirp.c',
1285      'slirp/src/socket.c',
1286      'slirp/src/state.c',
1287      'slirp/src/stream.c',
1288      'slirp/src/tcp_input.c',
1289      'slirp/src/tcp_output.c',
1290      'slirp/src/tcp_subr.c',
1291      'slirp/src/tcp_timer.c',
1292      'slirp/src/tftp.c',
1293      'slirp/src/udp.c',
1294      'slirp/src/udp6.c',
1295      'slirp/src/util.c',
1296      'slirp/src/version.c',
1297      'slirp/src/vmstate.c',
1298    ]
1299
1300    configure_file(
1301      input : 'slirp/src/libslirp-version.h.in',
1302      output : 'libslirp-version.h',
1303      configuration: slirp_conf)
1304
1305    slirp_inc = include_directories('slirp', 'slirp/src')
1306    libslirp = static_library('slirp',
1307                              sources: slirp_files,
1308                              c_args: slirp_cargs,
1309                              include_directories: slirp_inc)
1310    slirp = declare_dependency(link_with: libslirp,
1311                               dependencies: slirp_deps,
1312                               include_directories: slirp_inc)
1313  endif
1314endif
1315
1316fdt = not_found
1317fdt_opt = get_option('fdt')
1318if have_system
1319  if fdt_opt in ['enabled', 'auto', 'system']
1320    have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1321    fdt = cc.find_library('fdt', static: enable_static,
1322                          required: fdt_opt == 'system' or
1323                                    fdt_opt == 'enabled' and not have_internal)
1324    if fdt.found() and cc.links('''
1325       #include <libfdt.h>
1326       #include <libfdt_env.h>
1327       int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1328         dependencies: fdt)
1329      fdt_opt = 'system'
1330    elif have_internal
1331      fdt_opt = 'internal'
1332    else
1333      fdt_opt = 'disabled'
1334    endif
1335  endif
1336  if fdt_opt == 'internal'
1337    fdt_files = files(
1338      'dtc/libfdt/fdt.c',
1339      'dtc/libfdt/fdt_ro.c',
1340      'dtc/libfdt/fdt_wip.c',
1341      'dtc/libfdt/fdt_sw.c',
1342      'dtc/libfdt/fdt_rw.c',
1343      'dtc/libfdt/fdt_strerror.c',
1344      'dtc/libfdt/fdt_empty_tree.c',
1345      'dtc/libfdt/fdt_addresses.c',
1346      'dtc/libfdt/fdt_overlay.c',
1347      'dtc/libfdt/fdt_check.c',
1348    )
1349
1350    fdt_inc = include_directories('dtc/libfdt')
1351    libfdt = static_library('fdt',
1352                            sources: fdt_files,
1353                            include_directories: fdt_inc)
1354    fdt = declare_dependency(link_with: libfdt,
1355                             include_directories: fdt_inc)
1356  endif
1357endif
1358if not fdt.found() and fdt_required.length() > 0
1359  error('fdt not available but required by targets ' + ', '.join(fdt_required))
1360endif
1361
1362config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1363config_host_data.set('CONFIG_FDT', fdt.found())
1364config_host_data.set('CONFIG_SLIRP', slirp.found())
1365
1366#####################
1367# Generated sources #
1368#####################
1369
1370genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1371
1372hxtool = find_program('scripts/hxtool')
1373shaderinclude = find_program('scripts/shaderinclude.pl')
1374qapi_gen = find_program('scripts/qapi-gen.py')
1375qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1376                     meson.source_root() / 'scripts/qapi/commands.py',
1377                     meson.source_root() / 'scripts/qapi/common.py',
1378                     meson.source_root() / 'scripts/qapi/error.py',
1379                     meson.source_root() / 'scripts/qapi/events.py',
1380                     meson.source_root() / 'scripts/qapi/expr.py',
1381                     meson.source_root() / 'scripts/qapi/gen.py',
1382                     meson.source_root() / 'scripts/qapi/introspect.py',
1383                     meson.source_root() / 'scripts/qapi/parser.py',
1384                     meson.source_root() / 'scripts/qapi/schema.py',
1385                     meson.source_root() / 'scripts/qapi/source.py',
1386                     meson.source_root() / 'scripts/qapi/types.py',
1387                     meson.source_root() / 'scripts/qapi/visit.py',
1388                     meson.source_root() / 'scripts/qapi/common.py',
1389                     meson.source_root() / 'scripts/qapi-gen.py'
1390]
1391
1392tracetool = [
1393  python, files('scripts/tracetool.py'),
1394   '--backend=' + config_host['TRACE_BACKENDS']
1395]
1396
1397qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1398                    meson.current_source_dir(),
1399                    config_host['PKGVERSION'], meson.project_version()]
1400qemu_version = custom_target('qemu-version.h',
1401                             output: 'qemu-version.h',
1402                             command: qemu_version_cmd,
1403                             capture: true,
1404                             build_by_default: true,
1405                             build_always_stale: true)
1406genh += qemu_version
1407
1408hxdep = []
1409hx_headers = [
1410  ['qemu-options.hx', 'qemu-options.def'],
1411  ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1412]
1413if have_system
1414  hx_headers += [
1415    ['hmp-commands.hx', 'hmp-commands.h'],
1416    ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1417  ]
1418endif
1419foreach d : hx_headers
1420  hxdep += custom_target(d[1],
1421                input: files(d[0]),
1422                output: d[1],
1423                capture: true,
1424                build_by_default: true, # to be removed when added to a target
1425                command: [hxtool, '-h', '@INPUT0@'])
1426endforeach
1427genh += hxdep
1428
1429###################
1430# Collect sources #
1431###################
1432
1433authz_ss = ss.source_set()
1434blockdev_ss = ss.source_set()
1435block_ss = ss.source_set()
1436bsd_user_ss = ss.source_set()
1437chardev_ss = ss.source_set()
1438common_ss = ss.source_set()
1439crypto_ss = ss.source_set()
1440io_ss = ss.source_set()
1441linux_user_ss = ss.source_set()
1442qmp_ss = ss.source_set()
1443qom_ss = ss.source_set()
1444softmmu_ss = ss.source_set()
1445specific_fuzz_ss = ss.source_set()
1446specific_ss = ss.source_set()
1447stub_ss = ss.source_set()
1448trace_ss = ss.source_set()
1449user_ss = ss.source_set()
1450util_ss = ss.source_set()
1451
1452modules = {}
1453hw_arch = {}
1454target_arch = {}
1455target_softmmu_arch = {}
1456
1457###############
1458# Trace files #
1459###############
1460
1461# TODO: add each directory to the subdirs from its own meson.build, once
1462# we have those
1463trace_events_subdirs = [
1464  'accel/kvm',
1465  'accel/tcg',
1466  'crypto',
1467  'monitor',
1468]
1469if have_user
1470  trace_events_subdirs += [ 'linux-user' ]
1471endif
1472if have_block
1473  trace_events_subdirs += [
1474    'authz',
1475    'block',
1476    'io',
1477    'nbd',
1478    'scsi',
1479  ]
1480endif
1481if have_system
1482  trace_events_subdirs += [
1483    'audio',
1484    'backends',
1485    'backends/tpm',
1486    'chardev',
1487    'hw/9pfs',
1488    'hw/acpi',
1489    'hw/alpha',
1490    'hw/arm',
1491    'hw/audio',
1492    'hw/block',
1493    'hw/block/dataplane',
1494    'hw/char',
1495    'hw/display',
1496    'hw/dma',
1497    'hw/hppa',
1498    'hw/hyperv',
1499    'hw/i2c',
1500    'hw/i386',
1501    'hw/i386/xen',
1502    'hw/ide',
1503    'hw/input',
1504    'hw/intc',
1505    'hw/isa',
1506    'hw/mem',
1507    'hw/mips',
1508    'hw/misc',
1509    'hw/misc/macio',
1510    'hw/net',
1511    'hw/net/can',
1512    'hw/nvram',
1513    'hw/pci',
1514    'hw/pci-host',
1515    'hw/ppc',
1516    'hw/rdma',
1517    'hw/rdma/vmw',
1518    'hw/rtc',
1519    'hw/s390x',
1520    'hw/scsi',
1521    'hw/sd',
1522    'hw/sparc',
1523    'hw/sparc64',
1524    'hw/ssi',
1525    'hw/timer',
1526    'hw/tpm',
1527    'hw/usb',
1528    'hw/vfio',
1529    'hw/virtio',
1530    'hw/watchdog',
1531    'hw/xen',
1532    'hw/gpio',
1533    'migration',
1534    'net',
1535    'softmmu',
1536    'ui',
1537  ]
1538endif
1539trace_events_subdirs += [
1540  'hw/core',
1541  'qapi',
1542  'qom',
1543  'target/arm',
1544  'target/hppa',
1545  'target/i386',
1546  'target/i386/kvm',
1547  'target/mips',
1548  'target/ppc',
1549  'target/riscv',
1550  'target/s390x',
1551  'target/sparc',
1552  'util',
1553]
1554
1555vhost_user = not_found
1556if 'CONFIG_VHOST_USER' in config_host
1557  libvhost_user = subproject('libvhost-user')
1558  vhost_user = libvhost_user.get_variable('vhost_user_dep')
1559endif
1560
1561subdir('qapi')
1562subdir('qobject')
1563subdir('stubs')
1564subdir('trace')
1565subdir('util')
1566subdir('qom')
1567subdir('authz')
1568subdir('crypto')
1569subdir('ui')
1570
1571
1572if enable_modules
1573  libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1574  modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1575endif
1576
1577stub_ss = stub_ss.apply(config_all, strict: false)
1578
1579util_ss.add_all(trace_ss)
1580util_ss = util_ss.apply(config_all, strict: false)
1581libqemuutil = static_library('qemuutil',
1582                             sources: util_ss.sources() + stub_ss.sources() + genh,
1583                             dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1584qemuutil = declare_dependency(link_with: libqemuutil,
1585                              sources: genh + version_res)
1586
1587decodetree = generator(find_program('scripts/decodetree.py'),
1588                       output: 'decode-@BASENAME@.c.inc',
1589                       arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1590
1591subdir('audio')
1592subdir('io')
1593subdir('chardev')
1594subdir('fsdev')
1595subdir('libdecnumber')
1596subdir('target')
1597subdir('dump')
1598
1599block_ss.add(files(
1600  'block.c',
1601  'blockjob.c',
1602  'job.c',
1603  'qemu-io-cmds.c',
1604))
1605block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1606
1607subdir('nbd')
1608subdir('scsi')
1609subdir('block')
1610
1611blockdev_ss.add(files(
1612  'blockdev.c',
1613  'blockdev-nbd.c',
1614  'iothread.c',
1615  'job-qmp.c',
1616))
1617
1618# os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1619# os-win32.c does not
1620blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1621softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1622
1623common_ss.add(files('cpus-common.c'))
1624
1625subdir('softmmu')
1626
1627common_ss.add(capstone)
1628specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1629specific_ss.add(files('exec-vary.c'))
1630specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1631  'fpu/softfloat.c',
1632  'tcg/optimize.c',
1633  'tcg/tcg-common.c',
1634  'tcg/tcg-op-gvec.c',
1635  'tcg/tcg-op-vec.c',
1636  'tcg/tcg-op.c',
1637  'tcg/tcg.c',
1638))
1639specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1640
1641subdir('backends')
1642subdir('disas')
1643subdir('migration')
1644subdir('monitor')
1645subdir('net')
1646subdir('replay')
1647subdir('hw')
1648subdir('accel')
1649subdir('plugins')
1650subdir('bsd-user')
1651subdir('linux-user')
1652
1653bsd_user_ss.add(files('gdbstub.c'))
1654specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1655
1656linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1657specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1658
1659# needed for fuzzing binaries
1660subdir('tests/qtest/libqos')
1661subdir('tests/qtest/fuzz')
1662
1663########################
1664# Library dependencies #
1665########################
1666
1667block_mods = []
1668softmmu_mods = []
1669foreach d, list : modules
1670  foreach m, module_ss : list
1671    if enable_modules and targetos != 'windows'
1672      module_ss = module_ss.apply(config_all, strict: false)
1673      sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1674                          dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1675      if d == 'block'
1676        block_mods += sl
1677      else
1678        softmmu_mods += sl
1679      endif
1680    else
1681      if d == 'block'
1682        block_ss.add_all(module_ss)
1683      else
1684        softmmu_ss.add_all(module_ss)
1685      endif
1686    endif
1687  endforeach
1688endforeach
1689
1690nm = find_program('nm')
1691undefsym = find_program('scripts/undefsym.py')
1692block_syms = custom_target('block.syms', output: 'block.syms',
1693                             input: [libqemuutil, block_mods],
1694                             capture: true,
1695                             command: [undefsym, nm, '@INPUT@'])
1696qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1697                             input: [libqemuutil, softmmu_mods],
1698                             capture: true,
1699                             command: [undefsym, nm, '@INPUT@'])
1700
1701qom_ss = qom_ss.apply(config_host, strict: false)
1702libqom = static_library('qom', qom_ss.sources() + genh,
1703                        dependencies: [qom_ss.dependencies()],
1704                        name_suffix: 'fa')
1705
1706qom = declare_dependency(link_whole: libqom)
1707
1708authz_ss = authz_ss.apply(config_host, strict: false)
1709libauthz = static_library('authz', authz_ss.sources() + genh,
1710                          dependencies: [authz_ss.dependencies()],
1711                          name_suffix: 'fa',
1712                          build_by_default: false)
1713
1714authz = declare_dependency(link_whole: libauthz,
1715                           dependencies: qom)
1716
1717crypto_ss = crypto_ss.apply(config_host, strict: false)
1718libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1719                           dependencies: [crypto_ss.dependencies()],
1720                           name_suffix: 'fa',
1721                           build_by_default: false)
1722
1723crypto = declare_dependency(link_whole: libcrypto,
1724                            dependencies: [authz, qom])
1725
1726io_ss = io_ss.apply(config_host, strict: false)
1727libio = static_library('io', io_ss.sources() + genh,
1728                       dependencies: [io_ss.dependencies()],
1729                       link_with: libqemuutil,
1730                       name_suffix: 'fa',
1731                       build_by_default: false)
1732
1733io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1734
1735libmigration = static_library('migration', sources: migration_files + genh,
1736                              name_suffix: 'fa',
1737                              build_by_default: false)
1738migration = declare_dependency(link_with: libmigration,
1739                               dependencies: [zlib, qom, io])
1740softmmu_ss.add(migration)
1741
1742block_ss = block_ss.apply(config_host, strict: false)
1743libblock = static_library('block', block_ss.sources() + genh,
1744                          dependencies: block_ss.dependencies(),
1745                          link_depends: block_syms,
1746                          name_suffix: 'fa',
1747                          build_by_default: false)
1748
1749block = declare_dependency(link_whole: [libblock],
1750                           link_args: '@block.syms',
1751                           dependencies: [crypto, io])
1752
1753blockdev_ss = blockdev_ss.apply(config_host, strict: false)
1754libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
1755                             dependencies: blockdev_ss.dependencies(),
1756                             name_suffix: 'fa',
1757                             build_by_default: false)
1758
1759blockdev = declare_dependency(link_whole: [libblockdev],
1760                              dependencies: [block])
1761
1762qmp_ss = qmp_ss.apply(config_host, strict: false)
1763libqmp = static_library('qmp', qmp_ss.sources() + genh,
1764                        dependencies: qmp_ss.dependencies(),
1765                        name_suffix: 'fa',
1766                        build_by_default: false)
1767
1768qmp = declare_dependency(link_whole: [libqmp])
1769
1770libchardev = static_library('chardev', chardev_ss.sources() + genh,
1771                            name_suffix: 'fa',
1772                            build_by_default: false)
1773
1774chardev = declare_dependency(link_whole: libchardev)
1775
1776libhwcore = static_library('hwcore', sources: hwcore_files + genh,
1777                           name_suffix: 'fa',
1778                           build_by_default: false)
1779hwcore = declare_dependency(link_whole: libhwcore)
1780common_ss.add(hwcore)
1781
1782###########
1783# Targets #
1784###########
1785
1786foreach m : block_mods + softmmu_mods
1787  shared_module(m.name(),
1788                name_prefix: '',
1789                link_whole: m,
1790                install: true,
1791                install_dir: qemu_moddir)
1792endforeach
1793
1794softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
1795common_ss.add(qom, qemuutil)
1796
1797common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
1798common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
1799
1800common_all = common_ss.apply(config_all, strict: false)
1801common_all = static_library('common',
1802                            build_by_default: false,
1803                            sources: common_all.sources() + genh,
1804                            dependencies: common_all.dependencies(),
1805                            name_suffix: 'fa')
1806
1807feature_to_c = find_program('scripts/feature_to_c.sh')
1808
1809emulators = {}
1810foreach target : target_dirs
1811  config_target = config_target_mak[target]
1812  target_name = config_target['TARGET_NAME']
1813  arch = config_target['TARGET_BASE_ARCH']
1814  arch_srcs = [config_target_h[target]]
1815  arch_deps = []
1816  c_args = ['-DNEED_CPU_H',
1817            '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
1818            '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
1819  link_args = emulator_link_args
1820
1821  config_target += config_host
1822  target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
1823  if targetos == 'linux'
1824    target_inc += include_directories('linux-headers', is_system: true)
1825  endif
1826  if target.endswith('-softmmu')
1827    qemu_target_name = 'qemu-system-' + target_name
1828    target_type='system'
1829    t = target_softmmu_arch[arch].apply(config_target, strict: false)
1830    arch_srcs += t.sources()
1831    arch_deps += t.dependencies()
1832
1833    hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
1834    hw = hw_arch[hw_dir].apply(config_target, strict: false)
1835    arch_srcs += hw.sources()
1836    arch_deps += hw.dependencies()
1837
1838    arch_srcs += config_devices_h[target]
1839    link_args += ['@block.syms', '@qemu.syms']
1840  else
1841    abi = config_target['TARGET_ABI_DIR']
1842    target_type='user'
1843    qemu_target_name = 'qemu-' + target_name
1844    if 'CONFIG_LINUX_USER' in config_target
1845      base_dir = 'linux-user'
1846      target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
1847    else
1848      base_dir = 'bsd-user'
1849    endif
1850    target_inc += include_directories(
1851      base_dir,
1852      base_dir / abi,
1853    )
1854    if 'CONFIG_LINUX_USER' in config_target
1855      dir = base_dir / abi
1856      arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
1857      if config_target.has_key('TARGET_SYSTBL_ABI')
1858        arch_srcs += \
1859          syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
1860                                             extra_args : config_target['TARGET_SYSTBL_ABI'])
1861      endif
1862    endif
1863  endif
1864
1865  if 'TARGET_XML_FILES' in config_target
1866    gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
1867                                output: target + '-gdbstub-xml.c',
1868                                input: files(config_target['TARGET_XML_FILES'].split()),
1869                                command: [feature_to_c, '@INPUT@'],
1870                                capture: true)
1871    arch_srcs += gdbstub_xml
1872  endif
1873
1874  t = target_arch[arch].apply(config_target, strict: false)
1875  arch_srcs += t.sources()
1876  arch_deps += t.dependencies()
1877
1878  target_common = common_ss.apply(config_target, strict: false)
1879  objects = common_all.extract_objects(target_common.sources())
1880  deps = target_common.dependencies()
1881
1882  target_specific = specific_ss.apply(config_target, strict: false)
1883  arch_srcs += target_specific.sources()
1884  arch_deps += target_specific.dependencies()
1885
1886  lib = static_library('qemu-' + target,
1887                 sources: arch_srcs + genh,
1888                 dependencies: arch_deps,
1889                 objects: objects,
1890                 include_directories: target_inc,
1891                 c_args: c_args,
1892                 build_by_default: false,
1893                 name_suffix: 'fa')
1894
1895  if target.endswith('-softmmu')
1896    execs = [{
1897      'name': 'qemu-system-' + target_name,
1898      'gui': false,
1899      'sources': files('softmmu/main.c'),
1900      'dependencies': []
1901    }]
1902    if targetos == 'windows' and (sdl.found() or gtk.found())
1903      execs += [{
1904        'name': 'qemu-system-' + target_name + 'w',
1905        'gui': true,
1906        'sources': files('softmmu/main.c'),
1907        'dependencies': []
1908      }]
1909    endif
1910    if config_host.has_key('CONFIG_FUZZ')
1911      specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
1912      execs += [{
1913        'name': 'qemu-fuzz-' + target_name,
1914        'gui': false,
1915        'sources': specific_fuzz.sources(),
1916        'dependencies': specific_fuzz.dependencies(),
1917      }]
1918    endif
1919  else
1920    execs = [{
1921      'name': 'qemu-' + target_name,
1922      'gui': false,
1923      'sources': [],
1924      'dependencies': []
1925    }]
1926  endif
1927  foreach exe: execs
1928    emulators += {exe['name']:
1929         executable(exe['name'], exe['sources'],
1930               install: true,
1931               c_args: c_args,
1932               dependencies: arch_deps + deps + exe['dependencies'],
1933               objects: lib.extract_all_objects(recursive: true),
1934               link_language: link_language,
1935               link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
1936               link_args: link_args,
1937               gui_app: exe['gui'])
1938    }
1939
1940    if 'CONFIG_TRACE_SYSTEMTAP' in config_host
1941      foreach stp: [
1942        {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
1943        {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
1944        {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
1945        {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
1946      ]
1947        custom_target(exe['name'] + stp['ext'],
1948                      input: trace_events_all,
1949                      output: exe['name'] + stp['ext'],
1950                      capture: true,
1951                      install: stp['install'],
1952                      install_dir: get_option('datadir') / 'systemtap/tapset',
1953                      command: [
1954                        tracetool, '--group=all', '--format=' + stp['fmt'],
1955                        '--binary=' + stp['bin'],
1956                        '--target-name=' + target_name,
1957                        '--target-type=' + target_type,
1958                        '--probe-prefix=qemu.' + target_type + '.' + target_name,
1959                        '@INPUT@',
1960                      ])
1961      endforeach
1962    endif
1963  endforeach
1964endforeach
1965
1966# Other build targets
1967
1968if 'CONFIG_PLUGIN' in config_host
1969  install_headers('include/qemu/qemu-plugin.h')
1970endif
1971
1972if 'CONFIG_GUEST_AGENT' in config_host
1973  subdir('qga')
1974endif
1975
1976# Don't build qemu-keymap if xkbcommon is not explicitly enabled
1977# when we don't build tools or system
1978if xkbcommon.found()
1979  # used for the update-keymaps target, so include rules even if !have_tools
1980  qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
1981                           dependencies: [qemuutil, xkbcommon], install: have_tools)
1982endif
1983
1984if have_tools
1985  qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
1986             dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
1987  qemu_io = executable('qemu-io', files('qemu-io.c'),
1988             dependencies: [block, qemuutil], install: true)
1989  qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
1990               dependencies: [blockdev, qemuutil], install: true)
1991
1992  subdir('storage-daemon')
1993  subdir('contrib/rdmacm-mux')
1994  subdir('contrib/elf2dmp')
1995
1996  executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
1997             dependencies: qemuutil,
1998             install: true)
1999
2000  if 'CONFIG_VHOST_USER' in config_host
2001    subdir('contrib/vhost-user-blk')
2002    subdir('contrib/vhost-user-gpu')
2003    subdir('contrib/vhost-user-input')
2004    subdir('contrib/vhost-user-scsi')
2005  endif
2006
2007  if targetos == 'linux'
2008    executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2009               dependencies: [qemuutil, libcap_ng],
2010               install: true,
2011               install_dir: get_option('libexecdir'))
2012
2013    executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2014               dependencies: [authz, crypto, io, qom, qemuutil,
2015                              libcap_ng, mpathpersist],
2016               install: true)
2017  endif
2018
2019  if 'CONFIG_IVSHMEM' in config_host
2020    subdir('contrib/ivshmem-client')
2021    subdir('contrib/ivshmem-server')
2022  endif
2023endif
2024
2025subdir('scripts')
2026subdir('tools')
2027subdir('pc-bios')
2028subdir('docs')
2029subdir('tests')
2030if 'CONFIG_GTK' in config_host
2031  subdir('po')
2032endif
2033
2034if host_machine.system() == 'windows'
2035  nsis_cmd = [
2036    find_program('scripts/nsis.py'),
2037    '@OUTPUT@',
2038    get_option('prefix'),
2039    meson.current_source_dir(),
2040    host_machine.cpu(),
2041    '--',
2042    '-DDISPLAYVERSION=' + meson.project_version(),
2043  ]
2044  if build_docs
2045    nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2046  endif
2047  if 'CONFIG_GTK' in config_host
2048    nsis_cmd += '-DCONFIG_GTK=y'
2049  endif
2050
2051  nsis = custom_target('nsis',
2052                       output: 'qemu-setup-' + meson.project_version() + '.exe',
2053                       input: files('qemu.nsi'),
2054                       build_always_stale: true,
2055                       command: nsis_cmd + ['@INPUT@'])
2056  alias_target('installer', nsis)
2057endif
2058
2059#########################
2060# Configuration summary #
2061#########################
2062
2063summary_info = {}
2064summary_info += {'Install prefix':    get_option('prefix')}
2065summary_info += {'BIOS directory':    qemu_datadir}
2066summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
2067summary_info += {'binary directory':  get_option('bindir')}
2068summary_info += {'library directory': get_option('libdir')}
2069summary_info += {'module directory':  qemu_moddir}
2070summary_info += {'libexec directory': get_option('libexecdir')}
2071summary_info += {'include directory': get_option('includedir')}
2072summary_info += {'config directory':  get_option('sysconfdir')}
2073if targetos != 'windows'
2074  summary_info += {'local state directory': get_option('localstatedir')}
2075  summary_info += {'Manual directory':      get_option('mandir')}
2076else
2077  summary_info += {'local state directory': 'queried at runtime'}
2078endif
2079summary_info += {'Doc directory':     get_option('docdir')}
2080summary_info += {'Build directory':   meson.current_build_dir()}
2081summary_info += {'Source path':       meson.current_source_dir()}
2082summary_info += {'GIT binary':        config_host['GIT']}
2083summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
2084summary_info += {'C compiler':        meson.get_compiler('c').cmd_array()[0]}
2085summary_info += {'Host C compiler':   meson.get_compiler('c', native: true).cmd_array()[0]}
2086if link_language == 'cpp'
2087  summary_info += {'C++ compiler':      meson.get_compiler('cpp').cmd_array()[0]}
2088else
2089  summary_info += {'C++ compiler':      false}
2090endif
2091if targetos == 'darwin'
2092  summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2093endif
2094summary_info += {'ARFLAGS':           config_host['ARFLAGS']}
2095summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
2096                                               + ['-O' + get_option('optimization')]
2097                                               + (get_option('debug') ? ['-g'] : []))}
2098if link_language == 'cpp'
2099  summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
2100                                               + ['-O' + get_option('optimization')]
2101                                               + (get_option('debug') ? ['-g'] : []))}
2102endif
2103link_args = get_option(link_language + '_link_args')
2104if link_args.length() > 0
2105  summary_info += {'LDFLAGS':         ' '.join(link_args)}
2106endif
2107summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
2108summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
2109summary_info += {'make':              config_host['MAKE']}
2110summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2111summary_info += {'sphinx-build':      sphinx_build.found()}
2112summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
2113# TODO: add back version
2114summary_info += {'slirp support':     slirp_opt == 'disabled' ? false : slirp_opt}
2115if slirp_opt != 'disabled'
2116  summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
2117endif
2118summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
2119if config_host.has_key('CONFIG_MODULES')
2120  summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2121endif
2122summary_info += {'host CPU':          cpu}
2123summary_info += {'host endianness':   build_machine.endian()}
2124summary_info += {'target list':       ' '.join(target_dirs)}
2125summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
2126summary_info += {'sparse enabled':    sparse.found()}
2127summary_info += {'strip binaries':    get_option('strip')}
2128summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
2129summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2130summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
2131if targetos == 'darwin'
2132  summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
2133endif
2134# TODO: add back version
2135summary_info += {'SDL support':       sdl.found()}
2136summary_info += {'SDL image support': sdl_image.found()}
2137# TODO: add back version
2138summary_info += {'GTK support':       config_host.has_key('CONFIG_GTK')}
2139summary_info += {'GTK GL support':    config_host.has_key('CONFIG_GTK_GL')}
2140summary_info += {'pixman':            pixman.found()}
2141# TODO: add back version
2142summary_info += {'VTE support':       config_host.has_key('CONFIG_VTE')}
2143summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
2144summary_info += {'GNUTLS support':    config_host.has_key('CONFIG_GNUTLS')}
2145# TODO: add back version
2146summary_info += {'libgcrypt':         config_host.has_key('CONFIG_GCRYPT')}
2147if config_host.has_key('CONFIG_GCRYPT')
2148   summary_info += {'  hmac':            config_host.has_key('CONFIG_GCRYPT_HMAC')}
2149   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2150endif
2151# TODO: add back version
2152summary_info += {'nettle':            config_host.has_key('CONFIG_NETTLE')}
2153if config_host.has_key('CONFIG_NETTLE')
2154   summary_info += {'  XTS':             not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2155endif
2156summary_info += {'libtasn1':          config_host.has_key('CONFIG_TASN1')}
2157summary_info += {'PAM':               config_host.has_key('CONFIG_AUTH_PAM')}
2158summary_info += {'iconv support':     iconv.found()}
2159summary_info += {'curses support':    curses.found()}
2160# TODO: add back version
2161summary_info += {'virgl support':     config_host.has_key('CONFIG_VIRGL')}
2162summary_info += {'curl support':      config_host.has_key('CONFIG_CURL')}
2163summary_info += {'mingw32 support':   targetos == 'windows'}
2164summary_info += {'Audio drivers':     config_host['CONFIG_AUDIO_DRIVERS']}
2165summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2166summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2167summary_info += {'VirtFS support':    config_host.has_key('CONFIG_VIRTFS')}
2168summary_info += {'build virtiofs daemon': have_virtiofsd}
2169summary_info += {'Multipath support': mpathpersist.found()}
2170summary_info += {'VNC support':       vnc.found()}
2171if vnc.found()
2172  summary_info += {'VNC SASL support':  sasl.found()}
2173  summary_info += {'VNC JPEG support':  jpeg.found()}
2174  summary_info += {'VNC PNG support':   png.found()}
2175endif
2176summary_info += {'xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
2177if config_host.has_key('CONFIG_XEN_BACKEND')
2178  summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2179endif
2180summary_info += {'brlapi support':    config_host.has_key('CONFIG_BRLAPI')}
2181summary_info += {'Documentation':     build_docs}
2182summary_info += {'PIE':               get_option('b_pie')}
2183summary_info += {'vde support':       config_host.has_key('CONFIG_VDE')}
2184summary_info += {'netmap support':    config_host.has_key('CONFIG_NETMAP')}
2185summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2186summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2187summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
2188summary_info += {'Install blobs':     get_option('install_blobs')}
2189summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
2190summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
2191summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
2192summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
2193summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
2194if config_all.has_key('CONFIG_TCG')
2195  summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2196  summary_info += {'TCG interpreter':   config_host.has_key('CONFIG_TCG_INTERPRETER')}
2197endif
2198summary_info += {'malloc trim support': has_malloc_trim}
2199summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
2200summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
2201summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
2202summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
2203summary_info += {'preadv support':    config_host.has_key('CONFIG_PREADV')}
2204summary_info += {'fdatasync':         config_host.has_key('CONFIG_FDATASYNC')}
2205summary_info += {'madvise':           config_host.has_key('CONFIG_MADVISE')}
2206summary_info += {'posix_madvise':     config_host.has_key('CONFIG_POSIX_MADVISE')}
2207summary_info += {'posix_memalign':    config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2208summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
2209summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2210summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2211summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2212summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2213summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2214summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2215summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2216summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2217summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2218summary_info += {'Trace backends':    config_host['TRACE_BACKENDS']}
2219if config_host['TRACE_BACKENDS'].split().contains('simple')
2220  summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2221endif
2222# TODO: add back protocol and server version
2223summary_info += {'spice support':     config_host.has_key('CONFIG_SPICE')}
2224summary_info += {'rbd support':       config_host.has_key('CONFIG_RBD')}
2225summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
2226summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2227summary_info += {'U2F support':       u2f.found()}
2228summary_info += {'libusb':            config_host.has_key('CONFIG_USB_LIBUSB')}
2229summary_info += {'usb net redir':     config_host.has_key('CONFIG_USB_REDIR')}
2230summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
2231summary_info += {'OpenGL dmabufs':    config_host.has_key('CONFIG_OPENGL_DMABUF')}
2232summary_info += {'libiscsi support':  config_host.has_key('CONFIG_LIBISCSI')}
2233summary_info += {'libnfs support':    config_host.has_key('CONFIG_LIBNFS')}
2234summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2235if targetos == 'windows'
2236  if 'WIN_SDK' in config_host
2237    summary_info += {'Windows SDK':       config_host['WIN_SDK']}
2238  endif
2239  summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
2240  summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2241  summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI')}
2242endif
2243summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
2244summary_info += {'CFI support':       get_option('cfi')}
2245summary_info += {'CFI debug support': get_option('cfi_debug')}
2246summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2247summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
2248summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2249summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
2250summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
2251summary_info += {'GlusterFS support': config_host.has_key('CONFIG_GLUSTERFS')}
2252summary_info += {'gcov':              get_option('b_coverage')}
2253summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
2254summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
2255summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2256summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2257summary_info += {'lzo support':       config_host.has_key('CONFIG_LZO')}
2258summary_info += {'snappy support':    config_host.has_key('CONFIG_SNAPPY')}
2259summary_info += {'bzip2 support':     config_host.has_key('CONFIG_BZIP2')}
2260summary_info += {'lzfse support':     config_host.has_key('CONFIG_LZFSE')}
2261summary_info += {'zstd support':      config_host.has_key('CONFIG_ZSTD')}
2262summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2263summary_info += {'libxml2':           config_host.has_key('CONFIG_LIBXML2')}
2264summary_info += {'memory allocator':  get_option('malloc')}
2265summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2266summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2267summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2268summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
2269summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
2270summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
2271summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
2272summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
2273summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
2274summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
2275summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2276summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
2277summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
2278summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
2279summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2280summary_info += {'libudev':           libudev.found()}
2281summary_info += {'default devices':   config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
2282summary_info += {'plugin support':    config_host.has_key('CONFIG_PLUGIN')}
2283summary_info += {'fuzzing support':   config_host.has_key('CONFIG_FUZZ')}
2284if config_host.has_key('HAVE_GDB_BIN')
2285  summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
2286endif
2287summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
2288summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
2289summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
2290summary_info += {'FUSE exports':      fuse.found()}
2291summary_info += {'FUSE lseek':        fuse_lseek.found()}
2292summary(summary_info, bool_yn: true)
2293
2294if not supported_cpus.contains(cpu)
2295  message()
2296  warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2297  message()
2298  message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2299  message('The QEMU project intends to remove support for this host CPU in')
2300  message('a future release if nobody volunteers to maintain it and to')
2301  message('provide a build host for our continuous integration setup.')
2302  message('configure has succeeded and you can continue to build, but')
2303  message('if you care about QEMU on this platform you should contact')
2304  message('us upstream at qemu-devel@nongnu.org.')
2305endif
2306
2307if not supported_oses.contains(targetos)
2308  message()
2309  warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2310  message()
2311  message('Host OS ' + targetos + 'support is not currently maintained.')
2312  message('The QEMU project intends to remove support for this host OS in')
2313  message('a future release if nobody volunteers to maintain it and to')
2314  message('provide a build host for our continuous integration setup.')
2315  message('configure has succeeded and you can continue to build, but')
2316  message('if you care about QEMU on this platform you should contact')
2317  message('us upstream at qemu-devel@nongnu.org.')
2318endif
2319