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