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