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