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