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