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