target/arm: Enable FEAT_CSV2_2 for -cpu max
[qemu.git] / meson.build
blobfa672e57bcfb8b513e08b51d79d3d09a3c2c5824
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')
3030 if enable_modules
3031   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3032   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3033 endif
3035 stub_ss = stub_ss.apply(config_all, strict: false)
3037 util_ss.add_all(trace_ss)
3038 util_ss = util_ss.apply(config_all, strict: false)
3039 libqemuutil = static_library('qemuutil',
3040                              sources: util_ss.sources() + stub_ss.sources() + genh,
3041                              dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
3042 qemuutil = declare_dependency(link_with: libqemuutil,
3043                               sources: genh + version_res)
3045 if have_system or have_user
3046   decodetree = generator(find_program('scripts/decodetree.py'),
3047                          output: 'decode-@BASENAME@.c.inc',
3048                          arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3049   subdir('libdecnumber')
3050   subdir('target')
3051 endif
3053 subdir('audio')
3054 subdir('io')
3055 subdir('chardev')
3056 subdir('fsdev')
3057 subdir('dump')
3059 if have_block
3060   block_ss.add(files(
3061     'block.c',
3062     'blockjob.c',
3063     'job.c',
3064     'qemu-io-cmds.c',
3065   ))
3066   if config_host_data.get('CONFIG_REPLICATION')
3067     block_ss.add(files('replication.c'))
3068   endif
3070   subdir('nbd')
3071   subdir('scsi')
3072   subdir('block')
3074   blockdev_ss.add(files(
3075     'blockdev.c',
3076     'blockdev-nbd.c',
3077     'iothread.c',
3078     'job-qmp.c',
3079   ), gnutls)
3081   # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3082   # os-win32.c does not
3083   blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
3084   softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
3085 endif
3087 common_ss.add(files('cpus-common.c'))
3089 subdir('softmmu')
3091 common_ss.add(capstone)
3092 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
3094 # Work around a gcc bug/misfeature wherein constant propagation looks
3095 # through an alias:
3096 #   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3097 # to guess that a const variable is always zero.  Without lto, this is
3098 # impossible, as the alias is restricted to page-vary-common.c.  Indeed,
3099 # without lto, not even the alias is required -- we simply use different
3100 # declarations in different compilation units.
3101 pagevary = files('page-vary-common.c')
3102 if get_option('b_lto')
3103   pagevary_flags = ['-fno-lto']
3104   if get_option('cfi')
3105     pagevary_flags += '-fno-sanitize=cfi-icall'
3106   endif
3107   pagevary = static_library('page-vary-common', sources: pagevary + genh,
3108                             c_args: pagevary_flags)
3109   pagevary = declare_dependency(link_with: pagevary)
3110 endif
3111 common_ss.add(pagevary)
3112 specific_ss.add(files('page-vary.c'))
3114 subdir('backends')
3115 subdir('disas')
3116 subdir('migration')
3117 subdir('monitor')
3118 subdir('net')
3119 subdir('replay')
3120 subdir('semihosting')
3121 subdir('hw')
3122 subdir('tcg')
3123 subdir('fpu')
3124 subdir('accel')
3125 subdir('plugins')
3126 subdir('ebpf')
3128 common_user_inc = []
3130 subdir('common-user')
3131 subdir('bsd-user')
3132 subdir('linux-user')
3134 # needed for fuzzing binaries
3135 subdir('tests/qtest/libqos')
3136 subdir('tests/qtest/fuzz')
3138 # accel modules
3139 tcg_real_module_ss = ss.source_set()
3140 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3141 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3142 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3143                                 'tcg': tcg_real_module_ss }}
3145 ########################
3146 # Library dependencies #
3147 ########################
3149 modinfo_collect = find_program('scripts/modinfo-collect.py')
3150 modinfo_generate = find_program('scripts/modinfo-generate.py')
3151 modinfo_files = []
3153 block_mods = []
3154 softmmu_mods = []
3155 foreach d, list : modules
3156   foreach m, module_ss : list
3157     if enable_modules and targetos != 'windows'
3158       module_ss = module_ss.apply(config_all, strict: false)
3159       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3160                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3161       if d == 'block'
3162         block_mods += sl
3163       else
3164         softmmu_mods += sl
3165       endif
3166       if module_ss.sources() != []
3167         # FIXME: Should use sl.extract_all_objects(recursive: true) as
3168         # input. Sources can be used multiple times but objects are
3169         # unique when it comes to lookup in compile_commands.json.
3170         # Depnds on a mesion version with
3171         # https://github.com/mesonbuild/meson/pull/8900
3172         modinfo_files += custom_target(d + '-' + m + '.modinfo',
3173                                        output: d + '-' + m + '.modinfo',
3174                                        input: module_ss.sources() + genh,
3175                                        capture: true,
3176                                        command: [modinfo_collect, module_ss.sources()])
3177       endif
3178     else
3179       if d == 'block'
3180         block_ss.add_all(module_ss)
3181       else
3182         softmmu_ss.add_all(module_ss)
3183       endif
3184     endif
3185   endforeach
3186 endforeach
3188 foreach d, list : target_modules
3189   foreach m, module_ss : list
3190     if enable_modules and targetos != 'windows'
3191       foreach target : target_dirs
3192         if target.endswith('-softmmu')
3193           config_target = config_target_mak[target]
3194           config_target += config_host
3195           target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3196           c_args = ['-DNEED_CPU_H',
3197                     '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3198                     '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3199           target_module_ss = module_ss.apply(config_target, strict: false)
3200           if target_module_ss.sources() != []
3201             module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3202             sl = static_library(module_name,
3203                                 [genh, target_module_ss.sources()],
3204                                 dependencies: [modulecommon, target_module_ss.dependencies()],
3205                                 include_directories: target_inc,
3206                                 c_args: c_args,
3207                                 pic: true)
3208             softmmu_mods += sl
3209             # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3210             modinfo_files += custom_target(module_name + '.modinfo',
3211                                            output: module_name + '.modinfo',
3212                                            input: target_module_ss.sources() + genh,
3213                                            capture: true,
3214                                            command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3215           endif
3216         endif
3217       endforeach
3218     else
3219       specific_ss.add_all(module_ss)
3220     endif
3221   endforeach
3222 endforeach
3224 if enable_modules
3225   modinfo_src = custom_target('modinfo.c',
3226                               output: 'modinfo.c',
3227                               input: modinfo_files,
3228                               command: [modinfo_generate, '@INPUT@'],
3229                               capture: true)
3230   modinfo_lib = static_library('modinfo', modinfo_src)
3231   modinfo_dep = declare_dependency(link_whole: modinfo_lib)
3232   softmmu_ss.add(modinfo_dep)
3233 endif
3235 nm = find_program('nm')
3236 undefsym = find_program('scripts/undefsym.py')
3237 block_syms = custom_target('block.syms', output: 'block.syms',
3238                              input: [libqemuutil, block_mods],
3239                              capture: true,
3240                              command: [undefsym, nm, '@INPUT@'])
3241 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3242                              input: [libqemuutil, softmmu_mods],
3243                              capture: true,
3244                              command: [undefsym, nm, '@INPUT@'])
3246 qom_ss = qom_ss.apply(config_host, strict: false)
3247 libqom = static_library('qom', qom_ss.sources() + genh,
3248                         dependencies: [qom_ss.dependencies()],
3249                         name_suffix: 'fa')
3251 qom = declare_dependency(link_whole: libqom)
3253 authz_ss = authz_ss.apply(config_host, strict: false)
3254 libauthz = static_library('authz', authz_ss.sources() + genh,
3255                           dependencies: [authz_ss.dependencies()],
3256                           name_suffix: 'fa',
3257                           build_by_default: false)
3259 authz = declare_dependency(link_whole: libauthz,
3260                            dependencies: qom)
3262 crypto_ss = crypto_ss.apply(config_host, strict: false)
3263 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3264                            dependencies: [crypto_ss.dependencies()],
3265                            name_suffix: 'fa',
3266                            build_by_default: false)
3268 crypto = declare_dependency(link_whole: libcrypto,
3269                             dependencies: [authz, qom])
3271 io_ss = io_ss.apply(config_host, strict: false)
3272 libio = static_library('io', io_ss.sources() + genh,
3273                        dependencies: [io_ss.dependencies()],
3274                        link_with: libqemuutil,
3275                        name_suffix: 'fa',
3276                        build_by_default: false)
3278 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3280 libmigration = static_library('migration', sources: migration_files + genh,
3281                               name_suffix: 'fa',
3282                               build_by_default: false)
3283 migration = declare_dependency(link_with: libmigration,
3284                                dependencies: [zlib, qom, io])
3285 softmmu_ss.add(migration)
3287 block_ss = block_ss.apply(config_host, strict: false)
3288 libblock = static_library('block', block_ss.sources() + genh,
3289                           dependencies: block_ss.dependencies(),
3290                           link_depends: block_syms,
3291                           name_suffix: 'fa',
3292                           build_by_default: false)
3294 block = declare_dependency(link_whole: [libblock],
3295                            link_args: '@block.syms',
3296                            dependencies: [crypto, io])
3298 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
3299 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3300                              dependencies: blockdev_ss.dependencies(),
3301                              name_suffix: 'fa',
3302                              build_by_default: false)
3304 blockdev = declare_dependency(link_whole: [libblockdev],
3305                               dependencies: [block])
3307 qmp_ss = qmp_ss.apply(config_host, strict: false)
3308 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3309                         dependencies: qmp_ss.dependencies(),
3310                         name_suffix: 'fa',
3311                         build_by_default: false)
3313 qmp = declare_dependency(link_whole: [libqmp])
3315 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3316                             name_suffix: 'fa',
3317                             dependencies: chardev_ss.dependencies(),
3318                             build_by_default: false)
3320 chardev = declare_dependency(link_whole: libchardev)
3322 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
3323 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3324                            name_suffix: 'fa',
3325                            build_by_default: false)
3326 hwcore = declare_dependency(link_whole: libhwcore)
3327 common_ss.add(hwcore)
3329 ###########
3330 # Targets #
3331 ###########
3333 emulator_modules = []
3334 foreach m : block_mods + softmmu_mods
3335   emulator_modules += shared_module(m.name(),
3336                 build_by_default: true,
3337                 name_prefix: '',
3338                 link_whole: m,
3339                 install: true,
3340                 install_dir: qemu_moddir)
3341 endforeach
3343 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3344 common_ss.add(qom, qemuutil)
3346 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
3347 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3349 common_all = common_ss.apply(config_all, strict: false)
3350 common_all = static_library('common',
3351                             build_by_default: false,
3352                             sources: common_all.sources() + genh,
3353                             include_directories: common_user_inc,
3354                             implicit_include_directories: false,
3355                             dependencies: common_all.dependencies(),
3356                             name_suffix: 'fa')
3358 feature_to_c = find_program('scripts/feature_to_c.sh')
3360 if targetos == 'darwin'
3361   entitlement = find_program('scripts/entitlement.sh')
3362 endif
3364 emulators = {}
3365 foreach target : target_dirs
3366   config_target = config_target_mak[target]
3367   target_name = config_target['TARGET_NAME']
3368   target_base_arch = config_target['TARGET_BASE_ARCH']
3369   arch_srcs = [config_target_h[target]]
3370   arch_deps = []
3371   c_args = ['-DNEED_CPU_H',
3372             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3373             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3374   link_args = emulator_link_args
3376   config_target += config_host
3377   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3378   if targetos == 'linux'
3379     target_inc += include_directories('linux-headers', is_system: true)
3380   endif
3381   if target.endswith('-softmmu')
3382     qemu_target_name = 'qemu-system-' + target_name
3383     target_type='system'
3384     t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3385     arch_srcs += t.sources()
3386     arch_deps += t.dependencies()
3388     hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3389     hw = hw_arch[hw_dir].apply(config_target, strict: false)
3390     arch_srcs += hw.sources()
3391     arch_deps += hw.dependencies()
3393     arch_srcs += config_devices_h[target]
3394     link_args += ['@block.syms', '@qemu.syms']
3395   else
3396     abi = config_target['TARGET_ABI_DIR']
3397     target_type='user'
3398     target_inc += common_user_inc
3399     qemu_target_name = 'qemu-' + target_name
3400     if target_base_arch in target_user_arch
3401       t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3402       arch_srcs += t.sources()
3403       arch_deps += t.dependencies()
3404     endif
3405     if 'CONFIG_LINUX_USER' in config_target
3406       base_dir = 'linux-user'
3407     endif
3408     if 'CONFIG_BSD_USER' in config_target
3409       base_dir = 'bsd-user'
3410       target_inc += include_directories('bsd-user/' / targetos)
3411       target_inc += include_directories('bsd-user/host/' / host_arch)
3412       dir = base_dir / abi
3413       arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3414     endif
3415     target_inc += include_directories(
3416       base_dir,
3417       base_dir / abi,
3418     )
3419     if 'CONFIG_LINUX_USER' in config_target
3420       dir = base_dir / abi
3421       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3422       if config_target.has_key('TARGET_SYSTBL_ABI')
3423         arch_srcs += \
3424           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3425                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
3426       endif
3427     endif
3428   endif
3430   if 'TARGET_XML_FILES' in config_target
3431     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3432                                 output: target + '-gdbstub-xml.c',
3433                                 input: files(config_target['TARGET_XML_FILES'].split()),
3434                                 command: [feature_to_c, '@INPUT@'],
3435                                 capture: true)
3436     arch_srcs += gdbstub_xml
3437   endif
3439   t = target_arch[target_base_arch].apply(config_target, strict: false)
3440   arch_srcs += t.sources()
3441   arch_deps += t.dependencies()
3443   target_common = common_ss.apply(config_target, strict: false)
3444   objects = common_all.extract_objects(target_common.sources())
3445   deps = target_common.dependencies()
3447   target_specific = specific_ss.apply(config_target, strict: false)
3448   arch_srcs += target_specific.sources()
3449   arch_deps += target_specific.dependencies()
3451   lib = static_library('qemu-' + target,
3452                  sources: arch_srcs + genh,
3453                  dependencies: arch_deps,
3454                  objects: objects,
3455                  include_directories: target_inc,
3456                  c_args: c_args,
3457                  build_by_default: false,
3458                  name_suffix: 'fa')
3460   if target.endswith('-softmmu')
3461     execs = [{
3462       'name': 'qemu-system-' + target_name,
3463       'win_subsystem': 'console',
3464       'sources': files('softmmu/main.c'),
3465       'dependencies': []
3466     }]
3467     if targetos == 'windows' and (sdl.found() or gtk.found())
3468       execs += [{
3469         'name': 'qemu-system-' + target_name + 'w',
3470         'win_subsystem': 'windows',
3471         'sources': files('softmmu/main.c'),
3472         'dependencies': []
3473       }]
3474     endif
3475     if get_option('fuzzing')
3476       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3477       execs += [{
3478         'name': 'qemu-fuzz-' + target_name,
3479         'win_subsystem': 'console',
3480         'sources': specific_fuzz.sources(),
3481         'dependencies': specific_fuzz.dependencies(),
3482       }]
3483     endif
3484   else
3485     execs = [{
3486       'name': 'qemu-' + target_name,
3487       'win_subsystem': 'console',
3488       'sources': [],
3489       'dependencies': []
3490     }]
3491   endif
3492   foreach exe: execs
3493     exe_name = exe['name']
3494     if targetos == 'darwin'
3495       exe_name += '-unsigned'
3496     endif
3498     emulator = executable(exe_name, exe['sources'],
3499                install: true,
3500                c_args: c_args,
3501                dependencies: arch_deps + deps + exe['dependencies'],
3502                objects: lib.extract_all_objects(recursive: true),
3503                link_language: link_language,
3504                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3505                link_args: link_args,
3506                win_subsystem: exe['win_subsystem'])
3508     if targetos == 'darwin'
3509       icon = 'pc-bios/qemu.rsrc'
3510       build_input = [emulator, files(icon)]
3511       install_input = [
3512         get_option('bindir') / exe_name,
3513         meson.current_source_dir() / icon
3514       ]
3515       if 'CONFIG_HVF' in config_target
3516         entitlements = 'accel/hvf/entitlements.plist'
3517         build_input += files(entitlements)
3518         install_input += meson.current_source_dir() / entitlements
3519       endif
3521       emulators += {exe['name'] : custom_target(exe['name'],
3522                    input: build_input,
3523                    output: exe['name'],
3524                    command: [entitlement, '@OUTPUT@', '@INPUT@'])
3525       }
3527       meson.add_install_script(entitlement, '--install',
3528                                get_option('bindir') / exe['name'],
3529                                install_input)
3530     else
3531       emulators += {exe['name']: emulator}
3532     endif
3534     if stap.found()
3535       foreach stp: [
3536         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3537         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3538         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3539         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3540       ]
3541         custom_target(exe['name'] + stp['ext'],
3542                       input: trace_events_all,
3543                       output: exe['name'] + stp['ext'],
3544                       install: stp['install'],
3545                       install_dir: get_option('datadir') / 'systemtap/tapset',
3546                       command: [
3547                         tracetool, '--group=all', '--format=' + stp['fmt'],
3548                         '--binary=' + stp['bin'],
3549                         '--target-name=' + target_name,
3550                         '--target-type=' + target_type,
3551                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
3552                         '@INPUT@', '@OUTPUT@'
3553                       ],
3554                       depend_files: tracetool_depends)
3555       endforeach
3556     endif
3557   endforeach
3558 endforeach
3560 # Other build targets
3562 if 'CONFIG_PLUGIN' in config_host
3563   install_headers('include/qemu/qemu-plugin.h')
3564 endif
3566 subdir('qga')
3568 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3569 # when we don't build tools or system
3570 if xkbcommon.found()
3571   # used for the update-keymaps target, so include rules even if !have_tools
3572   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3573                            dependencies: [qemuutil, xkbcommon], install: have_tools)
3574 endif
3576 if have_tools
3577   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3578              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3579   qemu_io = executable('qemu-io', files('qemu-io.c'),
3580              dependencies: [block, qemuutil], install: true)
3581   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3582                dependencies: [blockdev, qemuutil, gnutls, selinux],
3583                install: true)
3585   subdir('storage-daemon')
3586   subdir('contrib/rdmacm-mux')
3587   subdir('contrib/elf2dmp')
3589   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3590              dependencies: qemuutil,
3591              install: true)
3593   if have_vhost_user
3594     subdir('contrib/vhost-user-blk')
3595     subdir('contrib/vhost-user-gpu')
3596     subdir('contrib/vhost-user-input')
3597     subdir('contrib/vhost-user-scsi')
3598   endif
3600   if targetos == 'linux'
3601     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3602                dependencies: [qemuutil, libcap_ng],
3603                install: true,
3604                install_dir: get_option('libexecdir'))
3606     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3607                dependencies: [authz, crypto, io, qom, qemuutil,
3608                               libcap_ng, mpathpersist],
3609                install: true)
3610   endif
3612   if have_ivshmem
3613     subdir('contrib/ivshmem-client')
3614     subdir('contrib/ivshmem-server')
3615   endif
3616 endif
3618 subdir('scripts')
3619 subdir('tools')
3620 subdir('pc-bios')
3621 subdir('docs')
3622 subdir('tests')
3623 if gtk.found()
3624   subdir('po')
3625 endif
3627 if host_machine.system() == 'windows'
3628   nsis_cmd = [
3629     find_program('scripts/nsis.py'),
3630     '@OUTPUT@',
3631     get_option('prefix'),
3632     meson.current_source_dir(),
3633     host_machine.cpu(),
3634     '--',
3635     '-DDISPLAYVERSION=' + meson.project_version(),
3636   ]
3637   if build_docs
3638     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3639   endif
3640   if gtk.found()
3641     nsis_cmd += '-DCONFIG_GTK=y'
3642   endif
3644   nsis = custom_target('nsis',
3645                        output: 'qemu-setup-' + meson.project_version() + '.exe',
3646                        input: files('qemu.nsi'),
3647                        build_always_stale: true,
3648                        command: nsis_cmd + ['@INPUT@'])
3649   alias_target('installer', nsis)
3650 endif
3652 #########################
3653 # Configuration summary #
3654 #########################
3656 # Directories
3657 summary_info = {}
3658 summary_info += {'Install prefix':    get_option('prefix')}
3659 summary_info += {'BIOS directory':    qemu_datadir}
3660 summary_info += {'firmware path':     get_option('prefix') / get_option('qemu_firmwarepath')}
3661 summary_info += {'binary directory':  get_option('prefix') / get_option('bindir')}
3662 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
3663 summary_info += {'module directory':  qemu_moddir}
3664 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
3665 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
3666 summary_info += {'config directory':  get_option('prefix') / get_option('sysconfdir')}
3667 if targetos != 'windows'
3668   summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
3669   summary_info += {'Manual directory':      get_option('prefix') / get_option('mandir')}
3670 else
3671   summary_info += {'local state directory': 'queried at runtime'}
3672 endif
3673 summary_info += {'Doc directory':     get_option('prefix') / get_option('docdir')}
3674 summary_info += {'Build directory':   meson.current_build_dir()}
3675 summary_info += {'Source path':       meson.current_source_dir()}
3676 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
3677 summary(summary_info, bool_yn: true, section: 'Directories')
3679 # Host binaries
3680 summary_info = {}
3681 summary_info += {'git':               config_host['GIT']}
3682 summary_info += {'make':              config_host['MAKE']}
3683 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3684 summary_info += {'sphinx-build':      sphinx_build}
3685 if config_host.has_key('HAVE_GDB_BIN')
3686   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
3687 endif
3688 summary_info += {'iasl':              iasl}
3689 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
3690 if targetos == 'windows' and have_ga
3691   summary_info += {'wixl':            wixl}
3692 endif
3693 if slirp_opt != 'disabled' and have_system
3694   summary_info += {'smbd':            have_slirp_smbd ? smbd_path : false}
3695 endif
3696 summary(summary_info, bool_yn: true, section: 'Host binaries')
3698 # Configurable features
3699 summary_info = {}
3700 summary_info += {'Documentation':     build_docs}
3701 summary_info += {'system-mode emulation': have_system}
3702 summary_info += {'user-mode emulation': have_user}
3703 summary_info += {'block layer':       have_block}
3704 summary_info += {'Install blobs':     get_option('install_blobs')}
3705 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
3706 if config_host.has_key('CONFIG_MODULES')
3707   summary_info += {'alternative module path': get_option('module_upgrades')}
3708 endif
3709 summary_info += {'fuzzing support':   get_option('fuzzing')}
3710 if have_system
3711   summary_info += {'Audio drivers':     ' '.join(audio_drivers_selected)}
3712 endif
3713 summary_info += {'Trace backends':    ','.join(get_option('trace_backends'))}
3714 if 'simple' in get_option('trace_backends')
3715   summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3716 endif
3717 summary_info += {'D-Bus display':     dbus_display}
3718 summary_info += {'QOM debugging':     get_option('qom_cast_debug')}
3719 summary_info += {'vhost-kernel support': have_vhost_kernel}
3720 summary_info += {'vhost-net support': have_vhost_net}
3721 summary_info += {'vhost-user support': have_vhost_user}
3722 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
3723 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3724 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
3725 summary_info += {'build guest agent': have_ga}
3726 summary(summary_info, bool_yn: true, section: 'Configurable features')
3728 # Compilation information
3729 summary_info = {}
3730 summary_info += {'host CPU':          cpu}
3731 summary_info += {'host endianness':   build_machine.endian()}
3732 summary_info += {'C compiler':        ' '.join(meson.get_compiler('c').cmd_array())}
3733 summary_info += {'Host C compiler':   ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3734 if link_language == 'cpp'
3735   summary_info += {'C++ compiler':    ' '.join(meson.get_compiler('cpp').cmd_array())}
3736 else
3737   summary_info += {'C++ compiler':      false}
3738 endif
3739 if targetos == 'darwin'
3740   summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3741 endif
3742 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
3743                                                + ['-O' + get_option('optimization')]
3744                                                + (get_option('debug') ? ['-g'] : []))}
3745 if link_language == 'cpp'
3746   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
3747                                                + ['-O' + get_option('optimization')]
3748                                                + (get_option('debug') ? ['-g'] : []))}
3749 endif
3750 if targetos == 'darwin'
3751   summary_info += {'OBJCFLAGS':       ' '.join(get_option('objc_args')
3752                                                + ['-O' + get_option('optimization')]
3753                                                + (get_option('debug') ? ['-g'] : []))}
3754 endif
3755 link_args = get_option(link_language + '_link_args')
3756 if link_args.length() > 0
3757   summary_info += {'LDFLAGS':         ' '.join(link_args)}
3758 endif
3759 summary_info += {'QEMU_CFLAGS':       ' '.join(qemu_cflags)}
3760 summary_info += {'QEMU_CXXFLAGS':     ' '.join(qemu_cxxflags)}
3761 summary_info += {'QEMU_OBJCFLAGS':    ' '.join(qemu_objcflags)}
3762 summary_info += {'QEMU_LDFLAGS':      ' '.join(qemu_ldflags)}
3763 summary_info += {'profiler':          get_option('profiler')}
3764 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3765 summary_info += {'PIE':               get_option('b_pie')}
3766 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
3767 summary_info += {'malloc trim support': has_malloc_trim}
3768 summary_info += {'membarrier':        have_membarrier}
3769 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
3770 summary_info += {'mutex debugging':   get_option('debug_mutex')}
3771 summary_info += {'memory allocator':  get_option('malloc')}
3772 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
3773 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
3774 summary_info += {'gprof enabled':     get_option('gprof')}
3775 summary_info += {'gcov':              get_option('b_coverage')}
3776 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
3777 summary_info += {'CFI support':       get_option('cfi')}
3778 if get_option('cfi')
3779   summary_info += {'CFI debug support': get_option('cfi_debug')}
3780 endif
3781 summary_info += {'strip binaries':    get_option('strip')}
3782 summary_info += {'sparse':            sparse}
3783 summary_info += {'mingw32 support':   targetos == 'windows'}
3785 # snarf the cross-compilation information for tests
3786 foreach target: target_dirs
3787   tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3788   if fs.exists(tcg_mak)
3789     config_cross_tcg = keyval.load(tcg_mak)
3790     target = config_cross_tcg['TARGET_NAME']
3791     compiler = ''
3792     if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3793       summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3794                                           ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3795     elif 'CROSS_CC_GUEST' in config_cross_tcg
3796       summary_info += {target + ' tests'
3797                                 : config_cross_tcg['CROSS_CC_GUEST'] }
3798     endif
3799    endif
3800 endforeach
3802 summary(summary_info, bool_yn: true, section: 'Compilation')
3804 # Targets and accelerators
3805 summary_info = {}
3806 if have_system
3807   summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
3808   summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
3809   summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
3810   summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
3811   summary_info += {'NVMM support':      config_all.has_key('CONFIG_NVMM')}
3812   summary_info += {'Xen support':       xen.found()}
3813   if xen.found()
3814     summary_info += {'xen ctrl version':  xen.version()}
3815   endif
3816 endif
3817 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
3818 if config_all.has_key('CONFIG_TCG')
3819   if get_option('tcg_interpreter')
3820     summary_info += {'TCG backend':   'TCI (TCG with bytecode interpreter, slow)'}
3821   else
3822     summary_info += {'TCG backend':   'native (@0@)'.format(cpu)}
3823   endif
3824   summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3825   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3826 endif
3827 summary_info += {'target list':       ' '.join(target_dirs)}
3828 if have_system
3829   summary_info += {'default devices':   get_option('default_devices')}
3830   summary_info += {'out of process emulation': multiprocess_allowed}
3831 endif
3832 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3834 # Block layer
3835 summary_info = {}
3836 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3837 summary_info += {'coroutine pool':    have_coroutine_pool}
3838 if have_block
3839   summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
3840   summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
3841   summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
3842   summary_info += {'VirtFS support':    have_virtfs}
3843   summary_info += {'build virtiofs daemon': have_virtiofsd}
3844   summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
3845   summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
3846   summary_info += {'bochs support':     get_option('bochs').allowed()}
3847   summary_info += {'cloop support':     get_option('cloop').allowed()}
3848   summary_info += {'dmg support':       get_option('dmg').allowed()}
3849   summary_info += {'qcow v1 support':   get_option('qcow1').allowed()}
3850   summary_info += {'vdi support':       get_option('vdi').allowed()}
3851   summary_info += {'vvfat support':     get_option('vvfat').allowed()}
3852   summary_info += {'qed support':       get_option('qed').allowed()}
3853   summary_info += {'parallels support': get_option('parallels').allowed()}
3854   summary_info += {'FUSE exports':      fuse}
3855 endif
3856 summary(summary_info, bool_yn: true, section: 'Block layer support')
3858 # Crypto
3859 summary_info = {}
3860 summary_info += {'TLS priority':      get_option('tls_priority')}
3861 summary_info += {'GNUTLS support':    gnutls}
3862 if gnutls.found()
3863   summary_info += {'  GNUTLS crypto':   gnutls_crypto.found()}
3864 endif
3865 summary_info += {'libgcrypt':         gcrypt}
3866 summary_info += {'nettle':            nettle}
3867 if nettle.found()
3868    summary_info += {'  XTS':             xts != 'private'}
3869 endif
3870 summary_info += {'AF_ALG support':    have_afalg}
3871 summary_info += {'rng-none':          get_option('rng_none')}
3872 summary_info += {'Linux keyring':     have_keyring}
3873 summary(summary_info, bool_yn: true, section: 'Crypto')
3875 # Libraries
3876 summary_info = {}
3877 if targetos == 'darwin'
3878   summary_info += {'Cocoa support':   cocoa}
3879 endif
3880 summary_info += {'SDL support':       sdl}
3881 summary_info += {'SDL image support': sdl_image}
3882 summary_info += {'GTK support':       gtk}
3883 summary_info += {'pixman':            pixman}
3884 summary_info += {'VTE support':       vte}
3885 summary_info += {'slirp support':     slirp_opt == 'internal' ? slirp_opt : slirp}
3886 summary_info += {'libtasn1':          tasn1}
3887 summary_info += {'PAM':               pam}
3888 summary_info += {'iconv support':     iconv}
3889 summary_info += {'curses support':    curses}
3890 summary_info += {'virgl support':     virgl}
3891 summary_info += {'curl support':      curl}
3892 summary_info += {'Multipath support': mpathpersist}
3893 summary_info += {'PNG support':       png}
3894 summary_info += {'VNC support':       vnc}
3895 if vnc.found()
3896   summary_info += {'VNC SASL support':  sasl}
3897   summary_info += {'VNC JPEG support':  jpeg}
3898 endif
3899 if targetos not in ['darwin', 'haiku', 'windows']
3900   summary_info += {'OSS support':     oss}
3901 elif targetos == 'darwin'
3902   summary_info += {'CoreAudio support': coreaudio}
3903 elif targetos == 'windows'
3904   summary_info += {'DirectSound support': dsound}
3905 endif
3906 if targetos == 'linux'
3907   summary_info += {'ALSA support':    alsa}
3908   summary_info += {'PulseAudio support': pulse}
3909 endif
3910 summary_info += {'JACK support':      jack}
3911 summary_info += {'brlapi support':    brlapi}
3912 summary_info += {'vde support':       vde}
3913 summary_info += {'netmap support':    have_netmap}
3914 summary_info += {'l2tpv3 support':    have_l2tpv3}
3915 summary_info += {'Linux AIO support': libaio}
3916 summary_info += {'Linux io_uring support': linux_io_uring}
3917 summary_info += {'ATTR/XATTR support': libattr}
3918 summary_info += {'RDMA support':      rdma}
3919 summary_info += {'PVRDMA support':    have_pvrdma}
3920 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
3921 summary_info += {'libcap-ng support': libcap_ng}
3922 summary_info += {'bpf support':       libbpf}
3923 summary_info += {'spice protocol support': spice_protocol}
3924 if spice_protocol.found()
3925   summary_info += {'  spice server support': spice}
3926 endif
3927 summary_info += {'rbd support':       rbd}
3928 summary_info += {'smartcard support': cacard}
3929 summary_info += {'U2F support':       u2f}
3930 summary_info += {'libusb':            libusb}
3931 summary_info += {'usb net redir':     usbredir}
3932 summary_info += {'OpenGL support (epoxy)': opengl}
3933 summary_info += {'GBM':               gbm}
3934 summary_info += {'libiscsi support':  libiscsi}
3935 summary_info += {'libnfs support':    libnfs}
3936 if targetos == 'windows'
3937   if have_ga
3938     summary_info += {'QGA VSS support':   have_qga_vss}
3939   endif
3940 endif
3941 summary_info += {'seccomp support':   seccomp}
3942 summary_info += {'GlusterFS support': glusterfs}
3943 summary_info += {'TPM support':       have_tpm}
3944 summary_info += {'libssh support':    libssh}
3945 summary_info += {'lzo support':       lzo}
3946 summary_info += {'snappy support':    snappy}
3947 summary_info += {'bzip2 support':     libbzip2}
3948 summary_info += {'lzfse support':     liblzfse}
3949 summary_info += {'zstd support':      zstd}
3950 summary_info += {'NUMA host support': numa}
3951 summary_info += {'capstone':          capstone_opt == 'internal' ? capstone_opt : capstone}
3952 summary_info += {'libpmem support':   libpmem}
3953 summary_info += {'libdaxctl support': libdaxctl}
3954 summary_info += {'libudev':           libudev}
3955 # Dummy dependency, keep .found()
3956 summary_info += {'FUSE lseek':        fuse_lseek.found()}
3957 summary_info += {'selinux':           selinux}
3958 summary(summary_info, bool_yn: true, section: 'Dependencies')
3960 if not supported_cpus.contains(cpu)
3961   message()
3962   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3963   message()
3964   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3965   message('The QEMU project intends to remove support for this host CPU in')
3966   message('a future release if nobody volunteers to maintain it and to')
3967   message('provide a build host for our continuous integration setup.')
3968   message('configure has succeeded and you can continue to build, but')
3969   message('if you care about QEMU on this platform you should contact')
3970   message('us upstream at qemu-devel@nongnu.org.')
3971 endif
3973 if not supported_oses.contains(targetos)
3974   message()
3975   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3976   message()
3977   message('Host OS ' + targetos + 'support is not currently maintained.')
3978   message('The QEMU project intends to remove support for this host OS in')
3979   message('a future release if nobody volunteers to maintain it and to')
3980   message('provide a build host for our continuous integration setup.')
3981   message('configure has succeeded and you can continue to build, but')
3982   message('if you care about QEMU on this platform you should contact')
3983   message('us upstream at qemu-devel@nongnu.org.')
3984 endif