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