vhost-user-scsi: avoid unlink(NULL) with fd passing
[qemu/ar7.git] / meson.build
blob9b20dcd14333919cdb548634b658b7ce2665cd54
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'))
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'])
10 not_found = dependency('', required: false)
11 keyval = import('keyval')
12 ss = import('sourceset')
13 fs = import('fs')
15 sh = find_program('sh')
16 cc = meson.get_compiler('c')
17 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
18 enable_modules = 'CONFIG_MODULES' in config_host
19 enable_static = 'CONFIG_STATIC' in config_host
21 # Allow both shared and static libraries unless --enable-static
22 static_kwargs = enable_static ? {'static': true} : {}
24 # Temporary directory used for files created while
25 # configure runs. Since it is in the build directory
26 # we can safely blow away any previous version of it
27 # (and we need not jump through hoops to try to delete
28 # it when configure exits.)
29 tmpdir = meson.current_build_dir() / 'meson-private/temp'
31 if get_option('qemu_suffix').startswith('/')
32   error('qemu_suffix cannot start with a /')
33 endif
35 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
36 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
37 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
38 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
40 qemu_desktopdir = get_option('datadir') / 'applications'
41 qemu_icondir = get_option('datadir') / 'icons'
43 config_host_data = configuration_data()
44 genh = []
45 qapi_trace_events = []
47 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']
52 cpu = host_machine.cpu_family()
54 # Unify riscv* to a single family.
55 if cpu in ['riscv32', 'riscv64']
56   cpu = 'riscv'
57 endif
59 targetos = host_machine.system()
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
81 python = import('python').find_installation()
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
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
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)
115 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
117 if cpu in ['aarch64']
118   accelerator_targets += {
119     'CONFIG_HVF': ['aarch64-softmmu']
120   }
121 endif
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
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
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
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
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
176 ##################
177 # Compiler flags #
178 ##################
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()
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
193 if get_option('gprof')
194   qemu_cflags += ['-p']
195   qemu_cxxflags += ['-p']
196   qemu_objcflags += ['-p']
197   qemu_ldflags += ['-p']
198 endif
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'])
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'])
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
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'])
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
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'])
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
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
273 ###########################################
274 # Target-specific checks and dependencies #
275 ###########################################
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
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
303 # Miscellaneous Linux-only features
304 get_option('mpath') \
305   .require(targetos == 'linux', error_message: 'Multipath is supported only on Linux')
307 multiprocess_allowed = get_option('multiprocess') \
308   .require(targetos == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
309   .allowed()
311 have_tpm = get_option('tpm') \
312   .require(targetos != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
313   .allowed()
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()
330 have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel
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
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')
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
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
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'])
442   accelerators += 'CONFIG_TCG'
443   config_host += { 'CONFIG_TCG': 'y' }
444 endif
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
459 ################
460 # Dependencies #
461 ################
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)
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
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)
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
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; }'''
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
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
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
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
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
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
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
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)
660 rt = cc.find_library('rt', required: false)
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
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
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
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     }'''
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
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
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
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
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>
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>
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       {}
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
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
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
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
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
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
1033   if not dsound.found()
1034     if get_option('dsound').enabled()
1035       error('DirectSound not found')
1036     endif
1037   endif
1038 endif
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
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()
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
1094 # We prefer use of gnutls for crypto, unless the options
1095 # explicitly asked for nettle or gcrypt.
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'
1103 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1104   error('Only one of gcrypt & nettle can be enabled')
1105 endif
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
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
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])
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
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
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
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
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
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
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
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
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()
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
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)
1408 has_gettid = cc.has_function('gettid')
1410 # libselinux
1411 selinux = dependency('libselinux',
1412                      required: get_option('selinux'),
1413                      method: 'pkg-config', kwargs: static_kwargs)
1415 # Malloc tests
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
1435 # Check whether the glibc provides statx()
1437 gnu_source_prefix = '''
1438   #ifndef _GNU_SOURCE
1439   #define _GNU_SOURCE
1440   #endif
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   }'''
1450 has_statx = cc.links(statx_test)
1452 # Check whether statx() provides mount ID information
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   }'''
1462 has_statx_mnt_id = cc.links(statx_mnt_id_test)
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()
1472 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1473   error('Cannot enable fuse-lseek while fuse is disabled')
1474 endif
1476 fuse = dependency('fuse3', required: get_option('fuse'),
1477                   version: '>=3.1', method: 'pkg-config',
1478                   kwargs: static_kwargs)
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
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
1511 #################
1512 # config-host.h #
1513 #################
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
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
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) + '", ')
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
1594 have_host_block_device = (targetos != 'darwin' or
1595     cc.has_header('IOKit/storage/IOMedia.h'))
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()
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()
1617 have_virtfs_proxy_helper = targetos != 'darwin' and have_virtfs and have_tools
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
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'))
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
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
1672 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
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'))
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_GCRYPT', gcrypt.found())
1746 config_host_data.set('CONFIG_NETTLE', nettle.found())
1747 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1748 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1749 config_host_data.set('CONFIG_STATX', has_statx)
1750 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
1751 config_host_data.set('CONFIG_ZSTD', zstd.found())
1752 config_host_data.set('CONFIG_FUSE', fuse.found())
1753 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1754 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1755 if spice_protocol.found()
1756 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
1757 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
1758 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
1759 endif
1760 config_host_data.set('CONFIG_SPICE', spice.found())
1761 config_host_data.set('CONFIG_X11', x11.found())
1762 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
1763 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1764 config_host_data.set('CONFIG_SELINUX', selinux.found())
1765 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
1766 if xen.found()
1767   # protect from xen.version() having less than three components
1768   xen_version = xen.version().split('.') + ['0', '0']
1769   xen_ctrl_version = xen_version[0] + \
1770     ('0' + xen_version[1]).substring(-2) + \
1771     ('0' + xen_version[2]).substring(-2)
1772   config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
1773 endif
1774 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1775 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1776 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1777 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1779 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1780 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1782 have_coroutine_pool = get_option('coroutine_pool')
1783 if get_option('debug_stack_usage') and have_coroutine_pool
1784   message('Disabling coroutine pool to measure stack usage')
1785   have_coroutine_pool = false
1786 endif
1787 config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool)
1788 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
1789 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
1790 config_host_data.set('CONFIG_GPROF', get_option('gprof'))
1791 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
1792 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
1793 config_host_data.set('CONFIG_REPLICATION', get_option('live_block_migration').allowed())
1795 # has_header
1796 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1797 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1798 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1799 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1800 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1801 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1802 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1803 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1804 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1806 # has_function
1807 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1808 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1809 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1810 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1811 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1812 # Note that we need to specify prefix: here to avoid incorrectly
1813 # thinking that Windows has posix_memalign()
1814 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
1815 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
1816 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
1817 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
1818 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1819 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1820 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
1821 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1822 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1823 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1824 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1825 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1826 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1827 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
1828 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1829 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1830 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1831 if rdma.found()
1832   config_host_data.set('HAVE_IBV_ADVISE_MR',
1833                        cc.has_function('ibv_advise_mr',
1834                                        dependencies: rdma,
1835                                        prefix: '#include <infiniband/verbs.h>'))
1836 endif
1838 # has_header_symbol
1839 config_host_data.set('CONFIG_BYTESWAP_H',
1840                      cc.has_header_symbol('byteswap.h', 'bswap_32'))
1841 config_host_data.set('CONFIG_EPOLL_CREATE1',
1842                      cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1843 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1844                      cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1845                      cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1846 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1847                      cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1848 config_host_data.set('CONFIG_FIEMAP',
1849                      cc.has_header('linux/fiemap.h') and
1850                      cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1851 config_host_data.set('CONFIG_GETRANDOM',
1852                      cc.has_function('getrandom') and
1853                      cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1854 config_host_data.set('CONFIG_INOTIFY',
1855                      cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1856 config_host_data.set('CONFIG_INOTIFY1',
1857                      cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1858 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1859                      cc.has_header_symbol('machine/bswap.h', 'bswap32',
1860                                           prefix: '''#include <sys/endian.h>
1861                                                      #include <sys/types.h>'''))
1862 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1863                      cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1864 config_host_data.set('CONFIG_RTNETLINK',
1865                      cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1866 config_host_data.set('CONFIG_SYSMACROS',
1867                      cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1868 config_host_data.set('HAVE_OPTRESET',
1869                      cc.has_header_symbol('getopt.h', 'optreset'))
1870 config_host_data.set('HAVE_IPPROTO_MPTCP',
1871                      cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1873 # has_member
1874 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1875                      cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1876                                    prefix: '#include <signal.h>'))
1877 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1878                      cc.has_member('struct stat', 'st_atim',
1879                                    prefix: '#include <sys/stat.h>'))
1881 # has_type
1882 config_host_data.set('CONFIG_IOVEC',
1883                      cc.has_type('struct iovec',
1884                                  prefix: '#include <sys/uio.h>'))
1885 config_host_data.set('HAVE_UTMPX',
1886                      cc.has_type('struct utmpx',
1887                                  prefix: '#include <utmpx.h>'))
1889 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1890   #include <sys/eventfd.h>
1891   int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1892 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1893   #include <unistd.h>
1894   int main(void) {
1895   #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1896   return fdatasync(0);
1897   #else
1898   #error Not supported
1899   #endif
1900   }'''))
1902 has_madvise = cc.links(gnu_source_prefix + '''
1903   #include <sys/types.h>
1904   #include <sys/mman.h>
1905   #include <stddef.h>
1906   int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
1907 missing_madvise_proto = false
1908 if has_madvise
1909   # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
1910   # but forget to prototype it. In this case, has_madvise will be true (the
1911   # test program links despite a compile warning). To detect the
1912   # missing-prototype case, we try again with a definitely-bogus prototype.
1913   # This will only compile if the system headers don't provide the prototype;
1914   # otherwise the conflicting prototypes will cause a compiler error.
1915   missing_madvise_proto = cc.links(gnu_source_prefix + '''
1916     #include <sys/types.h>
1917     #include <sys/mman.h>
1918     #include <stddef.h>
1919     extern int madvise(int);
1920     int main(void) { return madvise(0); }''')
1921 endif
1922 config_host_data.set('CONFIG_MADVISE', has_madvise)
1923 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
1925 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1926   #include <sys/mman.h>
1927   int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1928 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1929   #include <fcntl.h>
1930   #if !defined(AT_EMPTY_PATH)
1931   # error missing definition
1932   #else
1933   int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1934   #endif'''))
1935 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1936   #include <unistd.h>
1937   #include <fcntl.h>
1939   int main(void)
1940   {
1941       int pipefd[2];
1942       return pipe2(pipefd, O_CLOEXEC);
1943   }'''))
1944 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1945   #include <sys/mman.h>
1946   #include <stddef.h>
1947   int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1949 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
1950   #include <pthread.h>
1952   static void *f(void *p) { return NULL; }
1953   int main(void)
1954   {
1955     pthread_t thread;
1956     pthread_create(&thread, 0, f, 0);
1957     pthread_setname_np(thread, "QEMU");
1958     return 0;
1959   }''', dependencies: threads))
1960 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
1961   #include <pthread.h>
1963   static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
1964   int main(void)
1965   {
1966     pthread_t thread;
1967     pthread_create(&thread, 0, f, 0);
1968     return 0;
1969   }''', dependencies: threads))
1970 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
1971   #include <pthread.h>
1972   #include <time.h>
1974   int main(void)
1975   {
1976     pthread_condattr_t attr
1977     pthread_condattr_init(&attr);
1978     pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
1979     return 0;
1980   }''', dependencies: threads))
1982 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1983   #include <sys/signalfd.h>
1984   #include <stddef.h>
1985   int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1986 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1987   #include <unistd.h>
1988   #include <fcntl.h>
1989   #include <limits.h>
1991   int main(void)
1992   {
1993     int len, fd = 0;
1994     len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1995     splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1996     return 0;
1997   }'''))
1999 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
2000   #include <sys/mman.h>
2001   int main(int argc, char *argv[]) {
2002     return mlockall(MCL_FUTURE);
2003   }'''))
2005 have_l2tpv3 = false
2006 if get_option('l2tpv3').allowed() and have_system
2007   have_l2tpv3 = cc.has_type('struct mmsghdr',
2008     prefix: gnu_source_prefix + '''
2009       #include <sys/socket.h>
2010       #include <linux/ip.h>''')
2011 endif
2012 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2014 have_netmap = false
2015 if get_option('netmap').allowed() and have_system
2016   have_netmap = cc.compiles('''
2017     #include <inttypes.h>
2018     #include <net/if.h>
2019     #include <net/netmap.h>
2020     #include <net/netmap_user.h>
2021     #if (NETMAP_API < 11) || (NETMAP_API > 15)
2022     #error
2023     #endif
2024     int main(void) { return 0; }''')
2025   if not have_netmap and get_option('netmap').enabled()
2026     error('Netmap headers not available')
2027   endif
2028 endif
2029 config_host_data.set('CONFIG_NETMAP', have_netmap)
2031 # Work around a system header bug with some kernel/XFS header
2032 # versions where they both try to define 'struct fsxattr':
2033 # xfs headers will not try to redefine structs from linux headers
2034 # if this macro is set.
2035 config_host_data.set('HAVE_FSXATTR', cc.links('''
2036   #include <linux/fs.h>
2037   struct fsxattr foo;
2038   int main(void) {
2039     return 0;
2040   }'''))
2042 # Some versions of Mac OS X incorrectly define SIZE_MAX
2043 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2044     #include <stdint.h>
2045     #include <stdio.h>
2046     int main(int argc, char *argv[]) {
2047         return printf("%zu", SIZE_MAX);
2048     }''', args: ['-Werror']))
2050 atomic_test = '''
2051   #include <stdint.h>
2052   int main(void)
2053   {
2054     @0@ x = 0, y = 0;
2055     y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2056     __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2057     __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2058     __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2059     __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2060     return 0;
2061   }'''
2063 # See if 64-bit atomic operations are supported.
2064 # Note that without __atomic builtins, we can only
2065 # assume atomic loads/stores max at pointer size.
2066 config_host_data.set('CONFIG_ATOMIC64', cc.links(atomic_test.format('uint64_t')))
2068 has_int128 = cc.links('''
2069   __int128_t a;
2070   __uint128_t b;
2071   int main (void) {
2072     a = a + b;
2073     b = a * b;
2074     a = a * a;
2075     return 0;
2076   }''')
2078 config_host_data.set('CONFIG_INT128', has_int128)
2080 if has_int128
2081   # "do we have 128-bit atomics which are handled inline and specifically not
2082   # via libatomic". The reason we can't use libatomic is documented in the
2083   # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2084   has_atomic128 = cc.links(atomic_test.format('unsigned __int128'))
2086   config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2088   if not has_atomic128
2089     has_cmpxchg128 = cc.links('''
2090       int main(void)
2091       {
2092         unsigned __int128 x = 0, y = 0;
2093         __sync_val_compare_and_swap_16(&x, y, x);
2094         return 0;
2095       }
2096     ''')
2098     config_host_data.set('CONFIG_CMPXCHG128', has_cmpxchg128)
2099   endif
2100 endif
2102 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2103   #include <sys/auxv.h>
2104   int main(void) {
2105     return getauxval(AT_HWCAP) == 0;
2106   }'''))
2108 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2109   #include <linux/usbdevice_fs.h>
2111   #ifndef USBDEVFS_GET_CAPABILITIES
2112   #error "USBDEVFS_GET_CAPABILITIES undefined"
2113   #endif
2115   #ifndef USBDEVFS_DISCONNECT_CLAIM
2116   #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2117   #endif
2119   int main(void) { return 0; }'''))
2121 have_keyring = get_option('keyring') \
2122   .require(targetos == 'linux', error_message: 'keyring is only available on Linux') \
2123   .require(cc.compiles('''
2124     #include <errno.h>
2125     #include <asm/unistd.h>
2126     #include <linux/keyctl.h>
2127     #include <sys/syscall.h>
2128     #include <unistd.h>
2129     int main(void) {
2130         return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2131     }'''), error_message: 'keyctl syscall not available on this system').allowed()
2132 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2134 have_cpuid_h = cc.links('''
2135   #include <cpuid.h>
2136   int main(void) {
2137     unsigned a, b, c, d;
2138     unsigned max = __get_cpuid_max(0, 0);
2140     if (max >= 1) {
2141         __cpuid(1, a, b, c, d);
2142     }
2144     if (max >= 7) {
2145         __cpuid_count(7, 0, a, b, c, d);
2146     }
2148     return 0;
2149   }''')
2150 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2152 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2153   .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2154   .require(cc.links('''
2155     #pragma GCC push_options
2156     #pragma GCC target("avx2")
2157     #include <cpuid.h>
2158     #include <immintrin.h>
2159     static int bar(void *a) {
2160       __m256i x = *(__m256i *)a;
2161       return _mm256_testz_si256(x, x);
2162     }
2163     int main(int argc, char *argv[]) { return bar(argv[0]); }
2164   '''), error_message: 'AVX2 not available').allowed())
2166 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2167   .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2168   .require(cc.links('''
2169     #pragma GCC push_options
2170     #pragma GCC target("avx512f")
2171     #include <cpuid.h>
2172     #include <immintrin.h>
2173     static int bar(void *a) {
2174       __m512i x = *(__m512i *)a;
2175       return _mm512_test_epi64_mask(x, x);
2176     }
2177     int main(int argc, char *argv[]) { return bar(argv[0]); }
2178   '''), error_message: 'AVX512F not available').allowed())
2180 have_pvrdma = get_option('pvrdma') \
2181   .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
2182   .require(cc.compiles(gnu_source_prefix + '''
2183     #include <sys/mman.h>
2184     int main(void)
2185     {
2186       char buf = 0;
2187       void *addr = &buf;
2188       addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2190       return 0;
2191     }'''), error_message: 'PVRDMA requires mremap').allowed()
2193 if have_pvrdma
2194   config_host_data.set('LEGACY_RDMA_REG_MR', not cc.links('''
2195     #include <infiniband/verbs.h>
2196     int main(void)
2197     {
2198       struct ibv_mr *mr;
2199       struct ibv_pd *pd = NULL;
2200       size_t length = 10;
2201       uint64_t iova = 0;
2202       int access = 0;
2203       void *addr = NULL;
2205       mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2206       ibv_dereg_mr(mr);
2207       return 0;
2208     }'''))
2209 endif
2211 if get_option('membarrier').disabled()
2212   have_membarrier = false
2213 elif targetos == 'windows'
2214   have_membarrier = true
2215 elif targetos == 'linux'
2216   have_membarrier = cc.compiles('''
2217     #include <linux/membarrier.h>
2218     #include <sys/syscall.h>
2219     #include <unistd.h>
2220     #include <stdlib.h>
2221     int main(void) {
2222         syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2223         syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2224         exit(0);
2225     }''')
2226 endif
2227 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2228   .require(have_membarrier, error_message: 'membarrier system call not available') \
2229   .allowed())
2231 have_afalg = get_option('crypto_afalg') \
2232   .require(cc.compiles(gnu_source_prefix + '''
2233     #include <errno.h>
2234     #include <sys/types.h>
2235     #include <sys/socket.h>
2236     #include <linux/if_alg.h>
2237     int main(void) {
2238       int sock;
2239       sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2240       return sock;
2241     }
2242   '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2243 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2245 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2246   'linux/vm_sockets.h', 'AF_VSOCK',
2247   prefix: '#include <sys/socket.h>',
2250 have_vss = false
2251 have_vss_sdk = false # old xp/2003 SDK
2252 if targetos == 'windows' and link_language == 'cpp'
2253   have_vss = cxx.compiles('''
2254     #define __MIDL_user_allocate_free_DEFINED__
2255     #include <vss.h>
2256     int main(void) { return VSS_CTX_BACKUP; }''')
2257   have_vss_sdk = cxx.has_header('vscoordint.h')
2258 endif
2259 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2261 foreach k, v: config_host
2262   if k.startswith('CONFIG_')
2263     config_host_data.set(k, v == 'y' ? 1 : v)
2264   endif
2265 endforeach
2267 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2268 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2269 if targetos == 'windows'
2270   config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2271     #include <stdio.h>
2272     int main(void) {
2273       _lock_file(NULL);
2274       _unlock_file(NULL);
2275       return 0;
2276     }''', name: '_lock_file and _unlock_file'))
2277 endif
2279 ########################
2280 # Target configuration #
2281 ########################
2283 minikconf = find_program('scripts/minikconf.py')
2284 config_all = {}
2285 config_all_devices = {}
2286 config_all_disas = {}
2287 config_devices_mak_list = []
2288 config_devices_h = {}
2289 config_target_h = {}
2290 config_target_mak = {}
2292 disassemblers = {
2293   'alpha' : ['CONFIG_ALPHA_DIS'],
2294   'arm' : ['CONFIG_ARM_DIS'],
2295   'avr' : ['CONFIG_AVR_DIS'],
2296   'cris' : ['CONFIG_CRIS_DIS'],
2297   'hexagon' : ['CONFIG_HEXAGON_DIS'],
2298   'hppa' : ['CONFIG_HPPA_DIS'],
2299   'i386' : ['CONFIG_I386_DIS'],
2300   'x86_64' : ['CONFIG_I386_DIS'],
2301   'm68k' : ['CONFIG_M68K_DIS'],
2302   'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2303   'mips' : ['CONFIG_MIPS_DIS'],
2304   'nios2' : ['CONFIG_NIOS2_DIS'],
2305   'or1k' : ['CONFIG_OPENRISC_DIS'],
2306   'ppc' : ['CONFIG_PPC_DIS'],
2307   'riscv' : ['CONFIG_RISCV_DIS'],
2308   'rx' : ['CONFIG_RX_DIS'],
2309   's390' : ['CONFIG_S390_DIS'],
2310   'sh4' : ['CONFIG_SH4_DIS'],
2311   'sparc' : ['CONFIG_SPARC_DIS'],
2312   'xtensa' : ['CONFIG_XTENSA_DIS'],
2314 if link_language == 'cpp'
2315   disassemblers += {
2316     'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
2317     'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
2318     'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
2319   }
2320 endif
2322 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2323 host_kconfig = \
2324   (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2325   (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2326   (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2327   (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2328   (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2329   (x11.found() ? ['CONFIG_X11=y'] : []) + \
2330   (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
2331   (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2332   (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2333   (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2334   ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
2335   (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
2336   (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
2338 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2340 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2341 actual_target_dirs = []
2342 fdt_required = []
2343 foreach target : target_dirs
2344   config_target = { 'TARGET_NAME': target.split('-')[0] }
2345   if target.endswith('linux-user')
2346     if targetos != 'linux'
2347       if default_targets
2348         continue
2349       endif
2350       error('Target @0@ is only available on a Linux host'.format(target))
2351     endif
2352     config_target += { 'CONFIG_LINUX_USER': 'y' }
2353   elif target.endswith('bsd-user')
2354     if 'CONFIG_BSD' not in config_host
2355       if default_targets
2356         continue
2357       endif
2358       error('Target @0@ is only available on a BSD host'.format(target))
2359     endif
2360     config_target += { 'CONFIG_BSD_USER': 'y' }
2361   elif target.endswith('softmmu')
2362     config_target += { 'CONFIG_SOFTMMU': 'y' }
2363   endif
2364   if target.endswith('-user')
2365     config_target += {
2366       'CONFIG_USER_ONLY': 'y',
2367       'CONFIG_QEMU_INTERP_PREFIX':
2368         get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
2369     }
2370   endif
2372   accel_kconfig = []
2373   foreach sym: accelerators
2374     if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2375       config_target += { sym: 'y' }
2376       config_all += { sym: 'y' }
2377       if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
2378         config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
2379       endif
2380       if target in modular_tcg
2381         config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2382       else
2383         config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2384       endif
2385       accel_kconfig += [ sym + '=y' ]
2386     endif
2387   endforeach
2388   if accel_kconfig.length() == 0
2389     if default_targets
2390       continue
2391     endif
2392     error('No accelerator available for target @0@'.format(target))
2393   endif
2395   actual_target_dirs += target
2396   config_target += keyval.load('configs/targets' / target + '.mak')
2397   config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
2399   if 'TARGET_NEED_FDT' in config_target
2400     fdt_required += target
2401   endif
2403   # Add default keys
2404   if 'TARGET_BASE_ARCH' not in config_target
2405     config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2406   endif
2407   if 'TARGET_ABI_DIR' not in config_target
2408     config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2409   endif
2410   if 'TARGET_BIG_ENDIAN' not in config_target
2411     config_target += {'TARGET_BIG_ENDIAN': 'n'}
2412   endif
2414   foreach k, v: disassemblers
2415     if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
2416       foreach sym: v
2417         config_target += { sym: 'y' }
2418         config_all_disas += { sym: 'y' }
2419       endforeach
2420     endif
2421   endforeach
2423   config_target_data = configuration_data()
2424   foreach k, v: config_target
2425     if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2426       # do nothing
2427     elif ignored.contains(k)
2428       # do nothing
2429     elif k == 'TARGET_BASE_ARCH'
2430       # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2431       # not used to select files from sourcesets.
2432       config_target_data.set('TARGET_' + v.to_upper(), 1)
2433     elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
2434       config_target_data.set_quoted(k, v)
2435     elif v == 'y'
2436       config_target_data.set(k, 1)
2437     elif v == 'n'
2438       config_target_data.set(k, 0)
2439     else
2440       config_target_data.set(k, v)
2441     endif
2442   endforeach
2443   config_target_data.set('QEMU_ARCH',
2444                          'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
2445   config_target_h += {target: configure_file(output: target + '-config-target.h',
2446                                                configuration: config_target_data)}
2448   if target.endswith('-softmmu')
2449     config_input = meson.get_external_property(target, 'default')
2450     config_devices_mak = target + '-config-devices.mak'
2451     config_devices_mak = configure_file(
2452       input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2453       output: config_devices_mak,
2454       depfile: config_devices_mak + '.d',
2455       capture: true,
2456       command: [minikconf,
2457                 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2458                 config_devices_mak, '@DEPFILE@', '@INPUT@',
2459                 host_kconfig, accel_kconfig,
2460                 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
2462     config_devices_data = configuration_data()
2463     config_devices = keyval.load(config_devices_mak)
2464     foreach k, v: config_devices
2465       config_devices_data.set(k, 1)
2466     endforeach
2467     config_devices_mak_list += config_devices_mak
2468     config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2469                                                 configuration: config_devices_data)}
2470     config_target += config_devices
2471     config_all_devices += config_devices
2472   endif
2473   config_target_mak += {target: config_target}
2474 endforeach
2475 target_dirs = actual_target_dirs
2477 # This configuration is used to build files that are shared by
2478 # multiple binaries, and then extracted out of the "common"
2479 # static_library target.
2481 # We do not use all_sources()/all_dependencies(), because it would
2482 # build literally all source files, including devices only used by
2483 # targets that are not built for this compilation.  The CONFIG_ALL
2484 # pseudo symbol replaces it.
2486 config_all += config_all_devices
2487 config_all += config_host
2488 config_all += config_all_disas
2489 config_all += {
2490   'CONFIG_XEN': xen.found(),
2491   'CONFIG_SOFTMMU': have_system,
2492   'CONFIG_USER_ONLY': have_user,
2493   'CONFIG_ALL': true,
2496 target_configs_h = []
2497 foreach target: target_dirs
2498   target_configs_h += config_target_h[target]
2499   target_configs_h += config_devices_h.get(target, [])
2500 endforeach
2501 genh += custom_target('config-poison.h',
2502                       input: [target_configs_h],
2503                       output: 'config-poison.h',
2504                       capture: true,
2505                       command: [find_program('scripts/make-config-poison.sh'),
2506                                 target_configs_h])
2508 ##############
2509 # Submodules #
2510 ##############
2512 capstone = not_found
2513 capstone_opt = get_option('capstone')
2514 if capstone_opt in ['enabled', 'auto', 'system']
2515   have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
2516   capstone = dependency('capstone', version: '>=4.0',
2517                         kwargs: static_kwargs, method: 'pkg-config',
2518                         required: capstone_opt == 'system' or
2519                                   capstone_opt == 'enabled' and not have_internal)
2521   # Some versions of capstone have broken pkg-config file
2522   # that reports a wrong -I path, causing the #include to
2523   # fail later. If the system has such a broken version
2524   # do not use it.
2525   if capstone.found() and not cc.compiles('#include <capstone.h>',
2526                                           dependencies: [capstone])
2527     capstone = not_found
2528     if capstone_opt == 'system'
2529       error('system capstone requested, it does not appear to work')
2530     endif
2531   endif
2533   if capstone.found()
2534     capstone_opt = 'system'
2535   elif have_internal
2536     capstone_opt = 'internal'
2537   else
2538     capstone_opt = 'disabled'
2539   endif
2540 endif
2541 if capstone_opt == 'internal'
2542   capstone_data = configuration_data()
2543   capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
2545   capstone_files = files(
2546     'capstone/cs.c',
2547     'capstone/MCInst.c',
2548     'capstone/MCInstrDesc.c',
2549     'capstone/MCRegisterInfo.c',
2550     'capstone/SStream.c',
2551     'capstone/utils.c'
2552   )
2554   if 'CONFIG_ARM_DIS' in config_all_disas
2555     capstone_data.set('CAPSTONE_HAS_ARM', '1')
2556     capstone_files += files(
2557       'capstone/arch/ARM/ARMDisassembler.c',
2558       'capstone/arch/ARM/ARMInstPrinter.c',
2559       'capstone/arch/ARM/ARMMapping.c',
2560       'capstone/arch/ARM/ARMModule.c'
2561     )
2562   endif
2564   # FIXME: This config entry currently depends on a c++ compiler.
2565   # Which is needed for building libvixl, but not for capstone.
2566   if 'CONFIG_ARM_A64_DIS' in config_all_disas
2567     capstone_data.set('CAPSTONE_HAS_ARM64', '1')
2568     capstone_files += files(
2569       'capstone/arch/AArch64/AArch64BaseInfo.c',
2570       'capstone/arch/AArch64/AArch64Disassembler.c',
2571       'capstone/arch/AArch64/AArch64InstPrinter.c',
2572       'capstone/arch/AArch64/AArch64Mapping.c',
2573       'capstone/arch/AArch64/AArch64Module.c'
2574     )
2575   endif
2577   if 'CONFIG_PPC_DIS' in config_all_disas
2578     capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
2579     capstone_files += files(
2580       'capstone/arch/PowerPC/PPCDisassembler.c',
2581       'capstone/arch/PowerPC/PPCInstPrinter.c',
2582       'capstone/arch/PowerPC/PPCMapping.c',
2583       'capstone/arch/PowerPC/PPCModule.c'
2584     )
2585   endif
2587   if 'CONFIG_S390_DIS' in config_all_disas
2588     capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
2589     capstone_files += files(
2590       'capstone/arch/SystemZ/SystemZDisassembler.c',
2591       'capstone/arch/SystemZ/SystemZInstPrinter.c',
2592       'capstone/arch/SystemZ/SystemZMapping.c',
2593       'capstone/arch/SystemZ/SystemZModule.c',
2594       'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
2595     )
2596   endif
2598   if 'CONFIG_I386_DIS' in config_all_disas
2599     capstone_data.set('CAPSTONE_HAS_X86', 1)
2600     capstone_files += files(
2601       'capstone/arch/X86/X86Disassembler.c',
2602       'capstone/arch/X86/X86DisassemblerDecoder.c',
2603       'capstone/arch/X86/X86ATTInstPrinter.c',
2604       'capstone/arch/X86/X86IntelInstPrinter.c',
2605       'capstone/arch/X86/X86InstPrinterCommon.c',
2606       'capstone/arch/X86/X86Mapping.c',
2607       'capstone/arch/X86/X86Module.c'
2608     )
2609   endif
2611   configure_file(output: 'capstone-defs.h', configuration: capstone_data)
2613   capstone_cargs = [
2614     # FIXME: There does not seem to be a way to completely replace the c_args
2615     # that come from add_project_arguments() -- we can only add to them.
2616     # So: disable all warnings with a big hammer.
2617     '-Wno-error', '-w',
2619     # Include all configuration defines via a header file, which will wind up
2620     # as a dependency on the object file, and thus changes here will result
2621     # in a rebuild.
2622     '-include', 'capstone-defs.h'
2623   ]
2625   libcapstone = static_library('capstone',
2626                                build_by_default: false,
2627                                sources: capstone_files,
2628                                c_args: capstone_cargs,
2629                                include_directories: 'capstone/include')
2630   capstone = declare_dependency(link_with: libcapstone,
2631                                 include_directories: 'capstone/include/capstone')
2632 endif
2634 slirp = not_found
2635 slirp_opt = 'disabled'
2636 if have_system
2637   slirp_opt = get_option('slirp')
2638   if slirp_opt in ['enabled', 'auto', 'system']
2639     have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2640     slirp_dep_required = (slirp_opt == 'system' or
2641                           slirp_opt == 'enabled' and not have_internal)
2642     slirp = dependency('slirp', kwargs: static_kwargs,
2643                        method: 'pkg-config', version: '>=4.1.0',
2644                        required: slirp_dep_required)
2645     # slirp <4.7 is incompatible with CFI support in QEMU.  This is because
2646     # it passes function pointers within libslirp as callbacks for timers.
2647     # When using a system-wide shared libslirp, the type information for the
2648     # callback is missing and the timer call produces a false positive with CFI.
2649     # Do not use the "version" keyword argument to produce a better error.
2650     # with control-flow integrity.
2651     if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
2652       if slirp_dep_required
2653         error('Control-Flow Integrity requires libslirp 4.7.')
2654       else
2655         warning('Control-Flow Integrity requires libslirp 4.7, not using system-wide libslirp.')
2656         slirp = not_found
2657       endif
2658     endif
2659     if slirp.found()
2660       slirp_opt = 'system'
2661     elif have_internal
2662       slirp_opt = 'internal'
2663     else
2664       slirp_opt = 'disabled'
2665     endif
2666   endif
2667   if slirp_opt == 'internal'
2668     slirp_deps = []
2669     if targetos == 'windows'
2670       slirp_deps = cc.find_library('iphlpapi')
2671     elif targetos == 'darwin'
2672       slirp_deps = cc.find_library('resolv')
2673     endif
2674     slirp_conf = configuration_data()
2675     slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2676     slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2677     slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2678     slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2679     slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2680     slirp_files = [
2681       'slirp/src/arp_table.c',
2682       'slirp/src/bootp.c',
2683       'slirp/src/cksum.c',
2684       'slirp/src/dhcpv6.c',
2685       'slirp/src/dnssearch.c',
2686       'slirp/src/if.c',
2687       'slirp/src/ip6_icmp.c',
2688       'slirp/src/ip6_input.c',
2689       'slirp/src/ip6_output.c',
2690       'slirp/src/ip_icmp.c',
2691       'slirp/src/ip_input.c',
2692       'slirp/src/ip_output.c',
2693       'slirp/src/mbuf.c',
2694       'slirp/src/misc.c',
2695       'slirp/src/ncsi.c',
2696       'slirp/src/ndp_table.c',
2697       'slirp/src/sbuf.c',
2698       'slirp/src/slirp.c',
2699       'slirp/src/socket.c',
2700       'slirp/src/state.c',
2701       'slirp/src/stream.c',
2702       'slirp/src/tcp_input.c',
2703       'slirp/src/tcp_output.c',
2704       'slirp/src/tcp_subr.c',
2705       'slirp/src/tcp_timer.c',
2706       'slirp/src/tftp.c',
2707       'slirp/src/udp.c',
2708       'slirp/src/udp6.c',
2709       'slirp/src/util.c',
2710       'slirp/src/version.c',
2711       'slirp/src/vmstate.c',
2712     ]
2714     configure_file(
2715       input : 'slirp/src/libslirp-version.h.in',
2716       output : 'libslirp-version.h',
2717       configuration: slirp_conf)
2719     slirp_inc = include_directories('slirp', 'slirp/src')
2720     libslirp = static_library('slirp',
2721                               build_by_default: false,
2722                               sources: slirp_files,
2723                               c_args: slirp_cargs,
2724                               include_directories: slirp_inc)
2725     slirp = declare_dependency(link_with: libslirp,
2726                                dependencies: slirp_deps,
2727                                include_directories: slirp_inc)
2728   endif
2729 endif
2731 fdt = not_found
2732 if have_system
2733   fdt_opt = get_option('fdt')
2734   if fdt_opt in ['enabled', 'auto', 'system']
2735     have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2736     fdt = cc.find_library('fdt', kwargs: static_kwargs,
2737                           required: fdt_opt == 'system' or
2738                                     fdt_opt == 'enabled' and not have_internal)
2739     if fdt.found() and cc.links('''
2740        #include <libfdt.h>
2741        #include <libfdt_env.h>
2742        int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2743          dependencies: fdt)
2744       fdt_opt = 'system'
2745     elif fdt_opt == 'system'
2746        error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2747     elif have_internal
2748       fdt_opt = 'internal'
2749     else
2750       fdt_opt = 'disabled'
2751       fdt = not_found
2752     endif
2753   endif
2754   if fdt_opt == 'internal'
2755     fdt_files = files(
2756       'dtc/libfdt/fdt.c',
2757       'dtc/libfdt/fdt_ro.c',
2758       'dtc/libfdt/fdt_wip.c',
2759       'dtc/libfdt/fdt_sw.c',
2760       'dtc/libfdt/fdt_rw.c',
2761       'dtc/libfdt/fdt_strerror.c',
2762       'dtc/libfdt/fdt_empty_tree.c',
2763       'dtc/libfdt/fdt_addresses.c',
2764       'dtc/libfdt/fdt_overlay.c',
2765       'dtc/libfdt/fdt_check.c',
2766     )
2768     fdt_inc = include_directories('dtc/libfdt')
2769     libfdt = static_library('fdt',
2770                             build_by_default: false,
2771                             sources: fdt_files,
2772                             include_directories: fdt_inc)
2773     fdt = declare_dependency(link_with: libfdt,
2774                              include_directories: fdt_inc)
2775   endif
2776 else
2777   fdt_opt = 'disabled'
2778 endif
2779 if not fdt.found() and fdt_required.length() > 0
2780   error('fdt not available but required by targets ' + ', '.join(fdt_required))
2781 endif
2783 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2784 config_host_data.set('CONFIG_FDT', fdt.found())
2785 config_host_data.set('CONFIG_SLIRP', slirp.found())
2787 #####################
2788 # Generated sources #
2789 #####################
2791 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2793 hxtool = find_program('scripts/hxtool')
2794 shaderinclude = find_program('scripts/shaderinclude.pl')
2795 qapi_gen = find_program('scripts/qapi-gen.py')
2796 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2797                      meson.current_source_dir() / 'scripts/qapi/commands.py',
2798                      meson.current_source_dir() / 'scripts/qapi/common.py',
2799                      meson.current_source_dir() / 'scripts/qapi/error.py',
2800                      meson.current_source_dir() / 'scripts/qapi/events.py',
2801                      meson.current_source_dir() / 'scripts/qapi/expr.py',
2802                      meson.current_source_dir() / 'scripts/qapi/gen.py',
2803                      meson.current_source_dir() / 'scripts/qapi/introspect.py',
2804                      meson.current_source_dir() / 'scripts/qapi/parser.py',
2805                      meson.current_source_dir() / 'scripts/qapi/schema.py',
2806                      meson.current_source_dir() / 'scripts/qapi/source.py',
2807                      meson.current_source_dir() / 'scripts/qapi/types.py',
2808                      meson.current_source_dir() / 'scripts/qapi/visit.py',
2809                      meson.current_source_dir() / 'scripts/qapi/common.py',
2810                      meson.current_source_dir() / 'scripts/qapi-gen.py'
2813 tracetool = [
2814   python, files('scripts/tracetool.py'),
2815    '--backend=' + ','.join(get_option('trace_backends'))
2817 tracetool_depends = files(
2818   'scripts/tracetool/backend/log.py',
2819   'scripts/tracetool/backend/__init__.py',
2820   'scripts/tracetool/backend/dtrace.py',
2821   'scripts/tracetool/backend/ftrace.py',
2822   'scripts/tracetool/backend/simple.py',
2823   'scripts/tracetool/backend/syslog.py',
2824   'scripts/tracetool/backend/ust.py',
2825   'scripts/tracetool/format/ust_events_c.py',
2826   'scripts/tracetool/format/ust_events_h.py',
2827   'scripts/tracetool/format/__init__.py',
2828   'scripts/tracetool/format/d.py',
2829   'scripts/tracetool/format/simpletrace_stap.py',
2830   'scripts/tracetool/format/c.py',
2831   'scripts/tracetool/format/h.py',
2832   'scripts/tracetool/format/log_stap.py',
2833   'scripts/tracetool/format/stap.py',
2834   'scripts/tracetool/__init__.py',
2835   'scripts/tracetool/transform.py',
2836   'scripts/tracetool/vcpu.py'
2839 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2840                     meson.current_source_dir(),
2841                     get_option('pkgversion'), meson.project_version()]
2842 qemu_version = custom_target('qemu-version.h',
2843                              output: 'qemu-version.h',
2844                              command: qemu_version_cmd,
2845                              capture: true,
2846                              build_by_default: true,
2847                              build_always_stale: true)
2848 genh += qemu_version
2850 hxdep = []
2851 hx_headers = [
2852   ['qemu-options.hx', 'qemu-options.def'],
2853   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2855 if have_system
2856   hx_headers += [
2857     ['hmp-commands.hx', 'hmp-commands.h'],
2858     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2859   ]
2860 endif
2861 foreach d : hx_headers
2862   hxdep += custom_target(d[1],
2863                 input: files(d[0]),
2864                 output: d[1],
2865                 capture: true,
2866                 build_by_default: true, # to be removed when added to a target
2867                 command: [hxtool, '-h', '@INPUT0@'])
2868 endforeach
2869 genh += hxdep
2871 ###################
2872 # Collect sources #
2873 ###################
2875 authz_ss = ss.source_set()
2876 blockdev_ss = ss.source_set()
2877 block_ss = ss.source_set()
2878 chardev_ss = ss.source_set()
2879 common_ss = ss.source_set()
2880 crypto_ss = ss.source_set()
2881 hwcore_ss = ss.source_set()
2882 io_ss = ss.source_set()
2883 qmp_ss = ss.source_set()
2884 qom_ss = ss.source_set()
2885 softmmu_ss = ss.source_set()
2886 specific_fuzz_ss = ss.source_set()
2887 specific_ss = ss.source_set()
2888 stub_ss = ss.source_set()
2889 trace_ss = ss.source_set()
2890 user_ss = ss.source_set()
2891 util_ss = ss.source_set()
2893 # accel modules
2894 qtest_module_ss = ss.source_set()
2895 tcg_module_ss = ss.source_set()
2897 modules = {}
2898 target_modules = {}
2899 hw_arch = {}
2900 target_arch = {}
2901 target_softmmu_arch = {}
2902 target_user_arch = {}
2904 ###############
2905 # Trace files #
2906 ###############
2908 # TODO: add each directory to the subdirs from its own meson.build, once
2909 # we have those
2910 trace_events_subdirs = [
2911   'crypto',
2912   'qapi',
2913   'qom',
2914   'monitor',
2915   'util',
2917 if have_linux_user
2918   trace_events_subdirs += [ 'linux-user' ]
2919 endif
2920 if have_bsd_user
2921   trace_events_subdirs += [ 'bsd-user' ]
2922 endif
2923 if have_block
2924   trace_events_subdirs += [
2925     'authz',
2926     'block',
2927     'io',
2928     'nbd',
2929     'scsi',
2930   ]
2931 endif
2932 if have_system
2933   trace_events_subdirs += [
2934     'accel/kvm',
2935     'audio',
2936     'backends',
2937     'backends/tpm',
2938     'chardev',
2939     'ebpf',
2940     'hw/9pfs',
2941     'hw/acpi',
2942     'hw/adc',
2943     'hw/alpha',
2944     'hw/arm',
2945     'hw/audio',
2946     'hw/block',
2947     'hw/block/dataplane',
2948     'hw/char',
2949     'hw/display',
2950     'hw/dma',
2951     'hw/hyperv',
2952     'hw/i2c',
2953     'hw/i386',
2954     'hw/i386/xen',
2955     'hw/ide',
2956     'hw/input',
2957     'hw/intc',
2958     'hw/isa',
2959     'hw/mem',
2960     'hw/mips',
2961     'hw/misc',
2962     'hw/misc/macio',
2963     'hw/net',
2964     'hw/net/can',
2965     'hw/nubus',
2966     'hw/nvme',
2967     'hw/nvram',
2968     'hw/pci',
2969     'hw/pci-host',
2970     'hw/ppc',
2971     'hw/rdma',
2972     'hw/rdma/vmw',
2973     'hw/rtc',
2974     'hw/s390x',
2975     'hw/scsi',
2976     'hw/sd',
2977     'hw/sh4',
2978     'hw/sparc',
2979     'hw/sparc64',
2980     'hw/ssi',
2981     'hw/timer',
2982     'hw/tpm',
2983     'hw/usb',
2984     'hw/vfio',
2985     'hw/virtio',
2986     'hw/watchdog',
2987     'hw/xen',
2988     'hw/gpio',
2989     'migration',
2990     'net',
2991     'softmmu',
2992     'ui',
2993     'hw/remote',
2994   ]
2995 endif
2996 if have_system or have_user
2997   trace_events_subdirs += [
2998     'accel/tcg',
2999     'hw/core',
3000     'target/arm',
3001     'target/arm/hvf',
3002     'target/hppa',
3003     'target/i386',
3004     'target/i386/kvm',
3005     'target/mips/tcg',
3006     'target/nios2',
3007     'target/ppc',
3008     'target/riscv',
3009     'target/s390x',
3010     'target/s390x/kvm',
3011     'target/sparc',
3012   ]
3013 endif
3015 vhost_user = not_found
3016 if targetos == 'linux' and have_vhost_user
3017   libvhost_user = subproject('libvhost-user')
3018   vhost_user = libvhost_user.get_variable('vhost_user_dep')
3019 endif
3021 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3022 # that is filled in by qapi/.
3023 subdir('qapi')
3024 subdir('qobject')
3025 subdir('stubs')
3026 subdir('trace')
3027 subdir('util')
3028 subdir('qom')
3029 subdir('authz')
3030 subdir('crypto')
3031 subdir('ui')
3032 subdir('hw')
3035 if enable_modules
3036   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3037   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3038 endif
3040 qom_ss = qom_ss.apply(config_host, strict: false)
3041 libqom = static_library('qom', qom_ss.sources() + genh,
3042                         dependencies: [qom_ss.dependencies()],
3043                         name_suffix: 'fa')
3044 qom = declare_dependency(link_whole: libqom)
3046 event_loop_base = files('event-loop-base.c')
3047 event_loop_base = static_library('event-loop-base', sources: event_loop_base + genh,
3048                                  build_by_default: true)
3049 event_loop_base = declare_dependency(link_whole: event_loop_base,
3050                                      dependencies: [qom])
3052 stub_ss = stub_ss.apply(config_all, strict: false)
3054 util_ss.add_all(trace_ss)
3055 util_ss = util_ss.apply(config_all, strict: false)
3056 libqemuutil = static_library('qemuutil',
3057                              sources: util_ss.sources() + stub_ss.sources() + genh,
3058                              dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
3059 qemuutil = declare_dependency(link_with: libqemuutil,
3060                               sources: genh + version_res,
3061                               dependencies: [event_loop_base])
3063 if have_system or have_user
3064   decodetree = generator(find_program('scripts/decodetree.py'),
3065                          output: 'decode-@BASENAME@.c.inc',
3066                          arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3067   subdir('libdecnumber')
3068   subdir('target')
3069 endif
3071 subdir('audio')
3072 subdir('io')
3073 subdir('chardev')
3074 subdir('fsdev')
3075 subdir('dump')
3077 if have_block
3078   block_ss.add(files(
3079     'block.c',
3080     'blockjob.c',
3081     'job.c',
3082     'qemu-io-cmds.c',
3083   ))
3084   if config_host_data.get('CONFIG_REPLICATION')
3085     block_ss.add(files('replication.c'))
3086   endif
3088   subdir('nbd')
3089   subdir('scsi')
3090   subdir('block')
3092   blockdev_ss.add(files(
3093     'blockdev.c',
3094     'blockdev-nbd.c',
3095     'iothread.c',
3096     'job-qmp.c',
3097   ), gnutls)
3099   # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3100   # os-win32.c does not
3101   blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
3102   softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
3103 endif
3105 common_ss.add(files('cpus-common.c'))
3107 subdir('softmmu')
3109 common_ss.add(capstone)
3110 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
3112 # Work around a gcc bug/misfeature wherein constant propagation looks
3113 # through an alias:
3114 #   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3115 # to guess that a const variable is always zero.  Without lto, this is
3116 # impossible, as the alias is restricted to page-vary-common.c.  Indeed,
3117 # without lto, not even the alias is required -- we simply use different
3118 # declarations in different compilation units.
3119 pagevary = files('page-vary-common.c')
3120 if get_option('b_lto')
3121   pagevary_flags = ['-fno-lto']
3122   if get_option('cfi')
3123     pagevary_flags += '-fno-sanitize=cfi-icall'
3124   endif
3125   pagevary = static_library('page-vary-common', sources: pagevary + genh,
3126                             c_args: pagevary_flags)
3127   pagevary = declare_dependency(link_with: pagevary)
3128 endif
3129 common_ss.add(pagevary)
3130 specific_ss.add(files('page-vary.c'))
3132 subdir('backends')
3133 subdir('disas')
3134 subdir('migration')
3135 subdir('monitor')
3136 subdir('net')
3137 subdir('replay')
3138 subdir('semihosting')
3139 subdir('tcg')
3140 subdir('fpu')
3141 subdir('accel')
3142 subdir('plugins')
3143 subdir('ebpf')
3145 common_user_inc = []
3147 subdir('common-user')
3148 subdir('bsd-user')
3149 subdir('linux-user')
3151 # needed for fuzzing binaries
3152 subdir('tests/qtest/libqos')
3153 subdir('tests/qtest/fuzz')
3155 # accel modules
3156 tcg_real_module_ss = ss.source_set()
3157 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3158 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3159 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3160                                 'tcg': tcg_real_module_ss }}
3162 ########################
3163 # Library dependencies #
3164 ########################
3166 modinfo_collect = find_program('scripts/modinfo-collect.py')
3167 modinfo_generate = find_program('scripts/modinfo-generate.py')
3168 modinfo_files = []
3170 block_mods = []
3171 softmmu_mods = []
3172 foreach d, list : modules
3173   foreach m, module_ss : list
3174     if enable_modules and targetos != 'windows'
3175       module_ss = module_ss.apply(config_all, strict: false)
3176       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3177                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3178       if d == 'block'
3179         block_mods += sl
3180       else
3181         softmmu_mods += sl
3182       endif
3183       if module_ss.sources() != []
3184         # FIXME: Should use sl.extract_all_objects(recursive: true) as
3185         # input. Sources can be used multiple times but objects are
3186         # unique when it comes to lookup in compile_commands.json.
3187         # Depnds on a mesion version with
3188         # https://github.com/mesonbuild/meson/pull/8900
3189         modinfo_files += custom_target(d + '-' + m + '.modinfo',
3190                                        output: d + '-' + m + '.modinfo',
3191                                        input: module_ss.sources() + genh,
3192                                        capture: true,
3193                                        command: [modinfo_collect, module_ss.sources()])
3194       endif
3195     else
3196       if d == 'block'
3197         block_ss.add_all(module_ss)
3198       else
3199         softmmu_ss.add_all(module_ss)
3200       endif
3201     endif
3202   endforeach
3203 endforeach
3205 foreach d, list : target_modules
3206   foreach m, module_ss : list
3207     if enable_modules and targetos != 'windows'
3208       foreach target : target_dirs
3209         if target.endswith('-softmmu')
3210           config_target = config_target_mak[target]
3211           config_target += config_host
3212           target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3213           c_args = ['-DNEED_CPU_H',
3214                     '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3215                     '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3216           target_module_ss = module_ss.apply(config_target, strict: false)
3217           if target_module_ss.sources() != []
3218             module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3219             sl = static_library(module_name,
3220                                 [genh, target_module_ss.sources()],
3221                                 dependencies: [modulecommon, target_module_ss.dependencies()],
3222                                 include_directories: target_inc,
3223                                 c_args: c_args,
3224                                 pic: true)
3225             softmmu_mods += sl
3226             # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3227             modinfo_files += custom_target(module_name + '.modinfo',
3228                                            output: module_name + '.modinfo',
3229                                            input: target_module_ss.sources() + genh,
3230                                            capture: true,
3231                                            command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3232           endif
3233         endif
3234       endforeach
3235     else
3236       specific_ss.add_all(module_ss)
3237     endif
3238   endforeach
3239 endforeach
3241 if enable_modules
3242   modinfo_src = custom_target('modinfo.c',
3243                               output: 'modinfo.c',
3244                               input: modinfo_files,
3245                               command: [modinfo_generate, '@INPUT@'],
3246                               capture: true)
3247   modinfo_lib = static_library('modinfo', modinfo_src)
3248   modinfo_dep = declare_dependency(link_whole: modinfo_lib)
3249   softmmu_ss.add(modinfo_dep)
3250 endif
3252 nm = find_program('nm')
3253 undefsym = find_program('scripts/undefsym.py')
3254 block_syms = custom_target('block.syms', output: 'block.syms',
3255                              input: [libqemuutil, block_mods],
3256                              capture: true,
3257                              command: [undefsym, nm, '@INPUT@'])
3258 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3259                              input: [libqemuutil, softmmu_mods],
3260                              capture: true,
3261                              command: [undefsym, nm, '@INPUT@'])
3263 authz_ss = authz_ss.apply(config_host, strict: false)
3264 libauthz = static_library('authz', authz_ss.sources() + genh,
3265                           dependencies: [authz_ss.dependencies()],
3266                           name_suffix: 'fa',
3267                           build_by_default: false)
3269 authz = declare_dependency(link_whole: libauthz,
3270                            dependencies: qom)
3272 crypto_ss = crypto_ss.apply(config_host, strict: false)
3273 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3274                            dependencies: [crypto_ss.dependencies()],
3275                            name_suffix: 'fa',
3276                            build_by_default: false)
3278 crypto = declare_dependency(link_whole: libcrypto,
3279                             dependencies: [authz, qom])
3281 io_ss = io_ss.apply(config_host, strict: false)
3282 libio = static_library('io', io_ss.sources() + genh,
3283                        dependencies: [io_ss.dependencies()],
3284                        link_with: libqemuutil,
3285                        name_suffix: 'fa',
3286                        build_by_default: false)
3288 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3290 libmigration = static_library('migration', sources: migration_files + genh,
3291                               name_suffix: 'fa',
3292                               build_by_default: false)
3293 migration = declare_dependency(link_with: libmigration,
3294                                dependencies: [zlib, qom, io])
3295 softmmu_ss.add(migration)
3297 block_ss = block_ss.apply(config_host, strict: false)
3298 libblock = static_library('block', block_ss.sources() + genh,
3299                           dependencies: block_ss.dependencies(),
3300                           link_depends: block_syms,
3301                           name_suffix: 'fa',
3302                           build_by_default: false)
3304 block = declare_dependency(link_whole: [libblock],
3305                            link_args: '@block.syms',
3306                            dependencies: [crypto, io])
3308 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
3309 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3310                              dependencies: blockdev_ss.dependencies(),
3311                              name_suffix: 'fa',
3312                              build_by_default: false)
3314 blockdev = declare_dependency(link_whole: [libblockdev],
3315                               dependencies: [block, event_loop_base])
3317 qmp_ss = qmp_ss.apply(config_host, strict: false)
3318 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3319                         dependencies: qmp_ss.dependencies(),
3320                         name_suffix: 'fa',
3321                         build_by_default: false)
3323 qmp = declare_dependency(link_whole: [libqmp])
3325 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3326                             name_suffix: 'fa',
3327                             dependencies: chardev_ss.dependencies(),
3328                             build_by_default: false)
3330 chardev = declare_dependency(link_whole: libchardev)
3332 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
3333 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3334                            name_suffix: 'fa',
3335                            build_by_default: false)
3336 hwcore = declare_dependency(link_whole: libhwcore)
3337 common_ss.add(hwcore)
3339 ###########
3340 # Targets #
3341 ###########
3343 emulator_modules = []
3344 foreach m : block_mods + softmmu_mods
3345   emulator_modules += shared_module(m.name(),
3346                 build_by_default: true,
3347                 name_prefix: '',
3348                 link_whole: m,
3349                 install: true,
3350                 install_dir: qemu_moddir)
3351 endforeach
3353 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3354 common_ss.add(qom, qemuutil)
3356 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
3357 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3359 common_all = common_ss.apply(config_all, strict: false)
3360 common_all = static_library('common',
3361                             build_by_default: false,
3362                             sources: common_all.sources() + genh,
3363                             include_directories: common_user_inc,
3364                             implicit_include_directories: false,
3365                             dependencies: common_all.dependencies(),
3366                             name_suffix: 'fa')
3368 feature_to_c = find_program('scripts/feature_to_c.sh')
3370 if targetos == 'darwin'
3371   entitlement = find_program('scripts/entitlement.sh')
3372 endif
3374 emulators = {}
3375 foreach target : target_dirs
3376   config_target = config_target_mak[target]
3377   target_name = config_target['TARGET_NAME']
3378   target_base_arch = config_target['TARGET_BASE_ARCH']
3379   arch_srcs = [config_target_h[target]]
3380   arch_deps = []
3381   c_args = ['-DNEED_CPU_H',
3382             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3383             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3384   link_args = emulator_link_args
3386   config_target += config_host
3387   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3388   if targetos == 'linux'
3389     target_inc += include_directories('linux-headers', is_system: true)
3390   endif
3391   if target.endswith('-softmmu')
3392     qemu_target_name = 'qemu-system-' + target_name
3393     target_type='system'
3394     t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3395     arch_srcs += t.sources()
3396     arch_deps += t.dependencies()
3398     hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3399     hw = hw_arch[hw_dir].apply(config_target, strict: false)
3400     arch_srcs += hw.sources()
3401     arch_deps += hw.dependencies()
3403     arch_srcs += config_devices_h[target]
3404     link_args += ['@block.syms', '@qemu.syms']
3405   else
3406     abi = config_target['TARGET_ABI_DIR']
3407     target_type='user'
3408     target_inc += common_user_inc
3409     qemu_target_name = 'qemu-' + target_name
3410     if target_base_arch in target_user_arch
3411       t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3412       arch_srcs += t.sources()
3413       arch_deps += t.dependencies()
3414     endif
3415     if 'CONFIG_LINUX_USER' in config_target
3416       base_dir = 'linux-user'
3417     endif
3418     if 'CONFIG_BSD_USER' in config_target
3419       base_dir = 'bsd-user'
3420       target_inc += include_directories('bsd-user/' / targetos)
3421       target_inc += include_directories('bsd-user/host/' / host_arch)
3422       dir = base_dir / abi
3423       arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3424     endif
3425     target_inc += include_directories(
3426       base_dir,
3427       base_dir / abi,
3428     )
3429     if 'CONFIG_LINUX_USER' in config_target
3430       dir = base_dir / abi
3431       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3432       if config_target.has_key('TARGET_SYSTBL_ABI')
3433         arch_srcs += \
3434           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3435                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
3436       endif
3437     endif
3438   endif
3440   if 'TARGET_XML_FILES' in config_target
3441     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3442                                 output: target + '-gdbstub-xml.c',
3443                                 input: files(config_target['TARGET_XML_FILES'].split()),
3444                                 command: [feature_to_c, '@INPUT@'],
3445                                 capture: true)
3446     arch_srcs += gdbstub_xml
3447   endif
3449   t = target_arch[target_base_arch].apply(config_target, strict: false)
3450   arch_srcs += t.sources()
3451   arch_deps += t.dependencies()
3453   target_common = common_ss.apply(config_target, strict: false)
3454   objects = common_all.extract_objects(target_common.sources())
3455   deps = target_common.dependencies()
3457   target_specific = specific_ss.apply(config_target, strict: false)
3458   arch_srcs += target_specific.sources()
3459   arch_deps += target_specific.dependencies()
3461   lib = static_library('qemu-' + target,
3462                  sources: arch_srcs + genh,
3463                  dependencies: arch_deps,
3464                  objects: objects,
3465                  include_directories: target_inc,
3466                  c_args: c_args,
3467                  build_by_default: false,
3468                  name_suffix: 'fa')
3470   if target.endswith('-softmmu')
3471     execs = [{
3472       'name': 'qemu-system-' + target_name,
3473       'win_subsystem': 'console',
3474       'sources': files('softmmu/main.c'),
3475       'dependencies': []
3476     }]
3477     if targetos == 'windows' and (sdl.found() or gtk.found())
3478       execs += [{
3479         'name': 'qemu-system-' + target_name + 'w',
3480         'win_subsystem': 'windows',
3481         'sources': files('softmmu/main.c'),
3482         'dependencies': []
3483       }]
3484     endif
3485     if get_option('fuzzing')
3486       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3487       execs += [{
3488         'name': 'qemu-fuzz-' + target_name,
3489         'win_subsystem': 'console',
3490         'sources': specific_fuzz.sources(),
3491         'dependencies': specific_fuzz.dependencies(),
3492       }]
3493     endif
3494   else
3495     execs = [{
3496       'name': 'qemu-' + target_name,
3497       'win_subsystem': 'console',
3498       'sources': [],
3499       'dependencies': []
3500     }]
3501   endif
3502   foreach exe: execs
3503     exe_name = exe['name']
3504     if targetos == 'darwin'
3505       exe_name += '-unsigned'
3506     endif
3508     emulator = executable(exe_name, exe['sources'],
3509                install: true,
3510                c_args: c_args,
3511                dependencies: arch_deps + deps + exe['dependencies'],
3512                objects: lib.extract_all_objects(recursive: true),
3513                link_language: link_language,
3514                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3515                link_args: link_args,
3516                win_subsystem: exe['win_subsystem'])
3518     if targetos == 'darwin'
3519       icon = 'pc-bios/qemu.rsrc'
3520       build_input = [emulator, files(icon)]
3521       install_input = [
3522         get_option('bindir') / exe_name,
3523         meson.current_source_dir() / icon
3524       ]
3525       if 'CONFIG_HVF' in config_target
3526         entitlements = 'accel/hvf/entitlements.plist'
3527         build_input += files(entitlements)
3528         install_input += meson.current_source_dir() / entitlements
3529       endif
3531       emulators += {exe['name'] : custom_target(exe['name'],
3532                    input: build_input,
3533                    output: exe['name'],
3534                    command: [entitlement, '@OUTPUT@', '@INPUT@'])
3535       }
3537       meson.add_install_script(entitlement, '--install',
3538                                get_option('bindir') / exe['name'],
3539                                install_input)
3540     else
3541       emulators += {exe['name']: emulator}
3542     endif
3544     if stap.found()
3545       foreach stp: [
3546         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3547         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3548         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3549         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3550       ]
3551         custom_target(exe['name'] + stp['ext'],
3552                       input: trace_events_all,
3553                       output: exe['name'] + stp['ext'],
3554                       install: stp['install'],
3555                       install_dir: get_option('datadir') / 'systemtap/tapset',
3556                       command: [
3557                         tracetool, '--group=all', '--format=' + stp['fmt'],
3558                         '--binary=' + stp['bin'],
3559                         '--target-name=' + target_name,
3560                         '--target-type=' + target_type,
3561                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
3562                         '@INPUT@', '@OUTPUT@'
3563                       ],
3564                       depend_files: tracetool_depends)
3565       endforeach
3566     endif
3567   endforeach
3568 endforeach
3570 # Other build targets
3572 if 'CONFIG_PLUGIN' in config_host
3573   install_headers('include/qemu/qemu-plugin.h')
3574 endif
3576 subdir('qga')
3578 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3579 # when we don't build tools or system
3580 if xkbcommon.found()
3581   # used for the update-keymaps target, so include rules even if !have_tools
3582   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3583                            dependencies: [qemuutil, xkbcommon], install: have_tools)
3584 endif
3586 if have_tools
3587   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3588              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3589   qemu_io = executable('qemu-io', files('qemu-io.c'),
3590              dependencies: [block, qemuutil], install: true)
3591   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3592                dependencies: [blockdev, qemuutil, gnutls, selinux],
3593                install: true)
3595   subdir('storage-daemon')
3596   subdir('contrib/rdmacm-mux')
3597   subdir('contrib/elf2dmp')
3599   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3600              dependencies: qemuutil,
3601              install: true)
3603   if have_vhost_user
3604     subdir('contrib/vhost-user-blk')
3605     subdir('contrib/vhost-user-gpu')
3606     subdir('contrib/vhost-user-input')
3607     subdir('contrib/vhost-user-scsi')
3608   endif
3610   if targetos == 'linux'
3611     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3612                dependencies: [qemuutil, libcap_ng],
3613                install: true,
3614                install_dir: get_option('libexecdir'))
3616     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3617                dependencies: [authz, crypto, io, qom, qemuutil,
3618                               libcap_ng, mpathpersist],
3619                install: true)
3620   endif
3622   if have_ivshmem
3623     subdir('contrib/ivshmem-client')
3624     subdir('contrib/ivshmem-server')
3625   endif
3626 endif
3628 subdir('scripts')
3629 subdir('tools')
3630 subdir('pc-bios')
3631 subdir('docs')
3632 subdir('tests')
3633 if gtk.found()
3634   subdir('po')
3635 endif
3637 if host_machine.system() == 'windows'
3638   nsis_cmd = [
3639     find_program('scripts/nsis.py'),
3640     '@OUTPUT@',
3641     get_option('prefix'),
3642     meson.current_source_dir(),
3643     host_machine.cpu(),
3644     '--',
3645     '-DDISPLAYVERSION=' + meson.project_version(),
3646   ]
3647   if build_docs
3648     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3649   endif
3650   if gtk.found()
3651     nsis_cmd += '-DCONFIG_GTK=y'
3652   endif
3654   nsis = custom_target('nsis',
3655                        output: 'qemu-setup-' + meson.project_version() + '.exe',
3656                        input: files('qemu.nsi'),
3657                        build_always_stale: true,
3658                        command: nsis_cmd + ['@INPUT@'])
3659   alias_target('installer', nsis)
3660 endif
3662 #########################
3663 # Configuration summary #
3664 #########################
3666 # Directories
3667 summary_info = {}
3668 summary_info += {'Install prefix':    get_option('prefix')}
3669 summary_info += {'BIOS directory':    qemu_datadir}
3670 summary_info += {'firmware path':     get_option('prefix') / get_option('qemu_firmwarepath')}
3671 summary_info += {'binary directory':  get_option('prefix') / get_option('bindir')}
3672 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
3673 summary_info += {'module directory':  qemu_moddir}
3674 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
3675 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
3676 summary_info += {'config directory':  get_option('prefix') / get_option('sysconfdir')}
3677 if targetos != 'windows'
3678   summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
3679   summary_info += {'Manual directory':      get_option('prefix') / get_option('mandir')}
3680 else
3681   summary_info += {'local state directory': 'queried at runtime'}
3682 endif
3683 summary_info += {'Doc directory':     get_option('prefix') / get_option('docdir')}
3684 summary_info += {'Build directory':   meson.current_build_dir()}
3685 summary_info += {'Source path':       meson.current_source_dir()}
3686 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
3687 summary(summary_info, bool_yn: true, section: 'Directories')
3689 # Host binaries
3690 summary_info = {}
3691 summary_info += {'git':               config_host['GIT']}
3692 summary_info += {'make':              config_host['MAKE']}
3693 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3694 summary_info += {'sphinx-build':      sphinx_build}
3695 if config_host.has_key('HAVE_GDB_BIN')
3696   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
3697 endif
3698 summary_info += {'iasl':              iasl}
3699 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
3700 if targetos == 'windows' and have_ga
3701   summary_info += {'wixl':            wixl}
3702 endif
3703 if slirp_opt != 'disabled' and have_system
3704   summary_info += {'smbd':            have_slirp_smbd ? smbd_path : false}
3705 endif
3706 summary(summary_info, bool_yn: true, section: 'Host binaries')
3708 # Configurable features
3709 summary_info = {}
3710 summary_info += {'Documentation':     build_docs}
3711 summary_info += {'system-mode emulation': have_system}
3712 summary_info += {'user-mode emulation': have_user}
3713 summary_info += {'block layer':       have_block}
3714 summary_info += {'Install blobs':     get_option('install_blobs')}
3715 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
3716 if config_host.has_key('CONFIG_MODULES')
3717   summary_info += {'alternative module path': get_option('module_upgrades')}
3718 endif
3719 summary_info += {'fuzzing support':   get_option('fuzzing')}
3720 if have_system
3721   summary_info += {'Audio drivers':     ' '.join(audio_drivers_selected)}
3722 endif
3723 summary_info += {'Trace backends':    ','.join(get_option('trace_backends'))}
3724 if 'simple' in get_option('trace_backends')
3725   summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3726 endif
3727 summary_info += {'D-Bus display':     dbus_display}
3728 summary_info += {'QOM debugging':     get_option('qom_cast_debug')}
3729 summary_info += {'vhost-kernel support': have_vhost_kernel}
3730 summary_info += {'vhost-net support': have_vhost_net}
3731 summary_info += {'vhost-user support': have_vhost_user}
3732 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
3733 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3734 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
3735 summary_info += {'build guest agent': have_ga}
3736 summary(summary_info, bool_yn: true, section: 'Configurable features')
3738 # Compilation information
3739 summary_info = {}
3740 summary_info += {'host CPU':          cpu}
3741 summary_info += {'host endianness':   build_machine.endian()}
3742 summary_info += {'C compiler':        ' '.join(meson.get_compiler('c').cmd_array())}
3743 summary_info += {'Host C compiler':   ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3744 if link_language == 'cpp'
3745   summary_info += {'C++ compiler':    ' '.join(meson.get_compiler('cpp').cmd_array())}
3746 else
3747   summary_info += {'C++ compiler':      false}
3748 endif
3749 if targetos == 'darwin'
3750   summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3751 endif
3752 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
3753                                                + ['-O' + get_option('optimization')]
3754                                                + (get_option('debug') ? ['-g'] : []))}
3755 if link_language == 'cpp'
3756   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
3757                                                + ['-O' + get_option('optimization')]
3758                                                + (get_option('debug') ? ['-g'] : []))}
3759 endif
3760 if targetos == 'darwin'
3761   summary_info += {'OBJCFLAGS':       ' '.join(get_option('objc_args')
3762                                                + ['-O' + get_option('optimization')]
3763                                                + (get_option('debug') ? ['-g'] : []))}
3764 endif
3765 link_args = get_option(link_language + '_link_args')
3766 if link_args.length() > 0
3767   summary_info += {'LDFLAGS':         ' '.join(link_args)}
3768 endif
3769 summary_info += {'QEMU_CFLAGS':       ' '.join(qemu_cflags)}
3770 summary_info += {'QEMU_CXXFLAGS':     ' '.join(qemu_cxxflags)}
3771 summary_info += {'QEMU_OBJCFLAGS':    ' '.join(qemu_objcflags)}
3772 summary_info += {'QEMU_LDFLAGS':      ' '.join(qemu_ldflags)}
3773 summary_info += {'profiler':          get_option('profiler')}
3774 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3775 summary_info += {'PIE':               get_option('b_pie')}
3776 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
3777 summary_info += {'malloc trim support': has_malloc_trim}
3778 summary_info += {'membarrier':        have_membarrier}
3779 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
3780 summary_info += {'mutex debugging':   get_option('debug_mutex')}
3781 summary_info += {'memory allocator':  get_option('malloc')}
3782 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
3783 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
3784 summary_info += {'gprof enabled':     get_option('gprof')}
3785 summary_info += {'gcov':              get_option('b_coverage')}
3786 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
3787 summary_info += {'CFI support':       get_option('cfi')}
3788 if get_option('cfi')
3789   summary_info += {'CFI debug support': get_option('cfi_debug')}
3790 endif
3791 summary_info += {'strip binaries':    get_option('strip')}
3792 summary_info += {'sparse':            sparse}
3793 summary_info += {'mingw32 support':   targetos == 'windows'}
3795 # snarf the cross-compilation information for tests
3796 foreach target: target_dirs
3797   tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3798   if fs.exists(tcg_mak)
3799     config_cross_tcg = keyval.load(tcg_mak)
3800     target = config_cross_tcg['TARGET_NAME']
3801     compiler = ''
3802     if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3803       summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3804                                           ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3805     elif 'CROSS_CC_GUEST' in config_cross_tcg
3806       summary_info += {target + ' tests'
3807                                 : config_cross_tcg['CROSS_CC_GUEST'] }
3808     endif
3809    endif
3810 endforeach
3812 summary(summary_info, bool_yn: true, section: 'Compilation')
3814 # Targets and accelerators
3815 summary_info = {}
3816 if have_system
3817   summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
3818   summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
3819   summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
3820   summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
3821   summary_info += {'NVMM support':      config_all.has_key('CONFIG_NVMM')}
3822   summary_info += {'Xen support':       xen.found()}
3823   if xen.found()
3824     summary_info += {'xen ctrl version':  xen.version()}
3825   endif
3826 endif
3827 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
3828 if config_all.has_key('CONFIG_TCG')
3829   if get_option('tcg_interpreter')
3830     summary_info += {'TCG backend':   'TCI (TCG with bytecode interpreter, slow)'}
3831   else
3832     summary_info += {'TCG backend':   'native (@0@)'.format(cpu)}
3833   endif
3834   summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3835   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3836 endif
3837 summary_info += {'target list':       ' '.join(target_dirs)}
3838 if have_system
3839   summary_info += {'default devices':   get_option('default_devices')}
3840   summary_info += {'out of process emulation': multiprocess_allowed}
3841 endif
3842 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3844 # Block layer
3845 summary_info = {}
3846 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3847 summary_info += {'coroutine pool':    have_coroutine_pool}
3848 if have_block
3849   summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
3850   summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
3851   summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
3852   summary_info += {'VirtFS support':    have_virtfs}
3853   summary_info += {'build virtiofs daemon': have_virtiofsd}
3854   summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
3855   summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
3856   summary_info += {'bochs support':     get_option('bochs').allowed()}
3857   summary_info += {'cloop support':     get_option('cloop').allowed()}
3858   summary_info += {'dmg support':       get_option('dmg').allowed()}
3859   summary_info += {'qcow v1 support':   get_option('qcow1').allowed()}
3860   summary_info += {'vdi support':       get_option('vdi').allowed()}
3861   summary_info += {'vvfat support':     get_option('vvfat').allowed()}
3862   summary_info += {'qed support':       get_option('qed').allowed()}
3863   summary_info += {'parallels support': get_option('parallels').allowed()}
3864   summary_info += {'FUSE exports':      fuse}
3865 endif
3866 summary(summary_info, bool_yn: true, section: 'Block layer support')
3868 # Crypto
3869 summary_info = {}
3870 summary_info += {'TLS priority':      get_option('tls_priority')}
3871 summary_info += {'GNUTLS support':    gnutls}
3872 if gnutls.found()
3873   summary_info += {'  GNUTLS crypto':   gnutls_crypto.found()}
3874 endif
3875 summary_info += {'libgcrypt':         gcrypt}
3876 summary_info += {'nettle':            nettle}
3877 if nettle.found()
3878    summary_info += {'  XTS':             xts != 'private'}
3879 endif
3880 summary_info += {'AF_ALG support':    have_afalg}
3881 summary_info += {'rng-none':          get_option('rng_none')}
3882 summary_info += {'Linux keyring':     have_keyring}
3883 summary(summary_info, bool_yn: true, section: 'Crypto')
3885 # Libraries
3886 summary_info = {}
3887 if targetos == 'darwin'
3888   summary_info += {'Cocoa support':   cocoa}
3889 endif
3890 summary_info += {'SDL support':       sdl}
3891 summary_info += {'SDL image support': sdl_image}
3892 summary_info += {'GTK support':       gtk}
3893 summary_info += {'pixman':            pixman}
3894 summary_info += {'VTE support':       vte}
3895 summary_info += {'slirp support':     slirp_opt == 'internal' ? slirp_opt : slirp}
3896 summary_info += {'libtasn1':          tasn1}
3897 summary_info += {'PAM':               pam}
3898 summary_info += {'iconv support':     iconv}
3899 summary_info += {'curses support':    curses}
3900 summary_info += {'virgl support':     virgl}
3901 summary_info += {'curl support':      curl}
3902 summary_info += {'Multipath support': mpathpersist}
3903 summary_info += {'PNG support':       png}
3904 summary_info += {'VNC support':       vnc}
3905 if vnc.found()
3906   summary_info += {'VNC SASL support':  sasl}
3907   summary_info += {'VNC JPEG support':  jpeg}
3908 endif
3909 if targetos not in ['darwin', 'haiku', 'windows']
3910   summary_info += {'OSS support':     oss}
3911 elif targetos == 'darwin'
3912   summary_info += {'CoreAudio support': coreaudio}
3913 elif targetos == 'windows'
3914   summary_info += {'DirectSound support': dsound}
3915 endif
3916 if targetos == 'linux'
3917   summary_info += {'ALSA support':    alsa}
3918   summary_info += {'PulseAudio support': pulse}
3919 endif
3920 summary_info += {'JACK support':      jack}
3921 summary_info += {'brlapi support':    brlapi}
3922 summary_info += {'vde support':       vde}
3923 summary_info += {'netmap support':    have_netmap}
3924 summary_info += {'l2tpv3 support':    have_l2tpv3}
3925 summary_info += {'Linux AIO support': libaio}
3926 summary_info += {'Linux io_uring support': linux_io_uring}
3927 summary_info += {'ATTR/XATTR support': libattr}
3928 summary_info += {'RDMA support':      rdma}
3929 summary_info += {'PVRDMA support':    have_pvrdma}
3930 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
3931 summary_info += {'libcap-ng support': libcap_ng}
3932 summary_info += {'bpf support':       libbpf}
3933 summary_info += {'spice protocol support': spice_protocol}
3934 if spice_protocol.found()
3935   summary_info += {'  spice server support': spice}
3936 endif
3937 summary_info += {'rbd support':       rbd}
3938 summary_info += {'smartcard support': cacard}
3939 summary_info += {'U2F support':       u2f}
3940 summary_info += {'libusb':            libusb}
3941 summary_info += {'usb net redir':     usbredir}
3942 summary_info += {'OpenGL support (epoxy)': opengl}
3943 summary_info += {'GBM':               gbm}
3944 summary_info += {'libiscsi support':  libiscsi}
3945 summary_info += {'libnfs support':    libnfs}
3946 if targetos == 'windows'
3947   if have_ga
3948     summary_info += {'QGA VSS support':   have_qga_vss}
3949   endif
3950 endif
3951 summary_info += {'seccomp support':   seccomp}
3952 summary_info += {'GlusterFS support': glusterfs}
3953 summary_info += {'TPM support':       have_tpm}
3954 summary_info += {'libssh support':    libssh}
3955 summary_info += {'lzo support':       lzo}
3956 summary_info += {'snappy support':    snappy}
3957 summary_info += {'bzip2 support':     libbzip2}
3958 summary_info += {'lzfse support':     liblzfse}
3959 summary_info += {'zstd support':      zstd}
3960 summary_info += {'NUMA host support': numa}
3961 summary_info += {'capstone':          capstone_opt == 'internal' ? capstone_opt : capstone}
3962 summary_info += {'libpmem support':   libpmem}
3963 summary_info += {'libdaxctl support': libdaxctl}
3964 summary_info += {'libudev':           libudev}
3965 # Dummy dependency, keep .found()
3966 summary_info += {'FUSE lseek':        fuse_lseek.found()}
3967 summary_info += {'selinux':           selinux}
3968 summary(summary_info, bool_yn: true, section: 'Dependencies')
3970 if not supported_cpus.contains(cpu)
3971   message()
3972   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3973   message()
3974   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3975   message('The QEMU project intends to remove support for this host CPU in')
3976   message('a future release if nobody volunteers to maintain it and to')
3977   message('provide a build host for our continuous integration setup.')
3978   message('configure has succeeded and you can continue to build, but')
3979   message('if you care about QEMU on this platform you should contact')
3980   message('us upstream at qemu-devel@nongnu.org.')
3981 endif
3983 if not supported_oses.contains(targetos)
3984   message()
3985   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3986   message()
3987   message('Host OS ' + targetos + 'support is not currently maintained.')
3988   message('The QEMU project intends to remove support for this host OS in')
3989   message('a future release if nobody volunteers to maintain it and to')
3990   message('provide a build host for our continuous integration setup.')
3991   message('configure has succeeded and you can continue to build, but')
3992   message('if you care about QEMU on this platform you should contact')
3993   message('us upstream at qemu-devel@nongnu.org.')
3994 endif