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