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'],
4 version: files('VERSION'))
6 add_test_setup('quick', exclude_suites: ['block', 'slow', 'thorough'], is_default: true)
7 add_test_setup('slow', exclude_suites: ['block', 'thorough'], env: ['G_TEST_SLOW=1', 'SPEED=slow'])
8 add_test_setup('thorough', exclude_suites: ['block'], env: ['G_TEST_SLOW=1', 'SPEED=thorough'])
10 not_found = dependency('', required: false)
11 keyval = import('keyval')
12 ss = import('sourceset')
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 /')
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()
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']
59 targetos = host_machine.system()
61 target_dirs = config_host['TARGET_DIRS'].split()
62 have_linux_user = 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')
70 have_user = have_linux_user or have_bsd_user
71 have_tools = get_option('tools') \
72 .disable_auto_if(not have_system) \
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') \
79 have_block = have_system or have_tools
81 python = import('python').find_installation()
83 if cpu not in supported_cpus
93 if cpu in ['x86', 'x86_64']
94 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
96 kvm_targets = ['aarch64-softmmu']
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']
110 if get_option('kvm').allowed() and targetos == 'linux'
111 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
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']
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'],
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'],
139 # Darwin does not support references to thread-local variables in modules
140 if targetos != 'darwin'
141 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
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()
156 if 'dtrace' in get_option('trace_backends')
157 dtrace = find_program('dtrace', required: true)
158 stap = find_program('stap', required: false)
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
165 add_global_arguments('-DSTAP_SDT_V2',
166 native: false, language: ['c', 'cpp', 'objc'])
174 qemu_cflags = config_host['QEMU_CFLAGS'].split()
175 qemu_cxxflags = config_host['QEMU_CXXFLAGS'].split()
176 qemu_ldflags = config_host['QEMU_LDFLAGS'].split()
178 if get_option('gprof')
179 qemu_cflags += ['-p']
180 qemu_cxxflags += ['-p']
181 qemu_ldflags += ['-p']
184 # Specify linker-script with add_project_link_arguments so that it is not placed
185 # within a linker --start-group/--end-group pair
186 if get_option('fuzzing')
187 add_project_link_arguments(['-Wl,-T,',
188 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
189 native: false, language: ['c', 'cpp', 'objc'])
191 # Specify a filter to only instrument code that is directly related to
193 configure_file(output: 'instrumentation-filter',
194 input: 'scripts/oss-fuzz/instrumentation-filter-template',
196 add_global_arguments(
197 cc.get_supported_arguments('-fsanitize-coverage-allowlist=instrumentation-filter'),
198 native: false, language: ['c', 'cpp', 'objc'])
200 if get_option('fuzzing_engine') == ''
201 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
202 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
203 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
204 # unable to bind the fuzzer-related callbacks added by instrumentation.
205 add_global_arguments('-fsanitize=fuzzer-no-link',
206 native: false, language: ['c', 'cpp', 'objc'])
207 add_global_link_arguments('-fsanitize=fuzzer-no-link',
208 native: false, language: ['c', 'cpp', 'objc'])
209 # For the actual fuzzer binaries, we need to link against the libfuzzer
210 # library. They need to be configurable, to support OSS-Fuzz
211 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
213 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
214 # the needed CFLAGS have already been provided
215 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
219 add_global_arguments(qemu_cflags, native: false, language: ['c', 'objc'])
220 add_global_arguments(qemu_cxxflags, native: false, language: ['cpp'])
221 add_global_link_arguments(qemu_ldflags, native: false, language: ['c', 'cpp', 'objc'])
223 if targetos == 'linux'
224 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
225 '-isystem', 'linux-headers',
226 language: ['c', 'cpp'])
229 add_project_arguments('-iquote', '.',
230 '-iquote', meson.current_source_dir(),
231 '-iquote', meson.current_source_dir() / 'include',
232 '-iquote', meson.current_source_dir() / 'disas/libvixl',
233 language: ['c', 'cpp', 'objc'])
235 link_language = meson.get_external_property('link_language', 'cpp')
236 if link_language == 'cpp'
237 add_languages('cpp', required: true, native: false)
238 cxx = meson.get_compiler('cpp')
243 if host_machine.system() == 'darwin'
244 add_languages('objc', required: false, native: false)
247 sparse = find_program('cgcc', required: get_option('sparse'))
250 command: [find_program('scripts/check_sparse.py'),
251 'compile_commands.json', sparse.full_path(), '-Wbitwise',
252 '-Wno-transparent-union', '-Wno-old-initializer',
253 '-Wno-non-pointer-null'])
256 ###########################################
257 # Target-specific checks and dependencies #
258 ###########################################
261 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
264 #include <sys/types.h>
265 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
266 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
268 args: ['-Werror', '-fsanitize=fuzzer'])
269 error('Your compiler does not support -fsanitize=fuzzer')
273 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
274 error('ftrace is supported only on Linux')
276 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
279 openlog("qemu", LOG_PID, LOG_DAEMON);
280 syslog(LOG_INFO, "configure");
283 error('syslog is not supported on this system')
286 # Miscellaneous Linux-only features
287 get_option('mpath') \
288 .require(targetos == 'linux', error_message: 'Multipath is supported only on Linux')
290 multiprocess_allowed = get_option('multiprocess') \
291 .require(targetos == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
294 have_tpm = get_option('tpm') \
295 .require(targetos != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
298 # Target-specific libraries and flags
299 libm = cc.find_library('m', required: false)
300 threads = dependency('threads')
301 util = cc.find_library('util', required: false)
307 emulator_link_args = []
313 if targetos == 'windows'
314 midl = find_program('midl', required: false)
315 widl = find_program('widl', required: false)
316 socket = cc.find_library('ws2_32')
317 winmm = cc.find_library('winmm')
319 win = import('windows')
320 version_res = win.compile_resources('version.rc',
321 depend_files: files('pc-bios/qemu-nsis.ico'),
322 include_directories: include_directories('.'))
324 elif targetos == 'darwin'
325 coref = dependency('appleframeworks', modules: 'CoreFoundation')
326 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
327 host_dsosuf = '.dylib'
328 elif targetos == 'sunos'
329 socket = [cc.find_library('socket'),
330 cc.find_library('nsl'),
331 cc.find_library('resolv')]
332 elif targetos == 'haiku'
333 socket = [cc.find_library('posix_error_mapper'),
334 cc.find_library('network'),
335 cc.find_library('bsd')]
336 elif targetos == 'openbsd'
337 if get_option('tcg').allowed() and target_dirs.length() > 0
338 # Disable OpenBSD W^X if available
339 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
343 # Target-specific configuration of accelerators
345 if get_option('kvm').allowed() and targetos == 'linux'
346 accelerators += 'CONFIG_KVM'
348 if get_option('xen').allowed() and 'CONFIG_XEN_BACKEND' in config_host
349 accelerators += 'CONFIG_XEN'
350 have_xen_pci_passthrough = get_option('xen_pci_passthrough').allowed() and targetos == 'linux'
352 have_xen_pci_passthrough = false
354 if get_option('whpx').allowed() and targetos == 'windows'
355 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
356 error('WHPX requires 64-bit host')
357 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
358 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
359 accelerators += 'CONFIG_WHPX'
362 if get_option('hvf').allowed()
363 hvf = dependency('appleframeworks', modules: 'Hypervisor',
364 required: get_option('hvf'))
366 accelerators += 'CONFIG_HVF'
369 if get_option('hax').allowed()
370 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
371 accelerators += 'CONFIG_HAX'
374 if targetos == 'netbsd'
375 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
377 accelerators += 'CONFIG_NVMM'
382 if get_option('tcg').allowed()
383 if host_arch == 'unknown'
384 if get_option('tcg_interpreter')
385 warning('Unsupported CPU @0@, will use TCG with TCI (slow)'.format(cpu))
387 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
389 elif get_option('tcg_interpreter')
390 warning('Use of the TCG interpreter is not recommended on this host')
391 warning('architecture. There is a native TCG execution backend available')
392 warning('which provides substantially better performance and reliability.')
393 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
394 warning('configuration option on this architecture to use the native')
397 if get_option('tcg_interpreter')
399 elif host_arch == 'sparc64'
401 elif host_arch == 'x86_64'
403 elif host_arch == 'ppc64'
406 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
407 language: ['c', 'cpp', 'objc'])
409 accelerators += 'CONFIG_TCG'
410 config_host += { 'CONFIG_TCG': 'y' }
413 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
414 error('KVM not available on this platform')
416 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
417 error('HVF not available on this platform')
419 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
420 error('NVMM not available on this platform')
422 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
423 error('WHPX not available on this platform')
425 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
426 if 'CONFIG_XEN' in accelerators
427 error('Xen PCI passthrough not available on this platform')
429 error('Xen PCI passthrough requested but Xen not enabled')
437 # The path to glib.h is added to all compilation commands. This was
438 # grandfathered in from the QEMU Makefiles.
439 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
440 native: false, language: ['c', 'cpp', 'objc'])
441 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
442 link_args: config_host['GLIB_LIBS'].split(),
443 version: config_host['GLIB_VERSION'])
444 # override glib dep with the configure results (for subprojects)
445 meson.override_dependency('glib-2.0', glib)
448 if 'CONFIG_GIO' in config_host
449 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
450 link_args: config_host['GIO_LIBS'].split(),
451 version: config_host['GLIB_VERSION'])
454 if 'ust' in get_option('trace_backends')
455 lttng = dependency('lttng-ust', required: true, method: 'pkg-config',
456 kwargs: static_kwargs)
459 if have_system or have_tools
460 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
461 method: 'pkg-config', kwargs: static_kwargs)
463 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
466 if not get_option('linux_aio').auto() or have_block
467 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
468 required: get_option('linux_aio'),
469 kwargs: static_kwargs)
471 linux_io_uring = not_found
472 if not get_option('linux_io_uring').auto() or have_block
473 linux_io_uring = dependency('liburing', version: '>=0.3',
474 required: get_option('linux_io_uring'),
475 method: 'pkg-config', kwargs: static_kwargs)
478 if not get_option('libnfs').auto() or have_block
479 libnfs = dependency('libnfs', version: '>=1.9.3',
480 required: get_option('libnfs'),
481 method: 'pkg-config', kwargs: static_kwargs)
486 #include <sys/types.h>
487 #ifdef CONFIG_LIBATTR
488 #include <attr/xattr.h>
490 #include <sys/xattr.h>
492 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
495 have_old_libattr = false
496 if get_option('attr').allowed()
497 if cc.links(libattr_test)
498 libattr = declare_dependency()
500 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
501 required: get_option('attr'),
502 kwargs: static_kwargs)
503 if libattr.found() and not \
504 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
506 if get_option('attr').enabled()
507 error('could not link libattr')
509 warning('could not link libattr, disabling')
512 have_old_libattr = libattr.found()
517 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
518 if cocoa.found() and get_option('sdl').enabled()
519 error('Cocoa and SDL cannot be enabled at the same time')
521 if cocoa.found() and get_option('gtk').enabled()
522 error('Cocoa and GTK+ cannot be enabled at the same time')
526 if not get_option('seccomp').auto() or have_system or have_tools
527 seccomp = dependency('libseccomp', version: '>=2.3.0',
528 required: get_option('seccomp'),
529 method: 'pkg-config', kwargs: static_kwargs)
532 libcap_ng = not_found
533 if not get_option('cap_ng').auto() or have_system or have_tools
534 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
535 required: get_option('cap_ng'),
536 kwargs: static_kwargs)
538 if libcap_ng.found() and not cc.links('''
542 capng_capability_to_name(CAPNG_EFFECTIVE);
544 }''', dependencies: libcap_ng)
545 libcap_ng = not_found
546 if get_option('cap_ng').enabled()
547 error('could not link libcap-ng')
549 warning('could not link libcap-ng, disabling')
553 if get_option('xkbcommon').auto() and not have_system and not have_tools
554 xkbcommon = not_found
556 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
557 method: 'pkg-config', kwargs: static_kwargs)
561 if not get_option('vde').auto() or have_system or have_tools
562 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
563 required: get_option('vde'),
564 kwargs: static_kwargs)
566 if vde.found() and not cc.links('''
567 #include <libvdeplug.h>
570 struct vde_open_args a = {0, 0, 0};
574 }''', dependencies: vde)
576 if get_option('cap_ng').enabled()
577 error('could not link libvdeplug')
579 warning('could not link libvdeplug, disabling')
584 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
585 pulse = dependency('libpulse', required: get_option('pa'),
586 method: 'pkg-config', kwargs: static_kwargs)
589 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
590 alsa = dependency('alsa', required: get_option('alsa'),
591 method: 'pkg-config', kwargs: static_kwargs)
594 if not get_option('jack').auto() or have_system
595 jack = dependency('jack', required: get_option('jack'),
596 method: 'pkg-config', kwargs: static_kwargs)
599 spice_protocol = not_found
600 if not get_option('spice_protocol').auto() or have_system
601 spice_protocol = dependency('spice-protocol', version: '>=0.12.3',
602 required: get_option('spice_protocol'),
603 method: 'pkg-config', kwargs: static_kwargs)
606 if not get_option('spice').auto() or have_system
607 spice = dependency('spice-server', version: '>=0.12.5',
608 required: get_option('spice'),
609 method: 'pkg-config', kwargs: static_kwargs)
611 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
613 rt = cc.find_library('rt', required: false)
616 if not get_option('libiscsi').auto() or have_block
617 libiscsi = dependency('libiscsi', version: '>=1.9.0',
618 required: get_option('libiscsi'),
619 method: 'pkg-config', kwargs: static_kwargs)
622 if not get_option('zstd').auto() or have_block
623 zstd = dependency('libzstd', version: '>=1.4.0',
624 required: get_option('zstd'),
625 method: 'pkg-config', kwargs: static_kwargs)
629 have_vhost_user_gpu = have_tools and targetos == 'linux' and pixman.found()
630 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
631 virgl = dependency('virglrenderer',
632 method: 'pkg-config',
633 required: get_option('virglrenderer'),
634 kwargs: static_kwargs)
637 if not get_option('curl').auto() or have_block
638 curl = dependency('libcurl', version: '>=7.29.0',
639 method: 'pkg-config',
640 required: get_option('curl'),
641 kwargs: static_kwargs)
644 if targetos == 'linux' and (have_system or have_tools)
645 libudev = dependency('libudev',
646 method: 'pkg-config',
647 required: get_option('libudev'),
648 kwargs: static_kwargs)
651 mpathlibs = [libudev]
652 mpathpersist = not_found
653 mpathpersist_new_api = false
654 if targetos == 'linux' and have_tools and get_option('mpath').allowed()
655 mpath_test_source_new = '''
657 #include <mpath_persist.h>
658 unsigned mpath_mx_alloc_len = 1024;
660 static struct config *multipath_conf;
661 extern struct udev *udev;
662 extern struct config *get_multipath_config(void);
663 extern void put_multipath_config(struct config *conf);
665 struct config *get_multipath_config(void) { return multipath_conf; }
666 void put_multipath_config(struct config *conf) { }
669 multipath_conf = mpath_lib_init();
672 mpath_test_source_old = '''
674 #include <mpath_persist.h>
675 unsigned mpath_mx_alloc_len = 1024;
678 struct udev *udev = udev_new();
679 mpath_lib_init(udev);
682 libmpathpersist = cc.find_library('mpathpersist',
683 required: get_option('mpath'),
684 kwargs: static_kwargs)
685 if libmpathpersist.found()
686 mpathlibs += libmpathpersist
688 mpathlibs += cc.find_library('devmapper',
689 required: get_option('mpath'),
690 kwargs: static_kwargs)
692 mpathlibs += cc.find_library('multipath',
693 required: get_option('mpath'),
694 kwargs: static_kwargs)
695 foreach lib: mpathlibs
701 if mpathlibs.length() == 0
702 msg = 'Dependencies missing for libmpathpersist'
703 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
704 mpathpersist = declare_dependency(dependencies: mpathlibs)
705 mpathpersist_new_api = true
706 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
707 mpathpersist = declare_dependency(dependencies: mpathlibs)
709 msg = 'Cannot detect libmpathpersist API'
711 if not mpathpersist.found()
712 if get_option('mpath').enabled()
715 warning(msg + ', disabling')
723 if have_system and get_option('curses').allowed()
725 #if defined(__APPLE__) || defined(__OpenBSD__)
726 #define _XOPEN_SOURCE_EXTENDED 1
733 setlocale(LC_ALL, "");
735 addwstr(L"wide chars\n");
737 add_wch(WACS_DEGREE);
741 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
742 foreach curses_dep : curses_dep_list
743 if not curses.found()
744 curses = dependency(curses_dep,
746 method: 'pkg-config',
747 kwargs: static_kwargs)
750 msg = get_option('curses').enabled() ? 'curses library not found' : ''
751 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
753 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
754 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
756 msg = 'curses package not usable'
760 if not curses.found()
761 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
762 if targetos != 'windows' and not has_curses_h
763 message('Trying with /usr/include/ncursesw')
764 curses_compile_args += ['-I/usr/include/ncursesw']
765 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
768 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
769 foreach curses_libname : curses_libname_list
770 libcurses = cc.find_library(curses_libname,
772 kwargs: static_kwargs)
774 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
775 curses = declare_dependency(compile_args: curses_compile_args,
776 dependencies: [libcurses])
779 msg = 'curses library not usable'
785 if get_option('iconv').allowed()
786 foreach link_args : [ ['-liconv'], [] ]
787 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
788 # We need to use libiconv if available because mixing libiconv's headers with
789 # the system libc does not work.
790 # However, without adding glib to the dependencies -L/usr/local/lib will not be
791 # included in the command line and libiconv will not be found.
795 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
796 return conv != (iconv_t) -1;
797 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
798 iconv = declare_dependency(link_args: link_args, dependencies: glib)
803 if curses.found() and not iconv.found()
804 if get_option('iconv').enabled()
805 error('iconv not available')
807 msg = 'iconv required for curses UI but not available'
810 if not curses.found() and msg != ''
811 if get_option('curses').enabled()
814 warning(msg + ', disabling')
820 if not get_option('brlapi').auto() or have_system
821 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
822 required: get_option('brlapi'),
823 kwargs: static_kwargs)
824 if brlapi.found() and not cc.links('''
827 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
829 if get_option('brlapi').enabled()
830 error('could not link brlapi')
832 warning('could not link brlapi, disabling')
838 if not get_option('sdl').auto() or (have_system and not cocoa.found())
839 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
840 sdl_image = not_found
843 # work around 2.0.8 bug
844 sdl = declare_dependency(compile_args: '-Wno-undef',
846 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
847 method: 'pkg-config', kwargs: static_kwargs)
849 if get_option('sdl_image').enabled()
850 error('sdl-image required, but SDL was @0@'.format(
851 get_option('sdl').disabled() ? 'disabled' : 'not found'))
853 sdl_image = not_found
857 if not get_option('rbd').auto() or have_block
858 librados = cc.find_library('rados', required: get_option('rbd'),
859 kwargs: static_kwargs)
860 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
861 required: get_option('rbd'),
862 kwargs: static_kwargs)
863 if librados.found() and librbd.found()
866 #include <rbd/librbd.h>
869 rados_create(&cluster, NULL);
870 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
874 }''', dependencies: [librbd, librados])
875 rbd = declare_dependency(dependencies: [librbd, librados])
876 elif get_option('rbd').enabled()
877 error('librbd >= 1.12.0 required')
879 warning('librbd >= 1.12.0 not found, disabling')
884 glusterfs = not_found
885 glusterfs_ftruncate_has_stat = false
886 glusterfs_iocb_has_stat = false
887 if not get_option('glusterfs').auto() or have_block
888 glusterfs = dependency('glusterfs-api', version: '>=3',
889 required: get_option('glusterfs'),
890 method: 'pkg-config', kwargs: static_kwargs)
892 glusterfs_ftruncate_has_stat = cc.links('''
893 #include <glusterfs/api/glfs.h>
898 /* new glfs_ftruncate() passes two additional args */
899 return glfs_ftruncate(NULL, 0, NULL, NULL);
901 ''', dependencies: glusterfs)
902 glusterfs_iocb_has_stat = cc.links('''
903 #include <glusterfs/api/glfs.h>
905 /* new glfs_io_cbk() passes two additional glfs_stat structs */
907 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
913 glfs_io_cbk iocb = &glusterfs_iocb;
914 iocb(NULL, 0 , NULL, NULL, NULL);
917 ''', dependencies: glusterfs)
922 if not get_option('libssh').auto() or have_block
923 libssh = dependency('libssh', version: '>=0.8.7',
924 method: 'pkg-config',
925 required: get_option('libssh'),
926 kwargs: static_kwargs)
930 if not get_option('bzip2').auto() or have_block
931 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
932 required: get_option('bzip2'),
933 kwargs: static_kwargs)
934 if libbzip2.found() and not cc.links('''
936 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
938 if get_option('bzip2').enabled()
939 error('could not link libbzip2')
941 warning('could not link libbzip2, disabling')
947 if not get_option('lzfse').auto() or have_block
948 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
949 required: get_option('lzfse'),
950 kwargs: static_kwargs)
952 if liblzfse.found() and not cc.links('''
954 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
956 if get_option('lzfse').enabled()
957 error('could not link liblzfse')
959 warning('could not link liblzfse, disabling')
964 if get_option('oss').allowed() and have_system
965 if not cc.has_header('sys/soundcard.h')
967 elif targetos == 'netbsd'
968 oss = cc.find_library('ossaudio', required: get_option('oss'),
969 kwargs: static_kwargs)
971 oss = declare_dependency()
975 if get_option('oss').enabled()
976 error('OSS not found')
981 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
982 if cc.has_header('dsound.h')
983 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
986 if not dsound.found()
987 if get_option('dsound').enabled()
988 error('DirectSound not found')
993 coreaudio = not_found
994 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
995 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
996 required: get_option('coreaudio'))
1000 if 'CONFIG_OPENGL' in config_host
1001 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
1002 link_args: config_host['OPENGL_LIBS'].split())
1005 if (have_system or have_tools) and (virgl.found() or opengl.found())
1006 gbm = dependency('gbm', method: 'pkg-config', required: false,
1007 kwargs: static_kwargs)
1009 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and gbm.found()
1012 gnutls_crypto = not_found
1013 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1014 # For general TLS support our min gnutls matches
1015 # that implied by our platform support matrix
1017 # For the crypto backends, we look for a newer
1020 # Version 3.6.8 is needed to get XTS
1021 # Version 3.6.13 is needed to get PBKDF
1022 # Version 3.6.14 is needed to get HW accelerated XTS
1024 # If newer enough gnutls isn't available, we can
1025 # still use a different crypto backend to satisfy
1026 # the platform support requirements
1027 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1028 method: 'pkg-config',
1030 kwargs: static_kwargs)
1031 if gnutls_crypto.found()
1032 gnutls = gnutls_crypto
1034 # Our min version if all we need is TLS
1035 gnutls = dependency('gnutls', version: '>=3.5.18',
1036 method: 'pkg-config',
1037 required: get_option('gnutls'),
1038 kwargs: static_kwargs)
1042 # We prefer use of gnutls for crypto, unless the options
1043 # explicitly asked for nettle or gcrypt.
1045 # If gnutls isn't available for crypto, then we'll prefer
1046 # gcrypt over nettle for performance reasons.
1051 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1052 error('Only one of gcrypt & nettle can be enabled')
1055 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1056 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1057 gnutls_crypto = not_found
1060 if not gnutls_crypto.found()
1061 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1062 gcrypt = dependency('libgcrypt', version: '>=1.8',
1063 method: 'config-tool',
1064 required: get_option('gcrypt'),
1065 kwargs: static_kwargs)
1066 # Debian has removed -lgpg-error from libgcrypt-config
1067 # as it "spreads unnecessary dependencies" which in
1068 # turn breaks static builds...
1069 if gcrypt.found() and enable_static
1070 gcrypt = declare_dependency(dependencies: [
1072 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
1075 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1076 nettle = dependency('nettle', version: '>=3.4',
1077 method: 'pkg-config',
1078 required: get_option('nettle'),
1079 kwargs: static_kwargs)
1080 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1089 if not get_option('gtk').auto() or (have_system and not cocoa.found())
1090 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1091 method: 'pkg-config',
1092 required: get_option('gtk'),
1093 kwargs: static_kwargs)
1095 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1096 method: 'pkg-config',
1098 kwargs: static_kwargs)
1099 gtk = declare_dependency(dependencies: [gtk, gtkx11])
1101 if not get_option('vte').auto() or have_system
1102 vte = dependency('vte-2.91',
1103 method: 'pkg-config',
1104 required: get_option('vte'),
1105 kwargs: static_kwargs)
1112 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
1113 kwargs: static_kwargs)
1119 if get_option('vnc').allowed() and have_system
1120 vnc = declare_dependency() # dummy dependency
1121 png = dependency('libpng', required: get_option('vnc_png'),
1122 method: 'pkg-config', kwargs: static_kwargs)
1123 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1124 method: 'pkg-config', kwargs: static_kwargs)
1125 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1126 required: get_option('vnc_sasl'),
1127 kwargs: static_kwargs)
1129 sasl = declare_dependency(dependencies: sasl,
1130 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1135 if not get_option('auth_pam').auto() or have_system
1136 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1137 required: get_option('auth_pam'),
1138 kwargs: static_kwargs)
1140 if pam.found() and not cc.links('''
1142 #include <security/pam_appl.h>
1144 const char *service_name = "qemu";
1145 const char *user = "frank";
1146 const struct pam_conv pam_conv = { 0 };
1147 pam_handle_t *pamh = NULL;
1148 pam_start(service_name, user, &pam_conv, &pamh);
1150 }''', dependencies: pam)
1152 if get_option('auth_pam').enabled()
1153 error('could not link libpam')
1155 warning('could not link libpam, disabling')
1160 if not get_option('snappy').auto() or have_system
1161 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1162 required: get_option('snappy'),
1163 kwargs: static_kwargs)
1165 if snappy.found() and not linker.links('''
1166 #include <snappy-c.h>
1167 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1169 if get_option('snappy').enabled()
1170 error('could not link libsnappy')
1172 warning('could not link libsnappy, disabling')
1177 if not get_option('lzo').auto() or have_system
1178 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1179 required: get_option('lzo'),
1180 kwargs: static_kwargs)
1182 if lzo.found() and not cc.links('''
1183 #include <lzo/lzo1x.h>
1184 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1186 if get_option('lzo').enabled()
1187 error('could not link liblzo2')
1189 warning('could not link liblzo2, disabling')
1194 if not get_option('numa').auto() or have_system or have_tools
1195 numa = cc.find_library('numa', has_headers: ['numa.h'],
1196 required: get_option('numa'),
1197 kwargs: static_kwargs)
1199 if numa.found() and not cc.links('''
1201 int main(void) { return numa_available(); }
1202 ''', dependencies: numa)
1204 if get_option('numa').enabled()
1205 error('could not link numa')
1207 warning('could not link numa, disabling')
1212 if 'CONFIG_RDMA' in config_host
1213 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
1216 if 'CONFIG_XEN_BACKEND' in config_host
1217 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
1218 link_args: config_host['XEN_LIBS'].split())
1221 if not get_option('smartcard').auto() or have_system
1222 cacard = dependency('libcacard', required: get_option('smartcard'),
1223 version: '>=2.5.1', method: 'pkg-config',
1224 kwargs: static_kwargs)
1228 u2f = dependency('u2f-emu', required: get_option('u2f'),
1229 method: 'pkg-config',
1230 kwargs: static_kwargs)
1232 usbredir = not_found
1233 if not get_option('usb_redir').auto() or have_system
1234 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1235 version: '>=0.6', method: 'pkg-config',
1236 kwargs: static_kwargs)
1239 if not get_option('libusb').auto() or have_system
1240 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1241 version: '>=1.0.13', method: 'pkg-config',
1242 kwargs: static_kwargs)
1246 if not get_option('libpmem').auto() or have_system
1247 libpmem = dependency('libpmem', required: get_option('libpmem'),
1248 method: 'pkg-config', kwargs: static_kwargs)
1250 libdaxctl = not_found
1251 if not get_option('libdaxctl').auto() or have_system
1252 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1253 version: '>=57', method: 'pkg-config',
1254 kwargs: static_kwargs)
1258 tasn1 = dependency('libtasn1',
1259 method: 'pkg-config',
1260 kwargs: static_kwargs)
1262 keyutils = dependency('libkeyutils', required: false,
1263 method: 'pkg-config', kwargs: static_kwargs)
1265 has_gettid = cc.has_function('gettid')
1268 selinux = dependency('libselinux',
1269 required: get_option('selinux'),
1270 method: 'pkg-config', kwargs: static_kwargs)
1275 if get_option('malloc') == 'system'
1277 get_option('malloc_trim').allowed() and \
1278 cc.links('''#include <malloc.h>
1279 int main(void) { malloc_trim(0); return 0; }''')
1281 has_malloc_trim = false
1282 malloc = cc.find_library(get_option('malloc'), required: true)
1284 if not has_malloc_trim and get_option('malloc_trim').enabled()
1285 if get_option('malloc') == 'system'
1286 error('malloc_trim not available on this platform.')
1288 error('malloc_trim not available with non-libc memory allocator')
1292 # Check whether the glibc provides statx()
1294 gnu_source_prefix = '''
1299 statx_test = gnu_source_prefix + '''
1300 #include <sys/stat.h>
1302 struct statx statxbuf;
1303 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1307 has_statx = cc.links(statx_test)
1309 # Check whether statx() provides mount ID information
1311 statx_mnt_id_test = gnu_source_prefix + '''
1312 #include <sys/stat.h>
1314 struct statx statxbuf;
1315 statx(0, "", 0, STATX_BASIC_STATS | STATX_MNT_ID, &statxbuf);
1316 return statxbuf.stx_mnt_id;
1319 has_statx_mnt_id = cc.links(statx_mnt_id_test)
1321 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
1322 .require(targetos == 'linux',
1323 error_message: 'vhost_user_blk_server requires linux') \
1324 .require('CONFIG_VHOST_USER' in config_host,
1325 error_message: 'vhost_user_blk_server requires vhost-user support') \
1326 .disable_auto_if(not have_system) \
1329 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1330 error('Cannot enable fuse-lseek while fuse is disabled')
1333 fuse = dependency('fuse3', required: get_option('fuse'),
1334 version: '>=3.1', method: 'pkg-config',
1335 kwargs: static_kwargs)
1337 fuse_lseek = not_found
1338 if get_option('fuse_lseek').allowed()
1339 if fuse.version().version_compare('>=3.8')
1341 fuse_lseek = declare_dependency()
1342 elif get_option('fuse_lseek').enabled()
1344 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1346 error('fuse-lseek requires libfuse, which was not found')
1352 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1353 if libbpf.found() and not cc.links('''
1354 #include <bpf/libbpf.h>
1357 bpf_object__destroy_skeleton(NULL);
1359 }''', dependencies: libbpf)
1361 if get_option('bpf').enabled()
1362 error('libbpf skeleton test failed')
1364 warning('libbpf skeleton test failed, disabling')
1372 audio_drivers_selected = []
1374 audio_drivers_available = {
1375 'alsa': alsa.found(),
1376 'coreaudio': coreaudio.found(),
1377 'dsound': dsound.found(),
1378 'jack': jack.found(),
1380 'pa': pulse.found(),
1383 foreach k, v: audio_drivers_available
1384 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1387 # Default to native drivers first, OSS second, SDL third
1388 audio_drivers_priority = \
1389 [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
1390 (targetos == 'linux' ? [] : [ 'sdl' ])
1391 audio_drivers_default = []
1392 foreach k: audio_drivers_priority
1393 if audio_drivers_available[k]
1394 audio_drivers_default += k
1398 foreach k: get_option('audio_drv_list')
1400 audio_drivers_selected += audio_drivers_default
1401 elif not audio_drivers_available[k]
1402 error('Audio driver "@0@" not available.'.format(k))
1404 audio_drivers_selected += k
1408 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1409 '"' + '", "'.join(audio_drivers_selected) + '", ')
1411 if get_option('cfi')
1413 # Check for dependency on LTO
1414 if not get_option('b_lto')
1415 error('Selected Control-Flow Integrity but LTO is disabled')
1417 if config_host.has_key('CONFIG_MODULES')
1418 error('Selected Control-Flow Integrity is not compatible with modules')
1420 # Check for cfi flags. CFI requires LTO so we can't use
1421 # get_supported_arguments, but need a more complex "compiles" which allows
1423 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1424 args: ['-flto', '-fsanitize=cfi-icall'] )
1425 cfi_flags += '-fsanitize=cfi-icall'
1427 error('-fsanitize=cfi-icall is not supported by the compiler')
1429 if cc.compiles('int main () { return 0; }',
1430 name: '-fsanitize-cfi-icall-generalize-pointers',
1431 args: ['-flto', '-fsanitize=cfi-icall',
1432 '-fsanitize-cfi-icall-generalize-pointers'] )
1433 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1435 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1437 if get_option('cfi_debug')
1438 if cc.compiles('int main () { return 0; }',
1439 name: '-fno-sanitize-trap=cfi-icall',
1440 args: ['-flto', '-fsanitize=cfi-icall',
1441 '-fno-sanitize-trap=cfi-icall'] )
1442 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1444 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1447 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1448 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1451 have_host_block_device = (targetos != 'darwin' or
1452 cc.has_header('IOKit/storage/IOMedia.h'))
1454 # FIXME enable_modules shouldn't be necessary, but: https://github.com/mesonbuild/meson/issues/8333
1455 dbus_display = get_option('dbus_display') \
1456 .require(gio.version().version_compare('>=2.64'),
1457 error_message: '-display dbus requires glib>=2.64') \
1458 .require(enable_modules,
1459 error_message: '-display dbus requires --enable-modules') \
1460 .require(config_host.has_key('GDBUS_CODEGEN'),
1461 error_message: '-display dbus requires gdbus-codegen') \
1464 have_virtfs = get_option('virtfs') \
1465 .require(targetos == 'linux' or targetos == 'darwin',
1466 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
1467 .require(targetos == 'linux' or cc.has_function('pthread_fchdir_np'),
1468 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
1469 .require(targetos == 'darwin' or (libattr.found() and libcap_ng.found()),
1470 error_message: 'virtio-9p (virtfs) on Linux requires libcap-ng-devel and libattr-devel') \
1471 .disable_auto_if(not have_tools and not have_system) \
1474 have_virtfs_proxy_helper = targetos != 'darwin' and have_virtfs and have_tools
1476 foreach k : get_option('trace_backends')
1477 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1479 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1480 if get_option('iasl') != ''
1481 config_host_data.set_quoted('CONFIG_IASL', get_option('iasl'))
1483 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1484 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1485 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1486 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1487 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1488 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1489 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1490 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1491 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1492 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1493 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1494 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1496 have_slirp_smbd = get_option('slirp_smbd') \
1497 .require(targetos != 'windows', error_message: 'Host smbd not supported on this platform.') \
1500 smbd_path = get_option('smbd')
1502 smbd_path = (targetos == 'solaris' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
1504 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
1507 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
1509 config_host_data.set('CONFIG_ATTR', libattr.found())
1510 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
1511 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1512 config_host_data.set('CONFIG_COCOA', cocoa.found())
1513 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1514 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1515 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1516 config_host_data.set('CONFIG_LZO', lzo.found())
1517 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1518 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1519 config_host_data.set('CONFIG_CURL', curl.found())
1520 config_host_data.set('CONFIG_CURSES', curses.found())
1521 config_host_data.set('CONFIG_GBM', gbm.found())
1522 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1523 if glusterfs.found()
1524 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1525 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1526 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1527 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1528 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1529 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1531 config_host_data.set('CONFIG_GTK', gtk.found())
1532 config_host_data.set('CONFIG_VTE', vte.found())
1533 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1534 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1535 config_host_data.set('CONFIG_EBPF', libbpf.found())
1536 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1537 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1538 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1539 config_host_data.set('CONFIG_LIBSSH', libssh.found())
1540 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1541 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1542 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1543 config_host_data.set('CONFIG_NUMA', numa.found())
1544 config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
1545 config_host_data.set('CONFIG_RBD', rbd.found())
1546 config_host_data.set('CONFIG_SDL', sdl.found())
1547 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1548 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1549 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1550 config_host_data.set('CONFIG_TPM', have_tpm)
1551 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1552 config_host_data.set('CONFIG_VDE', vde.found())
1553 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1554 config_host_data.set('CONFIG_VNC', vnc.found())
1555 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1556 config_host_data.set('CONFIG_VNC_PNG', png.found())
1557 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1558 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1559 config_host_data.set('CONFIG_VTE', vte.found())
1560 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1561 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1562 config_host_data.set('CONFIG_GETTID', has_gettid)
1563 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1564 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1565 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1566 config_host_data.set('CONFIG_NETTLE', nettle.found())
1567 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1568 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1569 config_host_data.set('CONFIG_STATX', has_statx)
1570 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
1571 config_host_data.set('CONFIG_ZSTD', zstd.found())
1572 config_host_data.set('CONFIG_FUSE', fuse.found())
1573 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1574 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1575 if spice_protocol.found()
1576 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
1577 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
1578 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
1580 config_host_data.set('CONFIG_SPICE', spice.found())
1581 config_host_data.set('CONFIG_X11', x11.found())
1582 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
1583 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1584 config_host_data.set('CONFIG_SELINUX', selinux.found())
1585 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1586 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1587 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1588 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1590 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1591 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1592 config_host_data.set('HOST_WORDS_BIGENDIAN', host_machine.endian() == 'big')
1594 have_coroutine_pool = get_option('coroutine_pool')
1595 if get_option('debug_stack_usage') and have_coroutine_pool
1596 message('Disabling coroutine pool to measure stack usage')
1597 have_coroutine_pool = false
1599 config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool)
1600 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
1601 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
1602 config_host_data.set('CONFIG_GPROF', get_option('gprof'))
1603 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
1604 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
1605 config_host_data.set('CONFIG_REPLICATION', get_option('live_block_migration').allowed())
1608 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1609 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1610 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1611 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1612 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1613 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1614 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1615 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1616 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1619 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1620 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1621 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1622 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1623 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1624 # Note that we need to specify prefix: here to avoid incorrectly
1625 # thinking that Windows has posix_memalign()
1626 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
1627 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
1628 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
1629 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
1630 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1631 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1632 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
1633 config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
1634 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1635 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1636 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1637 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1638 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1639 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1640 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1641 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1642 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1644 config_host_data.set('HAVE_IBV_ADVISE_MR',
1645 cc.has_function('ibv_advise_mr',
1646 args: config_host['RDMA_LIBS'].split(),
1647 prefix: '#include <infiniband/verbs.h>'))
1651 config_host_data.set('CONFIG_BYTESWAP_H',
1652 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1653 config_host_data.set('CONFIG_EPOLL_CREATE1',
1654 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1655 config_host_data.set('CONFIG_HAS_ENVIRON',
1656 cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix))
1657 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1658 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1659 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1660 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1661 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1662 config_host_data.set('CONFIG_FIEMAP',
1663 cc.has_header('linux/fiemap.h') and
1664 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1665 config_host_data.set('CONFIG_GETRANDOM',
1666 cc.has_function('getrandom') and
1667 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1668 config_host_data.set('CONFIG_INOTIFY',
1669 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1670 config_host_data.set('CONFIG_INOTIFY1',
1671 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1672 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1673 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1674 prefix: '''#include <sys/endian.h>
1675 #include <sys/types.h>'''))
1676 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1677 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1678 config_host_data.set('CONFIG_RTNETLINK',
1679 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1680 config_host_data.set('CONFIG_SYSMACROS',
1681 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1682 config_host_data.set('HAVE_OPTRESET',
1683 cc.has_header_symbol('getopt.h', 'optreset'))
1684 config_host_data.set('HAVE_IPPROTO_MPTCP',
1685 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1688 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1689 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1690 prefix: '#include <signal.h>'))
1691 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1692 cc.has_member('struct stat', 'st_atim',
1693 prefix: '#include <sys/stat.h>'))
1696 config_host_data.set('CONFIG_IOVEC',
1697 cc.has_type('struct iovec',
1698 prefix: '#include <sys/uio.h>'))
1699 config_host_data.set('HAVE_UTMPX',
1700 cc.has_type('struct utmpx',
1701 prefix: '#include <utmpx.h>'))
1703 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1704 #include <sys/eventfd.h>
1705 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1706 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1709 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1710 return fdatasync(0);
1712 #error Not supported
1715 config_host_data.set('CONFIG_MADVISE', cc.links(gnu_source_prefix + '''
1716 #include <sys/types.h>
1717 #include <sys/mman.h>
1719 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }'''))
1720 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1721 #include <sys/mman.h>
1722 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1723 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1725 #if !defined(AT_EMPTY_PATH)
1726 # error missing definition
1728 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1730 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1737 return pipe2(pipefd, O_CLOEXEC);
1739 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1740 #include <sys/mman.h>
1742 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1744 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
1745 #include <pthread.h>
1747 static void *f(void *p) { return NULL; }
1751 pthread_create(&thread, 0, f, 0);
1752 pthread_setname_np(thread, "QEMU");
1754 }''', dependencies: threads))
1755 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
1756 #include <pthread.h>
1758 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
1762 pthread_create(&thread, 0, f, 0);
1764 }''', dependencies: threads))
1766 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1767 #include <sys/signalfd.h>
1769 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1770 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1778 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1779 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1783 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
1784 #include <sys/mman.h>
1785 int main(int argc, char *argv[]) {
1786 return mlockall(MCL_FUTURE);
1790 if get_option('l2tpv3').allowed() and have_system
1791 have_l2tpv3 = cc.has_type('struct mmsghdr',
1792 prefix: gnu_source_prefix + '''
1793 #include <sys/socket.h>
1794 #include <linux/ip.h>''')
1796 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
1799 if get_option('netmap').allowed() and have_system
1800 have_netmap = cc.compiles('''
1801 #include <inttypes.h>
1803 #include <net/netmap.h>
1804 #include <net/netmap_user.h>
1805 #if (NETMAP_API < 11) || (NETMAP_API > 15)
1808 int main(void) { return 0; }''')
1809 if not have_netmap and get_option('netmap').enabled()
1810 error('Netmap headers not available')
1813 config_host_data.set('CONFIG_NETMAP', have_netmap)
1815 # Work around a system header bug with some kernel/XFS header
1816 # versions where they both try to define 'struct fsxattr':
1817 # xfs headers will not try to redefine structs from linux headers
1818 # if this macro is set.
1819 config_host_data.set('HAVE_FSXATTR', cc.links('''
1820 #include <linux/fs.h>
1826 # Some versions of Mac OS X incorrectly define SIZE_MAX
1827 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1830 int main(int argc, char *argv[]) {
1831 return printf("%zu", SIZE_MAX);
1832 }''', args: ['-Werror']))
1834 # See if 64-bit atomic operations are supported.
1835 # Note that without __atomic builtins, we can only
1836 # assume atomic loads/stores max at pointer size.
1837 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
1841 uint64_t x = 0, y = 0;
1842 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
1843 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
1844 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
1845 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
1846 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
1850 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
1851 #include <sys/auxv.h>
1853 return getauxval(AT_HWCAP) == 0;
1856 have_cpuid_h = cc.links('''
1859 unsigned a, b, c, d;
1860 unsigned max = __get_cpuid_max(0, 0);
1863 __cpuid(1, a, b, c, d);
1867 __cpuid_count(7, 0, a, b, c, d);
1872 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
1874 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
1875 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
1876 .require(cc.links('''
1877 #pragma GCC push_options
1878 #pragma GCC target("avx2")
1880 #include <immintrin.h>
1881 static int bar(void *a) {
1882 __m256i x = *(__m256i *)a;
1883 return _mm256_testz_si256(x, x);
1885 int main(int argc, char *argv[]) { return bar(argv[0]); }
1886 '''), error_message: 'AVX2 not available').allowed())
1888 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
1889 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
1890 .require(cc.links('''
1891 #pragma GCC push_options
1892 #pragma GCC target("avx512f")
1894 #include <immintrin.h>
1895 static int bar(void *a) {
1896 __m512i x = *(__m512i *)a;
1897 return _mm512_test_epi64_mask(x, x);
1899 int main(int argc, char *argv[]) { return bar(argv[0]); }
1900 '''), error_message: 'AVX512F not available').allowed())
1902 if get_option('membarrier').disabled()
1903 have_membarrier = false
1904 elif targetos == 'windows'
1905 have_membarrier = true
1906 elif targetos == 'linux'
1907 have_membarrier = cc.compiles('''
1908 #include <linux/membarrier.h>
1909 #include <sys/syscall.h>
1913 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
1914 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
1918 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
1919 .require(have_membarrier, error_message: 'membarrier system call not available') \
1922 have_afalg = get_option('crypto_afalg') \
1923 .require(cc.compiles(gnu_source_prefix + '''
1925 #include <sys/types.h>
1926 #include <sys/socket.h>
1927 #include <linux/if_alg.h>
1930 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
1933 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
1934 config_host_data.set('CONFIG_AF_ALG', have_afalg)
1936 config_host_data.set('CONFIG_AF_VSOCK', cc.compiles(gnu_source_prefix + '''
1938 #include <sys/types.h>
1939 #include <sys/socket.h>
1940 #if !defined(AF_VSOCK)
1941 # error missing AF_VSOCK flag
1943 #include <linux/vm_sockets.h>
1946 struct sockaddr_vm svm;
1947 socklen_t len = sizeof(svm);
1948 sock = socket(AF_VSOCK, SOCK_STREAM, 0);
1949 ret = getpeername(sock, (struct sockaddr *)&svm, &len);
1950 if ((ret == -1) && (errno == ENOTCONN)) {
1957 have_vss_sdk = false # old xp/2003 SDK
1958 if targetos == 'windows' and link_language == 'cpp'
1959 have_vss = cxx.compiles('''
1960 #define __MIDL_user_allocate_free_DEFINED__
1962 int main(void) { return VSS_CTX_BACKUP; }''')
1963 have_vss_sdk = cxx.has_header('vscoordint.h')
1965 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
1967 have_ntddscsi = false
1968 if targetos == 'windows'
1969 have_ntddscsi = cc.compiles('''
1970 #include <windows.h>
1971 #include <ntddscsi.h>
1973 #if !defined(IOCTL_SCSI_GET_ADDRESS)
1974 #error Missing required ioctl definitions
1976 SCSI_ADDRESS addr = { .Lun = 0, .TargetId = 0, .PathId = 0 };
1981 config_host_data.set('HAVE_NTDDSCSI', have_ntddscsi)
1983 ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target
1985 arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1986 foreach k, v: config_host
1987 if ignored.contains(k)
1989 elif arrays.contains(k)
1991 v = '"' + '", "'.join(v.split()) + '", '
1993 config_host_data.set(k, v)
1994 elif k.startswith('CONFIG_')
1995 config_host_data.set(k, v == 'y' ? 1 : v)
1999 ########################
2000 # Target configuration #
2001 ########################
2003 minikconf = find_program('scripts/minikconf.py')
2005 config_all_devices = {}
2006 config_all_disas = {}
2007 config_devices_mak_list = []
2008 config_devices_h = {}
2009 config_target_h = {}
2010 config_target_mak = {}
2013 'alpha' : ['CONFIG_ALPHA_DIS'],
2014 'arm' : ['CONFIG_ARM_DIS'],
2015 'avr' : ['CONFIG_AVR_DIS'],
2016 'cris' : ['CONFIG_CRIS_DIS'],
2017 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2018 'hppa' : ['CONFIG_HPPA_DIS'],
2019 'i386' : ['CONFIG_I386_DIS'],
2020 'x86_64' : ['CONFIG_I386_DIS'],
2021 'm68k' : ['CONFIG_M68K_DIS'],
2022 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2023 'mips' : ['CONFIG_MIPS_DIS'],
2024 'nios2' : ['CONFIG_NIOS2_DIS'],
2025 'or1k' : ['CONFIG_OPENRISC_DIS'],
2026 'ppc' : ['CONFIG_PPC_DIS'],
2027 'riscv' : ['CONFIG_RISCV_DIS'],
2028 'rx' : ['CONFIG_RX_DIS'],
2029 's390' : ['CONFIG_S390_DIS'],
2030 'sh4' : ['CONFIG_SH4_DIS'],
2031 'sparc' : ['CONFIG_SPARC_DIS'],
2032 'xtensa' : ['CONFIG_XTENSA_DIS'],
2034 if link_language == 'cpp'
2036 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
2037 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
2038 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
2042 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2044 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2045 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2046 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2047 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2048 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
2049 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2050 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
2051 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2052 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2053 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2054 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
2055 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
2056 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
2058 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2060 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2061 actual_target_dirs = []
2063 foreach target : target_dirs
2064 config_target = { 'TARGET_NAME': target.split('-')[0] }
2065 if target.endswith('linux-user')
2066 if targetos != 'linux'
2070 error('Target @0@ is only available on a Linux host'.format(target))
2072 config_target += { 'CONFIG_LINUX_USER': 'y' }
2073 elif target.endswith('bsd-user')
2074 if 'CONFIG_BSD' not in config_host
2078 error('Target @0@ is only available on a BSD host'.format(target))
2080 config_target += { 'CONFIG_BSD_USER': 'y' }
2081 elif target.endswith('softmmu')
2082 config_target += { 'CONFIG_SOFTMMU': 'y' }
2084 if target.endswith('-user')
2086 'CONFIG_USER_ONLY': 'y',
2087 'CONFIG_QEMU_INTERP_PREFIX':
2088 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
2093 foreach sym: accelerators
2094 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2095 config_target += { sym: 'y' }
2096 config_all += { sym: 'y' }
2097 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
2098 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
2099 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
2100 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
2102 if target in modular_tcg
2103 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2105 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2107 accel_kconfig += [ sym + '=y' ]
2110 if accel_kconfig.length() == 0
2114 error('No accelerator available for target @0@'.format(target))
2117 actual_target_dirs += target
2118 config_target += keyval.load('configs/targets' / target + '.mak')
2119 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
2121 if 'TARGET_NEED_FDT' in config_target
2122 fdt_required += target
2126 if 'TARGET_BASE_ARCH' not in config_target
2127 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2129 if 'TARGET_ABI_DIR' not in config_target
2130 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2133 foreach k, v: disassemblers
2134 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
2136 config_target += { sym: 'y' }
2137 config_all_disas += { sym: 'y' }
2142 config_target_data = configuration_data()
2143 foreach k, v: config_target
2144 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2146 elif ignored.contains(k)
2148 elif k == 'TARGET_BASE_ARCH'
2149 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2150 # not used to select files from sourcesets.
2151 config_target_data.set('TARGET_' + v.to_upper(), 1)
2152 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
2153 config_target_data.set_quoted(k, v)
2155 config_target_data.set(k, 1)
2157 config_target_data.set(k, v)
2160 config_target_data.set('QEMU_ARCH',
2161 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
2162 config_target_h += {target: configure_file(output: target + '-config-target.h',
2163 configuration: config_target_data)}
2165 if target.endswith('-softmmu')
2166 config_input = meson.get_external_property(target, 'default')
2167 config_devices_mak = target + '-config-devices.mak'
2168 config_devices_mak = configure_file(
2169 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2170 output: config_devices_mak,
2171 depfile: config_devices_mak + '.d',
2173 command: [minikconf,
2174 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2175 config_devices_mak, '@DEPFILE@', '@INPUT@',
2176 host_kconfig, accel_kconfig,
2177 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
2179 config_devices_data = configuration_data()
2180 config_devices = keyval.load(config_devices_mak)
2181 foreach k, v: config_devices
2182 config_devices_data.set(k, 1)
2184 config_devices_mak_list += config_devices_mak
2185 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2186 configuration: config_devices_data)}
2187 config_target += config_devices
2188 config_all_devices += config_devices
2190 config_target_mak += {target: config_target}
2192 target_dirs = actual_target_dirs
2194 # This configuration is used to build files that are shared by
2195 # multiple binaries, and then extracted out of the "common"
2196 # static_library target.
2198 # We do not use all_sources()/all_dependencies(), because it would
2199 # build literally all source files, including devices only used by
2200 # targets that are not built for this compilation. The CONFIG_ALL
2201 # pseudo symbol replaces it.
2203 config_all += config_all_devices
2204 config_all += config_host
2205 config_all += config_all_disas
2207 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
2208 'CONFIG_SOFTMMU': have_system,
2209 'CONFIG_USER_ONLY': have_user,
2213 target_configs_h = []
2214 foreach target: target_dirs
2215 target_configs_h += config_target_h[target]
2216 target_configs_h += config_devices_h.get(target, [])
2218 genh += custom_target('config-poison.h',
2219 input: [target_configs_h],
2220 output: 'config-poison.h',
2222 command: [find_program('scripts/make-config-poison.sh'),
2229 capstone = not_found
2230 capstone_opt = get_option('capstone')
2231 if capstone_opt in ['enabled', 'auto', 'system']
2232 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
2233 capstone = dependency('capstone', version: '>=4.0',
2234 kwargs: static_kwargs, method: 'pkg-config',
2235 required: capstone_opt == 'system' or
2236 capstone_opt == 'enabled' and not have_internal)
2238 # Some versions of capstone have broken pkg-config file
2239 # that reports a wrong -I path, causing the #include to
2240 # fail later. If the system has such a broken version
2242 if capstone.found() and not cc.compiles('#include <capstone.h>',
2243 dependencies: [capstone])
2244 capstone = not_found
2245 if capstone_opt == 'system'
2246 error('system capstone requested, it does not appear to work')
2251 capstone_opt = 'system'
2253 capstone_opt = 'internal'
2255 capstone_opt = 'disabled'
2258 if capstone_opt == 'internal'
2259 capstone_data = configuration_data()
2260 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
2262 capstone_files = files(
2264 'capstone/MCInst.c',
2265 'capstone/MCInstrDesc.c',
2266 'capstone/MCRegisterInfo.c',
2267 'capstone/SStream.c',
2271 if 'CONFIG_ARM_DIS' in config_all_disas
2272 capstone_data.set('CAPSTONE_HAS_ARM', '1')
2273 capstone_files += files(
2274 'capstone/arch/ARM/ARMDisassembler.c',
2275 'capstone/arch/ARM/ARMInstPrinter.c',
2276 'capstone/arch/ARM/ARMMapping.c',
2277 'capstone/arch/ARM/ARMModule.c'
2281 # FIXME: This config entry currently depends on a c++ compiler.
2282 # Which is needed for building libvixl, but not for capstone.
2283 if 'CONFIG_ARM_A64_DIS' in config_all_disas
2284 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
2285 capstone_files += files(
2286 'capstone/arch/AArch64/AArch64BaseInfo.c',
2287 'capstone/arch/AArch64/AArch64Disassembler.c',
2288 'capstone/arch/AArch64/AArch64InstPrinter.c',
2289 'capstone/arch/AArch64/AArch64Mapping.c',
2290 'capstone/arch/AArch64/AArch64Module.c'
2294 if 'CONFIG_PPC_DIS' in config_all_disas
2295 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
2296 capstone_files += files(
2297 'capstone/arch/PowerPC/PPCDisassembler.c',
2298 'capstone/arch/PowerPC/PPCInstPrinter.c',
2299 'capstone/arch/PowerPC/PPCMapping.c',
2300 'capstone/arch/PowerPC/PPCModule.c'
2304 if 'CONFIG_S390_DIS' in config_all_disas
2305 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
2306 capstone_files += files(
2307 'capstone/arch/SystemZ/SystemZDisassembler.c',
2308 'capstone/arch/SystemZ/SystemZInstPrinter.c',
2309 'capstone/arch/SystemZ/SystemZMapping.c',
2310 'capstone/arch/SystemZ/SystemZModule.c',
2311 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
2315 if 'CONFIG_I386_DIS' in config_all_disas
2316 capstone_data.set('CAPSTONE_HAS_X86', 1)
2317 capstone_files += files(
2318 'capstone/arch/X86/X86Disassembler.c',
2319 'capstone/arch/X86/X86DisassemblerDecoder.c',
2320 'capstone/arch/X86/X86ATTInstPrinter.c',
2321 'capstone/arch/X86/X86IntelInstPrinter.c',
2322 'capstone/arch/X86/X86InstPrinterCommon.c',
2323 'capstone/arch/X86/X86Mapping.c',
2324 'capstone/arch/X86/X86Module.c'
2328 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
2331 # FIXME: There does not seem to be a way to completely replace the c_args
2332 # that come from add_project_arguments() -- we can only add to them.
2333 # So: disable all warnings with a big hammer.
2336 # Include all configuration defines via a header file, which will wind up
2337 # as a dependency on the object file, and thus changes here will result
2339 '-include', 'capstone-defs.h'
2342 libcapstone = static_library('capstone',
2343 build_by_default: false,
2344 sources: capstone_files,
2345 c_args: capstone_cargs,
2346 include_directories: 'capstone/include')
2347 capstone = declare_dependency(link_with: libcapstone,
2348 include_directories: 'capstone/include/capstone')
2352 slirp_opt = 'disabled'
2354 slirp_opt = get_option('slirp')
2355 if slirp_opt in ['enabled', 'auto', 'system']
2356 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2357 slirp = dependency('slirp', kwargs: static_kwargs,
2358 method: 'pkg-config',
2359 required: slirp_opt == 'system' or
2360 slirp_opt == 'enabled' and not have_internal)
2362 slirp_opt = 'system'
2364 slirp_opt = 'internal'
2366 slirp_opt = 'disabled'
2369 if slirp_opt == 'internal'
2371 if targetos == 'windows'
2372 slirp_deps = cc.find_library('iphlpapi')
2373 elif targetos == 'darwin'
2374 slirp_deps = cc.find_library('resolv')
2376 slirp_conf = configuration_data()
2377 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2378 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2379 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2380 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2381 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2383 'slirp/src/arp_table.c',
2384 'slirp/src/bootp.c',
2385 'slirp/src/cksum.c',
2386 'slirp/src/dhcpv6.c',
2387 'slirp/src/dnssearch.c',
2389 'slirp/src/ip6_icmp.c',
2390 'slirp/src/ip6_input.c',
2391 'slirp/src/ip6_output.c',
2392 'slirp/src/ip_icmp.c',
2393 'slirp/src/ip_input.c',
2394 'slirp/src/ip_output.c',
2398 'slirp/src/ndp_table.c',
2400 'slirp/src/slirp.c',
2401 'slirp/src/socket.c',
2402 'slirp/src/state.c',
2403 'slirp/src/stream.c',
2404 'slirp/src/tcp_input.c',
2405 'slirp/src/tcp_output.c',
2406 'slirp/src/tcp_subr.c',
2407 'slirp/src/tcp_timer.c',
2412 'slirp/src/version.c',
2413 'slirp/src/vmstate.c',
2417 input : 'slirp/src/libslirp-version.h.in',
2418 output : 'libslirp-version.h',
2419 configuration: slirp_conf)
2421 slirp_inc = include_directories('slirp', 'slirp/src')
2422 libslirp = static_library('slirp',
2423 build_by_default: false,
2424 sources: slirp_files,
2425 c_args: slirp_cargs,
2426 include_directories: slirp_inc)
2427 slirp = declare_dependency(link_with: libslirp,
2428 dependencies: slirp_deps,
2429 include_directories: slirp_inc)
2433 # For CFI, we need to compile slirp as a static library together with qemu.
2434 # This is because we register slirp functions as callbacks for QEMU Timers.
2435 # When using a system-wide shared libslirp, the type information for the
2436 # callback is missing and the timer call produces a false positive with CFI.
2438 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2439 # with control-flow integrity.
2440 if get_option('cfi') and slirp_opt == 'system'
2441 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2442 + ' Please configure with --enable-slirp=git')
2447 fdt_opt = get_option('fdt')
2448 if fdt_opt in ['enabled', 'auto', 'system']
2449 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2450 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2451 required: fdt_opt == 'system' or
2452 fdt_opt == 'enabled' and not have_internal)
2453 if fdt.found() and cc.links('''
2455 #include <libfdt_env.h>
2456 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2459 elif fdt_opt == 'system'
2460 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2462 fdt_opt = 'internal'
2464 fdt_opt = 'disabled'
2468 if fdt_opt == 'internal'
2471 'dtc/libfdt/fdt_ro.c',
2472 'dtc/libfdt/fdt_wip.c',
2473 'dtc/libfdt/fdt_sw.c',
2474 'dtc/libfdt/fdt_rw.c',
2475 'dtc/libfdt/fdt_strerror.c',
2476 'dtc/libfdt/fdt_empty_tree.c',
2477 'dtc/libfdt/fdt_addresses.c',
2478 'dtc/libfdt/fdt_overlay.c',
2479 'dtc/libfdt/fdt_check.c',
2482 fdt_inc = include_directories('dtc/libfdt')
2483 libfdt = static_library('fdt',
2484 build_by_default: false,
2486 include_directories: fdt_inc)
2487 fdt = declare_dependency(link_with: libfdt,
2488 include_directories: fdt_inc)
2491 fdt_opt = 'disabled'
2493 if not fdt.found() and fdt_required.length() > 0
2494 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2497 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2498 config_host_data.set('CONFIG_FDT', fdt.found())
2499 config_host_data.set('CONFIG_SLIRP', slirp.found())
2501 #####################
2502 # Generated sources #
2503 #####################
2505 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2507 hxtool = find_program('scripts/hxtool')
2508 shaderinclude = find_program('scripts/shaderinclude.pl')
2509 qapi_gen = find_program('scripts/qapi-gen.py')
2510 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2511 meson.current_source_dir() / 'scripts/qapi/commands.py',
2512 meson.current_source_dir() / 'scripts/qapi/common.py',
2513 meson.current_source_dir() / 'scripts/qapi/error.py',
2514 meson.current_source_dir() / 'scripts/qapi/events.py',
2515 meson.current_source_dir() / 'scripts/qapi/expr.py',
2516 meson.current_source_dir() / 'scripts/qapi/gen.py',
2517 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2518 meson.current_source_dir() / 'scripts/qapi/parser.py',
2519 meson.current_source_dir() / 'scripts/qapi/schema.py',
2520 meson.current_source_dir() / 'scripts/qapi/source.py',
2521 meson.current_source_dir() / 'scripts/qapi/types.py',
2522 meson.current_source_dir() / 'scripts/qapi/visit.py',
2523 meson.current_source_dir() / 'scripts/qapi/common.py',
2524 meson.current_source_dir() / 'scripts/qapi-gen.py'
2528 python, files('scripts/tracetool.py'),
2529 '--backend=' + ','.join(get_option('trace_backends'))
2531 tracetool_depends = files(
2532 'scripts/tracetool/backend/log.py',
2533 'scripts/tracetool/backend/__init__.py',
2534 'scripts/tracetool/backend/dtrace.py',
2535 'scripts/tracetool/backend/ftrace.py',
2536 'scripts/tracetool/backend/simple.py',
2537 'scripts/tracetool/backend/syslog.py',
2538 'scripts/tracetool/backend/ust.py',
2539 'scripts/tracetool/format/ust_events_c.py',
2540 'scripts/tracetool/format/ust_events_h.py',
2541 'scripts/tracetool/format/__init__.py',
2542 'scripts/tracetool/format/d.py',
2543 'scripts/tracetool/format/simpletrace_stap.py',
2544 'scripts/tracetool/format/c.py',
2545 'scripts/tracetool/format/h.py',
2546 'scripts/tracetool/format/log_stap.py',
2547 'scripts/tracetool/format/stap.py',
2548 'scripts/tracetool/__init__.py',
2549 'scripts/tracetool/transform.py',
2550 'scripts/tracetool/vcpu.py'
2553 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2554 meson.current_source_dir(),
2555 config_host['PKGVERSION'], meson.project_version()]
2556 qemu_version = custom_target('qemu-version.h',
2557 output: 'qemu-version.h',
2558 command: qemu_version_cmd,
2560 build_by_default: true,
2561 build_always_stale: true)
2562 genh += qemu_version
2566 ['qemu-options.hx', 'qemu-options.def'],
2567 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2571 ['hmp-commands.hx', 'hmp-commands.h'],
2572 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2575 foreach d : hx_headers
2576 hxdep += custom_target(d[1],
2580 build_by_default: true, # to be removed when added to a target
2581 command: [hxtool, '-h', '@INPUT0@'])
2589 authz_ss = ss.source_set()
2590 blockdev_ss = ss.source_set()
2591 block_ss = ss.source_set()
2592 chardev_ss = ss.source_set()
2593 common_ss = ss.source_set()
2594 crypto_ss = ss.source_set()
2595 hwcore_ss = ss.source_set()
2596 io_ss = ss.source_set()
2597 qmp_ss = ss.source_set()
2598 qom_ss = ss.source_set()
2599 softmmu_ss = ss.source_set()
2600 specific_fuzz_ss = ss.source_set()
2601 specific_ss = ss.source_set()
2602 stub_ss = ss.source_set()
2603 trace_ss = ss.source_set()
2604 user_ss = ss.source_set()
2605 util_ss = ss.source_set()
2608 qtest_module_ss = ss.source_set()
2609 tcg_module_ss = ss.source_set()
2615 target_softmmu_arch = {}
2616 target_user_arch = {}
2622 # TODO: add each directory to the subdirs from its own meson.build, once
2624 trace_events_subdirs = [
2632 trace_events_subdirs += [ 'linux-user' ]
2635 trace_events_subdirs += [ 'bsd-user' ]
2638 trace_events_subdirs += [
2647 trace_events_subdirs += [
2661 'hw/block/dataplane',
2711 if have_system or have_user
2712 trace_events_subdirs += [
2730 vhost_user = not_found
2731 if targetos == 'linux' and 'CONFIG_VHOST_USER' in config_host
2732 libvhost_user = subproject('libvhost-user')
2733 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2736 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
2737 # that is filled in by qapi/.
2750 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2751 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2754 stub_ss = stub_ss.apply(config_all, strict: false)
2756 util_ss.add_all(trace_ss)
2757 util_ss = util_ss.apply(config_all, strict: false)
2758 libqemuutil = static_library('qemuutil',
2759 sources: util_ss.sources() + stub_ss.sources() + genh,
2760 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2761 qemuutil = declare_dependency(link_with: libqemuutil,
2762 sources: genh + version_res)
2764 if have_system or have_user
2765 decodetree = generator(find_program('scripts/decodetree.py'),
2766 output: 'decode-@BASENAME@.c.inc',
2767 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2768 subdir('libdecnumber')
2785 if config_host_data.get('CONFIG_REPLICATION')
2786 block_ss.add(files('replication.c'))
2793 blockdev_ss.add(files(
2800 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2801 # os-win32.c does not
2802 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2803 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2806 common_ss.add(files('cpus-common.c'))
2810 common_ss.add(capstone)
2811 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2813 # Work around a gcc bug/misfeature wherein constant propagation looks
2815 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2816 # to guess that a const variable is always zero. Without lto, this is
2817 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2818 # without lto, not even the alias is required -- we simply use different
2819 # declarations in different compilation units.
2820 pagevary = files('page-vary-common.c')
2821 if get_option('b_lto')
2822 pagevary_flags = ['-fno-lto']
2823 if get_option('cfi')
2824 pagevary_flags += '-fno-sanitize=cfi-icall'
2826 pagevary = static_library('page-vary-common', sources: pagevary,
2827 c_args: pagevary_flags)
2828 pagevary = declare_dependency(link_with: pagevary)
2830 common_ss.add(pagevary)
2831 specific_ss.add(files('page-vary.c'))
2839 subdir('semihosting')
2847 common_user_inc = []
2849 subdir('common-user')
2851 subdir('linux-user')
2853 # needed for fuzzing binaries
2854 subdir('tests/qtest/libqos')
2855 subdir('tests/qtest/fuzz')
2858 tcg_real_module_ss = ss.source_set()
2859 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
2860 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
2861 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
2862 'tcg': tcg_real_module_ss }}
2864 ########################
2865 # Library dependencies #
2866 ########################
2868 modinfo_collect = find_program('scripts/modinfo-collect.py')
2869 modinfo_generate = find_program('scripts/modinfo-generate.py')
2874 foreach d, list : modules
2875 foreach m, module_ss : list
2876 if enable_modules and targetos != 'windows'
2877 module_ss = module_ss.apply(config_all, strict: false)
2878 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2879 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2885 if module_ss.sources() != []
2886 # FIXME: Should use sl.extract_all_objects(recursive: true) as
2887 # input. Sources can be used multiple times but objects are
2888 # unique when it comes to lookup in compile_commands.json.
2889 # Depnds on a mesion version with
2890 # https://github.com/mesonbuild/meson/pull/8900
2891 modinfo_files += custom_target(d + '-' + m + '.modinfo',
2892 output: d + '-' + m + '.modinfo',
2893 input: module_ss.sources() + genh,
2895 command: [modinfo_collect, module_ss.sources()])
2899 block_ss.add_all(module_ss)
2901 softmmu_ss.add_all(module_ss)
2907 foreach d, list : target_modules
2908 foreach m, module_ss : list
2909 if enable_modules and targetos != 'windows'
2910 foreach target : target_dirs
2911 if target.endswith('-softmmu')
2912 config_target = config_target_mak[target]
2913 config_target += config_host
2914 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2915 c_args = ['-DNEED_CPU_H',
2916 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2917 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2918 target_module_ss = module_ss.apply(config_target, strict: false)
2919 if target_module_ss.sources() != []
2920 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
2921 sl = static_library(module_name,
2922 [genh, target_module_ss.sources()],
2923 dependencies: [modulecommon, target_module_ss.dependencies()],
2924 include_directories: target_inc,
2928 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
2929 modinfo_files += custom_target(module_name + '.modinfo',
2930 output: module_name + '.modinfo',
2931 input: target_module_ss.sources() + genh,
2933 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
2938 specific_ss.add_all(module_ss)
2944 modinfo_src = custom_target('modinfo.c',
2945 output: 'modinfo.c',
2946 input: modinfo_files,
2947 command: [modinfo_generate, '@INPUT@'],
2949 modinfo_lib = static_library('modinfo', modinfo_src)
2950 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
2951 softmmu_ss.add(modinfo_dep)
2954 nm = find_program('nm')
2955 undefsym = find_program('scripts/undefsym.py')
2956 block_syms = custom_target('block.syms', output: 'block.syms',
2957 input: [libqemuutil, block_mods],
2959 command: [undefsym, nm, '@INPUT@'])
2960 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2961 input: [libqemuutil, softmmu_mods],
2963 command: [undefsym, nm, '@INPUT@'])
2965 qom_ss = qom_ss.apply(config_host, strict: false)
2966 libqom = static_library('qom', qom_ss.sources() + genh,
2967 dependencies: [qom_ss.dependencies()],
2970 qom = declare_dependency(link_whole: libqom)
2972 authz_ss = authz_ss.apply(config_host, strict: false)
2973 libauthz = static_library('authz', authz_ss.sources() + genh,
2974 dependencies: [authz_ss.dependencies()],
2976 build_by_default: false)
2978 authz = declare_dependency(link_whole: libauthz,
2981 crypto_ss = crypto_ss.apply(config_host, strict: false)
2982 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2983 dependencies: [crypto_ss.dependencies()],
2985 build_by_default: false)
2987 crypto = declare_dependency(link_whole: libcrypto,
2988 dependencies: [authz, qom])
2990 io_ss = io_ss.apply(config_host, strict: false)
2991 libio = static_library('io', io_ss.sources() + genh,
2992 dependencies: [io_ss.dependencies()],
2993 link_with: libqemuutil,
2995 build_by_default: false)
2997 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2999 libmigration = static_library('migration', sources: migration_files + genh,
3001 build_by_default: false)
3002 migration = declare_dependency(link_with: libmigration,
3003 dependencies: [zlib, qom, io])
3004 softmmu_ss.add(migration)
3006 block_ss = block_ss.apply(config_host, strict: false)
3007 libblock = static_library('block', block_ss.sources() + genh,
3008 dependencies: block_ss.dependencies(),
3009 link_depends: block_syms,
3011 build_by_default: false)
3013 block = declare_dependency(link_whole: [libblock],
3014 link_args: '@block.syms',
3015 dependencies: [crypto, io])
3017 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
3018 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3019 dependencies: blockdev_ss.dependencies(),
3021 build_by_default: false)
3023 blockdev = declare_dependency(link_whole: [libblockdev],
3024 dependencies: [block])
3026 qmp_ss = qmp_ss.apply(config_host, strict: false)
3027 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3028 dependencies: qmp_ss.dependencies(),
3030 build_by_default: false)
3032 qmp = declare_dependency(link_whole: [libqmp])
3034 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3036 dependencies: [gnutls],
3037 build_by_default: false)
3039 chardev = declare_dependency(link_whole: libchardev)
3041 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
3042 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3044 build_by_default: false)
3045 hwcore = declare_dependency(link_whole: libhwcore)
3046 common_ss.add(hwcore)
3052 emulator_modules = []
3053 foreach m : block_mods + softmmu_mods
3054 emulator_modules += shared_module(m.name(),
3055 build_by_default: true,
3059 install_dir: qemu_moddir)
3062 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3063 common_ss.add(qom, qemuutil)
3065 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
3066 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3068 common_all = common_ss.apply(config_all, strict: false)
3069 common_all = static_library('common',
3070 build_by_default: false,
3071 sources: common_all.sources() + genh,
3072 include_directories: common_user_inc,
3073 implicit_include_directories: false,
3074 dependencies: common_all.dependencies(),
3077 feature_to_c = find_program('scripts/feature_to_c.sh')
3080 foreach target : target_dirs
3081 config_target = config_target_mak[target]
3082 target_name = config_target['TARGET_NAME']
3083 target_base_arch = config_target['TARGET_BASE_ARCH']
3084 arch_srcs = [config_target_h[target]]
3086 c_args = ['-DNEED_CPU_H',
3087 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3088 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3089 link_args = emulator_link_args
3091 config_target += config_host
3092 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3093 if targetos == 'linux'
3094 target_inc += include_directories('linux-headers', is_system: true)
3096 if target.endswith('-softmmu')
3097 qemu_target_name = 'qemu-system-' + target_name
3098 target_type='system'
3099 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3100 arch_srcs += t.sources()
3101 arch_deps += t.dependencies()
3103 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3104 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3105 arch_srcs += hw.sources()
3106 arch_deps += hw.dependencies()
3108 arch_srcs += config_devices_h[target]
3109 link_args += ['@block.syms', '@qemu.syms']
3111 abi = config_target['TARGET_ABI_DIR']
3113 target_inc += common_user_inc
3114 qemu_target_name = 'qemu-' + target_name
3115 if target_base_arch in target_user_arch
3116 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3117 arch_srcs += t.sources()
3118 arch_deps += t.dependencies()
3120 if 'CONFIG_LINUX_USER' in config_target
3121 base_dir = 'linux-user'
3123 if 'CONFIG_BSD_USER' in config_target
3124 base_dir = 'bsd-user'
3125 target_inc += include_directories('bsd-user/' / targetos)
3126 target_inc += include_directories('bsd-user/host/' / host_arch)
3127 dir = base_dir / abi
3128 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3130 target_inc += include_directories(
3134 if 'CONFIG_LINUX_USER' in config_target
3135 dir = base_dir / abi
3136 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3137 if config_target.has_key('TARGET_SYSTBL_ABI')
3139 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3140 extra_args : config_target['TARGET_SYSTBL_ABI'])
3145 if 'TARGET_XML_FILES' in config_target
3146 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3147 output: target + '-gdbstub-xml.c',
3148 input: files(config_target['TARGET_XML_FILES'].split()),
3149 command: [feature_to_c, '@INPUT@'],
3151 arch_srcs += gdbstub_xml
3154 t = target_arch[target_base_arch].apply(config_target, strict: false)
3155 arch_srcs += t.sources()
3156 arch_deps += t.dependencies()
3158 target_common = common_ss.apply(config_target, strict: false)
3159 objects = common_all.extract_objects(target_common.sources())
3160 deps = target_common.dependencies()
3162 target_specific = specific_ss.apply(config_target, strict: false)
3163 arch_srcs += target_specific.sources()
3164 arch_deps += target_specific.dependencies()
3166 lib = static_library('qemu-' + target,
3167 sources: arch_srcs + genh,
3168 dependencies: arch_deps,
3170 include_directories: target_inc,
3172 build_by_default: false,
3175 if target.endswith('-softmmu')
3177 'name': 'qemu-system-' + target_name,
3178 'win_subsystem': 'console',
3179 'sources': files('softmmu/main.c'),
3182 if targetos == 'windows' and (sdl.found() or gtk.found())
3184 'name': 'qemu-system-' + target_name + 'w',
3185 'win_subsystem': 'windows',
3186 'sources': files('softmmu/main.c'),
3190 if get_option('fuzzing')
3191 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3193 'name': 'qemu-fuzz-' + target_name,
3194 'win_subsystem': 'console',
3195 'sources': specific_fuzz.sources(),
3196 'dependencies': specific_fuzz.dependencies(),
3201 'name': 'qemu-' + target_name,
3202 'win_subsystem': 'console',
3208 exe_name = exe['name']
3209 if targetos == 'darwin'
3210 exe_name += '-unsigned'
3213 emulator = executable(exe_name, exe['sources'],
3216 dependencies: arch_deps + deps + exe['dependencies'],
3217 objects: lib.extract_all_objects(recursive: true),
3218 link_language: link_language,
3219 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3220 link_args: link_args,
3221 win_subsystem: exe['win_subsystem'])
3223 if targetos == 'darwin'
3224 icon = 'pc-bios/qemu.rsrc'
3225 build_input = [emulator, files(icon)]
3227 get_option('bindir') / exe_name,
3228 meson.current_source_dir() / icon
3230 if 'CONFIG_HVF' in config_target
3231 entitlements = 'accel/hvf/entitlements.plist'
3232 build_input += files(entitlements)
3233 install_input += meson.current_source_dir() / entitlements
3236 entitlement = find_program('scripts/entitlement.sh')
3237 emulators += {exe['name'] : custom_target(exe['name'],
3239 output: exe['name'],
3240 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3243 meson.add_install_script(entitlement, '--install',
3244 get_option('bindir') / exe['name'],
3247 emulators += {exe['name']: emulator}
3252 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3253 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3254 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3255 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3257 custom_target(exe['name'] + stp['ext'],
3258 input: trace_events_all,
3259 output: exe['name'] + stp['ext'],
3260 install: stp['install'],
3261 install_dir: get_option('datadir') / 'systemtap/tapset',
3263 tracetool, '--group=all', '--format=' + stp['fmt'],
3264 '--binary=' + stp['bin'],
3265 '--target-name=' + target_name,
3266 '--target-type=' + target_type,
3267 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3268 '@INPUT@', '@OUTPUT@'
3270 depend_files: tracetool_depends)
3276 # Other build targets
3278 if 'CONFIG_PLUGIN' in config_host
3279 install_headers('include/qemu/qemu-plugin.h')
3284 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3285 # when we don't build tools or system
3286 if xkbcommon.found()
3287 # used for the update-keymaps target, so include rules even if !have_tools
3288 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3289 dependencies: [qemuutil, xkbcommon], install: have_tools)
3293 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3294 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3295 qemu_io = executable('qemu-io', files('qemu-io.c'),
3296 dependencies: [block, qemuutil], install: true)
3297 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3298 dependencies: [blockdev, qemuutil, gnutls, selinux],
3301 subdir('storage-daemon')
3302 subdir('contrib/rdmacm-mux')
3303 subdir('contrib/elf2dmp')
3305 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3306 dependencies: qemuutil,
3309 if 'CONFIG_VHOST_USER' in config_host
3310 subdir('contrib/vhost-user-blk')
3311 subdir('contrib/vhost-user-gpu')
3312 subdir('contrib/vhost-user-input')
3313 subdir('contrib/vhost-user-scsi')
3316 if targetos == 'linux'
3317 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3318 dependencies: [qemuutil, libcap_ng],
3320 install_dir: get_option('libexecdir'))
3322 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3323 dependencies: [authz, crypto, io, qom, qemuutil,
3324 libcap_ng, mpathpersist],
3329 subdir('contrib/ivshmem-client')
3330 subdir('contrib/ivshmem-server')
3343 if host_machine.system() == 'windows'
3345 find_program('scripts/nsis.py'),
3347 get_option('prefix'),
3348 meson.current_source_dir(),
3351 '-DDISPLAYVERSION=' + meson.project_version(),
3354 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3357 nsis_cmd += '-DCONFIG_GTK=y'
3360 nsis = custom_target('nsis',
3361 output: 'qemu-setup-' + meson.project_version() + '.exe',
3362 input: files('qemu.nsi'),
3363 build_always_stale: true,
3364 command: nsis_cmd + ['@INPUT@'])
3365 alias_target('installer', nsis)
3368 #########################
3369 # Configuration summary #
3370 #########################
3374 summary_info += {'Install prefix': get_option('prefix')}
3375 summary_info += {'BIOS directory': qemu_datadir}
3376 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
3377 summary_info += {'binary directory': get_option('bindir')}
3378 summary_info += {'library directory': get_option('libdir')}
3379 summary_info += {'module directory': qemu_moddir}
3380 summary_info += {'libexec directory': get_option('libexecdir')}
3381 summary_info += {'include directory': get_option('includedir')}
3382 summary_info += {'config directory': get_option('sysconfdir')}
3383 if targetos != 'windows'
3384 summary_info += {'local state directory': get_option('localstatedir')}
3385 summary_info += {'Manual directory': get_option('mandir')}
3387 summary_info += {'local state directory': 'queried at runtime'}
3389 summary_info += {'Doc directory': get_option('docdir')}
3390 summary_info += {'Build directory': meson.current_build_dir()}
3391 summary_info += {'Source path': meson.current_source_dir()}
3392 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3393 summary(summary_info, bool_yn: true, section: 'Directories')
3397 summary_info += {'git': config_host['GIT']}
3398 summary_info += {'make': config_host['MAKE']}
3399 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3400 summary_info += {'sphinx-build': sphinx_build}
3401 if config_host.has_key('HAVE_GDB_BIN')
3402 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3404 if get_option('iasl') != ''
3405 summary_info += {'iasl': get_option('iasl')}
3407 summary_info += {'iasl': false}
3409 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3410 if targetos == 'windows' and have_ga
3411 summary_info += {'wixl': wixl}
3413 if slirp_opt != 'disabled' and have_system
3414 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
3416 summary(summary_info, bool_yn: true, section: 'Host binaries')
3418 # Configurable features
3420 summary_info += {'Documentation': build_docs}
3421 summary_info += {'system-mode emulation': have_system}
3422 summary_info += {'user-mode emulation': have_user}
3423 summary_info += {'block layer': have_block}
3424 summary_info += {'Install blobs': get_option('install_blobs')}
3425 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3426 if config_host.has_key('CONFIG_MODULES')
3427 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
3429 summary_info += {'fuzzing support': get_option('fuzzing')}
3431 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3433 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3434 if 'simple' in get_option('trace_backends')
3435 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3437 summary_info += {'D-Bus display': dbus_display}
3438 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
3439 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
3440 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
3441 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
3442 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
3443 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
3444 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
3445 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3446 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
3447 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
3448 summary_info += {'build guest agent': have_ga}
3449 summary(summary_info, bool_yn: true, section: 'Configurable features')
3451 # Compilation information
3453 summary_info += {'host CPU': cpu}
3454 summary_info += {'host endianness': build_machine.endian()}
3455 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3456 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3457 if link_language == 'cpp'
3458 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3460 summary_info += {'C++ compiler': false}
3462 if targetos == 'darwin'
3463 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3465 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3466 + ['-O' + get_option('optimization')]
3467 + (get_option('debug') ? ['-g'] : []))}
3468 if link_language == 'cpp'
3469 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3470 + ['-O' + get_option('optimization')]
3471 + (get_option('debug') ? ['-g'] : []))}
3473 link_args = get_option(link_language + '_link_args')
3474 if link_args.length() > 0
3475 summary_info += {'LDFLAGS': ' '.join(link_args)}
3477 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
3478 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
3479 summary_info += {'profiler': get_option('profiler')}
3480 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3481 summary_info += {'PIE': get_option('b_pie')}
3482 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3483 summary_info += {'malloc trim support': has_malloc_trim}
3484 summary_info += {'membarrier': have_membarrier}
3485 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
3486 summary_info += {'mutex debugging': get_option('debug_mutex')}
3487 summary_info += {'memory allocator': get_option('malloc')}
3488 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
3489 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
3490 summary_info += {'gprof enabled': get_option('gprof')}
3491 summary_info += {'gcov': get_option('b_coverage')}
3492 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3493 summary_info += {'CFI support': get_option('cfi')}
3494 if get_option('cfi')
3495 summary_info += {'CFI debug support': get_option('cfi_debug')}
3497 summary_info += {'strip binaries': get_option('strip')}
3498 summary_info += {'sparse': sparse}
3499 summary_info += {'mingw32 support': targetos == 'windows'}
3501 # snarf the cross-compilation information for tests
3502 foreach target: target_dirs
3503 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3504 if fs.exists(tcg_mak)
3505 config_cross_tcg = keyval.load(tcg_mak)
3506 target = config_cross_tcg['TARGET_NAME']
3508 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3509 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3510 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3511 elif 'CROSS_CC_GUEST' in config_cross_tcg
3512 summary_info += {target + ' tests'
3513 : config_cross_tcg['CROSS_CC_GUEST'] }
3518 summary(summary_info, bool_yn: true, section: 'Compilation')
3520 # Targets and accelerators
3523 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3524 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3525 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3526 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3527 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3528 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
3529 if config_host.has_key('CONFIG_XEN_BACKEND')
3530 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
3533 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3534 if config_all.has_key('CONFIG_TCG')
3535 if get_option('tcg_interpreter')
3536 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
3538 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3540 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3541 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3543 summary_info += {'target list': ' '.join(target_dirs)}
3545 summary_info += {'default devices': get_option('default_devices')}
3546 summary_info += {'out of process emulation': multiprocess_allowed}
3548 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3552 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3553 summary_info += {'coroutine pool': have_coroutine_pool}
3555 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3556 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3557 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
3558 summary_info += {'VirtFS support': have_virtfs}
3559 summary_info += {'build virtiofs daemon': have_virtiofsd}
3560 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
3561 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
3562 summary_info += {'bochs support': get_option('bochs').allowed()}
3563 summary_info += {'cloop support': get_option('cloop').allowed()}
3564 summary_info += {'dmg support': get_option('dmg').allowed()}
3565 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
3566 summary_info += {'vdi support': get_option('vdi').allowed()}
3567 summary_info += {'vvfat support': get_option('vvfat').allowed()}
3568 summary_info += {'qed support': get_option('qed').allowed()}
3569 summary_info += {'parallels support': get_option('parallels').allowed()}
3570 summary_info += {'FUSE exports': fuse}
3572 summary(summary_info, bool_yn: true, section: 'Block layer support')
3576 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
3577 summary_info += {'GNUTLS support': gnutls}
3579 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3581 summary_info += {'libgcrypt': gcrypt}
3582 summary_info += {'nettle': nettle}
3584 summary_info += {' XTS': xts != 'private'}
3586 summary_info += {'AF_ALG support': have_afalg}
3587 summary_info += {'rng-none': get_option('rng_none')}
3588 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
3589 summary(summary_info, bool_yn: true, section: 'Crypto')
3593 if targetos == 'darwin'
3594 summary_info += {'Cocoa support': cocoa}
3596 summary_info += {'SDL support': sdl}
3597 summary_info += {'SDL image support': sdl_image}
3598 summary_info += {'GTK support': gtk}
3599 summary_info += {'pixman': pixman}
3600 summary_info += {'VTE support': vte}
3601 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3602 summary_info += {'libtasn1': tasn1}
3603 summary_info += {'PAM': pam}
3604 summary_info += {'iconv support': iconv}
3605 summary_info += {'curses support': curses}
3606 summary_info += {'virgl support': virgl}
3607 summary_info += {'curl support': curl}
3608 summary_info += {'Multipath support': mpathpersist}
3609 summary_info += {'VNC support': vnc}
3611 summary_info += {'VNC SASL support': sasl}
3612 summary_info += {'VNC JPEG support': jpeg}
3613 summary_info += {'VNC PNG support': png}
3615 if targetos not in ['darwin', 'haiku', 'windows']
3616 summary_info += {'OSS support': oss}
3617 elif targetos == 'darwin'
3618 summary_info += {'CoreAudio support': coreaudio}
3619 elif targetos == 'windows'
3620 summary_info += {'DirectSound support': dsound}
3622 if targetos == 'linux'
3623 summary_info += {'ALSA support': alsa}
3624 summary_info += {'PulseAudio support': pulse}
3626 summary_info += {'JACK support': jack}
3627 summary_info += {'brlapi support': brlapi}
3628 summary_info += {'vde support': vde}
3629 summary_info += {'netmap support': have_netmap}
3630 summary_info += {'l2tpv3 support': have_l2tpv3}
3631 summary_info += {'Linux AIO support': libaio}
3632 summary_info += {'Linux io_uring support': linux_io_uring}
3633 summary_info += {'ATTR/XATTR support': libattr}
3634 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
3635 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
3636 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3637 summary_info += {'libcap-ng support': libcap_ng}
3638 summary_info += {'bpf support': libbpf}
3639 summary_info += {'spice protocol support': spice_protocol}
3640 if spice_protocol.found()
3641 summary_info += {' spice server support': spice}
3643 summary_info += {'rbd support': rbd}
3644 summary_info += {'smartcard support': cacard}
3645 summary_info += {'U2F support': u2f}
3646 summary_info += {'libusb': libusb}
3647 summary_info += {'usb net redir': usbredir}
3648 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
3649 summary_info += {'GBM': gbm}
3650 summary_info += {'libiscsi support': libiscsi}
3651 summary_info += {'libnfs support': libnfs}
3652 if targetos == 'windows'
3654 summary_info += {'QGA VSS support': have_qga_vss}
3655 summary_info += {'QGA w32 disk info': have_ntddscsi}
3658 summary_info += {'seccomp support': seccomp}
3659 summary_info += {'GlusterFS support': glusterfs}
3660 summary_info += {'TPM support': have_tpm}
3661 summary_info += {'libssh support': libssh}
3662 summary_info += {'lzo support': lzo}
3663 summary_info += {'snappy support': snappy}
3664 summary_info += {'bzip2 support': libbzip2}
3665 summary_info += {'lzfse support': liblzfse}
3666 summary_info += {'zstd support': zstd}
3667 summary_info += {'NUMA host support': numa}
3668 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3669 summary_info += {'libpmem support': libpmem}
3670 summary_info += {'libdaxctl support': libdaxctl}
3671 summary_info += {'libudev': libudev}
3672 # Dummy dependency, keep .found()
3673 summary_info += {'FUSE lseek': fuse_lseek.found()}
3674 summary_info += {'selinux': selinux}
3675 summary(summary_info, bool_yn: true, section: 'Dependencies')
3677 if not supported_cpus.contains(cpu)
3679 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3681 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3682 message('The QEMU project intends to remove support for this host CPU in')
3683 message('a future release if nobody volunteers to maintain it and to')
3684 message('provide a build host for our continuous integration setup.')
3685 message('configure has succeeded and you can continue to build, but')
3686 message('if you care about QEMU on this platform you should contact')
3687 message('us upstream at qemu-devel@nongnu.org.')
3690 if not supported_oses.contains(targetos)
3692 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3694 message('Host OS ' + targetos + 'support is not currently maintained.')
3695 message('The QEMU project intends to remove support for this host OS in')
3696 message('a future release if nobody volunteers to maintain it and to')
3697 message('provide a build host for our continuous integration setup.')
3698 message('configure has succeeded and you can continue to build, but')
3699 message('if you care about QEMU on this platform you should contact')
3700 message('us upstream at qemu-devel@nongnu.org.')