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