hw/block/fdc: Prevent end-of-track overrun (CVE-2021-3507)
[qemu/rayw.git] / meson.build
blob864e97945fe455b3923df9fb17e06c81329e71ec
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('''
2183     int main(void)
2184     {
2185       char buf = 0;
2186       void *addr = &buf;
2187       addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2189       return 0;
2190     }'''), error_message: 'PVRDMA requires mremap').allowed()
2192 if have_pvrdma
2193   config_host_data.set('LEGACY_RDMA_REG_MR', not cc.compiles('''
2194     #include <infiniband/verbs.h>
2195     int main(void)
2196     {
2197       struct ibv_mr *mr;
2198       struct ibv_pd *pd = NULL;
2199       size_t length = 10;
2200       uint64_t iova = 0;
2201       int access = 0;
2202       void *addr = NULL;
2204       mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2205       ibv_dereg_mr(mr);
2206       return 0;
2207     }'''))
2208 endif
2210 if get_option('membarrier').disabled()
2211   have_membarrier = false
2212 elif targetos == 'windows'
2213   have_membarrier = true
2214 elif targetos == 'linux'
2215   have_membarrier = cc.compiles('''
2216     #include <linux/membarrier.h>
2217     #include <sys/syscall.h>
2218     #include <unistd.h>
2219     #include <stdlib.h>
2220     int main(void) {
2221         syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2222         syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2223         exit(0);
2224     }''')
2225 endif
2226 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2227   .require(have_membarrier, error_message: 'membarrier system call not available') \
2228   .allowed())
2230 have_afalg = get_option('crypto_afalg') \
2231   .require(cc.compiles(gnu_source_prefix + '''
2232     #include <errno.h>
2233     #include <sys/types.h>
2234     #include <sys/socket.h>
2235     #include <linux/if_alg.h>
2236     int main(void) {
2237       int sock;
2238       sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2239       return sock;
2240     }
2241   '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2242 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2244 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2245   'linux/vm_sockets.h', 'AF_VSOCK',
2246   prefix: '#include <sys/socket.h>',
2249 have_vss = false
2250 have_vss_sdk = false # old xp/2003 SDK
2251 if targetos == 'windows' and link_language == 'cpp'
2252   have_vss = cxx.compiles('''
2253     #define __MIDL_user_allocate_free_DEFINED__
2254     #include <vss.h>
2255     int main(void) { return VSS_CTX_BACKUP; }''')
2256   have_vss_sdk = cxx.has_header('vscoordint.h')
2257 endif
2258 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2260 foreach k, v: config_host
2261   if k.startswith('CONFIG_')
2262     config_host_data.set(k, v == 'y' ? 1 : v)
2263   endif
2264 endforeach
2266 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2267 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2268 if targetos == 'windows'
2269   config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2270     #include <stdio.h>
2271     int main(void) {
2272       _lock_file(NULL);
2273       _unlock_file(NULL);
2274       return 0;
2275     }''', name: '_lock_file and _unlock_file'))
2276 endif
2278 ########################
2279 # Target configuration #
2280 ########################
2282 minikconf = find_program('scripts/minikconf.py')
2283 config_all = {}
2284 config_all_devices = {}
2285 config_all_disas = {}
2286 config_devices_mak_list = []
2287 config_devices_h = {}
2288 config_target_h = {}
2289 config_target_mak = {}
2291 disassemblers = {
2292   'alpha' : ['CONFIG_ALPHA_DIS'],
2293   'arm' : ['CONFIG_ARM_DIS'],
2294   'avr' : ['CONFIG_AVR_DIS'],
2295   'cris' : ['CONFIG_CRIS_DIS'],
2296   'hexagon' : ['CONFIG_HEXAGON_DIS'],
2297   'hppa' : ['CONFIG_HPPA_DIS'],
2298   'i386' : ['CONFIG_I386_DIS'],
2299   'x86_64' : ['CONFIG_I386_DIS'],
2300   'm68k' : ['CONFIG_M68K_DIS'],
2301   'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2302   'mips' : ['CONFIG_MIPS_DIS'],
2303   'nios2' : ['CONFIG_NIOS2_DIS'],
2304   'or1k' : ['CONFIG_OPENRISC_DIS'],
2305   'ppc' : ['CONFIG_PPC_DIS'],
2306   'riscv' : ['CONFIG_RISCV_DIS'],
2307   'rx' : ['CONFIG_RX_DIS'],
2308   's390' : ['CONFIG_S390_DIS'],
2309   'sh4' : ['CONFIG_SH4_DIS'],
2310   'sparc' : ['CONFIG_SPARC_DIS'],
2311   'xtensa' : ['CONFIG_XTENSA_DIS'],
2313 if link_language == 'cpp'
2314   disassemblers += {
2315     'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
2316     'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
2317     'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
2318   }
2319 endif
2321 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2322 host_kconfig = \
2323   (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2324   (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2325   (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2326   (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2327   (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2328   (x11.found() ? ['CONFIG_X11=y'] : []) + \
2329   (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
2330   (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2331   (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2332   (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2333   ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
2334   (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
2335   (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
2337 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2339 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2340 actual_target_dirs = []
2341 fdt_required = []
2342 foreach target : target_dirs
2343   config_target = { 'TARGET_NAME': target.split('-')[0] }
2344   if target.endswith('linux-user')
2345     if targetos != 'linux'
2346       if default_targets
2347         continue
2348       endif
2349       error('Target @0@ is only available on a Linux host'.format(target))
2350     endif
2351     config_target += { 'CONFIG_LINUX_USER': 'y' }
2352   elif target.endswith('bsd-user')
2353     if 'CONFIG_BSD' not in config_host
2354       if default_targets
2355         continue
2356       endif
2357       error('Target @0@ is only available on a BSD host'.format(target))
2358     endif
2359     config_target += { 'CONFIG_BSD_USER': 'y' }
2360   elif target.endswith('softmmu')
2361     config_target += { 'CONFIG_SOFTMMU': 'y' }
2362   endif
2363   if target.endswith('-user')
2364     config_target += {
2365       'CONFIG_USER_ONLY': 'y',
2366       'CONFIG_QEMU_INTERP_PREFIX':
2367         get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
2368     }
2369   endif
2371   accel_kconfig = []
2372   foreach sym: accelerators
2373     if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2374       config_target += { sym: 'y' }
2375       config_all += { sym: 'y' }
2376       if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
2377         config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
2378       endif
2379       if target in modular_tcg
2380         config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2381       else
2382         config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2383       endif
2384       accel_kconfig += [ sym + '=y' ]
2385     endif
2386   endforeach
2387   if accel_kconfig.length() == 0
2388     if default_targets
2389       continue
2390     endif
2391     error('No accelerator available for target @0@'.format(target))
2392   endif
2394   actual_target_dirs += target
2395   config_target += keyval.load('configs/targets' / target + '.mak')
2396   config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
2398   if 'TARGET_NEED_FDT' in config_target
2399     fdt_required += target
2400   endif
2402   # Add default keys
2403   if 'TARGET_BASE_ARCH' not in config_target
2404     config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2405   endif
2406   if 'TARGET_ABI_DIR' not in config_target
2407     config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2408   endif
2409   if 'TARGET_BIG_ENDIAN' not in config_target
2410     config_target += {'TARGET_BIG_ENDIAN': 'n'}
2411   endif
2413   foreach k, v: disassemblers
2414     if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
2415       foreach sym: v
2416         config_target += { sym: 'y' }
2417         config_all_disas += { sym: 'y' }
2418       endforeach
2419     endif
2420   endforeach
2422   config_target_data = configuration_data()
2423   foreach k, v: config_target
2424     if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2425       # do nothing
2426     elif ignored.contains(k)
2427       # do nothing
2428     elif k == 'TARGET_BASE_ARCH'
2429       # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2430       # not used to select files from sourcesets.
2431       config_target_data.set('TARGET_' + v.to_upper(), 1)
2432     elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
2433       config_target_data.set_quoted(k, v)
2434     elif v == 'y'
2435       config_target_data.set(k, 1)
2436     elif v == 'n'
2437       config_target_data.set(k, 0)
2438     else
2439       config_target_data.set(k, v)
2440     endif
2441   endforeach
2442   config_target_data.set('QEMU_ARCH',
2443                          'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
2444   config_target_h += {target: configure_file(output: target + '-config-target.h',
2445                                                configuration: config_target_data)}
2447   if target.endswith('-softmmu')
2448     config_input = meson.get_external_property(target, 'default')
2449     config_devices_mak = target + '-config-devices.mak'
2450     config_devices_mak = configure_file(
2451       input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2452       output: config_devices_mak,
2453       depfile: config_devices_mak + '.d',
2454       capture: true,
2455       command: [minikconf,
2456                 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2457                 config_devices_mak, '@DEPFILE@', '@INPUT@',
2458                 host_kconfig, accel_kconfig,
2459                 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
2461     config_devices_data = configuration_data()
2462     config_devices = keyval.load(config_devices_mak)
2463     foreach k, v: config_devices
2464       config_devices_data.set(k, 1)
2465     endforeach
2466     config_devices_mak_list += config_devices_mak
2467     config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2468                                                 configuration: config_devices_data)}
2469     config_target += config_devices
2470     config_all_devices += config_devices
2471   endif
2472   config_target_mak += {target: config_target}
2473 endforeach
2474 target_dirs = actual_target_dirs
2476 # This configuration is used to build files that are shared by
2477 # multiple binaries, and then extracted out of the "common"
2478 # static_library target.
2480 # We do not use all_sources()/all_dependencies(), because it would
2481 # build literally all source files, including devices only used by
2482 # targets that are not built for this compilation.  The CONFIG_ALL
2483 # pseudo symbol replaces it.
2485 config_all += config_all_devices
2486 config_all += config_host
2487 config_all += config_all_disas
2488 config_all += {
2489   'CONFIG_XEN': xen.found(),
2490   'CONFIG_SOFTMMU': have_system,
2491   'CONFIG_USER_ONLY': have_user,
2492   'CONFIG_ALL': true,
2495 target_configs_h = []
2496 foreach target: target_dirs
2497   target_configs_h += config_target_h[target]
2498   target_configs_h += config_devices_h.get(target, [])
2499 endforeach
2500 genh += custom_target('config-poison.h',
2501                       input: [target_configs_h],
2502                       output: 'config-poison.h',
2503                       capture: true,
2504                       command: [find_program('scripts/make-config-poison.sh'),
2505                                 target_configs_h])
2507 ##############
2508 # Submodules #
2509 ##############
2511 capstone = not_found
2512 capstone_opt = get_option('capstone')
2513 if capstone_opt in ['enabled', 'auto', 'system']
2514   have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
2515   capstone = dependency('capstone', version: '>=4.0',
2516                         kwargs: static_kwargs, method: 'pkg-config',
2517                         required: capstone_opt == 'system' or
2518                                   capstone_opt == 'enabled' and not have_internal)
2520   # Some versions of capstone have broken pkg-config file
2521   # that reports a wrong -I path, causing the #include to
2522   # fail later. If the system has such a broken version
2523   # do not use it.
2524   if capstone.found() and not cc.compiles('#include <capstone.h>',
2525                                           dependencies: [capstone])
2526     capstone = not_found
2527     if capstone_opt == 'system'
2528       error('system capstone requested, it does not appear to work')
2529     endif
2530   endif
2532   if capstone.found()
2533     capstone_opt = 'system'
2534   elif have_internal
2535     capstone_opt = 'internal'
2536   else
2537     capstone_opt = 'disabled'
2538   endif
2539 endif
2540 if capstone_opt == 'internal'
2541   capstone_data = configuration_data()
2542   capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
2544   capstone_files = files(
2545     'capstone/cs.c',
2546     'capstone/MCInst.c',
2547     'capstone/MCInstrDesc.c',
2548     'capstone/MCRegisterInfo.c',
2549     'capstone/SStream.c',
2550     'capstone/utils.c'
2551   )
2553   if 'CONFIG_ARM_DIS' in config_all_disas
2554     capstone_data.set('CAPSTONE_HAS_ARM', '1')
2555     capstone_files += files(
2556       'capstone/arch/ARM/ARMDisassembler.c',
2557       'capstone/arch/ARM/ARMInstPrinter.c',
2558       'capstone/arch/ARM/ARMMapping.c',
2559       'capstone/arch/ARM/ARMModule.c'
2560     )
2561   endif
2563   # FIXME: This config entry currently depends on a c++ compiler.
2564   # Which is needed for building libvixl, but not for capstone.
2565   if 'CONFIG_ARM_A64_DIS' in config_all_disas
2566     capstone_data.set('CAPSTONE_HAS_ARM64', '1')
2567     capstone_files += files(
2568       'capstone/arch/AArch64/AArch64BaseInfo.c',
2569       'capstone/arch/AArch64/AArch64Disassembler.c',
2570       'capstone/arch/AArch64/AArch64InstPrinter.c',
2571       'capstone/arch/AArch64/AArch64Mapping.c',
2572       'capstone/arch/AArch64/AArch64Module.c'
2573     )
2574   endif
2576   if 'CONFIG_PPC_DIS' in config_all_disas
2577     capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
2578     capstone_files += files(
2579       'capstone/arch/PowerPC/PPCDisassembler.c',
2580       'capstone/arch/PowerPC/PPCInstPrinter.c',
2581       'capstone/arch/PowerPC/PPCMapping.c',
2582       'capstone/arch/PowerPC/PPCModule.c'
2583     )
2584   endif
2586   if 'CONFIG_S390_DIS' in config_all_disas
2587     capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
2588     capstone_files += files(
2589       'capstone/arch/SystemZ/SystemZDisassembler.c',
2590       'capstone/arch/SystemZ/SystemZInstPrinter.c',
2591       'capstone/arch/SystemZ/SystemZMapping.c',
2592       'capstone/arch/SystemZ/SystemZModule.c',
2593       'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
2594     )
2595   endif
2597   if 'CONFIG_I386_DIS' in config_all_disas
2598     capstone_data.set('CAPSTONE_HAS_X86', 1)
2599     capstone_files += files(
2600       'capstone/arch/X86/X86Disassembler.c',
2601       'capstone/arch/X86/X86DisassemblerDecoder.c',
2602       'capstone/arch/X86/X86ATTInstPrinter.c',
2603       'capstone/arch/X86/X86IntelInstPrinter.c',
2604       'capstone/arch/X86/X86InstPrinterCommon.c',
2605       'capstone/arch/X86/X86Mapping.c',
2606       'capstone/arch/X86/X86Module.c'
2607     )
2608   endif
2610   configure_file(output: 'capstone-defs.h', configuration: capstone_data)
2612   capstone_cargs = [
2613     # FIXME: There does not seem to be a way to completely replace the c_args
2614     # that come from add_project_arguments() -- we can only add to them.
2615     # So: disable all warnings with a big hammer.
2616     '-Wno-error', '-w',
2618     # Include all configuration defines via a header file, which will wind up
2619     # as a dependency on the object file, and thus changes here will result
2620     # in a rebuild.
2621     '-include', 'capstone-defs.h'
2622   ]
2624   libcapstone = static_library('capstone',
2625                                build_by_default: false,
2626                                sources: capstone_files,
2627                                c_args: capstone_cargs,
2628                                include_directories: 'capstone/include')
2629   capstone = declare_dependency(link_with: libcapstone,
2630                                 include_directories: 'capstone/include/capstone')
2631 endif
2633 slirp = not_found
2634 slirp_opt = 'disabled'
2635 if have_system
2636   slirp_opt = get_option('slirp')
2637   if slirp_opt in ['enabled', 'auto', 'system']
2638     have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2639     slirp = dependency('slirp', kwargs: static_kwargs,
2640                        method: 'pkg-config',
2641                        required: slirp_opt == 'system' or
2642                                  slirp_opt == 'enabled' and not have_internal)
2643     if slirp.found()
2644       slirp_opt = 'system'
2645     elif have_internal
2646       slirp_opt = 'internal'
2647     else
2648       slirp_opt = 'disabled'
2649     endif
2650   endif
2651   if slirp_opt == 'internal'
2652     slirp_deps = []
2653     if targetos == 'windows'
2654       slirp_deps = cc.find_library('iphlpapi')
2655     elif targetos == 'darwin'
2656       slirp_deps = cc.find_library('resolv')
2657     endif
2658     slirp_conf = configuration_data()
2659     slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2660     slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2661     slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2662     slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2663     slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2664     slirp_files = [
2665       'slirp/src/arp_table.c',
2666       'slirp/src/bootp.c',
2667       'slirp/src/cksum.c',
2668       'slirp/src/dhcpv6.c',
2669       'slirp/src/dnssearch.c',
2670       'slirp/src/if.c',
2671       'slirp/src/ip6_icmp.c',
2672       'slirp/src/ip6_input.c',
2673       'slirp/src/ip6_output.c',
2674       'slirp/src/ip_icmp.c',
2675       'slirp/src/ip_input.c',
2676       'slirp/src/ip_output.c',
2677       'slirp/src/mbuf.c',
2678       'slirp/src/misc.c',
2679       'slirp/src/ncsi.c',
2680       'slirp/src/ndp_table.c',
2681       'slirp/src/sbuf.c',
2682       'slirp/src/slirp.c',
2683       'slirp/src/socket.c',
2684       'slirp/src/state.c',
2685       'slirp/src/stream.c',
2686       'slirp/src/tcp_input.c',
2687       'slirp/src/tcp_output.c',
2688       'slirp/src/tcp_subr.c',
2689       'slirp/src/tcp_timer.c',
2690       'slirp/src/tftp.c',
2691       'slirp/src/udp.c',
2692       'slirp/src/udp6.c',
2693       'slirp/src/util.c',
2694       'slirp/src/version.c',
2695       'slirp/src/vmstate.c',
2696     ]
2698     configure_file(
2699       input : 'slirp/src/libslirp-version.h.in',
2700       output : 'libslirp-version.h',
2701       configuration: slirp_conf)
2703     slirp_inc = include_directories('slirp', 'slirp/src')
2704     libslirp = static_library('slirp',
2705                               build_by_default: false,
2706                               sources: slirp_files,
2707                               c_args: slirp_cargs,
2708                               include_directories: slirp_inc)
2709     slirp = declare_dependency(link_with: libslirp,
2710                                dependencies: slirp_deps,
2711                                include_directories: slirp_inc)
2712   endif
2713 endif
2715 # For CFI, we need to compile slirp as a static library together with qemu.
2716 # This is because we register slirp functions as callbacks for QEMU Timers.
2717 # When using a system-wide shared libslirp, the type information for the
2718 # callback is missing and the timer call produces a false positive with CFI.
2720 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2721 # with control-flow integrity.
2722 if get_option('cfi') and slirp_opt == 'system'
2723   error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2724          + ' Please configure with --enable-slirp=git')
2725 endif
2727 fdt = not_found
2728 if have_system
2729   fdt_opt = get_option('fdt')
2730   if fdt_opt in ['enabled', 'auto', 'system']
2731     have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2732     fdt = cc.find_library('fdt', kwargs: static_kwargs,
2733                           required: fdt_opt == 'system' or
2734                                     fdt_opt == 'enabled' and not have_internal)
2735     if fdt.found() and cc.links('''
2736        #include <libfdt.h>
2737        #include <libfdt_env.h>
2738        int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2739          dependencies: fdt)
2740       fdt_opt = 'system'
2741     elif fdt_opt == 'system'
2742        error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2743     elif have_internal
2744       fdt_opt = 'internal'
2745     else
2746       fdt_opt = 'disabled'
2747       fdt = not_found
2748     endif
2749   endif
2750   if fdt_opt == 'internal'
2751     fdt_files = files(
2752       'dtc/libfdt/fdt.c',
2753       'dtc/libfdt/fdt_ro.c',
2754       'dtc/libfdt/fdt_wip.c',
2755       'dtc/libfdt/fdt_sw.c',
2756       'dtc/libfdt/fdt_rw.c',
2757       'dtc/libfdt/fdt_strerror.c',
2758       'dtc/libfdt/fdt_empty_tree.c',
2759       'dtc/libfdt/fdt_addresses.c',
2760       'dtc/libfdt/fdt_overlay.c',
2761       'dtc/libfdt/fdt_check.c',
2762     )
2764     fdt_inc = include_directories('dtc/libfdt')
2765     libfdt = static_library('fdt',
2766                             build_by_default: false,
2767                             sources: fdt_files,
2768                             include_directories: fdt_inc)
2769     fdt = declare_dependency(link_with: libfdt,
2770                              include_directories: fdt_inc)
2771   endif
2772 else
2773   fdt_opt = 'disabled'
2774 endif
2775 if not fdt.found() and fdt_required.length() > 0
2776   error('fdt not available but required by targets ' + ', '.join(fdt_required))
2777 endif
2779 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2780 config_host_data.set('CONFIG_FDT', fdt.found())
2781 config_host_data.set('CONFIG_SLIRP', slirp.found())
2783 #####################
2784 # Generated sources #
2785 #####################
2787 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2789 hxtool = find_program('scripts/hxtool')
2790 shaderinclude = find_program('scripts/shaderinclude.pl')
2791 qapi_gen = find_program('scripts/qapi-gen.py')
2792 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2793                      meson.current_source_dir() / 'scripts/qapi/commands.py',
2794                      meson.current_source_dir() / 'scripts/qapi/common.py',
2795                      meson.current_source_dir() / 'scripts/qapi/error.py',
2796                      meson.current_source_dir() / 'scripts/qapi/events.py',
2797                      meson.current_source_dir() / 'scripts/qapi/expr.py',
2798                      meson.current_source_dir() / 'scripts/qapi/gen.py',
2799                      meson.current_source_dir() / 'scripts/qapi/introspect.py',
2800                      meson.current_source_dir() / 'scripts/qapi/parser.py',
2801                      meson.current_source_dir() / 'scripts/qapi/schema.py',
2802                      meson.current_source_dir() / 'scripts/qapi/source.py',
2803                      meson.current_source_dir() / 'scripts/qapi/types.py',
2804                      meson.current_source_dir() / 'scripts/qapi/visit.py',
2805                      meson.current_source_dir() / 'scripts/qapi/common.py',
2806                      meson.current_source_dir() / 'scripts/qapi-gen.py'
2809 tracetool = [
2810   python, files('scripts/tracetool.py'),
2811    '--backend=' + ','.join(get_option('trace_backends'))
2813 tracetool_depends = files(
2814   'scripts/tracetool/backend/log.py',
2815   'scripts/tracetool/backend/__init__.py',
2816   'scripts/tracetool/backend/dtrace.py',
2817   'scripts/tracetool/backend/ftrace.py',
2818   'scripts/tracetool/backend/simple.py',
2819   'scripts/tracetool/backend/syslog.py',
2820   'scripts/tracetool/backend/ust.py',
2821   'scripts/tracetool/format/ust_events_c.py',
2822   'scripts/tracetool/format/ust_events_h.py',
2823   'scripts/tracetool/format/__init__.py',
2824   'scripts/tracetool/format/d.py',
2825   'scripts/tracetool/format/simpletrace_stap.py',
2826   'scripts/tracetool/format/c.py',
2827   'scripts/tracetool/format/h.py',
2828   'scripts/tracetool/format/log_stap.py',
2829   'scripts/tracetool/format/stap.py',
2830   'scripts/tracetool/__init__.py',
2831   'scripts/tracetool/transform.py',
2832   'scripts/tracetool/vcpu.py'
2835 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2836                     meson.current_source_dir(),
2837                     get_option('pkgversion'), meson.project_version()]
2838 qemu_version = custom_target('qemu-version.h',
2839                              output: 'qemu-version.h',
2840                              command: qemu_version_cmd,
2841                              capture: true,
2842                              build_by_default: true,
2843                              build_always_stale: true)
2844 genh += qemu_version
2846 hxdep = []
2847 hx_headers = [
2848   ['qemu-options.hx', 'qemu-options.def'],
2849   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2851 if have_system
2852   hx_headers += [
2853     ['hmp-commands.hx', 'hmp-commands.h'],
2854     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2855   ]
2856 endif
2857 foreach d : hx_headers
2858   hxdep += custom_target(d[1],
2859                 input: files(d[0]),
2860                 output: d[1],
2861                 capture: true,
2862                 build_by_default: true, # to be removed when added to a target
2863                 command: [hxtool, '-h', '@INPUT0@'])
2864 endforeach
2865 genh += hxdep
2867 ###################
2868 # Collect sources #
2869 ###################
2871 authz_ss = ss.source_set()
2872 blockdev_ss = ss.source_set()
2873 block_ss = ss.source_set()
2874 chardev_ss = ss.source_set()
2875 common_ss = ss.source_set()
2876 crypto_ss = ss.source_set()
2877 hwcore_ss = ss.source_set()
2878 io_ss = ss.source_set()
2879 qmp_ss = ss.source_set()
2880 qom_ss = ss.source_set()
2881 softmmu_ss = ss.source_set()
2882 specific_fuzz_ss = ss.source_set()
2883 specific_ss = ss.source_set()
2884 stub_ss = ss.source_set()
2885 trace_ss = ss.source_set()
2886 user_ss = ss.source_set()
2887 util_ss = ss.source_set()
2889 # accel modules
2890 qtest_module_ss = ss.source_set()
2891 tcg_module_ss = ss.source_set()
2893 modules = {}
2894 target_modules = {}
2895 hw_arch = {}
2896 target_arch = {}
2897 target_softmmu_arch = {}
2898 target_user_arch = {}
2900 ###############
2901 # Trace files #
2902 ###############
2904 # TODO: add each directory to the subdirs from its own meson.build, once
2905 # we have those
2906 trace_events_subdirs = [
2907   'crypto',
2908   'qapi',
2909   'qom',
2910   'monitor',
2911   'util',
2913 if have_linux_user
2914   trace_events_subdirs += [ 'linux-user' ]
2915 endif
2916 if have_bsd_user
2917   trace_events_subdirs += [ 'bsd-user' ]
2918 endif
2919 if have_block
2920   trace_events_subdirs += [
2921     'authz',
2922     'block',
2923     'io',
2924     'nbd',
2925     'scsi',
2926   ]
2927 endif
2928 if have_system
2929   trace_events_subdirs += [
2930     'accel/kvm',
2931     'audio',
2932     'backends',
2933     'backends/tpm',
2934     'chardev',
2935     'ebpf',
2936     'hw/9pfs',
2937     'hw/acpi',
2938     'hw/adc',
2939     'hw/alpha',
2940     'hw/arm',
2941     'hw/audio',
2942     'hw/block',
2943     'hw/block/dataplane',
2944     'hw/char',
2945     'hw/display',
2946     'hw/dma',
2947     'hw/hyperv',
2948     'hw/i2c',
2949     'hw/i386',
2950     'hw/i386/xen',
2951     'hw/ide',
2952     'hw/input',
2953     'hw/intc',
2954     'hw/isa',
2955     'hw/mem',
2956     'hw/mips',
2957     'hw/misc',
2958     'hw/misc/macio',
2959     'hw/net',
2960     'hw/net/can',
2961     'hw/nubus',
2962     'hw/nvme',
2963     'hw/nvram',
2964     'hw/pci',
2965     'hw/pci-host',
2966     'hw/ppc',
2967     'hw/rdma',
2968     'hw/rdma/vmw',
2969     'hw/rtc',
2970     'hw/s390x',
2971     'hw/scsi',
2972     'hw/sd',
2973     'hw/sh4',
2974     'hw/sparc',
2975     'hw/sparc64',
2976     'hw/ssi',
2977     'hw/timer',
2978     'hw/tpm',
2979     'hw/usb',
2980     'hw/vfio',
2981     'hw/virtio',
2982     'hw/watchdog',
2983     'hw/xen',
2984     'hw/gpio',
2985     'migration',
2986     'net',
2987     'softmmu',
2988     'ui',
2989     'hw/remote',
2990   ]
2991 endif
2992 if have_system or have_user
2993   trace_events_subdirs += [
2994     'accel/tcg',
2995     'hw/core',
2996     'target/arm',
2997     'target/arm/hvf',
2998     'target/hppa',
2999     'target/i386',
3000     'target/i386/kvm',
3001     'target/mips/tcg',
3002     'target/nios2',
3003     'target/ppc',
3004     'target/riscv',
3005     'target/s390x',
3006     'target/s390x/kvm',
3007     'target/sparc',
3008   ]
3009 endif
3011 vhost_user = not_found
3012 if targetos == 'linux' and have_vhost_user
3013   libvhost_user = subproject('libvhost-user')
3014   vhost_user = libvhost_user.get_variable('vhost_user_dep')
3015 endif
3017 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3018 # that is filled in by qapi/.
3019 subdir('qapi')
3020 subdir('qobject')
3021 subdir('stubs')
3022 subdir('trace')
3023 subdir('util')
3024 subdir('qom')
3025 subdir('authz')
3026 subdir('crypto')
3027 subdir('ui')
3028 subdir('hw')
3031 if enable_modules
3032   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3033   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3034 endif
3036 qom_ss = qom_ss.apply(config_host, strict: false)
3037 libqom = static_library('qom', qom_ss.sources() + genh,
3038                         dependencies: [qom_ss.dependencies()],
3039                         name_suffix: 'fa')
3040 qom = declare_dependency(link_whole: libqom)
3042 event_loop_base = files('event-loop-base.c')
3043 event_loop_base = static_library('event-loop-base', sources: event_loop_base + genh,
3044                                  build_by_default: true)
3045 event_loop_base = declare_dependency(link_whole: event_loop_base,
3046                                      dependencies: [qom])
3048 stub_ss = stub_ss.apply(config_all, strict: false)
3050 util_ss.add_all(trace_ss)
3051 util_ss = util_ss.apply(config_all, strict: false)
3052 libqemuutil = static_library('qemuutil',
3053                              sources: util_ss.sources() + stub_ss.sources() + genh,
3054                              dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
3055 qemuutil = declare_dependency(link_with: libqemuutil,
3056                               sources: genh + version_res,
3057                               dependencies: [event_loop_base])
3059 if have_system or have_user
3060   decodetree = generator(find_program('scripts/decodetree.py'),
3061                          output: 'decode-@BASENAME@.c.inc',
3062                          arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3063   subdir('libdecnumber')
3064   subdir('target')
3065 endif
3067 subdir('audio')
3068 subdir('io')
3069 subdir('chardev')
3070 subdir('fsdev')
3071 subdir('dump')
3073 if have_block
3074   block_ss.add(files(
3075     'block.c',
3076     'blockjob.c',
3077     'job.c',
3078     'qemu-io-cmds.c',
3079   ))
3080   if config_host_data.get('CONFIG_REPLICATION')
3081     block_ss.add(files('replication.c'))
3082   endif
3084   subdir('nbd')
3085   subdir('scsi')
3086   subdir('block')
3088   blockdev_ss.add(files(
3089     'blockdev.c',
3090     'blockdev-nbd.c',
3091     'iothread.c',
3092     'job-qmp.c',
3093   ), gnutls)
3095   # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3096   # os-win32.c does not
3097   blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
3098   softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
3099 endif
3101 common_ss.add(files('cpus-common.c'))
3103 subdir('softmmu')
3105 common_ss.add(capstone)
3106 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
3108 # Work around a gcc bug/misfeature wherein constant propagation looks
3109 # through an alias:
3110 #   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3111 # to guess that a const variable is always zero.  Without lto, this is
3112 # impossible, as the alias is restricted to page-vary-common.c.  Indeed,
3113 # without lto, not even the alias is required -- we simply use different
3114 # declarations in different compilation units.
3115 pagevary = files('page-vary-common.c')
3116 if get_option('b_lto')
3117   pagevary_flags = ['-fno-lto']
3118   if get_option('cfi')
3119     pagevary_flags += '-fno-sanitize=cfi-icall'
3120   endif
3121   pagevary = static_library('page-vary-common', sources: pagevary + genh,
3122                             c_args: pagevary_flags)
3123   pagevary = declare_dependency(link_with: pagevary)
3124 endif
3125 common_ss.add(pagevary)
3126 specific_ss.add(files('page-vary.c'))
3128 subdir('backends')
3129 subdir('disas')
3130 subdir('migration')
3131 subdir('monitor')
3132 subdir('net')
3133 subdir('replay')
3134 subdir('semihosting')
3135 subdir('tcg')
3136 subdir('fpu')
3137 subdir('accel')
3138 subdir('plugins')
3139 subdir('ebpf')
3141 common_user_inc = []
3143 subdir('common-user')
3144 subdir('bsd-user')
3145 subdir('linux-user')
3147 # needed for fuzzing binaries
3148 subdir('tests/qtest/libqos')
3149 subdir('tests/qtest/fuzz')
3151 # accel modules
3152 tcg_real_module_ss = ss.source_set()
3153 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3154 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3155 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3156                                 'tcg': tcg_real_module_ss }}
3158 ########################
3159 # Library dependencies #
3160 ########################
3162 modinfo_collect = find_program('scripts/modinfo-collect.py')
3163 modinfo_generate = find_program('scripts/modinfo-generate.py')
3164 modinfo_files = []
3166 block_mods = []
3167 softmmu_mods = []
3168 foreach d, list : modules
3169   foreach m, module_ss : list
3170     if enable_modules and targetos != 'windows'
3171       module_ss = module_ss.apply(config_all, strict: false)
3172       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3173                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3174       if d == 'block'
3175         block_mods += sl
3176       else
3177         softmmu_mods += sl
3178       endif
3179       if module_ss.sources() != []
3180         # FIXME: Should use sl.extract_all_objects(recursive: true) as
3181         # input. Sources can be used multiple times but objects are
3182         # unique when it comes to lookup in compile_commands.json.
3183         # Depnds on a mesion version with
3184         # https://github.com/mesonbuild/meson/pull/8900
3185         modinfo_files += custom_target(d + '-' + m + '.modinfo',
3186                                        output: d + '-' + m + '.modinfo',
3187                                        input: module_ss.sources() + genh,
3188                                        capture: true,
3189                                        command: [modinfo_collect, module_ss.sources()])
3190       endif
3191     else
3192       if d == 'block'
3193         block_ss.add_all(module_ss)
3194       else
3195         softmmu_ss.add_all(module_ss)
3196       endif
3197     endif
3198   endforeach
3199 endforeach
3201 foreach d, list : target_modules
3202   foreach m, module_ss : list
3203     if enable_modules and targetos != 'windows'
3204       foreach target : target_dirs
3205         if target.endswith('-softmmu')
3206           config_target = config_target_mak[target]
3207           config_target += config_host
3208           target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3209           c_args = ['-DNEED_CPU_H',
3210                     '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3211                     '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3212           target_module_ss = module_ss.apply(config_target, strict: false)
3213           if target_module_ss.sources() != []
3214             module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3215             sl = static_library(module_name,
3216                                 [genh, target_module_ss.sources()],
3217                                 dependencies: [modulecommon, target_module_ss.dependencies()],
3218                                 include_directories: target_inc,
3219                                 c_args: c_args,
3220                                 pic: true)
3221             softmmu_mods += sl
3222             # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3223             modinfo_files += custom_target(module_name + '.modinfo',
3224                                            output: module_name + '.modinfo',
3225                                            input: target_module_ss.sources() + genh,
3226                                            capture: true,
3227                                            command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3228           endif
3229         endif
3230       endforeach
3231     else
3232       specific_ss.add_all(module_ss)
3233     endif
3234   endforeach
3235 endforeach
3237 if enable_modules
3238   modinfo_src = custom_target('modinfo.c',
3239                               output: 'modinfo.c',
3240                               input: modinfo_files,
3241                               command: [modinfo_generate, '@INPUT@'],
3242                               capture: true)
3243   modinfo_lib = static_library('modinfo', modinfo_src)
3244   modinfo_dep = declare_dependency(link_whole: modinfo_lib)
3245   softmmu_ss.add(modinfo_dep)
3246 endif
3248 nm = find_program('nm')
3249 undefsym = find_program('scripts/undefsym.py')
3250 block_syms = custom_target('block.syms', output: 'block.syms',
3251                              input: [libqemuutil, block_mods],
3252                              capture: true,
3253                              command: [undefsym, nm, '@INPUT@'])
3254 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3255                              input: [libqemuutil, softmmu_mods],
3256                              capture: true,
3257                              command: [undefsym, nm, '@INPUT@'])
3259 authz_ss = authz_ss.apply(config_host, strict: false)
3260 libauthz = static_library('authz', authz_ss.sources() + genh,
3261                           dependencies: [authz_ss.dependencies()],
3262                           name_suffix: 'fa',
3263                           build_by_default: false)
3265 authz = declare_dependency(link_whole: libauthz,
3266                            dependencies: qom)
3268 crypto_ss = crypto_ss.apply(config_host, strict: false)
3269 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3270                            dependencies: [crypto_ss.dependencies()],
3271                            name_suffix: 'fa',
3272                            build_by_default: false)
3274 crypto = declare_dependency(link_whole: libcrypto,
3275                             dependencies: [authz, qom])
3277 io_ss = io_ss.apply(config_host, strict: false)
3278 libio = static_library('io', io_ss.sources() + genh,
3279                        dependencies: [io_ss.dependencies()],
3280                        link_with: libqemuutil,
3281                        name_suffix: 'fa',
3282                        build_by_default: false)
3284 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3286 libmigration = static_library('migration', sources: migration_files + genh,
3287                               name_suffix: 'fa',
3288                               build_by_default: false)
3289 migration = declare_dependency(link_with: libmigration,
3290                                dependencies: [zlib, qom, io])
3291 softmmu_ss.add(migration)
3293 block_ss = block_ss.apply(config_host, strict: false)
3294 libblock = static_library('block', block_ss.sources() + genh,
3295                           dependencies: block_ss.dependencies(),
3296                           link_depends: block_syms,
3297                           name_suffix: 'fa',
3298                           build_by_default: false)
3300 block = declare_dependency(link_whole: [libblock],
3301                            link_args: '@block.syms',
3302                            dependencies: [crypto, io])
3304 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
3305 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3306                              dependencies: blockdev_ss.dependencies(),
3307                              name_suffix: 'fa',
3308                              build_by_default: false)
3310 blockdev = declare_dependency(link_whole: [libblockdev],
3311                               dependencies: [block, event_loop_base])
3313 qmp_ss = qmp_ss.apply(config_host, strict: false)
3314 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3315                         dependencies: qmp_ss.dependencies(),
3316                         name_suffix: 'fa',
3317                         build_by_default: false)
3319 qmp = declare_dependency(link_whole: [libqmp])
3321 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3322                             name_suffix: 'fa',
3323                             dependencies: chardev_ss.dependencies(),
3324                             build_by_default: false)
3326 chardev = declare_dependency(link_whole: libchardev)
3328 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
3329 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3330                            name_suffix: 'fa',
3331                            build_by_default: false)
3332 hwcore = declare_dependency(link_whole: libhwcore)
3333 common_ss.add(hwcore)
3335 ###########
3336 # Targets #
3337 ###########
3339 emulator_modules = []
3340 foreach m : block_mods + softmmu_mods
3341   emulator_modules += shared_module(m.name(),
3342                 build_by_default: true,
3343                 name_prefix: '',
3344                 link_whole: m,
3345                 install: true,
3346                 install_dir: qemu_moddir)
3347 endforeach
3349 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3350 common_ss.add(qom, qemuutil)
3352 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
3353 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3355 common_all = common_ss.apply(config_all, strict: false)
3356 common_all = static_library('common',
3357                             build_by_default: false,
3358                             sources: common_all.sources() + genh,
3359                             include_directories: common_user_inc,
3360                             implicit_include_directories: false,
3361                             dependencies: common_all.dependencies(),
3362                             name_suffix: 'fa')
3364 feature_to_c = find_program('scripts/feature_to_c.sh')
3366 if targetos == 'darwin'
3367   entitlement = find_program('scripts/entitlement.sh')
3368 endif
3370 emulators = {}
3371 foreach target : target_dirs
3372   config_target = config_target_mak[target]
3373   target_name = config_target['TARGET_NAME']
3374   target_base_arch = config_target['TARGET_BASE_ARCH']
3375   arch_srcs = [config_target_h[target]]
3376   arch_deps = []
3377   c_args = ['-DNEED_CPU_H',
3378             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3379             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3380   link_args = emulator_link_args
3382   config_target += config_host
3383   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3384   if targetos == 'linux'
3385     target_inc += include_directories('linux-headers', is_system: true)
3386   endif
3387   if target.endswith('-softmmu')
3388     qemu_target_name = 'qemu-system-' + target_name
3389     target_type='system'
3390     t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3391     arch_srcs += t.sources()
3392     arch_deps += t.dependencies()
3394     hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3395     hw = hw_arch[hw_dir].apply(config_target, strict: false)
3396     arch_srcs += hw.sources()
3397     arch_deps += hw.dependencies()
3399     arch_srcs += config_devices_h[target]
3400     link_args += ['@block.syms', '@qemu.syms']
3401   else
3402     abi = config_target['TARGET_ABI_DIR']
3403     target_type='user'
3404     target_inc += common_user_inc
3405     qemu_target_name = 'qemu-' + target_name
3406     if target_base_arch in target_user_arch
3407       t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3408       arch_srcs += t.sources()
3409       arch_deps += t.dependencies()
3410     endif
3411     if 'CONFIG_LINUX_USER' in config_target
3412       base_dir = 'linux-user'
3413     endif
3414     if 'CONFIG_BSD_USER' in config_target
3415       base_dir = 'bsd-user'
3416       target_inc += include_directories('bsd-user/' / targetos)
3417       target_inc += include_directories('bsd-user/host/' / host_arch)
3418       dir = base_dir / abi
3419       arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3420     endif
3421     target_inc += include_directories(
3422       base_dir,
3423       base_dir / abi,
3424     )
3425     if 'CONFIG_LINUX_USER' in config_target
3426       dir = base_dir / abi
3427       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3428       if config_target.has_key('TARGET_SYSTBL_ABI')
3429         arch_srcs += \
3430           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3431                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
3432       endif
3433     endif
3434   endif
3436   if 'TARGET_XML_FILES' in config_target
3437     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3438                                 output: target + '-gdbstub-xml.c',
3439                                 input: files(config_target['TARGET_XML_FILES'].split()),
3440                                 command: [feature_to_c, '@INPUT@'],
3441                                 capture: true)
3442     arch_srcs += gdbstub_xml
3443   endif
3445   t = target_arch[target_base_arch].apply(config_target, strict: false)
3446   arch_srcs += t.sources()
3447   arch_deps += t.dependencies()
3449   target_common = common_ss.apply(config_target, strict: false)
3450   objects = common_all.extract_objects(target_common.sources())
3451   deps = target_common.dependencies()
3453   target_specific = specific_ss.apply(config_target, strict: false)
3454   arch_srcs += target_specific.sources()
3455   arch_deps += target_specific.dependencies()
3457   lib = static_library('qemu-' + target,
3458                  sources: arch_srcs + genh,
3459                  dependencies: arch_deps,
3460                  objects: objects,
3461                  include_directories: target_inc,
3462                  c_args: c_args,
3463                  build_by_default: false,
3464                  name_suffix: 'fa')
3466   if target.endswith('-softmmu')
3467     execs = [{
3468       'name': 'qemu-system-' + target_name,
3469       'win_subsystem': 'console',
3470       'sources': files('softmmu/main.c'),
3471       'dependencies': []
3472     }]
3473     if targetos == 'windows' and (sdl.found() or gtk.found())
3474       execs += [{
3475         'name': 'qemu-system-' + target_name + 'w',
3476         'win_subsystem': 'windows',
3477         'sources': files('softmmu/main.c'),
3478         'dependencies': []
3479       }]
3480     endif
3481     if get_option('fuzzing')
3482       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3483       execs += [{
3484         'name': 'qemu-fuzz-' + target_name,
3485         'win_subsystem': 'console',
3486         'sources': specific_fuzz.sources(),
3487         'dependencies': specific_fuzz.dependencies(),
3488       }]
3489     endif
3490   else
3491     execs = [{
3492       'name': 'qemu-' + target_name,
3493       'win_subsystem': 'console',
3494       'sources': [],
3495       'dependencies': []
3496     }]
3497   endif
3498   foreach exe: execs
3499     exe_name = exe['name']
3500     if targetos == 'darwin'
3501       exe_name += '-unsigned'
3502     endif
3504     emulator = executable(exe_name, exe['sources'],
3505                install: true,
3506                c_args: c_args,
3507                dependencies: arch_deps + deps + exe['dependencies'],
3508                objects: lib.extract_all_objects(recursive: true),
3509                link_language: link_language,
3510                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3511                link_args: link_args,
3512                win_subsystem: exe['win_subsystem'])
3514     if targetos == 'darwin'
3515       icon = 'pc-bios/qemu.rsrc'
3516       build_input = [emulator, files(icon)]
3517       install_input = [
3518         get_option('bindir') / exe_name,
3519         meson.current_source_dir() / icon
3520       ]
3521       if 'CONFIG_HVF' in config_target
3522         entitlements = 'accel/hvf/entitlements.plist'
3523         build_input += files(entitlements)
3524         install_input += meson.current_source_dir() / entitlements
3525       endif
3527       emulators += {exe['name'] : custom_target(exe['name'],
3528                    input: build_input,
3529                    output: exe['name'],
3530                    command: [entitlement, '@OUTPUT@', '@INPUT@'])
3531       }
3533       meson.add_install_script(entitlement, '--install',
3534                                get_option('bindir') / exe['name'],
3535                                install_input)
3536     else
3537       emulators += {exe['name']: emulator}
3538     endif
3540     if stap.found()
3541       foreach stp: [
3542         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3543         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3544         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3545         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3546       ]
3547         custom_target(exe['name'] + stp['ext'],
3548                       input: trace_events_all,
3549                       output: exe['name'] + stp['ext'],
3550                       install: stp['install'],
3551                       install_dir: get_option('datadir') / 'systemtap/tapset',
3552                       command: [
3553                         tracetool, '--group=all', '--format=' + stp['fmt'],
3554                         '--binary=' + stp['bin'],
3555                         '--target-name=' + target_name,
3556                         '--target-type=' + target_type,
3557                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
3558                         '@INPUT@', '@OUTPUT@'
3559                       ],
3560                       depend_files: tracetool_depends)
3561       endforeach
3562     endif
3563   endforeach
3564 endforeach
3566 # Other build targets
3568 if 'CONFIG_PLUGIN' in config_host
3569   install_headers('include/qemu/qemu-plugin.h')
3570 endif
3572 subdir('qga')
3574 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3575 # when we don't build tools or system
3576 if xkbcommon.found()
3577   # used for the update-keymaps target, so include rules even if !have_tools
3578   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3579                            dependencies: [qemuutil, xkbcommon], install: have_tools)
3580 endif
3582 if have_tools
3583   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3584              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3585   qemu_io = executable('qemu-io', files('qemu-io.c'),
3586              dependencies: [block, qemuutil], install: true)
3587   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3588                dependencies: [blockdev, qemuutil, gnutls, selinux],
3589                install: true)
3591   subdir('storage-daemon')
3592   subdir('contrib/rdmacm-mux')
3593   subdir('contrib/elf2dmp')
3595   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3596              dependencies: qemuutil,
3597              install: true)
3599   if have_vhost_user
3600     subdir('contrib/vhost-user-blk')
3601     subdir('contrib/vhost-user-gpu')
3602     subdir('contrib/vhost-user-input')
3603     subdir('contrib/vhost-user-scsi')
3604   endif
3606   if targetos == 'linux'
3607     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3608                dependencies: [qemuutil, libcap_ng],
3609                install: true,
3610                install_dir: get_option('libexecdir'))
3612     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3613                dependencies: [authz, crypto, io, qom, qemuutil,
3614                               libcap_ng, mpathpersist],
3615                install: true)
3616   endif
3618   if have_ivshmem
3619     subdir('contrib/ivshmem-client')
3620     subdir('contrib/ivshmem-server')
3621   endif
3622 endif
3624 subdir('scripts')
3625 subdir('tools')
3626 subdir('pc-bios')
3627 subdir('docs')
3628 subdir('tests')
3629 if gtk.found()
3630   subdir('po')
3631 endif
3633 if host_machine.system() == 'windows'
3634   nsis_cmd = [
3635     find_program('scripts/nsis.py'),
3636     '@OUTPUT@',
3637     get_option('prefix'),
3638     meson.current_source_dir(),
3639     host_machine.cpu(),
3640     '--',
3641     '-DDISPLAYVERSION=' + meson.project_version(),
3642   ]
3643   if build_docs
3644     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3645   endif
3646   if gtk.found()
3647     nsis_cmd += '-DCONFIG_GTK=y'
3648   endif
3650   nsis = custom_target('nsis',
3651                        output: 'qemu-setup-' + meson.project_version() + '.exe',
3652                        input: files('qemu.nsi'),
3653                        build_always_stale: true,
3654                        command: nsis_cmd + ['@INPUT@'])
3655   alias_target('installer', nsis)
3656 endif
3658 #########################
3659 # Configuration summary #
3660 #########################
3662 # Directories
3663 summary_info = {}
3664 summary_info += {'Install prefix':    get_option('prefix')}
3665 summary_info += {'BIOS directory':    qemu_datadir}
3666 summary_info += {'firmware path':     get_option('prefix') / get_option('qemu_firmwarepath')}
3667 summary_info += {'binary directory':  get_option('prefix') / get_option('bindir')}
3668 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
3669 summary_info += {'module directory':  qemu_moddir}
3670 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
3671 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
3672 summary_info += {'config directory':  get_option('prefix') / get_option('sysconfdir')}
3673 if targetos != 'windows'
3674   summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
3675   summary_info += {'Manual directory':      get_option('prefix') / get_option('mandir')}
3676 else
3677   summary_info += {'local state directory': 'queried at runtime'}
3678 endif
3679 summary_info += {'Doc directory':     get_option('prefix') / get_option('docdir')}
3680 summary_info += {'Build directory':   meson.current_build_dir()}
3681 summary_info += {'Source path':       meson.current_source_dir()}
3682 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
3683 summary(summary_info, bool_yn: true, section: 'Directories')
3685 # Host binaries
3686 summary_info = {}
3687 summary_info += {'git':               config_host['GIT']}
3688 summary_info += {'make':              config_host['MAKE']}
3689 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3690 summary_info += {'sphinx-build':      sphinx_build}
3691 if config_host.has_key('HAVE_GDB_BIN')
3692   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
3693 endif
3694 summary_info += {'iasl':              iasl}
3695 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
3696 if targetos == 'windows' and have_ga
3697   summary_info += {'wixl':            wixl}
3698 endif
3699 if slirp_opt != 'disabled' and have_system
3700   summary_info += {'smbd':            have_slirp_smbd ? smbd_path : false}
3701 endif
3702 summary(summary_info, bool_yn: true, section: 'Host binaries')
3704 # Configurable features
3705 summary_info = {}
3706 summary_info += {'Documentation':     build_docs}
3707 summary_info += {'system-mode emulation': have_system}
3708 summary_info += {'user-mode emulation': have_user}
3709 summary_info += {'block layer':       have_block}
3710 summary_info += {'Install blobs':     get_option('install_blobs')}
3711 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
3712 if config_host.has_key('CONFIG_MODULES')
3713   summary_info += {'alternative module path': get_option('module_upgrades')}
3714 endif
3715 summary_info += {'fuzzing support':   get_option('fuzzing')}
3716 if have_system
3717   summary_info += {'Audio drivers':     ' '.join(audio_drivers_selected)}
3718 endif
3719 summary_info += {'Trace backends':    ','.join(get_option('trace_backends'))}
3720 if 'simple' in get_option('trace_backends')
3721   summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3722 endif
3723 summary_info += {'D-Bus display':     dbus_display}
3724 summary_info += {'QOM debugging':     get_option('qom_cast_debug')}
3725 summary_info += {'vhost-kernel support': have_vhost_kernel}
3726 summary_info += {'vhost-net support': have_vhost_net}
3727 summary_info += {'vhost-user support': have_vhost_user}
3728 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
3729 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3730 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
3731 summary_info += {'build guest agent': have_ga}
3732 summary(summary_info, bool_yn: true, section: 'Configurable features')
3734 # Compilation information
3735 summary_info = {}
3736 summary_info += {'host CPU':          cpu}
3737 summary_info += {'host endianness':   build_machine.endian()}
3738 summary_info += {'C compiler':        ' '.join(meson.get_compiler('c').cmd_array())}
3739 summary_info += {'Host C compiler':   ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3740 if link_language == 'cpp'
3741   summary_info += {'C++ compiler':    ' '.join(meson.get_compiler('cpp').cmd_array())}
3742 else
3743   summary_info += {'C++ compiler':      false}
3744 endif
3745 if targetos == 'darwin'
3746   summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3747 endif
3748 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
3749                                                + ['-O' + get_option('optimization')]
3750                                                + (get_option('debug') ? ['-g'] : []))}
3751 if link_language == 'cpp'
3752   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
3753                                                + ['-O' + get_option('optimization')]
3754                                                + (get_option('debug') ? ['-g'] : []))}
3755 endif
3756 if targetos == 'darwin'
3757   summary_info += {'OBJCFLAGS':       ' '.join(get_option('objc_args')
3758                                                + ['-O' + get_option('optimization')]
3759                                                + (get_option('debug') ? ['-g'] : []))}
3760 endif
3761 link_args = get_option(link_language + '_link_args')
3762 if link_args.length() > 0
3763   summary_info += {'LDFLAGS':         ' '.join(link_args)}
3764 endif
3765 summary_info += {'QEMU_CFLAGS':       ' '.join(qemu_cflags)}
3766 summary_info += {'QEMU_CXXFLAGS':     ' '.join(qemu_cxxflags)}
3767 summary_info += {'QEMU_OBJCFLAGS':    ' '.join(qemu_objcflags)}
3768 summary_info += {'QEMU_LDFLAGS':      ' '.join(qemu_ldflags)}
3769 summary_info += {'profiler':          get_option('profiler')}
3770 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3771 summary_info += {'PIE':               get_option('b_pie')}
3772 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
3773 summary_info += {'malloc trim support': has_malloc_trim}
3774 summary_info += {'membarrier':        have_membarrier}
3775 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
3776 summary_info += {'mutex debugging':   get_option('debug_mutex')}
3777 summary_info += {'memory allocator':  get_option('malloc')}
3778 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
3779 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
3780 summary_info += {'gprof enabled':     get_option('gprof')}
3781 summary_info += {'gcov':              get_option('b_coverage')}
3782 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
3783 summary_info += {'CFI support':       get_option('cfi')}
3784 if get_option('cfi')
3785   summary_info += {'CFI debug support': get_option('cfi_debug')}
3786 endif
3787 summary_info += {'strip binaries':    get_option('strip')}
3788 summary_info += {'sparse':            sparse}
3789 summary_info += {'mingw32 support':   targetos == 'windows'}
3791 # snarf the cross-compilation information for tests
3792 foreach target: target_dirs
3793   tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3794   if fs.exists(tcg_mak)
3795     config_cross_tcg = keyval.load(tcg_mak)
3796     target = config_cross_tcg['TARGET_NAME']
3797     compiler = ''
3798     if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3799       summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3800                                           ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3801     elif 'CROSS_CC_GUEST' in config_cross_tcg
3802       summary_info += {target + ' tests'
3803                                 : config_cross_tcg['CROSS_CC_GUEST'] }
3804     endif
3805    endif
3806 endforeach
3808 summary(summary_info, bool_yn: true, section: 'Compilation')
3810 # Targets and accelerators
3811 summary_info = {}
3812 if have_system
3813   summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
3814   summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
3815   summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
3816   summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
3817   summary_info += {'NVMM support':      config_all.has_key('CONFIG_NVMM')}
3818   summary_info += {'Xen support':       xen.found()}
3819   if xen.found()
3820     summary_info += {'xen ctrl version':  xen.version()}
3821   endif
3822 endif
3823 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
3824 if config_all.has_key('CONFIG_TCG')
3825   if get_option('tcg_interpreter')
3826     summary_info += {'TCG backend':   'TCI (TCG with bytecode interpreter, slow)'}
3827   else
3828     summary_info += {'TCG backend':   'native (@0@)'.format(cpu)}
3829   endif
3830   summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3831   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3832 endif
3833 summary_info += {'target list':       ' '.join(target_dirs)}
3834 if have_system
3835   summary_info += {'default devices':   get_option('default_devices')}
3836   summary_info += {'out of process emulation': multiprocess_allowed}
3837 endif
3838 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3840 # Block layer
3841 summary_info = {}
3842 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3843 summary_info += {'coroutine pool':    have_coroutine_pool}
3844 if have_block
3845   summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
3846   summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
3847   summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
3848   summary_info += {'VirtFS support':    have_virtfs}
3849   summary_info += {'build virtiofs daemon': have_virtiofsd}
3850   summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
3851   summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
3852   summary_info += {'bochs support':     get_option('bochs').allowed()}
3853   summary_info += {'cloop support':     get_option('cloop').allowed()}
3854   summary_info += {'dmg support':       get_option('dmg').allowed()}
3855   summary_info += {'qcow v1 support':   get_option('qcow1').allowed()}
3856   summary_info += {'vdi support':       get_option('vdi').allowed()}
3857   summary_info += {'vvfat support':     get_option('vvfat').allowed()}
3858   summary_info += {'qed support':       get_option('qed').allowed()}
3859   summary_info += {'parallels support': get_option('parallels').allowed()}
3860   summary_info += {'FUSE exports':      fuse}
3861 endif
3862 summary(summary_info, bool_yn: true, section: 'Block layer support')
3864 # Crypto
3865 summary_info = {}
3866 summary_info += {'TLS priority':      get_option('tls_priority')}
3867 summary_info += {'GNUTLS support':    gnutls}
3868 if gnutls.found()
3869   summary_info += {'  GNUTLS crypto':   gnutls_crypto.found()}
3870 endif
3871 summary_info += {'libgcrypt':         gcrypt}
3872 summary_info += {'nettle':            nettle}
3873 if nettle.found()
3874    summary_info += {'  XTS':             xts != 'private'}
3875 endif
3876 summary_info += {'AF_ALG support':    have_afalg}
3877 summary_info += {'rng-none':          get_option('rng_none')}
3878 summary_info += {'Linux keyring':     have_keyring}
3879 summary(summary_info, bool_yn: true, section: 'Crypto')
3881 # Libraries
3882 summary_info = {}
3883 if targetos == 'darwin'
3884   summary_info += {'Cocoa support':   cocoa}
3885 endif
3886 summary_info += {'SDL support':       sdl}
3887 summary_info += {'SDL image support': sdl_image}
3888 summary_info += {'GTK support':       gtk}
3889 summary_info += {'pixman':            pixman}
3890 summary_info += {'VTE support':       vte}
3891 summary_info += {'slirp support':     slirp_opt == 'internal' ? slirp_opt : slirp}
3892 summary_info += {'libtasn1':          tasn1}
3893 summary_info += {'PAM':               pam}
3894 summary_info += {'iconv support':     iconv}
3895 summary_info += {'curses support':    curses}
3896 summary_info += {'virgl support':     virgl}
3897 summary_info += {'curl support':      curl}
3898 summary_info += {'Multipath support': mpathpersist}
3899 summary_info += {'PNG support':       png}
3900 summary_info += {'VNC support':       vnc}
3901 if vnc.found()
3902   summary_info += {'VNC SASL support':  sasl}
3903   summary_info += {'VNC JPEG support':  jpeg}
3904 endif
3905 if targetos not in ['darwin', 'haiku', 'windows']
3906   summary_info += {'OSS support':     oss}
3907 elif targetos == 'darwin'
3908   summary_info += {'CoreAudio support': coreaudio}
3909 elif targetos == 'windows'
3910   summary_info += {'DirectSound support': dsound}
3911 endif
3912 if targetos == 'linux'
3913   summary_info += {'ALSA support':    alsa}
3914   summary_info += {'PulseAudio support': pulse}
3915 endif
3916 summary_info += {'JACK support':      jack}
3917 summary_info += {'brlapi support':    brlapi}
3918 summary_info += {'vde support':       vde}
3919 summary_info += {'netmap support':    have_netmap}
3920 summary_info += {'l2tpv3 support':    have_l2tpv3}
3921 summary_info += {'Linux AIO support': libaio}
3922 summary_info += {'Linux io_uring support': linux_io_uring}
3923 summary_info += {'ATTR/XATTR support': libattr}
3924 summary_info += {'RDMA support':      rdma}
3925 summary_info += {'PVRDMA support':    have_pvrdma}
3926 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
3927 summary_info += {'libcap-ng support': libcap_ng}
3928 summary_info += {'bpf support':       libbpf}
3929 summary_info += {'spice protocol support': spice_protocol}
3930 if spice_protocol.found()
3931   summary_info += {'  spice server support': spice}
3932 endif
3933 summary_info += {'rbd support':       rbd}
3934 summary_info += {'smartcard support': cacard}
3935 summary_info += {'U2F support':       u2f}
3936 summary_info += {'libusb':            libusb}
3937 summary_info += {'usb net redir':     usbredir}
3938 summary_info += {'OpenGL support (epoxy)': opengl}
3939 summary_info += {'GBM':               gbm}
3940 summary_info += {'libiscsi support':  libiscsi}
3941 summary_info += {'libnfs support':    libnfs}
3942 if targetos == 'windows'
3943   if have_ga
3944     summary_info += {'QGA VSS support':   have_qga_vss}
3945   endif
3946 endif
3947 summary_info += {'seccomp support':   seccomp}
3948 summary_info += {'GlusterFS support': glusterfs}
3949 summary_info += {'TPM support':       have_tpm}
3950 summary_info += {'libssh support':    libssh}
3951 summary_info += {'lzo support':       lzo}
3952 summary_info += {'snappy support':    snappy}
3953 summary_info += {'bzip2 support':     libbzip2}
3954 summary_info += {'lzfse support':     liblzfse}
3955 summary_info += {'zstd support':      zstd}
3956 summary_info += {'NUMA host support': numa}
3957 summary_info += {'capstone':          capstone_opt == 'internal' ? capstone_opt : capstone}
3958 summary_info += {'libpmem support':   libpmem}
3959 summary_info += {'libdaxctl support': libdaxctl}
3960 summary_info += {'libudev':           libudev}
3961 # Dummy dependency, keep .found()
3962 summary_info += {'FUSE lseek':        fuse_lseek.found()}
3963 summary_info += {'selinux':           selinux}
3964 summary(summary_info, bool_yn: true, section: 'Dependencies')
3966 if not supported_cpus.contains(cpu)
3967   message()
3968   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3969   message()
3970   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3971   message('The QEMU project intends to remove support for this host CPU in')
3972   message('a future release if nobody volunteers to maintain it and to')
3973   message('provide a build host for our continuous integration setup.')
3974   message('configure has succeeded and you can continue to build, but')
3975   message('if you care about QEMU on this platform you should contact')
3976   message('us upstream at qemu-devel@nongnu.org.')
3977 endif
3979 if not supported_oses.contains(targetos)
3980   message()
3981   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3982   message()
3983   message('Host OS ' + targetos + 'support is not currently maintained.')
3984   message('The QEMU project intends to remove support for this host OS in')
3985   message('a future release if nobody volunteers to maintain it and to')
3986   message('provide a build host for our continuous integration setup.')
3987   message('configure has succeeded and you can continue to build, but')
3988   message('if you care about QEMU on this platform you should contact')
3989   message('us upstream at qemu-devel@nongnu.org.')
3990 endif