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