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 target_dirs = config_host['TARGET_DIRS'].split()
48 have_linux_user = false
51 foreach target : target_dirs
52 have_linux_user = have_linux_user or target.endswith('linux-user')
53 have_bsd_user = have_bsd_user or target.endswith('bsd-user')
54 have_system = have_system or target.endswith('-softmmu')
56 have_user = have_linux_user or have_bsd_user
57 have_tools = 'CONFIG_TOOLS' in config_host
58 have_block = have_system or have_tools
60 python = import('python').find_installation()
62 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
63 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
64 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc', 'sparc64']
66 cpu = host_machine.cpu_family()
68 # Unify riscv* to a single family.
69 if cpu in ['riscv32', 'riscv64']
73 targetos = host_machine.system()
75 if cpu not in supported_cpus
85 if cpu in ['x86', 'x86_64']
86 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
88 kvm_targets = ['aarch64-softmmu']
90 kvm_targets = ['s390x-softmmu']
91 elif cpu in ['ppc', 'ppc64']
92 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
93 elif cpu in ['mips', 'mips64']
94 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
96 kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
102 if get_option('kvm').allowed() and targetos == 'linux'
103 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
105 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
107 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
109 if cpu in ['aarch64']
110 accelerator_targets += {
111 'CONFIG_HVF': ['aarch64-softmmu']
115 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
116 # i386 emulator provides xenpv machine type for multiple architectures
117 accelerator_targets += {
118 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
121 if cpu in ['x86', 'x86_64']
122 accelerator_targets += {
123 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
124 'CONFIG_HVF': ['x86_64-softmmu'],
125 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
126 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
131 # Darwin does not support references to thread-local variables in modules
132 if targetos != 'darwin'
133 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
136 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
137 unpack_edk2_blobs = false
138 foreach target : edk2_targets
139 if target in target_dirs
140 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
141 unpack_edk2_blobs = bzip2.found()
148 if 'dtrace' in get_option('trace_backends')
149 dtrace = find_program('dtrace', required: true)
150 stap = find_program('stap', required: false)
152 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
153 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
154 # instead. QEMU --enable-modules depends on this because the SystemTap
155 # semaphores are linked into the main binary and not the module's shared
157 add_global_arguments('-DSTAP_SDT_V2',
158 native: false, language: ['c', 'cpp', 'objc'])
166 qemu_cflags = config_host['QEMU_CFLAGS'].split()
167 qemu_cxxflags = config_host['QEMU_CXXFLAGS'].split()
168 qemu_ldflags = config_host['QEMU_LDFLAGS'].split()
170 if get_option('gprof')
171 qemu_cflags += ['-p']
172 qemu_cxxflags += ['-p']
173 qemu_ldflags += ['-p']
176 # Specify linker-script with add_project_link_arguments so that it is not placed
177 # within a linker --start-group/--end-group pair
178 if get_option('fuzzing')
179 add_project_link_arguments(['-Wl,-T,',
180 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
181 native: false, language: ['c', 'cpp', 'objc'])
183 # Specify a filter to only instrument code that is directly related to
185 configure_file(output: 'instrumentation-filter',
186 input: 'scripts/oss-fuzz/instrumentation-filter-template',
188 add_global_arguments(
189 cc.get_supported_arguments('-fsanitize-coverage-allowlist=instrumentation-filter'),
190 native: false, language: ['c', 'cpp', 'objc'])
192 if get_option('fuzzing_engine') == ''
193 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
194 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
195 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
196 # unable to bind the fuzzer-related callbacks added by instrumentation.
197 add_global_arguments('-fsanitize=fuzzer-no-link',
198 native: false, language: ['c', 'cpp', 'objc'])
199 add_global_link_arguments('-fsanitize=fuzzer-no-link',
200 native: false, language: ['c', 'cpp', 'objc'])
201 # For the actual fuzzer binaries, we need to link against the libfuzzer
202 # library. They need to be configurable, to support OSS-Fuzz
203 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
205 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
206 # the needed CFLAGS have already been provided
207 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
211 add_global_arguments(qemu_cflags, native: false, language: ['c', 'objc'])
212 add_global_arguments(qemu_cxxflags, native: false, language: ['cpp'])
213 add_global_link_arguments(qemu_ldflags, native: false, language: ['c', 'cpp', 'objc'])
215 if targetos == 'linux'
216 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
217 '-isystem', 'linux-headers',
218 language: ['c', 'cpp'])
221 add_project_arguments('-iquote', '.',
222 '-iquote', meson.current_source_dir(),
223 '-iquote', meson.current_source_dir() / 'include',
224 '-iquote', meson.current_source_dir() / 'disas/libvixl',
225 language: ['c', 'cpp', 'objc'])
227 link_language = meson.get_external_property('link_language', 'cpp')
228 if link_language == 'cpp'
229 add_languages('cpp', required: true, native: false)
230 cxx = meson.get_compiler('cpp')
235 if host_machine.system() == 'darwin'
236 add_languages('objc', required: false, native: false)
239 sparse = find_program('cgcc', required: get_option('sparse'))
242 command: [find_program('scripts/check_sparse.py'),
243 'compile_commands.json', sparse.full_path(), '-Wbitwise',
244 '-Wno-transparent-union', '-Wno-old-initializer',
245 '-Wno-non-pointer-null'])
248 ###########################################
249 # Target-specific checks and dependencies #
250 ###########################################
253 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
256 #include <sys/types.h>
257 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
258 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
260 args: ['-Werror', '-fsanitize=fuzzer'])
261 error('Your compiler does not support -fsanitize=fuzzer')
265 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
266 error('ftrace is supported only on Linux')
268 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
271 openlog("qemu", LOG_PID, LOG_DAEMON);
272 syslog(LOG_INFO, "configure");
275 error('syslog is not supported on this system')
278 # Miscellaneous Linux-only features
279 get_option('mpath') \
280 .require(targetos == 'linux', error_message: 'Multipath is supported only on Linux')
282 multiprocess_allowed = get_option('multiprocess') \
283 .require(targetos == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
286 have_tpm = get_option('tpm') \
287 .require(targetos != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
290 # Target-specific libraries and flags
291 libm = cc.find_library('m', required: false)
292 threads = dependency('threads')
293 util = cc.find_library('util', required: false)
299 emulator_link_args = []
303 if targetos == 'windows'
304 socket = cc.find_library('ws2_32')
305 winmm = cc.find_library('winmm')
307 win = import('windows')
308 version_res = win.compile_resources('version.rc',
309 depend_files: files('pc-bios/qemu-nsis.ico'),
310 include_directories: include_directories('.'))
312 elif targetos == 'darwin'
313 coref = dependency('appleframeworks', modules: 'CoreFoundation')
314 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
315 host_dsosuf = '.dylib'
316 elif targetos == 'sunos'
317 socket = [cc.find_library('socket'),
318 cc.find_library('nsl'),
319 cc.find_library('resolv')]
320 elif targetos == 'haiku'
321 socket = [cc.find_library('posix_error_mapper'),
322 cc.find_library('network'),
323 cc.find_library('bsd')]
324 elif targetos == 'openbsd'
325 if get_option('tcg').allowed() and target_dirs.length() > 0
326 # Disable OpenBSD W^X if available
327 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
331 # Target-specific configuration of accelerators
333 if get_option('kvm').allowed() and targetos == 'linux'
334 accelerators += 'CONFIG_KVM'
336 if get_option('xen').allowed() and 'CONFIG_XEN_BACKEND' in config_host
337 accelerators += 'CONFIG_XEN'
338 have_xen_pci_passthrough = get_option('xen_pci_passthrough').allowed() and targetos == 'linux'
340 have_xen_pci_passthrough = false
342 if get_option('whpx').allowed() and targetos == 'windows'
343 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
344 error('WHPX requires 64-bit host')
345 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
346 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
347 accelerators += 'CONFIG_WHPX'
350 if get_option('hvf').allowed()
351 hvf = dependency('appleframeworks', modules: 'Hypervisor',
352 required: get_option('hvf'))
354 accelerators += 'CONFIG_HVF'
357 if get_option('hax').allowed()
358 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
359 accelerators += 'CONFIG_HAX'
362 if targetos == 'netbsd'
363 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
365 accelerators += 'CONFIG_NVMM'
370 if get_option('tcg').allowed()
371 if host_arch == 'unknown'
372 if get_option('tcg_interpreter')
373 warning('Unsupported CPU @0@, will use TCG with TCI (slow)'.format(cpu))
375 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
377 elif get_option('tcg_interpreter')
378 warning('Use of the TCG interpreter is not recommended on this host')
379 warning('architecture. There is a native TCG execution backend available')
380 warning('which provides substantially better performance and reliability.')
381 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
382 warning('configuration option on this architecture to use the native')
385 if get_option('tcg_interpreter')
387 elif host_arch == 'sparc64'
389 elif host_arch == 'x86_64'
391 elif host_arch == 'ppc64'
394 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
395 language: ['c', 'cpp', 'objc'])
397 accelerators += 'CONFIG_TCG'
398 config_host += { 'CONFIG_TCG': 'y' }
401 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
402 error('KVM not available on this platform')
404 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
405 error('HVF not available on this platform')
407 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
408 error('NVMM not available on this platform')
410 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
411 error('WHPX not available on this platform')
413 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
414 if 'CONFIG_XEN' in accelerators
415 error('Xen PCI passthrough not available on this platform')
417 error('Xen PCI passthrough requested but Xen not enabled')
425 # The path to glib.h is added to all compilation commands. This was
426 # grandfathered in from the QEMU Makefiles.
427 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
428 native: false, language: ['c', 'cpp', 'objc'])
429 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
430 link_args: config_host['GLIB_LIBS'].split(),
431 version: config_host['GLIB_VERSION'])
432 # override glib dep with the configure results (for subprojects)
433 meson.override_dependency('glib-2.0', glib)
436 if 'CONFIG_GIO' in config_host
437 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
438 link_args: config_host['GIO_LIBS'].split(),
439 version: config_host['GLIB_VERSION'])
442 if 'ust' in get_option('trace_backends')
443 lttng = dependency('lttng-ust', required: true, method: 'pkg-config',
444 kwargs: static_kwargs)
447 if have_system or have_tools
448 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
449 method: 'pkg-config', kwargs: static_kwargs)
451 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
454 if not get_option('linux_aio').auto() or have_block
455 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
456 required: get_option('linux_aio'),
457 kwargs: static_kwargs)
459 linux_io_uring = not_found
460 if not get_option('linux_io_uring').auto() or have_block
461 linux_io_uring = dependency('liburing', version: '>=0.3',
462 required: get_option('linux_io_uring'),
463 method: 'pkg-config', kwargs: static_kwargs)
466 if not get_option('libnfs').auto() or have_block
467 libnfs = dependency('libnfs', version: '>=1.9.3',
468 required: get_option('libnfs'),
469 method: 'pkg-config', kwargs: static_kwargs)
474 #include <sys/types.h>
475 #ifdef CONFIG_LIBATTR
476 #include <attr/xattr.h>
478 #include <sys/xattr.h>
480 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
483 have_old_libattr = false
484 if get_option('attr').allowed()
485 if cc.links(libattr_test)
486 libattr = declare_dependency()
488 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
489 required: get_option('attr'),
490 kwargs: static_kwargs)
491 if libattr.found() and not \
492 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
494 if get_option('attr').enabled()
495 error('could not link libattr')
497 warning('could not link libattr, disabling')
500 have_old_libattr = libattr.found()
505 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
506 if cocoa.found() and get_option('sdl').enabled()
507 error('Cocoa and SDL cannot be enabled at the same time')
509 if cocoa.found() and get_option('gtk').enabled()
510 error('Cocoa and GTK+ cannot be enabled at the same time')
514 if not get_option('seccomp').auto() or have_system or have_tools
515 seccomp = dependency('libseccomp', version: '>=2.3.0',
516 required: get_option('seccomp'),
517 method: 'pkg-config', kwargs: static_kwargs)
520 libcap_ng = not_found
521 if not get_option('cap_ng').auto() or have_system or have_tools
522 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
523 required: get_option('cap_ng'),
524 kwargs: static_kwargs)
526 if libcap_ng.found() and not cc.links('''
530 capng_capability_to_name(CAPNG_EFFECTIVE);
532 }''', dependencies: libcap_ng)
533 libcap_ng = not_found
534 if get_option('cap_ng').enabled()
535 error('could not link libcap-ng')
537 warning('could not link libcap-ng, disabling')
541 if get_option('xkbcommon').auto() and not have_system and not have_tools
542 xkbcommon = not_found
544 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
545 method: 'pkg-config', kwargs: static_kwargs)
549 if not get_option('vde').auto() or have_system or have_tools
550 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
551 required: get_option('vde'),
552 kwargs: static_kwargs)
554 if vde.found() and not cc.links('''
555 #include <libvdeplug.h>
558 struct vde_open_args a = {0, 0, 0};
562 }''', dependencies: vde)
564 if get_option('cap_ng').enabled()
565 error('could not link libvdeplug')
567 warning('could not link libvdeplug, disabling')
572 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
573 pulse = dependency('libpulse', required: get_option('pa'),
574 method: 'pkg-config', kwargs: static_kwargs)
577 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
578 alsa = dependency('alsa', required: get_option('alsa'),
579 method: 'pkg-config', kwargs: static_kwargs)
582 if not get_option('jack').auto() or have_system
583 jack = dependency('jack', required: get_option('jack'),
584 method: 'pkg-config', kwargs: static_kwargs)
587 spice_protocol = not_found
588 if not get_option('spice_protocol').auto() or have_system
589 spice_protocol = dependency('spice-protocol', version: '>=0.12.3',
590 required: get_option('spice_protocol'),
591 method: 'pkg-config', kwargs: static_kwargs)
594 if not get_option('spice').auto() or have_system
595 spice = dependency('spice-server', version: '>=0.12.5',
596 required: get_option('spice'),
597 method: 'pkg-config', kwargs: static_kwargs)
599 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
601 rt = cc.find_library('rt', required: false)
604 if not get_option('libiscsi').auto() or have_block
605 libiscsi = dependency('libiscsi', version: '>=1.9.0',
606 required: get_option('libiscsi'),
607 method: 'pkg-config', kwargs: static_kwargs)
610 if not get_option('zstd').auto() or have_block
611 zstd = dependency('libzstd', version: '>=1.4.0',
612 required: get_option('zstd'),
613 method: 'pkg-config', kwargs: static_kwargs)
616 if not get_option('virglrenderer').auto() or have_system
617 virgl = dependency('virglrenderer',
618 method: 'pkg-config',
619 required: get_option('virglrenderer'),
620 kwargs: static_kwargs)
623 if not get_option('curl').auto() or have_block
624 curl = dependency('libcurl', version: '>=7.29.0',
625 method: 'pkg-config',
626 required: get_option('curl'),
627 kwargs: static_kwargs)
630 if targetos == 'linux' and (have_system or have_tools)
631 libudev = dependency('libudev',
632 method: 'pkg-config',
633 required: get_option('libudev'),
634 kwargs: static_kwargs)
637 mpathlibs = [libudev]
638 mpathpersist = not_found
639 mpathpersist_new_api = false
640 if targetos == 'linux' and have_tools and get_option('mpath').allowed()
641 mpath_test_source_new = '''
643 #include <mpath_persist.h>
644 unsigned mpath_mx_alloc_len = 1024;
646 static struct config *multipath_conf;
647 extern struct udev *udev;
648 extern struct config *get_multipath_config(void);
649 extern void put_multipath_config(struct config *conf);
651 struct config *get_multipath_config(void) { return multipath_conf; }
652 void put_multipath_config(struct config *conf) { }
655 multipath_conf = mpath_lib_init();
658 mpath_test_source_old = '''
660 #include <mpath_persist.h>
661 unsigned mpath_mx_alloc_len = 1024;
664 struct udev *udev = udev_new();
665 mpath_lib_init(udev);
668 libmpathpersist = cc.find_library('mpathpersist',
669 required: get_option('mpath'),
670 kwargs: static_kwargs)
671 if libmpathpersist.found()
672 mpathlibs += libmpathpersist
674 mpathlibs += cc.find_library('devmapper',
675 required: get_option('mpath'),
676 kwargs: static_kwargs)
678 mpathlibs += cc.find_library('multipath',
679 required: get_option('mpath'),
680 kwargs: static_kwargs)
681 foreach lib: mpathlibs
687 if mpathlibs.length() == 0
688 msg = 'Dependencies missing for libmpathpersist'
689 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
690 mpathpersist = declare_dependency(dependencies: mpathlibs)
691 mpathpersist_new_api = true
692 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
693 mpathpersist = declare_dependency(dependencies: mpathlibs)
695 msg = 'Cannot detect libmpathpersist API'
697 if not mpathpersist.found()
698 if get_option('mpath').enabled()
701 warning(msg + ', disabling')
709 if have_system and get_option('curses').allowed()
711 #if defined(__APPLE__) || defined(__OpenBSD__)
712 #define _XOPEN_SOURCE_EXTENDED 1
719 setlocale(LC_ALL, "");
721 addwstr(L"wide chars\n");
723 add_wch(WACS_DEGREE);
727 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
728 foreach curses_dep : curses_dep_list
729 if not curses.found()
730 curses = dependency(curses_dep,
732 method: 'pkg-config',
733 kwargs: static_kwargs)
736 msg = get_option('curses').enabled() ? 'curses library not found' : ''
737 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
739 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
740 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
742 msg = 'curses package not usable'
746 if not curses.found()
747 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
748 if targetos != 'windows' and not has_curses_h
749 message('Trying with /usr/include/ncursesw')
750 curses_compile_args += ['-I/usr/include/ncursesw']
751 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
754 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
755 foreach curses_libname : curses_libname_list
756 libcurses = cc.find_library(curses_libname,
758 kwargs: static_kwargs)
760 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
761 curses = declare_dependency(compile_args: curses_compile_args,
762 dependencies: [libcurses])
765 msg = 'curses library not usable'
771 if get_option('iconv').allowed()
772 foreach link_args : [ ['-liconv'], [] ]
773 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
774 # We need to use libiconv if available because mixing libiconv's headers with
775 # the system libc does not work.
776 # However, without adding glib to the dependencies -L/usr/local/lib will not be
777 # included in the command line and libiconv will not be found.
781 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
782 return conv != (iconv_t) -1;
783 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
784 iconv = declare_dependency(link_args: link_args, dependencies: glib)
789 if curses.found() and not iconv.found()
790 if get_option('iconv').enabled()
791 error('iconv not available')
793 msg = 'iconv required for curses UI but not available'
796 if not curses.found() and msg != ''
797 if get_option('curses').enabled()
800 warning(msg + ', disabling')
806 if not get_option('brlapi').auto() or have_system
807 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
808 required: get_option('brlapi'),
809 kwargs: static_kwargs)
810 if brlapi.found() and not cc.links('''
813 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
815 if get_option('brlapi').enabled()
816 error('could not link brlapi')
818 warning('could not link brlapi, disabling')
824 if not get_option('sdl').auto() or (have_system and not cocoa.found())
825 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
826 sdl_image = not_found
829 # work around 2.0.8 bug
830 sdl = declare_dependency(compile_args: '-Wno-undef',
832 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
833 method: 'pkg-config', kwargs: static_kwargs)
835 if get_option('sdl_image').enabled()
836 error('sdl-image required, but SDL was @0@'.format(
837 get_option('sdl').disabled() ? 'disabled' : 'not found'))
839 sdl_image = not_found
843 if not get_option('rbd').auto() or have_block
844 librados = cc.find_library('rados', required: get_option('rbd'),
845 kwargs: static_kwargs)
846 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
847 required: get_option('rbd'),
848 kwargs: static_kwargs)
849 if librados.found() and librbd.found()
852 #include <rbd/librbd.h>
855 rados_create(&cluster, NULL);
856 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
860 }''', dependencies: [librbd, librados])
861 rbd = declare_dependency(dependencies: [librbd, librados])
862 elif get_option('rbd').enabled()
863 error('librbd >= 1.12.0 required')
865 warning('librbd >= 1.12.0 not found, disabling')
870 glusterfs = not_found
871 glusterfs_ftruncate_has_stat = false
872 glusterfs_iocb_has_stat = false
873 if not get_option('glusterfs').auto() or have_block
874 glusterfs = dependency('glusterfs-api', version: '>=3',
875 required: get_option('glusterfs'),
876 method: 'pkg-config', kwargs: static_kwargs)
878 glusterfs_ftruncate_has_stat = cc.links('''
879 #include <glusterfs/api/glfs.h>
884 /* new glfs_ftruncate() passes two additional args */
885 return glfs_ftruncate(NULL, 0, NULL, NULL);
887 ''', dependencies: glusterfs)
888 glusterfs_iocb_has_stat = cc.links('''
889 #include <glusterfs/api/glfs.h>
891 /* new glfs_io_cbk() passes two additional glfs_stat structs */
893 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
899 glfs_io_cbk iocb = &glusterfs_iocb;
900 iocb(NULL, 0 , NULL, NULL, NULL);
903 ''', dependencies: glusterfs)
908 if not get_option('libssh').auto() or have_block
909 libssh = dependency('libssh', version: '>=0.8.7',
910 method: 'pkg-config',
911 required: get_option('libssh'),
912 kwargs: static_kwargs)
916 if not get_option('bzip2').auto() or have_block
917 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
918 required: get_option('bzip2'),
919 kwargs: static_kwargs)
920 if libbzip2.found() and not cc.links('''
922 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
924 if get_option('bzip2').enabled()
925 error('could not link libbzip2')
927 warning('could not link libbzip2, disabling')
933 if not get_option('lzfse').auto() or have_block
934 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
935 required: get_option('lzfse'),
936 kwargs: static_kwargs)
938 if liblzfse.found() and not cc.links('''
940 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
942 if get_option('lzfse').enabled()
943 error('could not link liblzfse')
945 warning('could not link liblzfse, disabling')
950 if get_option('oss').allowed() and have_system
951 if not cc.has_header('sys/soundcard.h')
953 elif targetos == 'netbsd'
954 oss = cc.find_library('ossaudio', required: get_option('oss'),
955 kwargs: static_kwargs)
957 oss = declare_dependency()
961 if get_option('oss').enabled()
962 error('OSS not found')
967 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
968 if cc.has_header('dsound.h')
969 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
972 if not dsound.found()
973 if get_option('dsound').enabled()
974 error('DirectSound not found')
979 coreaudio = not_found
980 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
981 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
982 required: get_option('coreaudio'))
986 if 'CONFIG_OPENGL' in config_host
987 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
988 link_args: config_host['OPENGL_LIBS'].split())
991 if (have_system or have_tools) and (virgl.found() or opengl.found())
992 gbm = dependency('gbm', method: 'pkg-config', required: false,
993 kwargs: static_kwargs)
997 gnutls_crypto = not_found
998 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
999 # For general TLS support our min gnutls matches
1000 # that implied by our platform support matrix
1002 # For the crypto backends, we look for a newer
1005 # Version 3.6.8 is needed to get XTS
1006 # Version 3.6.13 is needed to get PBKDF
1007 # Version 3.6.14 is needed to get HW accelerated XTS
1009 # If newer enough gnutls isn't available, we can
1010 # still use a different crypto backend to satisfy
1011 # the platform support requirements
1012 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1013 method: 'pkg-config',
1015 kwargs: static_kwargs)
1016 if gnutls_crypto.found()
1017 gnutls = gnutls_crypto
1019 # Our min version if all we need is TLS
1020 gnutls = dependency('gnutls', version: '>=3.5.18',
1021 method: 'pkg-config',
1022 required: get_option('gnutls'),
1023 kwargs: static_kwargs)
1027 # We prefer use of gnutls for crypto, unless the options
1028 # explicitly asked for nettle or gcrypt.
1030 # If gnutls isn't available for crypto, then we'll prefer
1031 # gcrypt over nettle for performance reasons.
1036 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1037 error('Only one of gcrypt & nettle can be enabled')
1040 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1041 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1042 gnutls_crypto = not_found
1045 if not gnutls_crypto.found()
1046 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1047 gcrypt = dependency('libgcrypt', version: '>=1.8',
1048 method: 'config-tool',
1049 required: get_option('gcrypt'),
1050 kwargs: static_kwargs)
1051 # Debian has removed -lgpg-error from libgcrypt-config
1052 # as it "spreads unnecessary dependencies" which in
1053 # turn breaks static builds...
1054 if gcrypt.found() and enable_static
1055 gcrypt = declare_dependency(dependencies: [
1057 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
1060 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1061 nettle = dependency('nettle', version: '>=3.4',
1062 method: 'pkg-config',
1063 required: get_option('nettle'),
1064 kwargs: static_kwargs)
1065 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1074 if not get_option('gtk').auto() or (have_system and not cocoa.found())
1075 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1076 method: 'pkg-config',
1077 required: get_option('gtk'),
1078 kwargs: static_kwargs)
1080 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1081 method: 'pkg-config',
1083 kwargs: static_kwargs)
1084 gtk = declare_dependency(dependencies: [gtk, gtkx11])
1086 if not get_option('vte').auto() or have_system
1087 vte = dependency('vte-2.91',
1088 method: 'pkg-config',
1089 required: get_option('vte'),
1090 kwargs: static_kwargs)
1097 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
1098 kwargs: static_kwargs)
1104 if get_option('vnc').allowed() and have_system
1105 vnc = declare_dependency() # dummy dependency
1106 png = dependency('libpng', required: get_option('vnc_png'),
1107 method: 'pkg-config', kwargs: static_kwargs)
1108 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1109 method: 'pkg-config', kwargs: static_kwargs)
1110 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1111 required: get_option('vnc_sasl'),
1112 kwargs: static_kwargs)
1114 sasl = declare_dependency(dependencies: sasl,
1115 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1120 if not get_option('auth_pam').auto() or have_system
1121 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1122 required: get_option('auth_pam'),
1123 kwargs: static_kwargs)
1125 if pam.found() and not cc.links('''
1127 #include <security/pam_appl.h>
1129 const char *service_name = "qemu";
1130 const char *user = "frank";
1131 const struct pam_conv pam_conv = { 0 };
1132 pam_handle_t *pamh = NULL;
1133 pam_start(service_name, user, &pam_conv, &pamh);
1135 }''', dependencies: pam)
1137 if get_option('auth_pam').enabled()
1138 error('could not link libpam')
1140 warning('could not link libpam, disabling')
1145 if not get_option('snappy').auto() or have_system
1146 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1147 required: get_option('snappy'),
1148 kwargs: static_kwargs)
1150 if snappy.found() and not linker.links('''
1151 #include <snappy-c.h>
1152 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1154 if get_option('snappy').enabled()
1155 error('could not link libsnappy')
1157 warning('could not link libsnappy, disabling')
1162 if not get_option('lzo').auto() or have_system
1163 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1164 required: get_option('lzo'),
1165 kwargs: static_kwargs)
1167 if lzo.found() and not cc.links('''
1168 #include <lzo/lzo1x.h>
1169 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1171 if get_option('lzo').enabled()
1172 error('could not link liblzo2')
1174 warning('could not link liblzo2, disabling')
1179 if not get_option('numa').auto() or have_system or have_tools
1180 numa = cc.find_library('numa', has_headers: ['numa.h'],
1181 required: get_option('numa'),
1182 kwargs: static_kwargs)
1184 if numa.found() and not cc.links('''
1186 int main(void) { return numa_available(); }
1187 ''', dependencies: numa)
1189 if get_option('numa').enabled()
1190 error('could not link numa')
1192 warning('could not link numa, disabling')
1197 if 'CONFIG_RDMA' in config_host
1198 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
1201 if 'CONFIG_XEN_BACKEND' in config_host
1202 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
1203 link_args: config_host['XEN_LIBS'].split())
1206 if not get_option('smartcard').auto() or have_system
1207 cacard = dependency('libcacard', required: get_option('smartcard'),
1208 version: '>=2.5.1', method: 'pkg-config',
1209 kwargs: static_kwargs)
1213 u2f = dependency('u2f-emu', required: get_option('u2f'),
1214 method: 'pkg-config',
1215 kwargs: static_kwargs)
1217 usbredir = not_found
1218 if not get_option('usb_redir').auto() or have_system
1219 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1220 version: '>=0.6', method: 'pkg-config',
1221 kwargs: static_kwargs)
1224 if not get_option('libusb').auto() or have_system
1225 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1226 version: '>=1.0.13', method: 'pkg-config',
1227 kwargs: static_kwargs)
1231 if not get_option('libpmem').auto() or have_system
1232 libpmem = dependency('libpmem', required: get_option('libpmem'),
1233 method: 'pkg-config', kwargs: static_kwargs)
1235 libdaxctl = not_found
1236 if not get_option('libdaxctl').auto() or have_system
1237 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1238 version: '>=57', method: 'pkg-config',
1239 kwargs: static_kwargs)
1243 tasn1 = dependency('libtasn1',
1244 method: 'pkg-config',
1245 kwargs: static_kwargs)
1247 keyutils = dependency('libkeyutils', required: false,
1248 method: 'pkg-config', kwargs: static_kwargs)
1250 has_gettid = cc.has_function('gettid')
1253 selinux = dependency('libselinux',
1254 required: get_option('selinux'),
1255 method: 'pkg-config', kwargs: static_kwargs)
1260 if get_option('malloc') == 'system'
1262 get_option('malloc_trim').allowed() and \
1263 cc.links('''#include <malloc.h>
1264 int main(void) { malloc_trim(0); return 0; }''')
1266 has_malloc_trim = false
1267 malloc = cc.find_library(get_option('malloc'), required: true)
1269 if not has_malloc_trim and get_option('malloc_trim').enabled()
1270 if get_option('malloc') == 'system'
1271 error('malloc_trim not available on this platform.')
1273 error('malloc_trim not available with non-libc memory allocator')
1277 # Check whether the glibc provides statx()
1279 gnu_source_prefix = '''
1284 statx_test = gnu_source_prefix + '''
1285 #include <sys/stat.h>
1287 struct statx statxbuf;
1288 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1292 has_statx = cc.links(statx_test)
1294 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
1295 .require(targetos == 'linux',
1296 error_message: 'vhost_user_blk_server requires linux') \
1297 .require('CONFIG_VHOST_USER' in config_host,
1298 error_message: 'vhost_user_blk_server requires vhost-user support') \
1299 .disable_auto_if(not have_system) \
1302 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1303 error('Cannot enable fuse-lseek while fuse is disabled')
1306 fuse = dependency('fuse3', required: get_option('fuse'),
1307 version: '>=3.1', method: 'pkg-config',
1308 kwargs: static_kwargs)
1310 fuse_lseek = not_found
1311 if get_option('fuse_lseek').allowed()
1312 if fuse.version().version_compare('>=3.8')
1314 fuse_lseek = declare_dependency()
1315 elif get_option('fuse_lseek').enabled()
1317 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1319 error('fuse-lseek requires libfuse, which was not found')
1325 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1326 if libbpf.found() and not cc.links('''
1327 #include <bpf/libbpf.h>
1330 bpf_object__destroy_skeleton(NULL);
1332 }''', dependencies: libbpf)
1334 if get_option('bpf').enabled()
1335 error('libbpf skeleton test failed')
1337 warning('libbpf skeleton test failed, disabling')
1345 audio_drivers_selected = []
1347 audio_drivers_available = {
1348 'alsa': alsa.found(),
1349 'coreaudio': coreaudio.found(),
1350 'dsound': dsound.found(),
1351 'jack': jack.found(),
1353 'pa': pulse.found(),
1356 foreach k, v: audio_drivers_available
1357 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1360 # Default to native drivers first, OSS second, SDL third
1361 audio_drivers_priority = \
1362 [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
1363 (targetos == 'linux' ? [] : [ 'sdl' ])
1364 audio_drivers_default = []
1365 foreach k: audio_drivers_priority
1366 if audio_drivers_available[k]
1367 audio_drivers_default += k
1371 foreach k: get_option('audio_drv_list')
1373 audio_drivers_selected += audio_drivers_default
1374 elif not audio_drivers_available[k]
1375 error('Audio driver "@0@" not available.'.format(k))
1377 audio_drivers_selected += k
1381 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1382 '"' + '", "'.join(audio_drivers_selected) + '", ')
1384 if get_option('cfi')
1386 # Check for dependency on LTO
1387 if not get_option('b_lto')
1388 error('Selected Control-Flow Integrity but LTO is disabled')
1390 if config_host.has_key('CONFIG_MODULES')
1391 error('Selected Control-Flow Integrity is not compatible with modules')
1393 # Check for cfi flags. CFI requires LTO so we can't use
1394 # get_supported_arguments, but need a more complex "compiles" which allows
1396 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1397 args: ['-flto', '-fsanitize=cfi-icall'] )
1398 cfi_flags += '-fsanitize=cfi-icall'
1400 error('-fsanitize=cfi-icall is not supported by the compiler')
1402 if cc.compiles('int main () { return 0; }',
1403 name: '-fsanitize-cfi-icall-generalize-pointers',
1404 args: ['-flto', '-fsanitize=cfi-icall',
1405 '-fsanitize-cfi-icall-generalize-pointers'] )
1406 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1408 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1410 if get_option('cfi_debug')
1411 if cc.compiles('int main () { return 0; }',
1412 name: '-fno-sanitize-trap=cfi-icall',
1413 args: ['-flto', '-fsanitize=cfi-icall',
1414 '-fno-sanitize-trap=cfi-icall'] )
1415 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1417 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1420 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1421 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1424 have_host_block_device = (targetos != 'darwin' or
1425 cc.has_header('IOKit/storage/IOMedia.h'))
1427 # FIXME enable_modules shouldn't be necessary, but: https://github.com/mesonbuild/meson/issues/8333
1428 dbus_display = get_option('dbus_display') \
1429 .require(gio.version().version_compare('>=2.64'),
1430 error_message: '-display dbus requires glib>=2.64') \
1431 .require(enable_modules,
1432 error_message: '-display dbus requires --enable-modules') \
1433 .require(config_host.has_key('GDBUS_CODEGEN'),
1434 error_message: '-display dbus requires gdbus-codegen') \
1437 have_virtfs = get_option('virtfs') \
1438 .require(targetos == 'linux',
1439 error_message: 'virtio-9p (virtfs) requires Linux') \
1440 .require(libattr.found() and libcap_ng.found(),
1441 error_message: 'virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel') \
1442 .disable_auto_if(not have_tools and not have_system) \
1445 have_virtfs_proxy_helper = have_virtfs and have_tools
1447 foreach k : get_option('trace_backends')
1448 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1450 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1452 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1453 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1454 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1455 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1456 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1457 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1458 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1459 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1460 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1461 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1462 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1463 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1465 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
1467 config_host_data.set('CONFIG_ATTR', libattr.found())
1468 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
1469 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1470 config_host_data.set('CONFIG_COCOA', cocoa.found())
1471 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1472 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1473 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1474 config_host_data.set('CONFIG_LZO', lzo.found())
1475 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1476 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1477 config_host_data.set('CONFIG_CURL', curl.found())
1478 config_host_data.set('CONFIG_CURSES', curses.found())
1479 config_host_data.set('CONFIG_GBM', gbm.found())
1480 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1481 if glusterfs.found()
1482 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1483 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1484 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1485 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1486 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1487 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1489 config_host_data.set('CONFIG_GTK', gtk.found())
1490 config_host_data.set('CONFIG_VTE', vte.found())
1491 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1492 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1493 config_host_data.set('CONFIG_EBPF', libbpf.found())
1494 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1495 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1496 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1497 config_host_data.set('CONFIG_LIBSSH', libssh.found())
1498 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1499 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1500 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1501 config_host_data.set('CONFIG_NUMA', numa.found())
1502 config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
1503 config_host_data.set('CONFIG_RBD', rbd.found())
1504 config_host_data.set('CONFIG_SDL', sdl.found())
1505 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1506 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1507 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1508 config_host_data.set('CONFIG_TPM', have_tpm)
1509 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1510 config_host_data.set('CONFIG_VDE', vde.found())
1511 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1512 config_host_data.set('CONFIG_VNC', vnc.found())
1513 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1514 config_host_data.set('CONFIG_VNC_PNG', png.found())
1515 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1516 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1517 config_host_data.set('CONFIG_VTE', vte.found())
1518 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1519 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1520 config_host_data.set('CONFIG_GETTID', has_gettid)
1521 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1522 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1523 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1524 config_host_data.set('CONFIG_NETTLE', nettle.found())
1525 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1526 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1527 config_host_data.set('CONFIG_STATX', has_statx)
1528 config_host_data.set('CONFIG_ZSTD', zstd.found())
1529 config_host_data.set('CONFIG_FUSE', fuse.found())
1530 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1531 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1532 if spice_protocol.found()
1533 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
1534 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
1535 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
1537 config_host_data.set('CONFIG_SPICE', spice.found())
1538 config_host_data.set('CONFIG_X11', x11.found())
1539 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
1540 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1541 config_host_data.set('CONFIG_SELINUX', selinux.found())
1542 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1543 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1544 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1545 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1547 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1548 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1549 config_host_data.set('HOST_WORDS_BIGENDIAN', host_machine.endian() == 'big')
1551 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
1552 config_host_data.set('CONFIG_GPROF', get_option('gprof'))
1553 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
1554 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
1555 config_host_data.set('CONFIG_REPLICATION', get_option('live_block_migration').allowed())
1558 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1559 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1560 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1561 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1562 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1563 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1564 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1565 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1566 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1569 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1570 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1571 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1572 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1573 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1574 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
1575 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1576 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1577 config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
1578 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1579 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1580 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1581 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1582 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1583 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1584 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1585 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1586 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1588 config_host_data.set('HAVE_IBV_ADVISE_MR',
1589 cc.has_function('ibv_advise_mr',
1590 args: config_host['RDMA_LIBS'].split(),
1591 prefix: '#include <infiniband/verbs.h>'))
1595 config_host_data.set('CONFIG_BYTESWAP_H',
1596 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1597 config_host_data.set('CONFIG_EPOLL_CREATE1',
1598 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1599 config_host_data.set('CONFIG_HAS_ENVIRON',
1600 cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix))
1601 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1602 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1603 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1604 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1605 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1606 config_host_data.set('CONFIG_FIEMAP',
1607 cc.has_header('linux/fiemap.h') and
1608 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1609 config_host_data.set('CONFIG_GETRANDOM',
1610 cc.has_function('getrandom') and
1611 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1612 config_host_data.set('CONFIG_INOTIFY',
1613 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1614 config_host_data.set('CONFIG_INOTIFY1',
1615 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1616 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1617 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1618 prefix: '''#include <sys/endian.h>
1619 #include <sys/types.h>'''))
1620 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1621 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1622 config_host_data.set('CONFIG_RTNETLINK',
1623 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1624 config_host_data.set('CONFIG_SYSMACROS',
1625 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1626 config_host_data.set('HAVE_OPTRESET',
1627 cc.has_header_symbol('getopt.h', 'optreset'))
1628 config_host_data.set('HAVE_IPPROTO_MPTCP',
1629 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1632 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1633 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1634 prefix: '#include <signal.h>'))
1635 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1636 cc.has_member('struct stat', 'st_atim',
1637 prefix: '#include <sys/stat.h>'))
1640 config_host_data.set('CONFIG_IOVEC',
1641 cc.has_type('struct iovec',
1642 prefix: '#include <sys/uio.h>'))
1643 config_host_data.set('HAVE_UTMPX',
1644 cc.has_type('struct utmpx',
1645 prefix: '#include <utmpx.h>'))
1647 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1648 #include <sys/eventfd.h>
1649 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1650 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1653 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1654 return fdatasync(0);
1656 #error Not supported
1659 config_host_data.set('CONFIG_MADVISE', cc.links(gnu_source_prefix + '''
1660 #include <sys/types.h>
1661 #include <sys/mman.h>
1663 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }'''))
1664 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1665 #include <sys/mman.h>
1666 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1667 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1669 #if !defined(AT_EMPTY_PATH)
1670 # error missing definition
1672 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1674 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1681 return pipe2(pipefd, O_CLOEXEC);
1683 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1684 #include <sys/mman.h>
1686 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1688 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
1689 #include <pthread.h>
1691 static void *f(void *p) { return NULL; }
1695 pthread_create(&thread, 0, f, 0);
1696 pthread_setname_np(thread, "QEMU");
1698 }''', dependencies: threads))
1699 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
1700 #include <pthread.h>
1702 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
1706 pthread_create(&thread, 0, f, 0);
1708 }''', dependencies: threads))
1710 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1711 #include <sys/signalfd.h>
1713 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1714 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1722 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1723 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1727 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
1728 #include <sys/mman.h>
1729 int main(int argc, char *argv[]) {
1730 return mlockall(MCL_FUTURE);
1734 if get_option('l2tpv3').allowed() and have_system
1735 have_l2tpv3 = cc.has_type('struct mmsghdr',
1736 prefix: gnu_source_prefix + '''
1737 #include <sys/socket.h>
1738 #include <linux/ip.h>''')
1740 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
1743 if get_option('netmap').allowed() and have_system
1744 have_netmap = cc.compiles('''
1745 #include <inttypes.h>
1747 #include <net/netmap.h>
1748 #include <net/netmap_user.h>
1749 #if (NETMAP_API < 11) || (NETMAP_API > 15)
1752 int main(void) { return 0; }''')
1753 if not have_netmap and get_option('netmap').enabled()
1754 error('Netmap headers not available')
1757 config_host_data.set('CONFIG_NETMAP', have_netmap)
1759 # Work around a system header bug with some kernel/XFS header
1760 # versions where they both try to define 'struct fsxattr':
1761 # xfs headers will not try to redefine structs from linux headers
1762 # if this macro is set.
1763 config_host_data.set('HAVE_FSXATTR', cc.links('''
1764 #include <linux/fs.h>
1770 # Some versions of Mac OS X incorrectly define SIZE_MAX
1771 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1774 int main(int argc, char *argv[]) {
1775 return printf("%zu", SIZE_MAX);
1776 }''', args: ['-Werror']))
1778 # See if 64-bit atomic operations are supported.
1779 # Note that without __atomic builtins, we can only
1780 # assume atomic loads/stores max at pointer size.
1781 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
1785 uint64_t x = 0, y = 0;
1786 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
1787 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
1788 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
1789 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
1790 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
1794 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
1795 #include <sys/auxv.h>
1797 return getauxval(AT_HWCAP) == 0;
1800 have_cpuid_h = cc.links('''
1803 unsigned a, b, c, d;
1804 unsigned max = __get_cpuid_max(0, 0);
1807 __cpuid(1, a, b, c, d);
1811 __cpuid_count(7, 0, a, b, c, d);
1816 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
1818 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
1819 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
1820 .require(cc.links('''
1821 #pragma GCC push_options
1822 #pragma GCC target("avx2")
1824 #include <immintrin.h>
1825 static int bar(void *a) {
1826 __m256i x = *(__m256i *)a;
1827 return _mm256_testz_si256(x, x);
1829 int main(int argc, char *argv[]) { return bar(argv[0]); }
1830 '''), error_message: 'AVX2 not available').allowed())
1832 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
1833 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
1834 .require(cc.links('''
1835 #pragma GCC push_options
1836 #pragma GCC target("avx512f")
1838 #include <immintrin.h>
1839 static int bar(void *a) {
1840 __m512i x = *(__m512i *)a;
1841 return _mm512_test_epi64_mask(x, x);
1843 int main(int argc, char *argv[]) { return bar(argv[0]); }
1844 '''), error_message: 'AVX512F not available').allowed())
1846 if get_option('membarrier').disabled()
1847 have_membarrier = false
1848 elif targetos == 'windows'
1849 have_membarrier = true
1850 elif targetos == 'linux'
1851 have_membarrier = cc.compiles('''
1852 #include <linux/membarrier.h>
1853 #include <sys/syscall.h>
1857 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
1858 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
1862 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
1863 .require(have_membarrier, error_message: 'membarrier system call not available') \
1866 have_afalg = get_option('crypto_afalg') \
1867 .require(cc.compiles(gnu_source_prefix + '''
1869 #include <sys/types.h>
1870 #include <sys/socket.h>
1871 #include <linux/if_alg.h>
1874 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
1877 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
1878 config_host_data.set('CONFIG_AF_ALG', have_afalg)
1880 config_host_data.set('CONFIG_AF_VSOCK', cc.compiles(gnu_source_prefix + '''
1882 #include <sys/types.h>
1883 #include <sys/socket.h>
1884 #if !defined(AF_VSOCK)
1885 # error missing AF_VSOCK flag
1887 #include <linux/vm_sockets.h>
1890 struct sockaddr_vm svm;
1891 socklen_t len = sizeof(svm);
1892 sock = socket(AF_VSOCK, SOCK_STREAM, 0);
1893 ret = getpeername(sock, (struct sockaddr *)&svm, &len);
1894 if ((ret == -1) && (errno == ENOTCONN)) {
1900 ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target
1902 arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1903 strings = ['CONFIG_IASL']
1904 foreach k, v: config_host
1905 if ignored.contains(k)
1907 elif arrays.contains(k)
1909 v = '"' + '", "'.join(v.split()) + '", '
1911 config_host_data.set(k, v)
1912 elif strings.contains(k)
1913 config_host_data.set_quoted(k, v)
1914 elif k.startswith('CONFIG_')
1915 config_host_data.set(k, v == 'y' ? 1 : v)
1919 ########################
1920 # Target configuration #
1921 ########################
1923 minikconf = find_program('scripts/minikconf.py')
1925 config_all_devices = {}
1926 config_all_disas = {}
1927 config_devices_mak_list = []
1928 config_devices_h = {}
1929 config_target_h = {}
1930 config_target_mak = {}
1933 'alpha' : ['CONFIG_ALPHA_DIS'],
1934 'arm' : ['CONFIG_ARM_DIS'],
1935 'avr' : ['CONFIG_AVR_DIS'],
1936 'cris' : ['CONFIG_CRIS_DIS'],
1937 'hexagon' : ['CONFIG_HEXAGON_DIS'],
1938 'hppa' : ['CONFIG_HPPA_DIS'],
1939 'i386' : ['CONFIG_I386_DIS'],
1940 'x86_64' : ['CONFIG_I386_DIS'],
1941 'm68k' : ['CONFIG_M68K_DIS'],
1942 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1943 'mips' : ['CONFIG_MIPS_DIS'],
1944 'nios2' : ['CONFIG_NIOS2_DIS'],
1945 'or1k' : ['CONFIG_OPENRISC_DIS'],
1946 'ppc' : ['CONFIG_PPC_DIS'],
1947 'riscv' : ['CONFIG_RISCV_DIS'],
1948 'rx' : ['CONFIG_RX_DIS'],
1949 's390' : ['CONFIG_S390_DIS'],
1950 'sh4' : ['CONFIG_SH4_DIS'],
1951 'sparc' : ['CONFIG_SPARC_DIS'],
1952 'xtensa' : ['CONFIG_XTENSA_DIS'],
1954 if link_language == 'cpp'
1956 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1957 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1958 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1962 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
1964 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
1965 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
1966 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
1967 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
1968 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1969 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1970 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1971 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1972 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1973 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1974 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1975 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1976 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1978 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1980 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1981 actual_target_dirs = []
1983 foreach target : target_dirs
1984 config_target = { 'TARGET_NAME': target.split('-')[0] }
1985 if target.endswith('linux-user')
1986 if targetos != 'linux'
1990 error('Target @0@ is only available on a Linux host'.format(target))
1992 config_target += { 'CONFIG_LINUX_USER': 'y' }
1993 elif target.endswith('bsd-user')
1994 if 'CONFIG_BSD' not in config_host
1998 error('Target @0@ is only available on a BSD host'.format(target))
2000 config_target += { 'CONFIG_BSD_USER': 'y' }
2001 elif target.endswith('softmmu')
2002 config_target += { 'CONFIG_SOFTMMU': 'y' }
2004 if target.endswith('-user')
2006 'CONFIG_USER_ONLY': 'y',
2007 'CONFIG_QEMU_INTERP_PREFIX':
2008 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
2013 foreach sym: accelerators
2014 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2015 config_target += { sym: 'y' }
2016 config_all += { sym: 'y' }
2017 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
2018 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
2019 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
2020 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
2022 if target in modular_tcg
2023 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2025 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2027 accel_kconfig += [ sym + '=y' ]
2030 if accel_kconfig.length() == 0
2034 error('No accelerator available for target @0@'.format(target))
2037 actual_target_dirs += target
2038 config_target += keyval.load('configs/targets' / target + '.mak')
2039 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
2041 if 'TARGET_NEED_FDT' in config_target
2042 fdt_required += target
2046 if 'TARGET_BASE_ARCH' not in config_target
2047 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2049 if 'TARGET_ABI_DIR' not in config_target
2050 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2053 foreach k, v: disassemblers
2054 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
2056 config_target += { sym: 'y' }
2057 config_all_disas += { sym: 'y' }
2062 config_target_data = configuration_data()
2063 foreach k, v: config_target
2064 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2066 elif ignored.contains(k)
2068 elif k == 'TARGET_BASE_ARCH'
2069 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2070 # not used to select files from sourcesets.
2071 config_target_data.set('TARGET_' + v.to_upper(), 1)
2072 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
2073 config_target_data.set_quoted(k, v)
2075 config_target_data.set(k, 1)
2077 config_target_data.set(k, v)
2080 config_target_data.set('QEMU_ARCH',
2081 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
2082 config_target_h += {target: configure_file(output: target + '-config-target.h',
2083 configuration: config_target_data)}
2085 if target.endswith('-softmmu')
2086 config_input = meson.get_external_property(target, 'default')
2087 config_devices_mak = target + '-config-devices.mak'
2088 config_devices_mak = configure_file(
2089 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2090 output: config_devices_mak,
2091 depfile: config_devices_mak + '.d',
2093 command: [minikconf,
2094 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2095 config_devices_mak, '@DEPFILE@', '@INPUT@',
2096 host_kconfig, accel_kconfig,
2097 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
2099 config_devices_data = configuration_data()
2100 config_devices = keyval.load(config_devices_mak)
2101 foreach k, v: config_devices
2102 config_devices_data.set(k, 1)
2104 config_devices_mak_list += config_devices_mak
2105 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2106 configuration: config_devices_data)}
2107 config_target += config_devices
2108 config_all_devices += config_devices
2110 config_target_mak += {target: config_target}
2112 target_dirs = actual_target_dirs
2114 # This configuration is used to build files that are shared by
2115 # multiple binaries, and then extracted out of the "common"
2116 # static_library target.
2118 # We do not use all_sources()/all_dependencies(), because it would
2119 # build literally all source files, including devices only used by
2120 # targets that are not built for this compilation. The CONFIG_ALL
2121 # pseudo symbol replaces it.
2123 config_all += config_all_devices
2124 config_all += config_host
2125 config_all += config_all_disas
2127 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
2128 'CONFIG_SOFTMMU': have_system,
2129 'CONFIG_USER_ONLY': have_user,
2133 target_configs_h = []
2134 foreach target: target_dirs
2135 target_configs_h += config_target_h[target]
2136 target_configs_h += config_devices_h.get(target, [])
2138 genh += custom_target('config-poison.h',
2139 input: [target_configs_h],
2140 output: 'config-poison.h',
2142 command: [find_program('scripts/make-config-poison.sh'),
2149 capstone = not_found
2150 capstone_opt = get_option('capstone')
2151 if capstone_opt in ['enabled', 'auto', 'system']
2152 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
2153 capstone = dependency('capstone', version: '>=4.0',
2154 kwargs: static_kwargs, method: 'pkg-config',
2155 required: capstone_opt == 'system' or
2156 capstone_opt == 'enabled' and not have_internal)
2158 # Some versions of capstone have broken pkg-config file
2159 # that reports a wrong -I path, causing the #include to
2160 # fail later. If the system has such a broken version
2162 if capstone.found() and not cc.compiles('#include <capstone.h>',
2163 dependencies: [capstone])
2164 capstone = not_found
2165 if capstone_opt == 'system'
2166 error('system capstone requested, it does not appear to work')
2171 capstone_opt = 'system'
2173 capstone_opt = 'internal'
2175 capstone_opt = 'disabled'
2178 if capstone_opt == 'internal'
2179 capstone_data = configuration_data()
2180 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
2182 capstone_files = files(
2184 'capstone/MCInst.c',
2185 'capstone/MCInstrDesc.c',
2186 'capstone/MCRegisterInfo.c',
2187 'capstone/SStream.c',
2191 if 'CONFIG_ARM_DIS' in config_all_disas
2192 capstone_data.set('CAPSTONE_HAS_ARM', '1')
2193 capstone_files += files(
2194 'capstone/arch/ARM/ARMDisassembler.c',
2195 'capstone/arch/ARM/ARMInstPrinter.c',
2196 'capstone/arch/ARM/ARMMapping.c',
2197 'capstone/arch/ARM/ARMModule.c'
2201 # FIXME: This config entry currently depends on a c++ compiler.
2202 # Which is needed for building libvixl, but not for capstone.
2203 if 'CONFIG_ARM_A64_DIS' in config_all_disas
2204 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
2205 capstone_files += files(
2206 'capstone/arch/AArch64/AArch64BaseInfo.c',
2207 'capstone/arch/AArch64/AArch64Disassembler.c',
2208 'capstone/arch/AArch64/AArch64InstPrinter.c',
2209 'capstone/arch/AArch64/AArch64Mapping.c',
2210 'capstone/arch/AArch64/AArch64Module.c'
2214 if 'CONFIG_PPC_DIS' in config_all_disas
2215 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
2216 capstone_files += files(
2217 'capstone/arch/PowerPC/PPCDisassembler.c',
2218 'capstone/arch/PowerPC/PPCInstPrinter.c',
2219 'capstone/arch/PowerPC/PPCMapping.c',
2220 'capstone/arch/PowerPC/PPCModule.c'
2224 if 'CONFIG_S390_DIS' in config_all_disas
2225 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
2226 capstone_files += files(
2227 'capstone/arch/SystemZ/SystemZDisassembler.c',
2228 'capstone/arch/SystemZ/SystemZInstPrinter.c',
2229 'capstone/arch/SystemZ/SystemZMapping.c',
2230 'capstone/arch/SystemZ/SystemZModule.c',
2231 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
2235 if 'CONFIG_I386_DIS' in config_all_disas
2236 capstone_data.set('CAPSTONE_HAS_X86', 1)
2237 capstone_files += files(
2238 'capstone/arch/X86/X86Disassembler.c',
2239 'capstone/arch/X86/X86DisassemblerDecoder.c',
2240 'capstone/arch/X86/X86ATTInstPrinter.c',
2241 'capstone/arch/X86/X86IntelInstPrinter.c',
2242 'capstone/arch/X86/X86InstPrinterCommon.c',
2243 'capstone/arch/X86/X86Mapping.c',
2244 'capstone/arch/X86/X86Module.c'
2248 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
2251 # FIXME: There does not seem to be a way to completely replace the c_args
2252 # that come from add_project_arguments() -- we can only add to them.
2253 # So: disable all warnings with a big hammer.
2256 # Include all configuration defines via a header file, which will wind up
2257 # as a dependency on the object file, and thus changes here will result
2259 '-include', 'capstone-defs.h'
2262 libcapstone = static_library('capstone',
2263 build_by_default: false,
2264 sources: capstone_files,
2265 c_args: capstone_cargs,
2266 include_directories: 'capstone/include')
2267 capstone = declare_dependency(link_with: libcapstone,
2268 include_directories: 'capstone/include/capstone')
2272 slirp_opt = 'disabled'
2274 slirp_opt = get_option('slirp')
2275 if slirp_opt in ['enabled', 'auto', 'system']
2276 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2277 slirp = dependency('slirp', kwargs: static_kwargs,
2278 method: 'pkg-config',
2279 required: slirp_opt == 'system' or
2280 slirp_opt == 'enabled' and not have_internal)
2282 slirp_opt = 'system'
2284 slirp_opt = 'internal'
2286 slirp_opt = 'disabled'
2289 if slirp_opt == 'internal'
2291 if targetos == 'windows'
2292 slirp_deps = cc.find_library('iphlpapi')
2293 elif targetos == 'darwin'
2294 slirp_deps = cc.find_library('resolv')
2296 slirp_conf = configuration_data()
2297 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2298 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2299 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2300 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2301 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2303 'slirp/src/arp_table.c',
2304 'slirp/src/bootp.c',
2305 'slirp/src/cksum.c',
2306 'slirp/src/dhcpv6.c',
2307 'slirp/src/dnssearch.c',
2309 'slirp/src/ip6_icmp.c',
2310 'slirp/src/ip6_input.c',
2311 'slirp/src/ip6_output.c',
2312 'slirp/src/ip_icmp.c',
2313 'slirp/src/ip_input.c',
2314 'slirp/src/ip_output.c',
2318 'slirp/src/ndp_table.c',
2320 'slirp/src/slirp.c',
2321 'slirp/src/socket.c',
2322 'slirp/src/state.c',
2323 'slirp/src/stream.c',
2324 'slirp/src/tcp_input.c',
2325 'slirp/src/tcp_output.c',
2326 'slirp/src/tcp_subr.c',
2327 'slirp/src/tcp_timer.c',
2332 'slirp/src/version.c',
2333 'slirp/src/vmstate.c',
2337 input : 'slirp/src/libslirp-version.h.in',
2338 output : 'libslirp-version.h',
2339 configuration: slirp_conf)
2341 slirp_inc = include_directories('slirp', 'slirp/src')
2342 libslirp = static_library('slirp',
2343 build_by_default: false,
2344 sources: slirp_files,
2345 c_args: slirp_cargs,
2346 include_directories: slirp_inc)
2347 slirp = declare_dependency(link_with: libslirp,
2348 dependencies: slirp_deps,
2349 include_directories: slirp_inc)
2353 # For CFI, we need to compile slirp as a static library together with qemu.
2354 # This is because we register slirp functions as callbacks for QEMU Timers.
2355 # When using a system-wide shared libslirp, the type information for the
2356 # callback is missing and the timer call produces a false positive with CFI.
2358 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2359 # with control-flow integrity.
2360 if get_option('cfi') and slirp_opt == 'system'
2361 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2362 + ' Please configure with --enable-slirp=git')
2366 fdt_opt = get_option('fdt')
2368 if fdt_opt in ['enabled', 'auto', 'system']
2369 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2370 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2371 required: fdt_opt == 'system' or
2372 fdt_opt == 'enabled' and not have_internal)
2373 if fdt.found() and cc.links('''
2375 #include <libfdt_env.h>
2376 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2379 elif fdt_opt == 'system'
2380 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2382 fdt_opt = 'internal'
2384 fdt_opt = 'disabled'
2388 if fdt_opt == 'internal'
2391 'dtc/libfdt/fdt_ro.c',
2392 'dtc/libfdt/fdt_wip.c',
2393 'dtc/libfdt/fdt_sw.c',
2394 'dtc/libfdt/fdt_rw.c',
2395 'dtc/libfdt/fdt_strerror.c',
2396 'dtc/libfdt/fdt_empty_tree.c',
2397 'dtc/libfdt/fdt_addresses.c',
2398 'dtc/libfdt/fdt_overlay.c',
2399 'dtc/libfdt/fdt_check.c',
2402 fdt_inc = include_directories('dtc/libfdt')
2403 libfdt = static_library('fdt',
2404 build_by_default: false,
2406 include_directories: fdt_inc)
2407 fdt = declare_dependency(link_with: libfdt,
2408 include_directories: fdt_inc)
2411 if not fdt.found() and fdt_required.length() > 0
2412 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2415 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2416 config_host_data.set('CONFIG_FDT', fdt.found())
2417 config_host_data.set('CONFIG_SLIRP', slirp.found())
2419 #####################
2420 # Generated sources #
2421 #####################
2423 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2425 hxtool = find_program('scripts/hxtool')
2426 shaderinclude = find_program('scripts/shaderinclude.pl')
2427 qapi_gen = find_program('scripts/qapi-gen.py')
2428 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2429 meson.current_source_dir() / 'scripts/qapi/commands.py',
2430 meson.current_source_dir() / 'scripts/qapi/common.py',
2431 meson.current_source_dir() / 'scripts/qapi/error.py',
2432 meson.current_source_dir() / 'scripts/qapi/events.py',
2433 meson.current_source_dir() / 'scripts/qapi/expr.py',
2434 meson.current_source_dir() / 'scripts/qapi/gen.py',
2435 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2436 meson.current_source_dir() / 'scripts/qapi/parser.py',
2437 meson.current_source_dir() / 'scripts/qapi/schema.py',
2438 meson.current_source_dir() / 'scripts/qapi/source.py',
2439 meson.current_source_dir() / 'scripts/qapi/types.py',
2440 meson.current_source_dir() / 'scripts/qapi/visit.py',
2441 meson.current_source_dir() / 'scripts/qapi/common.py',
2442 meson.current_source_dir() / 'scripts/qapi-gen.py'
2446 python, files('scripts/tracetool.py'),
2447 '--backend=' + ','.join(get_option('trace_backends'))
2449 tracetool_depends = files(
2450 'scripts/tracetool/backend/log.py',
2451 'scripts/tracetool/backend/__init__.py',
2452 'scripts/tracetool/backend/dtrace.py',
2453 'scripts/tracetool/backend/ftrace.py',
2454 'scripts/tracetool/backend/simple.py',
2455 'scripts/tracetool/backend/syslog.py',
2456 'scripts/tracetool/backend/ust.py',
2457 'scripts/tracetool/format/ust_events_c.py',
2458 'scripts/tracetool/format/ust_events_h.py',
2459 'scripts/tracetool/format/__init__.py',
2460 'scripts/tracetool/format/d.py',
2461 'scripts/tracetool/format/simpletrace_stap.py',
2462 'scripts/tracetool/format/c.py',
2463 'scripts/tracetool/format/h.py',
2464 'scripts/tracetool/format/log_stap.py',
2465 'scripts/tracetool/format/stap.py',
2466 'scripts/tracetool/__init__.py',
2467 'scripts/tracetool/transform.py',
2468 'scripts/tracetool/vcpu.py'
2471 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2472 meson.current_source_dir(),
2473 config_host['PKGVERSION'], meson.project_version()]
2474 qemu_version = custom_target('qemu-version.h',
2475 output: 'qemu-version.h',
2476 command: qemu_version_cmd,
2478 build_by_default: true,
2479 build_always_stale: true)
2480 genh += qemu_version
2484 ['qemu-options.hx', 'qemu-options.def'],
2485 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2489 ['hmp-commands.hx', 'hmp-commands.h'],
2490 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2493 foreach d : hx_headers
2494 hxdep += custom_target(d[1],
2498 build_by_default: true, # to be removed when added to a target
2499 command: [hxtool, '-h', '@INPUT0@'])
2507 authz_ss = ss.source_set()
2508 blockdev_ss = ss.source_set()
2509 block_ss = ss.source_set()
2510 chardev_ss = ss.source_set()
2511 common_ss = ss.source_set()
2512 crypto_ss = ss.source_set()
2513 hwcore_ss = ss.source_set()
2514 io_ss = ss.source_set()
2515 qmp_ss = ss.source_set()
2516 qom_ss = ss.source_set()
2517 softmmu_ss = ss.source_set()
2518 specific_fuzz_ss = ss.source_set()
2519 specific_ss = ss.source_set()
2520 stub_ss = ss.source_set()
2521 trace_ss = ss.source_set()
2522 user_ss = ss.source_set()
2523 util_ss = ss.source_set()
2526 qtest_module_ss = ss.source_set()
2527 tcg_module_ss = ss.source_set()
2533 target_softmmu_arch = {}
2534 target_user_arch = {}
2540 # TODO: add each directory to the subdirs from its own meson.build, once
2542 trace_events_subdirs = [
2550 trace_events_subdirs += [ 'linux-user' ]
2553 trace_events_subdirs += [ 'bsd-user' ]
2556 trace_events_subdirs += [
2565 trace_events_subdirs += [
2579 'hw/block/dataplane',
2629 if have_system or have_user
2630 trace_events_subdirs += [
2647 vhost_user = not_found
2648 if 'CONFIG_VHOST_USER' in config_host
2649 libvhost_user = subproject('libvhost-user')
2650 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2653 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
2654 # that is filled in by qapi/.
2667 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2668 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2671 stub_ss = stub_ss.apply(config_all, strict: false)
2673 util_ss.add_all(trace_ss)
2674 util_ss = util_ss.apply(config_all, strict: false)
2675 libqemuutil = static_library('qemuutil',
2676 sources: util_ss.sources() + stub_ss.sources() + genh,
2677 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2678 qemuutil = declare_dependency(link_with: libqemuutil,
2679 sources: genh + version_res)
2681 if have_system or have_user
2682 decodetree = generator(find_program('scripts/decodetree.py'),
2683 output: 'decode-@BASENAME@.c.inc',
2684 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2685 subdir('libdecnumber')
2702 if config_host_data.get('CONFIG_REPLICATION')
2703 block_ss.add(files('replication.c'))
2710 blockdev_ss.add(files(
2717 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2718 # os-win32.c does not
2719 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2720 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2723 common_ss.add(files('cpus-common.c'))
2727 common_ss.add(capstone)
2728 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2730 # Work around a gcc bug/misfeature wherein constant propagation looks
2732 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2733 # to guess that a const variable is always zero. Without lto, this is
2734 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2735 # without lto, not even the alias is required -- we simply use different
2736 # declarations in different compilation units.
2737 pagevary = files('page-vary-common.c')
2738 if get_option('b_lto')
2739 pagevary_flags = ['-fno-lto']
2740 if get_option('cfi')
2741 pagevary_flags += '-fno-sanitize=cfi-icall'
2743 pagevary = static_library('page-vary-common', sources: pagevary,
2744 c_args: pagevary_flags)
2745 pagevary = declare_dependency(link_with: pagevary)
2747 common_ss.add(pagevary)
2748 specific_ss.add(files('page-vary.c'))
2756 subdir('semihosting')
2764 common_user_inc = []
2766 subdir('common-user')
2768 subdir('linux-user')
2770 # needed for fuzzing binaries
2771 subdir('tests/qtest/libqos')
2772 subdir('tests/qtest/fuzz')
2775 tcg_real_module_ss = ss.source_set()
2776 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
2777 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
2778 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
2779 'tcg': tcg_real_module_ss }}
2781 ########################
2782 # Library dependencies #
2783 ########################
2785 modinfo_collect = find_program('scripts/modinfo-collect.py')
2786 modinfo_generate = find_program('scripts/modinfo-generate.py')
2791 foreach d, list : modules
2792 foreach m, module_ss : list
2793 if enable_modules and targetos != 'windows'
2794 module_ss = module_ss.apply(config_all, strict: false)
2795 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2796 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2802 if module_ss.sources() != []
2803 # FIXME: Should use sl.extract_all_objects(recursive: true) as
2804 # input. Sources can be used multiple times but objects are
2805 # unique when it comes to lookup in compile_commands.json.
2806 # Depnds on a mesion version with
2807 # https://github.com/mesonbuild/meson/pull/8900
2808 modinfo_files += custom_target(d + '-' + m + '.modinfo',
2809 output: d + '-' + m + '.modinfo',
2810 input: module_ss.sources() + genh,
2812 command: [modinfo_collect, module_ss.sources()])
2816 block_ss.add_all(module_ss)
2818 softmmu_ss.add_all(module_ss)
2824 foreach d, list : target_modules
2825 foreach m, module_ss : list
2826 if enable_modules and targetos != 'windows'
2827 foreach target : target_dirs
2828 if target.endswith('-softmmu')
2829 config_target = config_target_mak[target]
2830 config_target += config_host
2831 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2832 c_args = ['-DNEED_CPU_H',
2833 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2834 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2835 target_module_ss = module_ss.apply(config_target, strict: false)
2836 if target_module_ss.sources() != []
2837 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
2838 sl = static_library(module_name,
2839 [genh, target_module_ss.sources()],
2840 dependencies: [modulecommon, target_module_ss.dependencies()],
2841 include_directories: target_inc,
2845 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
2846 modinfo_files += custom_target(module_name + '.modinfo',
2847 output: module_name + '.modinfo',
2848 input: target_module_ss.sources() + genh,
2850 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
2855 specific_ss.add_all(module_ss)
2861 modinfo_src = custom_target('modinfo.c',
2862 output: 'modinfo.c',
2863 input: modinfo_files,
2864 command: [modinfo_generate, '@INPUT@'],
2866 modinfo_lib = static_library('modinfo', modinfo_src)
2867 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
2868 softmmu_ss.add(modinfo_dep)
2871 nm = find_program('nm')
2872 undefsym = find_program('scripts/undefsym.py')
2873 block_syms = custom_target('block.syms', output: 'block.syms',
2874 input: [libqemuutil, block_mods],
2876 command: [undefsym, nm, '@INPUT@'])
2877 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2878 input: [libqemuutil, softmmu_mods],
2880 command: [undefsym, nm, '@INPUT@'])
2882 qom_ss = qom_ss.apply(config_host, strict: false)
2883 libqom = static_library('qom', qom_ss.sources() + genh,
2884 dependencies: [qom_ss.dependencies()],
2887 qom = declare_dependency(link_whole: libqom)
2889 authz_ss = authz_ss.apply(config_host, strict: false)
2890 libauthz = static_library('authz', authz_ss.sources() + genh,
2891 dependencies: [authz_ss.dependencies()],
2893 build_by_default: false)
2895 authz = declare_dependency(link_whole: libauthz,
2898 crypto_ss = crypto_ss.apply(config_host, strict: false)
2899 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2900 dependencies: [crypto_ss.dependencies()],
2902 build_by_default: false)
2904 crypto = declare_dependency(link_whole: libcrypto,
2905 dependencies: [authz, qom])
2907 io_ss = io_ss.apply(config_host, strict: false)
2908 libio = static_library('io', io_ss.sources() + genh,
2909 dependencies: [io_ss.dependencies()],
2910 link_with: libqemuutil,
2912 build_by_default: false)
2914 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2916 libmigration = static_library('migration', sources: migration_files + genh,
2918 build_by_default: false)
2919 migration = declare_dependency(link_with: libmigration,
2920 dependencies: [zlib, qom, io])
2921 softmmu_ss.add(migration)
2923 block_ss = block_ss.apply(config_host, strict: false)
2924 libblock = static_library('block', block_ss.sources() + genh,
2925 dependencies: block_ss.dependencies(),
2926 link_depends: block_syms,
2928 build_by_default: false)
2930 block = declare_dependency(link_whole: [libblock],
2931 link_args: '@block.syms',
2932 dependencies: [crypto, io])
2934 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2935 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2936 dependencies: blockdev_ss.dependencies(),
2938 build_by_default: false)
2940 blockdev = declare_dependency(link_whole: [libblockdev],
2941 dependencies: [block])
2943 qmp_ss = qmp_ss.apply(config_host, strict: false)
2944 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2945 dependencies: qmp_ss.dependencies(),
2947 build_by_default: false)
2949 qmp = declare_dependency(link_whole: [libqmp])
2951 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2953 dependencies: [gnutls],
2954 build_by_default: false)
2956 chardev = declare_dependency(link_whole: libchardev)
2958 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
2959 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
2961 build_by_default: false)
2962 hwcore = declare_dependency(link_whole: libhwcore)
2963 common_ss.add(hwcore)
2969 emulator_modules = []
2970 foreach m : block_mods + softmmu_mods
2971 emulator_modules += shared_module(m.name(),
2972 build_by_default: true,
2976 install_dir: qemu_moddir)
2979 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2980 common_ss.add(qom, qemuutil)
2982 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2983 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2985 common_all = common_ss.apply(config_all, strict: false)
2986 common_all = static_library('common',
2987 build_by_default: false,
2988 sources: common_all.sources() + genh,
2989 include_directories: common_user_inc,
2990 implicit_include_directories: false,
2991 dependencies: common_all.dependencies(),
2994 feature_to_c = find_program('scripts/feature_to_c.sh')
2997 foreach target : target_dirs
2998 config_target = config_target_mak[target]
2999 target_name = config_target['TARGET_NAME']
3000 target_base_arch = config_target['TARGET_BASE_ARCH']
3001 arch_srcs = [config_target_h[target]]
3003 c_args = ['-DNEED_CPU_H',
3004 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3005 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3006 link_args = emulator_link_args
3008 config_target += config_host
3009 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3010 if targetos == 'linux'
3011 target_inc += include_directories('linux-headers', is_system: true)
3013 if target.endswith('-softmmu')
3014 qemu_target_name = 'qemu-system-' + target_name
3015 target_type='system'
3016 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3017 arch_srcs += t.sources()
3018 arch_deps += t.dependencies()
3020 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3021 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3022 arch_srcs += hw.sources()
3023 arch_deps += hw.dependencies()
3025 arch_srcs += config_devices_h[target]
3026 link_args += ['@block.syms', '@qemu.syms']
3028 abi = config_target['TARGET_ABI_DIR']
3030 target_inc += common_user_inc
3031 qemu_target_name = 'qemu-' + target_name
3032 if target_base_arch in target_user_arch
3033 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3034 arch_srcs += t.sources()
3035 arch_deps += t.dependencies()
3037 if 'CONFIG_LINUX_USER' in config_target
3038 base_dir = 'linux-user'
3040 if 'CONFIG_BSD_USER' in config_target
3041 base_dir = 'bsd-user'
3042 target_inc += include_directories('bsd-user/' / targetos)
3043 target_inc += include_directories('bsd-user/host/' / host_arch)
3044 dir = base_dir / abi
3045 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3047 target_inc += include_directories(
3051 if 'CONFIG_LINUX_USER' in config_target
3052 dir = base_dir / abi
3053 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3054 if config_target.has_key('TARGET_SYSTBL_ABI')
3056 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3057 extra_args : config_target['TARGET_SYSTBL_ABI'])
3062 if 'TARGET_XML_FILES' in config_target
3063 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3064 output: target + '-gdbstub-xml.c',
3065 input: files(config_target['TARGET_XML_FILES'].split()),
3066 command: [feature_to_c, '@INPUT@'],
3068 arch_srcs += gdbstub_xml
3071 t = target_arch[target_base_arch].apply(config_target, strict: false)
3072 arch_srcs += t.sources()
3073 arch_deps += t.dependencies()
3075 target_common = common_ss.apply(config_target, strict: false)
3076 objects = common_all.extract_objects(target_common.sources())
3077 deps = target_common.dependencies()
3079 target_specific = specific_ss.apply(config_target, strict: false)
3080 arch_srcs += target_specific.sources()
3081 arch_deps += target_specific.dependencies()
3083 lib = static_library('qemu-' + target,
3084 sources: arch_srcs + genh,
3085 dependencies: arch_deps,
3087 include_directories: target_inc,
3089 build_by_default: false,
3092 if target.endswith('-softmmu')
3094 'name': 'qemu-system-' + target_name,
3095 'win_subsystem': 'console',
3096 'sources': files('softmmu/main.c'),
3099 if targetos == 'windows' and (sdl.found() or gtk.found())
3101 'name': 'qemu-system-' + target_name + 'w',
3102 'win_subsystem': 'windows',
3103 'sources': files('softmmu/main.c'),
3107 if get_option('fuzzing')
3108 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3110 'name': 'qemu-fuzz-' + target_name,
3111 'win_subsystem': 'console',
3112 'sources': specific_fuzz.sources(),
3113 'dependencies': specific_fuzz.dependencies(),
3118 'name': 'qemu-' + target_name,
3119 'win_subsystem': 'console',
3125 exe_name = exe['name']
3126 if targetos == 'darwin'
3127 exe_name += '-unsigned'
3130 emulator = executable(exe_name, exe['sources'],
3133 dependencies: arch_deps + deps + exe['dependencies'],
3134 objects: lib.extract_all_objects(recursive: true),
3135 link_language: link_language,
3136 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3137 link_args: link_args,
3138 win_subsystem: exe['win_subsystem'])
3140 if targetos == 'darwin'
3141 icon = 'pc-bios/qemu.rsrc'
3142 build_input = [emulator, files(icon)]
3144 get_option('bindir') / exe_name,
3145 meson.current_source_dir() / icon
3147 if 'CONFIG_HVF' in config_target
3148 entitlements = 'accel/hvf/entitlements.plist'
3149 build_input += files(entitlements)
3150 install_input += meson.current_source_dir() / entitlements
3153 entitlement = find_program('scripts/entitlement.sh')
3154 emulators += {exe['name'] : custom_target(exe['name'],
3156 output: exe['name'],
3157 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3160 meson.add_install_script(entitlement, '--install',
3161 get_option('bindir') / exe['name'],
3164 emulators += {exe['name']: emulator}
3169 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3170 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3171 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3172 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3174 custom_target(exe['name'] + stp['ext'],
3175 input: trace_events_all,
3176 output: exe['name'] + stp['ext'],
3177 install: stp['install'],
3178 install_dir: get_option('datadir') / 'systemtap/tapset',
3180 tracetool, '--group=all', '--format=' + stp['fmt'],
3181 '--binary=' + stp['bin'],
3182 '--target-name=' + target_name,
3183 '--target-type=' + target_type,
3184 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3185 '@INPUT@', '@OUTPUT@'
3187 depend_files: tracetool_depends)
3193 # Other build targets
3195 if 'CONFIG_PLUGIN' in config_host
3196 install_headers('include/qemu/qemu-plugin.h')
3199 if 'CONFIG_GUEST_AGENT' in config_host
3201 elif get_option('guest_agent_msi').enabled()
3202 error('Guest agent MSI requested, but the guest agent is not being built')
3205 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3206 # when we don't build tools or system
3207 if xkbcommon.found()
3208 # used for the update-keymaps target, so include rules even if !have_tools
3209 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3210 dependencies: [qemuutil, xkbcommon], install: have_tools)
3214 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3215 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3216 qemu_io = executable('qemu-io', files('qemu-io.c'),
3217 dependencies: [block, qemuutil], install: true)
3218 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3219 dependencies: [blockdev, qemuutil, gnutls, selinux],
3222 subdir('storage-daemon')
3223 subdir('contrib/rdmacm-mux')
3224 subdir('contrib/elf2dmp')
3226 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3227 dependencies: qemuutil,
3230 if 'CONFIG_VHOST_USER' in config_host
3231 subdir('contrib/vhost-user-blk')
3232 subdir('contrib/vhost-user-gpu')
3233 subdir('contrib/vhost-user-input')
3234 subdir('contrib/vhost-user-scsi')
3237 if targetos == 'linux'
3238 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3239 dependencies: [qemuutil, libcap_ng],
3241 install_dir: get_option('libexecdir'))
3243 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3244 dependencies: [authz, crypto, io, qom, qemuutil,
3245 libcap_ng, mpathpersist],
3250 subdir('contrib/ivshmem-client')
3251 subdir('contrib/ivshmem-server')
3264 if host_machine.system() == 'windows'
3266 find_program('scripts/nsis.py'),
3268 get_option('prefix'),
3269 meson.current_source_dir(),
3272 '-DDISPLAYVERSION=' + meson.project_version(),
3275 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3278 nsis_cmd += '-DCONFIG_GTK=y'
3281 nsis = custom_target('nsis',
3282 output: 'qemu-setup-' + meson.project_version() + '.exe',
3283 input: files('qemu.nsi'),
3284 build_always_stale: true,
3285 command: nsis_cmd + ['@INPUT@'])
3286 alias_target('installer', nsis)
3289 #########################
3290 # Configuration summary #
3291 #########################
3295 summary_info += {'Install prefix': get_option('prefix')}
3296 summary_info += {'BIOS directory': qemu_datadir}
3297 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
3298 summary_info += {'binary directory': get_option('bindir')}
3299 summary_info += {'library directory': get_option('libdir')}
3300 summary_info += {'module directory': qemu_moddir}
3301 summary_info += {'libexec directory': get_option('libexecdir')}
3302 summary_info += {'include directory': get_option('includedir')}
3303 summary_info += {'config directory': get_option('sysconfdir')}
3304 if targetos != 'windows'
3305 summary_info += {'local state directory': get_option('localstatedir')}
3306 summary_info += {'Manual directory': get_option('mandir')}
3308 summary_info += {'local state directory': 'queried at runtime'}
3310 summary_info += {'Doc directory': get_option('docdir')}
3311 summary_info += {'Build directory': meson.current_build_dir()}
3312 summary_info += {'Source path': meson.current_source_dir()}
3313 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3314 summary(summary_info, bool_yn: true, section: 'Directories')
3318 summary_info += {'git': config_host['GIT']}
3319 summary_info += {'make': config_host['MAKE']}
3320 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3321 summary_info += {'sphinx-build': sphinx_build}
3322 if config_host.has_key('HAVE_GDB_BIN')
3323 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3325 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3326 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
3327 summary_info += {'wixl': wixl}
3329 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
3330 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
3332 summary(summary_info, bool_yn: true, section: 'Host binaries')
3334 # Configurable features
3336 summary_info += {'Documentation': build_docs}
3337 summary_info += {'system-mode emulation': have_system}
3338 summary_info += {'user-mode emulation': have_user}
3339 summary_info += {'block layer': have_block}
3340 summary_info += {'Install blobs': get_option('install_blobs')}
3341 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3342 if config_host.has_key('CONFIG_MODULES')
3343 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
3345 summary_info += {'fuzzing support': get_option('fuzzing')}
3347 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3349 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3350 if 'simple' in get_option('trace_backends')
3351 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3353 summary_info += {'D-Bus display': dbus_display}
3354 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
3355 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
3356 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
3357 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
3358 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
3359 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
3360 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
3361 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3362 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
3363 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
3364 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
3365 summary(summary_info, bool_yn: true, section: 'Configurable features')
3367 # Compilation information
3369 summary_info += {'host CPU': cpu}
3370 summary_info += {'host endianness': build_machine.endian()}
3371 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3372 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3373 if link_language == 'cpp'
3374 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3376 summary_info += {'C++ compiler': false}
3378 if targetos == 'darwin'
3379 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3381 if targetos == 'windows'
3382 if 'WIN_SDK' in config_host
3383 summary_info += {'Windows SDK': config_host['WIN_SDK']}
3386 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3387 + ['-O' + get_option('optimization')]
3388 + (get_option('debug') ? ['-g'] : []))}
3389 if link_language == 'cpp'
3390 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3391 + ['-O' + get_option('optimization')]
3392 + (get_option('debug') ? ['-g'] : []))}
3394 link_args = get_option(link_language + '_link_args')
3395 if link_args.length() > 0
3396 summary_info += {'LDFLAGS': ' '.join(link_args)}
3398 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
3399 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
3400 summary_info += {'profiler': get_option('profiler')}
3401 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3402 summary_info += {'PIE': get_option('b_pie')}
3403 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3404 summary_info += {'malloc trim support': has_malloc_trim}
3405 summary_info += {'membarrier': have_membarrier}
3406 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
3407 summary_info += {'mutex debugging': get_option('debug_mutex')}
3408 summary_info += {'memory allocator': get_option('malloc')}
3409 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
3410 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
3411 summary_info += {'gprof enabled': get_option('gprof')}
3412 summary_info += {'gcov': get_option('b_coverage')}
3413 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3414 summary_info += {'CFI support': get_option('cfi')}
3415 if get_option('cfi')
3416 summary_info += {'CFI debug support': get_option('cfi_debug')}
3418 summary_info += {'strip binaries': get_option('strip')}
3419 summary_info += {'sparse': sparse}
3420 summary_info += {'mingw32 support': targetos == 'windows'}
3422 # snarf the cross-compilation information for tests
3423 foreach target: target_dirs
3424 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3425 if fs.exists(tcg_mak)
3426 config_cross_tcg = keyval.load(tcg_mak)
3427 target = config_cross_tcg['TARGET_NAME']
3429 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3430 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3431 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3432 elif 'CROSS_CC_GUEST' in config_cross_tcg
3433 summary_info += {target + ' tests'
3434 : config_cross_tcg['CROSS_CC_GUEST'] }
3439 summary(summary_info, bool_yn: true, section: 'Compilation')
3441 # Targets and accelerators
3444 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3445 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3446 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3447 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3448 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3449 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
3450 if config_host.has_key('CONFIG_XEN_BACKEND')
3451 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
3454 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3455 if config_all.has_key('CONFIG_TCG')
3456 if get_option('tcg_interpreter')
3457 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
3459 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3461 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3462 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3464 summary_info += {'target list': ' '.join(target_dirs)}
3466 summary_info += {'default devices': get_option('default_devices')}
3467 summary_info += {'out of process emulation': multiprocess_allowed}
3469 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3473 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3474 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
3476 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3477 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3478 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
3479 summary_info += {'VirtFS support': have_virtfs}
3480 summary_info += {'build virtiofs daemon': have_virtiofsd}
3481 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
3482 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
3483 summary_info += {'bochs support': get_option('bochs').allowed()}
3484 summary_info += {'cloop support': get_option('cloop').allowed()}
3485 summary_info += {'dmg support': get_option('dmg').allowed()}
3486 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
3487 summary_info += {'vdi support': get_option('vdi').allowed()}
3488 summary_info += {'vvfat support': get_option('vvfat').allowed()}
3489 summary_info += {'qed support': get_option('qed').allowed()}
3490 summary_info += {'parallels support': get_option('parallels').allowed()}
3491 summary_info += {'FUSE exports': fuse}
3493 summary(summary_info, bool_yn: true, section: 'Block layer support')
3497 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
3498 summary_info += {'GNUTLS support': gnutls}
3500 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3502 summary_info += {'libgcrypt': gcrypt}
3503 summary_info += {'nettle': nettle}
3505 summary_info += {' XTS': xts != 'private'}
3507 summary_info += {'AF_ALG support': have_afalg}
3508 summary_info += {'rng-none': get_option('rng_none')}
3509 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
3510 summary(summary_info, bool_yn: true, section: 'Crypto')
3514 if targetos == 'darwin'
3515 summary_info += {'Cocoa support': cocoa}
3517 summary_info += {'SDL support': sdl}
3518 summary_info += {'SDL image support': sdl_image}
3519 summary_info += {'GTK support': gtk}
3520 summary_info += {'pixman': pixman}
3521 summary_info += {'VTE support': vte}
3522 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3523 summary_info += {'libtasn1': tasn1}
3524 summary_info += {'PAM': pam}
3525 summary_info += {'iconv support': iconv}
3526 summary_info += {'curses support': curses}
3527 summary_info += {'virgl support': virgl}
3528 summary_info += {'curl support': curl}
3529 summary_info += {'Multipath support': mpathpersist}
3530 summary_info += {'VNC support': vnc}
3532 summary_info += {'VNC SASL support': sasl}
3533 summary_info += {'VNC JPEG support': jpeg}
3534 summary_info += {'VNC PNG support': png}
3536 if targetos not in ['darwin', 'haiku', 'windows']
3537 summary_info += {'OSS support': oss}
3538 elif targetos == 'darwin'
3539 summary_info += {'CoreAudio support': coreaudio}
3540 elif targetos == 'windows'
3541 summary_info += {'DirectSound support': dsound}
3543 if targetos == 'linux'
3544 summary_info += {'ALSA support': alsa}
3545 summary_info += {'PulseAudio support': pulse}
3547 summary_info += {'JACK support': jack}
3548 summary_info += {'brlapi support': brlapi}
3549 summary_info += {'vde support': vde}
3550 summary_info += {'netmap support': have_netmap}
3551 summary_info += {'l2tpv3 support': have_l2tpv3}
3552 summary_info += {'Linux AIO support': libaio}
3553 summary_info += {'Linux io_uring support': linux_io_uring}
3554 summary_info += {'ATTR/XATTR support': libattr}
3555 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
3556 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
3557 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3558 summary_info += {'libcap-ng support': libcap_ng}
3559 summary_info += {'bpf support': libbpf}
3560 summary_info += {'spice protocol support': spice_protocol}
3561 if spice_protocol.found()
3562 summary_info += {' spice server support': spice}
3564 summary_info += {'rbd support': rbd}
3565 summary_info += {'smartcard support': cacard}
3566 summary_info += {'U2F support': u2f}
3567 summary_info += {'libusb': libusb}
3568 summary_info += {'usb net redir': usbredir}
3569 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
3570 summary_info += {'GBM': gbm}
3571 summary_info += {'libiscsi support': libiscsi}
3572 summary_info += {'libnfs support': libnfs}
3573 if targetos == 'windows'
3574 if config_host.has_key('CONFIG_GUEST_AGENT')
3575 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
3576 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
3579 summary_info += {'seccomp support': seccomp}
3580 summary_info += {'GlusterFS support': glusterfs}
3581 summary_info += {'TPM support': have_tpm}
3582 summary_info += {'libssh support': libssh}
3583 summary_info += {'lzo support': lzo}
3584 summary_info += {'snappy support': snappy}
3585 summary_info += {'bzip2 support': libbzip2}
3586 summary_info += {'lzfse support': liblzfse}
3587 summary_info += {'zstd support': zstd}
3588 summary_info += {'NUMA host support': numa}
3589 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3590 summary_info += {'libpmem support': libpmem}
3591 summary_info += {'libdaxctl support': libdaxctl}
3592 summary_info += {'libudev': libudev}
3593 # Dummy dependency, keep .found()
3594 summary_info += {'FUSE lseek': fuse_lseek.found()}
3595 summary_info += {'selinux': selinux}
3596 summary(summary_info, bool_yn: true, section: 'Dependencies')
3598 if not supported_cpus.contains(cpu)
3600 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3602 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3603 message('The QEMU project intends to remove support for this host CPU in')
3604 message('a future release if nobody volunteers to maintain it and to')
3605 message('provide a build host for our continuous integration setup.')
3606 message('configure has succeeded and you can continue to build, but')
3607 message('if you care about QEMU on this platform you should contact')
3608 message('us upstream at qemu-devel@nongnu.org.')
3611 if not supported_oses.contains(targetos)
3613 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3615 message('Host OS ' + targetos + 'support is not currently maintained.')
3616 message('The QEMU project intends to remove support for this host OS in')
3617 message('a future release if nobody volunteers to maintain it and to')
3618 message('provide a build host for our continuous integration setup.')
3619 message('configure has succeeded and you can continue to build, but')
3620 message('if you care about QEMU on this platform you should contact')
3621 message('us upstream at qemu-devel@nongnu.org.')