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