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 # Specify linker-script with add_project_link_arguments so that it is not placed
171 # within a linker --start-group/--end-group pair
172 if get_option('fuzzing')
173 add_project_link_arguments(['-Wl,-T,',
174 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
175 native: false, language: ['c', 'cpp', 'objc'])
177 # Specify a filter to only instrument code that is directly related to
179 configure_file(output: 'instrumentation-filter',
180 input: 'scripts/oss-fuzz/instrumentation-filter-template',
182 add_global_arguments(
183 cc.get_supported_arguments('-fsanitize-coverage-allowlist=instrumentation-filter'),
184 native: false, language: ['c', 'cpp', 'objc'])
186 if get_option('fuzzing_engine') == ''
187 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
188 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
189 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
190 # unable to bind the fuzzer-related callbacks added by instrumentation.
191 add_global_arguments('-fsanitize=fuzzer-no-link',
192 native: false, language: ['c', 'cpp', 'objc'])
193 add_global_link_arguments('-fsanitize=fuzzer-no-link',
194 native: false, language: ['c', 'cpp', 'objc'])
195 # For the actual fuzzer binaries, we need to link against the libfuzzer
196 # library. They need to be configurable, to support OSS-Fuzz
197 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
199 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
200 # the needed CFLAGS have already been provided
201 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
205 add_global_arguments(qemu_cflags, native: false, language: ['c', 'objc'])
206 add_global_arguments(qemu_cxxflags, native: false, language: ['cpp'])
207 add_global_link_arguments(qemu_ldflags, native: false, language: ['c', 'cpp', 'objc'])
209 if targetos == 'linux'
210 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
211 '-isystem', 'linux-headers',
212 language: ['c', 'cpp'])
215 add_project_arguments('-iquote', '.',
216 '-iquote', meson.current_source_dir(),
217 '-iquote', meson.current_source_dir() / 'include',
218 '-iquote', meson.current_source_dir() / 'disas/libvixl',
219 language: ['c', 'cpp', 'objc'])
221 link_language = meson.get_external_property('link_language', 'cpp')
222 if link_language == 'cpp'
223 add_languages('cpp', required: true, native: false)
224 cxx = meson.get_compiler('cpp')
229 if host_machine.system() == 'darwin'
230 add_languages('objc', required: false, native: false)
233 sparse = find_program('cgcc', required: get_option('sparse'))
236 command: [find_program('scripts/check_sparse.py'),
237 'compile_commands.json', sparse.full_path(), '-Wbitwise',
238 '-Wno-transparent-union', '-Wno-old-initializer',
239 '-Wno-non-pointer-null'])
242 ###########################################
243 # Target-specific checks and dependencies #
244 ###########################################
247 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
250 #include <sys/types.h>
251 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
252 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
254 args: ['-Werror', '-fsanitize=fuzzer'])
255 error('Your compiler does not support -fsanitize=fuzzer')
259 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
260 error('ftrace is supported only on Linux')
262 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
265 openlog("qemu", LOG_PID, LOG_DAEMON);
266 syslog(LOG_INFO, "configure");
269 error('syslog is not supported on this system')
272 # Miscellaneous Linux-only features
273 get_option('mpath') \
274 .require(targetos == 'linux', error_message: 'Multipath is supported only on Linux')
276 multiprocess_allowed = get_option('multiprocess') \
277 .require(targetos == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
280 have_tpm = get_option('tpm') \
281 .require(targetos != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
284 # Target-specific libraries and flags
285 libm = cc.find_library('m', required: false)
286 threads = dependency('threads')
287 util = cc.find_library('util', required: false)
293 emulator_link_args = []
297 if targetos == 'windows'
298 socket = cc.find_library('ws2_32')
299 winmm = cc.find_library('winmm')
301 win = import('windows')
302 version_res = win.compile_resources('version.rc',
303 depend_files: files('pc-bios/qemu-nsis.ico'),
304 include_directories: include_directories('.'))
306 elif targetos == 'darwin'
307 coref = dependency('appleframeworks', modules: 'CoreFoundation')
308 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
309 host_dsosuf = '.dylib'
310 elif targetos == 'sunos'
311 socket = [cc.find_library('socket'),
312 cc.find_library('nsl'),
313 cc.find_library('resolv')]
314 elif targetos == 'haiku'
315 socket = [cc.find_library('posix_error_mapper'),
316 cc.find_library('network'),
317 cc.find_library('bsd')]
318 elif targetos == 'openbsd'
319 if get_option('tcg').allowed() and target_dirs.length() > 0
320 # Disable OpenBSD W^X if available
321 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
325 # Target-specific configuration of accelerators
327 if get_option('kvm').allowed() and targetos == 'linux'
328 accelerators += 'CONFIG_KVM'
330 if get_option('xen').allowed() and 'CONFIG_XEN_BACKEND' in config_host
331 accelerators += 'CONFIG_XEN'
332 have_xen_pci_passthrough = get_option('xen_pci_passthrough').allowed() and targetos == 'linux'
334 have_xen_pci_passthrough = false
336 if get_option('whpx').allowed() and targetos == 'windows'
337 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
338 error('WHPX requires 64-bit host')
339 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
340 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
341 accelerators += 'CONFIG_WHPX'
344 if get_option('hvf').allowed()
345 hvf = dependency('appleframeworks', modules: 'Hypervisor',
346 required: get_option('hvf'))
348 accelerators += 'CONFIG_HVF'
351 if get_option('hax').allowed()
352 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
353 accelerators += 'CONFIG_HAX'
356 if targetos == 'netbsd'
357 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
359 accelerators += 'CONFIG_NVMM'
364 if get_option('tcg').allowed()
365 if host_arch == 'unknown'
366 if get_option('tcg_interpreter')
367 warning('Unsupported CPU @0@, will use TCG with TCI (slow)'.format(cpu))
369 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
371 elif get_option('tcg_interpreter')
372 warning('Use of the TCG interpreter is not recommended on this host')
373 warning('architecture. There is a native TCG execution backend available')
374 warning('which provides substantially better performance and reliability.')
375 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
376 warning('configuration option on this architecture to use the native')
379 if get_option('tcg_interpreter')
381 elif host_arch == 'sparc64'
383 elif host_arch == 'x86_64'
385 elif host_arch == 'ppc64'
388 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
389 language: ['c', 'cpp', 'objc'])
391 accelerators += 'CONFIG_TCG'
392 config_host += { 'CONFIG_TCG': 'y' }
395 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
396 error('KVM not available on this platform')
398 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
399 error('HVF not available on this platform')
401 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
402 error('NVMM not available on this platform')
404 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
405 error('WHPX not available on this platform')
407 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
408 if 'CONFIG_XEN' in accelerators
409 error('Xen PCI passthrough not available on this platform')
411 error('Xen PCI passthrough requested but Xen not enabled')
419 # The path to glib.h is added to all compilation commands. This was
420 # grandfathered in from the QEMU Makefiles.
421 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
422 native: false, language: ['c', 'cpp', 'objc'])
423 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
424 link_args: config_host['GLIB_LIBS'].split(),
425 version: config_host['GLIB_VERSION'])
426 # override glib dep with the configure results (for subprojects)
427 meson.override_dependency('glib-2.0', glib)
430 if 'CONFIG_GIO' in config_host
431 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
432 link_args: config_host['GIO_LIBS'].split(),
433 version: config_host['GLIB_VERSION'])
436 if 'ust' in get_option('trace_backends')
437 lttng = dependency('lttng-ust', required: true, method: 'pkg-config',
438 kwargs: static_kwargs)
441 if have_system or have_tools
442 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
443 method: 'pkg-config', kwargs: static_kwargs)
445 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
448 if not get_option('linux_aio').auto() or have_block
449 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
450 required: get_option('linux_aio'),
451 kwargs: static_kwargs)
453 linux_io_uring = not_found
454 if not get_option('linux_io_uring').auto() or have_block
455 linux_io_uring = dependency('liburing', version: '>=0.3',
456 required: get_option('linux_io_uring'),
457 method: 'pkg-config', kwargs: static_kwargs)
460 if not get_option('libnfs').auto() or have_block
461 libnfs = dependency('libnfs', version: '>=1.9.3',
462 required: get_option('libnfs'),
463 method: 'pkg-config', kwargs: static_kwargs)
468 #include <sys/types.h>
469 #ifdef CONFIG_LIBATTR
470 #include <attr/xattr.h>
472 #include <sys/xattr.h>
474 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
477 have_old_libattr = false
478 if get_option('attr').allowed()
479 if cc.links(libattr_test)
480 libattr = declare_dependency()
482 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
483 required: get_option('attr'),
484 kwargs: static_kwargs)
485 if libattr.found() and not \
486 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
488 if get_option('attr').enabled()
489 error('could not link libattr')
491 warning('could not link libattr, disabling')
494 have_old_libattr = libattr.found()
499 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
500 if cocoa.found() and get_option('sdl').enabled()
501 error('Cocoa and SDL cannot be enabled at the same time')
503 if cocoa.found() and get_option('gtk').enabled()
504 error('Cocoa and GTK+ cannot be enabled at the same time')
508 if not get_option('seccomp').auto() or have_system or have_tools
509 seccomp = dependency('libseccomp', version: '>=2.3.0',
510 required: get_option('seccomp'),
511 method: 'pkg-config', kwargs: static_kwargs)
514 libcap_ng = not_found
515 if not get_option('cap_ng').auto() or have_system or have_tools
516 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
517 required: get_option('cap_ng'),
518 kwargs: static_kwargs)
520 if libcap_ng.found() and not cc.links('''
524 capng_capability_to_name(CAPNG_EFFECTIVE);
526 }''', dependencies: libcap_ng)
527 libcap_ng = not_found
528 if get_option('cap_ng').enabled()
529 error('could not link libcap-ng')
531 warning('could not link libcap-ng, disabling')
535 if get_option('xkbcommon').auto() and not have_system and not have_tools
536 xkbcommon = not_found
538 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
539 method: 'pkg-config', kwargs: static_kwargs)
543 if not get_option('vde').auto() or have_system or have_tools
544 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
545 required: get_option('vde'),
546 kwargs: static_kwargs)
548 if vde.found() and not cc.links('''
549 #include <libvdeplug.h>
552 struct vde_open_args a = {0, 0, 0};
556 }''', dependencies: vde)
558 if get_option('cap_ng').enabled()
559 error('could not link libvdeplug')
561 warning('could not link libvdeplug, disabling')
566 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
567 pulse = dependency('libpulse', required: get_option('pa'),
568 method: 'pkg-config', kwargs: static_kwargs)
571 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
572 alsa = dependency('alsa', required: get_option('alsa'),
573 method: 'pkg-config', kwargs: static_kwargs)
576 if not get_option('jack').auto() or have_system
577 jack = dependency('jack', required: get_option('jack'),
578 method: 'pkg-config', kwargs: static_kwargs)
581 spice_protocol = not_found
582 if not get_option('spice_protocol').auto() or have_system
583 spice_protocol = dependency('spice-protocol', version: '>=0.12.3',
584 required: get_option('spice_protocol'),
585 method: 'pkg-config', kwargs: static_kwargs)
588 if not get_option('spice').auto() or have_system
589 spice = dependency('spice-server', version: '>=0.12.5',
590 required: get_option('spice'),
591 method: 'pkg-config', kwargs: static_kwargs)
593 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
595 rt = cc.find_library('rt', required: false)
598 if not get_option('libiscsi').auto() or have_block
599 libiscsi = dependency('libiscsi', version: '>=1.9.0',
600 required: get_option('libiscsi'),
601 method: 'pkg-config', kwargs: static_kwargs)
604 if not get_option('zstd').auto() or have_block
605 zstd = dependency('libzstd', version: '>=1.4.0',
606 required: get_option('zstd'),
607 method: 'pkg-config', kwargs: static_kwargs)
610 if not get_option('virglrenderer').auto() or have_system
611 virgl = dependency('virglrenderer',
612 method: 'pkg-config',
613 required: get_option('virglrenderer'),
614 kwargs: static_kwargs)
617 if not get_option('curl').auto() or have_block
618 curl = dependency('libcurl', version: '>=7.29.0',
619 method: 'pkg-config',
620 required: get_option('curl'),
621 kwargs: static_kwargs)
624 if targetos == 'linux' and (have_system or have_tools)
625 libudev = dependency('libudev',
626 method: 'pkg-config',
627 required: get_option('libudev'),
628 kwargs: static_kwargs)
631 mpathlibs = [libudev]
632 mpathpersist = not_found
633 mpathpersist_new_api = false
634 if targetos == 'linux' and have_tools and get_option('mpath').allowed()
635 mpath_test_source_new = '''
637 #include <mpath_persist.h>
638 unsigned mpath_mx_alloc_len = 1024;
640 static struct config *multipath_conf;
641 extern struct udev *udev;
642 extern struct config *get_multipath_config(void);
643 extern void put_multipath_config(struct config *conf);
645 struct config *get_multipath_config(void) { return multipath_conf; }
646 void put_multipath_config(struct config *conf) { }
649 multipath_conf = mpath_lib_init();
652 mpath_test_source_old = '''
654 #include <mpath_persist.h>
655 unsigned mpath_mx_alloc_len = 1024;
658 struct udev *udev = udev_new();
659 mpath_lib_init(udev);
662 libmpathpersist = cc.find_library('mpathpersist',
663 required: get_option('mpath'),
664 kwargs: static_kwargs)
665 if libmpathpersist.found()
666 mpathlibs += libmpathpersist
668 mpathlibs += cc.find_library('devmapper',
669 required: get_option('mpath'),
670 kwargs: static_kwargs)
672 mpathlibs += cc.find_library('multipath',
673 required: get_option('mpath'),
674 kwargs: static_kwargs)
675 foreach lib: mpathlibs
681 if mpathlibs.length() == 0
682 msg = 'Dependencies missing for libmpathpersist'
683 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
684 mpathpersist = declare_dependency(dependencies: mpathlibs)
685 mpathpersist_new_api = true
686 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
687 mpathpersist = declare_dependency(dependencies: mpathlibs)
689 msg = 'Cannot detect libmpathpersist API'
691 if not mpathpersist.found()
692 if get_option('mpath').enabled()
695 warning(msg + ', disabling')
703 if have_system and get_option('curses').allowed()
705 #if defined(__APPLE__) || defined(__OpenBSD__)
706 #define _XOPEN_SOURCE_EXTENDED 1
713 setlocale(LC_ALL, "");
715 addwstr(L"wide chars\n");
717 add_wch(WACS_DEGREE);
721 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
722 foreach curses_dep : curses_dep_list
723 if not curses.found()
724 curses = dependency(curses_dep,
726 method: 'pkg-config',
727 kwargs: static_kwargs)
730 msg = get_option('curses').enabled() ? 'curses library not found' : ''
731 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
733 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
734 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
736 msg = 'curses package not usable'
740 if not curses.found()
741 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
742 if targetos != 'windows' and not has_curses_h
743 message('Trying with /usr/include/ncursesw')
744 curses_compile_args += ['-I/usr/include/ncursesw']
745 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
748 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
749 foreach curses_libname : curses_libname_list
750 libcurses = cc.find_library(curses_libname,
752 kwargs: static_kwargs)
754 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
755 curses = declare_dependency(compile_args: curses_compile_args,
756 dependencies: [libcurses])
759 msg = 'curses library not usable'
765 if get_option('iconv').allowed()
766 foreach link_args : [ ['-liconv'], [] ]
767 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
768 # We need to use libiconv if available because mixing libiconv's headers with
769 # the system libc does not work.
770 # However, without adding glib to the dependencies -L/usr/local/lib will not be
771 # included in the command line and libiconv will not be found.
775 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
776 return conv != (iconv_t) -1;
777 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
778 iconv = declare_dependency(link_args: link_args, dependencies: glib)
783 if curses.found() and not iconv.found()
784 if get_option('iconv').enabled()
785 error('iconv not available')
787 msg = 'iconv required for curses UI but not available'
790 if not curses.found() and msg != ''
791 if get_option('curses').enabled()
794 warning(msg + ', disabling')
800 if not get_option('brlapi').auto() or have_system
801 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
802 required: get_option('brlapi'),
803 kwargs: static_kwargs)
804 if brlapi.found() and not cc.links('''
807 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
809 if get_option('brlapi').enabled()
810 error('could not link brlapi')
812 warning('could not link brlapi, disabling')
818 if not get_option('sdl').auto() or (have_system and not cocoa.found())
819 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
820 sdl_image = not_found
823 # work around 2.0.8 bug
824 sdl = declare_dependency(compile_args: '-Wno-undef',
826 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
827 method: 'pkg-config', kwargs: static_kwargs)
829 if get_option('sdl_image').enabled()
830 error('sdl-image required, but SDL was @0@'.format(
831 get_option('sdl').disabled() ? 'disabled' : 'not found'))
833 sdl_image = not_found
837 if not get_option('rbd').auto() or have_block
838 librados = cc.find_library('rados', required: get_option('rbd'),
839 kwargs: static_kwargs)
840 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
841 required: get_option('rbd'),
842 kwargs: static_kwargs)
843 if librados.found() and librbd.found()
846 #include <rbd/librbd.h>
849 rados_create(&cluster, NULL);
850 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
854 }''', dependencies: [librbd, librados])
855 rbd = declare_dependency(dependencies: [librbd, librados])
856 elif get_option('rbd').enabled()
857 error('librbd >= 1.12.0 required')
859 warning('librbd >= 1.12.0 not found, disabling')
864 glusterfs = not_found
865 glusterfs_ftruncate_has_stat = false
866 glusterfs_iocb_has_stat = false
867 if not get_option('glusterfs').auto() or have_block
868 glusterfs = dependency('glusterfs-api', version: '>=3',
869 required: get_option('glusterfs'),
870 method: 'pkg-config', kwargs: static_kwargs)
872 glusterfs_ftruncate_has_stat = cc.links('''
873 #include <glusterfs/api/glfs.h>
878 /* new glfs_ftruncate() passes two additional args */
879 return glfs_ftruncate(NULL, 0, NULL, NULL);
881 ''', dependencies: glusterfs)
882 glusterfs_iocb_has_stat = cc.links('''
883 #include <glusterfs/api/glfs.h>
885 /* new glfs_io_cbk() passes two additional glfs_stat structs */
887 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
893 glfs_io_cbk iocb = &glusterfs_iocb;
894 iocb(NULL, 0 , NULL, NULL, NULL);
897 ''', dependencies: glusterfs)
902 if not get_option('libssh').auto() or have_block
903 libssh = dependency('libssh', version: '>=0.8.7',
904 method: 'pkg-config',
905 required: get_option('libssh'),
906 kwargs: static_kwargs)
910 if not get_option('bzip2').auto() or have_block
911 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
912 required: get_option('bzip2'),
913 kwargs: static_kwargs)
914 if libbzip2.found() and not cc.links('''
916 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
918 if get_option('bzip2').enabled()
919 error('could not link libbzip2')
921 warning('could not link libbzip2, disabling')
927 if not get_option('lzfse').auto() or have_block
928 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
929 required: get_option('lzfse'),
930 kwargs: static_kwargs)
932 if liblzfse.found() and not cc.links('''
934 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
936 if get_option('lzfse').enabled()
937 error('could not link liblzfse')
939 warning('could not link liblzfse, disabling')
944 if get_option('oss').allowed() and have_system
945 if not cc.has_header('sys/soundcard.h')
947 elif targetos == 'netbsd'
948 oss = cc.find_library('ossaudio', required: get_option('oss'),
949 kwargs: static_kwargs)
951 oss = declare_dependency()
955 if get_option('oss').enabled()
956 error('OSS not found')
961 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
962 if cc.has_header('dsound.h')
963 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
966 if not dsound.found()
967 if get_option('dsound').enabled()
968 error('DirectSound not found')
973 coreaudio = not_found
974 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
975 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
976 required: get_option('coreaudio'))
980 if 'CONFIG_OPENGL' in config_host
981 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
982 link_args: config_host['OPENGL_LIBS'].split())
985 if (have_system or have_tools) and (virgl.found() or opengl.found())
986 gbm = dependency('gbm', method: 'pkg-config', required: false,
987 kwargs: static_kwargs)
991 gnutls_crypto = not_found
992 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
993 # For general TLS support our min gnutls matches
994 # that implied by our platform support matrix
996 # For the crypto backends, we look for a newer
999 # Version 3.6.8 is needed to get XTS
1000 # Version 3.6.13 is needed to get PBKDF
1001 # Version 3.6.14 is needed to get HW accelerated XTS
1003 # If newer enough gnutls isn't available, we can
1004 # still use a different crypto backend to satisfy
1005 # the platform support requirements
1006 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1007 method: 'pkg-config',
1009 kwargs: static_kwargs)
1010 if gnutls_crypto.found()
1011 gnutls = gnutls_crypto
1013 # Our min version if all we need is TLS
1014 gnutls = dependency('gnutls', version: '>=3.5.18',
1015 method: 'pkg-config',
1016 required: get_option('gnutls'),
1017 kwargs: static_kwargs)
1021 # We prefer use of gnutls for crypto, unless the options
1022 # explicitly asked for nettle or gcrypt.
1024 # If gnutls isn't available for crypto, then we'll prefer
1025 # gcrypt over nettle for performance reasons.
1030 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1031 error('Only one of gcrypt & nettle can be enabled')
1034 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1035 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1036 gnutls_crypto = not_found
1039 if not gnutls_crypto.found()
1040 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1041 gcrypt = dependency('libgcrypt', version: '>=1.8',
1042 method: 'config-tool',
1043 required: get_option('gcrypt'),
1044 kwargs: static_kwargs)
1045 # Debian has removed -lgpg-error from libgcrypt-config
1046 # as it "spreads unnecessary dependencies" which in
1047 # turn breaks static builds...
1048 if gcrypt.found() and enable_static
1049 gcrypt = declare_dependency(dependencies: [
1051 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
1054 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1055 nettle = dependency('nettle', version: '>=3.4',
1056 method: 'pkg-config',
1057 required: get_option('nettle'),
1058 kwargs: static_kwargs)
1059 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1068 if not get_option('gtk').auto() or (have_system and not cocoa.found())
1069 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1070 method: 'pkg-config',
1071 required: get_option('gtk'),
1072 kwargs: static_kwargs)
1074 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1075 method: 'pkg-config',
1077 kwargs: static_kwargs)
1078 gtk = declare_dependency(dependencies: [gtk, gtkx11])
1080 if not get_option('vte').auto() or have_system
1081 vte = dependency('vte-2.91',
1082 method: 'pkg-config',
1083 required: get_option('vte'),
1084 kwargs: static_kwargs)
1091 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
1092 kwargs: static_kwargs)
1098 if get_option('vnc').allowed() and have_system
1099 vnc = declare_dependency() # dummy dependency
1100 png = dependency('libpng', required: get_option('vnc_png'),
1101 method: 'pkg-config', kwargs: static_kwargs)
1102 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1103 method: 'pkg-config', kwargs: static_kwargs)
1104 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1105 required: get_option('vnc_sasl'),
1106 kwargs: static_kwargs)
1108 sasl = declare_dependency(dependencies: sasl,
1109 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1114 if not get_option('auth_pam').auto() or have_system
1115 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1116 required: get_option('auth_pam'),
1117 kwargs: static_kwargs)
1119 if pam.found() and not cc.links('''
1121 #include <security/pam_appl.h>
1123 const char *service_name = "qemu";
1124 const char *user = "frank";
1125 const struct pam_conv pam_conv = { 0 };
1126 pam_handle_t *pamh = NULL;
1127 pam_start(service_name, user, &pam_conv, &pamh);
1129 }''', dependencies: pam)
1131 if get_option('auth_pam').enabled()
1132 error('could not link libpam')
1134 warning('could not link libpam, disabling')
1139 if not get_option('snappy').auto() or have_system
1140 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1141 required: get_option('snappy'),
1142 kwargs: static_kwargs)
1144 if snappy.found() and not linker.links('''
1145 #include <snappy-c.h>
1146 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1148 if get_option('snappy').enabled()
1149 error('could not link libsnappy')
1151 warning('could not link libsnappy, disabling')
1156 if not get_option('lzo').auto() or have_system
1157 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1158 required: get_option('lzo'),
1159 kwargs: static_kwargs)
1161 if lzo.found() and not cc.links('''
1162 #include <lzo/lzo1x.h>
1163 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1165 if get_option('lzo').enabled()
1166 error('could not link liblzo2')
1168 warning('could not link liblzo2, disabling')
1173 if not get_option('numa').auto() or have_system or have_tools
1174 numa = cc.find_library('numa', has_headers: ['numa.h'],
1175 required: get_option('numa'),
1176 kwargs: static_kwargs)
1178 if numa.found() and not cc.links('''
1180 int main(void) { return numa_available(); }
1181 ''', dependencies: numa)
1183 if get_option('numa').enabled()
1184 error('could not link numa')
1186 warning('could not link numa, disabling')
1191 if 'CONFIG_RDMA' in config_host
1192 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
1195 if 'CONFIG_XEN_BACKEND' in config_host
1196 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
1197 link_args: config_host['XEN_LIBS'].split())
1200 if not get_option('smartcard').auto() or have_system
1201 cacard = dependency('libcacard', required: get_option('smartcard'),
1202 version: '>=2.5.1', method: 'pkg-config',
1203 kwargs: static_kwargs)
1207 u2f = dependency('u2f-emu', required: get_option('u2f'),
1208 method: 'pkg-config',
1209 kwargs: static_kwargs)
1211 usbredir = not_found
1212 if not get_option('usb_redir').auto() or have_system
1213 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1214 version: '>=0.6', method: 'pkg-config',
1215 kwargs: static_kwargs)
1218 if not get_option('libusb').auto() or have_system
1219 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1220 version: '>=1.0.13', method: 'pkg-config',
1221 kwargs: static_kwargs)
1225 if not get_option('libpmem').auto() or have_system
1226 libpmem = dependency('libpmem', required: get_option('libpmem'),
1227 method: 'pkg-config', kwargs: static_kwargs)
1229 libdaxctl = not_found
1230 if not get_option('libdaxctl').auto() or have_system
1231 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1232 version: '>=57', method: 'pkg-config',
1233 kwargs: static_kwargs)
1237 tasn1 = dependency('libtasn1',
1238 method: 'pkg-config',
1239 kwargs: static_kwargs)
1241 keyutils = dependency('libkeyutils', required: false,
1242 method: 'pkg-config', kwargs: static_kwargs)
1244 has_gettid = cc.has_function('gettid')
1247 selinux = dependency('libselinux',
1248 required: get_option('selinux'),
1249 method: 'pkg-config', kwargs: static_kwargs)
1254 if get_option('malloc') == 'system'
1256 get_option('malloc_trim').allowed() and \
1257 cc.links('''#include <malloc.h>
1258 int main(void) { malloc_trim(0); return 0; }''')
1260 has_malloc_trim = false
1261 malloc = cc.find_library(get_option('malloc'), required: true)
1263 if not has_malloc_trim and get_option('malloc_trim').enabled()
1264 if get_option('malloc') == 'system'
1265 error('malloc_trim not available on this platform.')
1267 error('malloc_trim not available with non-libc memory allocator')
1271 # Check whether the glibc provides statx()
1273 gnu_source_prefix = '''
1278 statx_test = gnu_source_prefix + '''
1279 #include <sys/stat.h>
1281 struct statx statxbuf;
1282 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1286 has_statx = cc.links(statx_test)
1288 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
1289 .require(targetos == 'linux',
1290 error_message: 'vhost_user_blk_server requires linux') \
1291 .require('CONFIG_VHOST_USER' in config_host,
1292 error_message: 'vhost_user_blk_server requires vhost-user support') \
1293 .disable_auto_if(not have_system) \
1296 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1297 error('Cannot enable fuse-lseek while fuse is disabled')
1300 fuse = dependency('fuse3', required: get_option('fuse'),
1301 version: '>=3.1', method: 'pkg-config',
1302 kwargs: static_kwargs)
1304 fuse_lseek = not_found
1305 if get_option('fuse_lseek').allowed()
1306 if fuse.version().version_compare('>=3.8')
1308 fuse_lseek = declare_dependency()
1309 elif get_option('fuse_lseek').enabled()
1311 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1313 error('fuse-lseek requires libfuse, which was not found')
1319 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1320 if libbpf.found() and not cc.links('''
1321 #include <bpf/libbpf.h>
1324 bpf_object__destroy_skeleton(NULL);
1326 }''', dependencies: libbpf)
1328 if get_option('bpf').enabled()
1329 error('libbpf skeleton test failed')
1331 warning('libbpf skeleton test failed, disabling')
1339 audio_drivers_selected = []
1341 audio_drivers_available = {
1342 'alsa': alsa.found(),
1343 'coreaudio': coreaudio.found(),
1344 'dsound': dsound.found(),
1345 'jack': jack.found(),
1347 'pa': pulse.found(),
1350 foreach k, v: audio_drivers_available
1351 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1354 # Default to native drivers first, OSS second, SDL third
1355 audio_drivers_priority = \
1356 [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
1357 (targetos == 'linux' ? [] : [ 'sdl' ])
1358 audio_drivers_default = []
1359 foreach k: audio_drivers_priority
1360 if audio_drivers_available[k]
1361 audio_drivers_default += k
1365 foreach k: get_option('audio_drv_list')
1367 audio_drivers_selected += audio_drivers_default
1368 elif not audio_drivers_available[k]
1369 error('Audio driver "@0@" not available.'.format(k))
1371 audio_drivers_selected += k
1375 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1376 '"' + '", "'.join(audio_drivers_selected) + '", ')
1378 if get_option('cfi')
1380 # Check for dependency on LTO
1381 if not get_option('b_lto')
1382 error('Selected Control-Flow Integrity but LTO is disabled')
1384 if config_host.has_key('CONFIG_MODULES')
1385 error('Selected Control-Flow Integrity is not compatible with modules')
1387 # Check for cfi flags. CFI requires LTO so we can't use
1388 # get_supported_arguments, but need a more complex "compiles" which allows
1390 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1391 args: ['-flto', '-fsanitize=cfi-icall'] )
1392 cfi_flags += '-fsanitize=cfi-icall'
1394 error('-fsanitize=cfi-icall is not supported by the compiler')
1396 if cc.compiles('int main () { return 0; }',
1397 name: '-fsanitize-cfi-icall-generalize-pointers',
1398 args: ['-flto', '-fsanitize=cfi-icall',
1399 '-fsanitize-cfi-icall-generalize-pointers'] )
1400 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1402 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1404 if get_option('cfi_debug')
1405 if cc.compiles('int main () { return 0; }',
1406 name: '-fno-sanitize-trap=cfi-icall',
1407 args: ['-flto', '-fsanitize=cfi-icall',
1408 '-fno-sanitize-trap=cfi-icall'] )
1409 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1411 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1414 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1415 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1418 have_host_block_device = (targetos != 'darwin' or
1419 cc.has_header('IOKit/storage/IOMedia.h'))
1421 # FIXME enable_modules shouldn't be necessary, but: https://github.com/mesonbuild/meson/issues/8333
1422 dbus_display = get_option('dbus_display') \
1423 .require(gio.version().version_compare('>=2.64'),
1424 error_message: '-display dbus requires glib>=2.64') \
1425 .require(enable_modules,
1426 error_message: '-display dbus requires --enable-modules') \
1427 .require(config_host.has_key('GDBUS_CODEGEN'),
1428 error_message: '-display dbus requires gdbus-codegen') \
1431 have_virtfs = get_option('virtfs') \
1432 .require(targetos == 'linux',
1433 error_message: 'virtio-9p (virtfs) requires Linux') \
1434 .require(libattr.found() and libcap_ng.found(),
1435 error_message: 'virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel') \
1436 .disable_auto_if(not have_tools and not have_system) \
1439 have_virtfs_proxy_helper = have_virtfs and have_tools
1441 foreach k : get_option('trace_backends')
1442 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1444 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1446 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1447 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1448 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1449 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1450 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1451 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1452 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1453 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1454 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1455 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1456 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1457 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1459 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
1461 config_host_data.set('CONFIG_ATTR', libattr.found())
1462 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1463 config_host_data.set('CONFIG_COCOA', cocoa.found())
1464 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1465 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1466 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1467 config_host_data.set('CONFIG_LZO', lzo.found())
1468 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1469 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1470 config_host_data.set('CONFIG_CURL', curl.found())
1471 config_host_data.set('CONFIG_CURSES', curses.found())
1472 config_host_data.set('CONFIG_GBM', gbm.found())
1473 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1474 if glusterfs.found()
1475 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1476 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1477 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1478 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1479 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1480 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1482 config_host_data.set('CONFIG_GTK', gtk.found())
1483 config_host_data.set('CONFIG_VTE', vte.found())
1484 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1485 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1486 config_host_data.set('CONFIG_EBPF', libbpf.found())
1487 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1488 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1489 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1490 config_host_data.set('CONFIG_LIBSSH', libssh.found())
1491 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1492 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1493 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1494 config_host_data.set('CONFIG_NUMA', numa.found())
1495 config_host_data.set('CONFIG_RBD', rbd.found())
1496 config_host_data.set('CONFIG_SDL', sdl.found())
1497 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1498 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1499 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1500 config_host_data.set('CONFIG_TPM', have_tpm)
1501 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1502 config_host_data.set('CONFIG_VDE', vde.found())
1503 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1504 config_host_data.set('CONFIG_VNC', vnc.found())
1505 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1506 config_host_data.set('CONFIG_VNC_PNG', png.found())
1507 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1508 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1509 config_host_data.set('CONFIG_VTE', vte.found())
1510 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1511 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1512 config_host_data.set('CONFIG_GETTID', has_gettid)
1513 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1514 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1515 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1516 config_host_data.set('CONFIG_NETTLE', nettle.found())
1517 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1518 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1519 config_host_data.set('CONFIG_STATX', has_statx)
1520 config_host_data.set('CONFIG_ZSTD', zstd.found())
1521 config_host_data.set('CONFIG_FUSE', fuse.found())
1522 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1523 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1524 if spice_protocol.found()
1525 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
1526 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
1527 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
1529 config_host_data.set('CONFIG_SPICE', spice.found())
1530 config_host_data.set('CONFIG_X11', x11.found())
1531 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
1532 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1533 config_host_data.set('CONFIG_SELINUX', selinux.found())
1534 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1535 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1536 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1537 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1539 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1540 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1541 config_host_data.set('HOST_WORDS_BIGENDIAN', host_machine.endian() == 'big')
1543 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
1544 config_host_data.set('CONFIG_REPLICATION', get_option('live_block_migration').allowed())
1547 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1548 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1549 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1550 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1551 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1552 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1553 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1554 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1555 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1558 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1559 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1560 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1561 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1562 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1563 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
1564 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1565 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1566 config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
1567 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1568 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1569 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1570 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1571 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1572 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1573 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1574 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1575 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1577 config_host_data.set('HAVE_IBV_ADVISE_MR',
1578 cc.has_function('ibv_advise_mr',
1579 args: config_host['RDMA_LIBS'].split(),
1580 prefix: '#include <infiniband/verbs.h>'))
1584 config_host_data.set('CONFIG_BYTESWAP_H',
1585 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1586 config_host_data.set('CONFIG_EPOLL_CREATE1',
1587 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1588 config_host_data.set('CONFIG_HAS_ENVIRON',
1589 cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix))
1590 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1591 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1592 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1593 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1594 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1595 config_host_data.set('CONFIG_FIEMAP',
1596 cc.has_header('linux/fiemap.h') and
1597 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1598 config_host_data.set('CONFIG_GETRANDOM',
1599 cc.has_function('getrandom') and
1600 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1601 config_host_data.set('CONFIG_INOTIFY',
1602 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1603 config_host_data.set('CONFIG_INOTIFY1',
1604 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1605 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1606 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1607 prefix: '''#include <sys/endian.h>
1608 #include <sys/types.h>'''))
1609 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1610 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1611 config_host_data.set('CONFIG_RTNETLINK',
1612 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1613 config_host_data.set('CONFIG_SYSMACROS',
1614 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1615 config_host_data.set('HAVE_OPTRESET',
1616 cc.has_header_symbol('getopt.h', 'optreset'))
1617 config_host_data.set('HAVE_IPPROTO_MPTCP',
1618 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1621 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1622 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1623 prefix: '#include <signal.h>'))
1624 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1625 cc.has_member('struct stat', 'st_atim',
1626 prefix: '#include <sys/stat.h>'))
1629 config_host_data.set('CONFIG_IOVEC',
1630 cc.has_type('struct iovec',
1631 prefix: '#include <sys/uio.h>'))
1632 config_host_data.set('HAVE_UTMPX',
1633 cc.has_type('struct utmpx',
1634 prefix: '#include <utmpx.h>'))
1636 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1637 #include <sys/eventfd.h>
1638 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1639 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1642 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1643 return fdatasync(0);
1645 #error Not supported
1648 config_host_data.set('CONFIG_MADVISE', cc.links(gnu_source_prefix + '''
1649 #include <sys/types.h>
1650 #include <sys/mman.h>
1652 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }'''))
1653 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1654 #include <sys/mman.h>
1655 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1656 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1658 #if !defined(AT_EMPTY_PATH)
1659 # error missing definition
1661 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1663 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1670 return pipe2(pipefd, O_CLOEXEC);
1672 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1673 #include <sys/mman.h>
1675 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1677 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
1678 #include <pthread.h>
1680 static void *f(void *p) { return NULL; }
1684 pthread_create(&thread, 0, f, 0);
1685 pthread_setname_np(thread, "QEMU");
1687 }''', dependencies: threads))
1688 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
1689 #include <pthread.h>
1691 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
1695 pthread_create(&thread, 0, f, 0);
1697 }''', dependencies: threads))
1699 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1700 #include <sys/signalfd.h>
1702 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1703 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1711 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1712 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1716 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
1717 #include <sys/mman.h>
1718 int main(int argc, char *argv[]) {
1719 return mlockall(MCL_FUTURE);
1723 if get_option('l2tpv3').allowed() and have_system
1724 have_l2tpv3 = cc.has_type('struct mmsghdr',
1725 prefix: gnu_source_prefix + '''
1726 #include <sys/socket.h>
1727 #include <linux/ip.h>''')
1729 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
1732 if get_option('netmap').allowed() and have_system
1733 have_netmap = cc.compiles('''
1734 #include <inttypes.h>
1736 #include <net/netmap.h>
1737 #include <net/netmap_user.h>
1738 #if (NETMAP_API < 11) || (NETMAP_API > 15)
1741 int main(void) { return 0; }''')
1742 if not have_netmap and get_option('netmap').enabled()
1743 error('Netmap headers not available')
1746 config_host_data.set('CONFIG_NETMAP', have_netmap)
1748 # Work around a system header bug with some kernel/XFS header
1749 # versions where they both try to define 'struct fsxattr':
1750 # xfs headers will not try to redefine structs from linux headers
1751 # if this macro is set.
1752 config_host_data.set('HAVE_FSXATTR', cc.links('''
1753 #include <linux/fs.h>
1759 # Some versions of Mac OS X incorrectly define SIZE_MAX
1760 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1763 int main(int argc, char *argv[]) {
1764 return printf("%zu", SIZE_MAX);
1765 }''', args: ['-Werror']))
1767 # See if 64-bit atomic operations are supported.
1768 # Note that without __atomic builtins, we can only
1769 # assume atomic loads/stores max at pointer size.
1770 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
1774 uint64_t x = 0, y = 0;
1775 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
1776 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
1777 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
1778 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
1779 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
1783 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
1784 #include <sys/auxv.h>
1786 return getauxval(AT_HWCAP) == 0;
1789 have_cpuid_h = cc.links('''
1792 unsigned a, b, c, d;
1793 unsigned max = __get_cpuid_max(0, 0);
1796 __cpuid(1, a, b, c, d);
1800 __cpuid_count(7, 0, a, b, c, d);
1805 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
1807 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
1808 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
1809 .require(cc.links('''
1810 #pragma GCC push_options
1811 #pragma GCC target("avx2")
1813 #include <immintrin.h>
1814 static int bar(void *a) {
1815 __m256i x = *(__m256i *)a;
1816 return _mm256_testz_si256(x, x);
1818 int main(int argc, char *argv[]) { return bar(argv[0]); }
1819 '''), error_message: 'AVX2 not available').allowed())
1821 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
1822 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
1823 .require(cc.links('''
1824 #pragma GCC push_options
1825 #pragma GCC target("avx512f")
1827 #include <immintrin.h>
1828 static int bar(void *a) {
1829 __m512i x = *(__m512i *)a;
1830 return _mm512_test_epi64_mask(x, x);
1832 int main(int argc, char *argv[]) { return bar(argv[0]); }
1833 '''), error_message: 'AVX512F not available').allowed())
1835 if get_option('membarrier').disabled()
1836 have_membarrier = false
1837 elif targetos == 'windows'
1838 have_membarrier = true
1839 elif targetos == 'linux'
1840 have_membarrier = cc.compiles('''
1841 #include <linux/membarrier.h>
1842 #include <sys/syscall.h>
1846 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
1847 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
1851 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
1852 .require(have_membarrier, error_message: 'membarrier system call not available') \
1855 have_afalg = get_option('crypto_afalg') \
1856 .require(cc.compiles(gnu_source_prefix + '''
1858 #include <sys/types.h>
1859 #include <sys/socket.h>
1860 #include <linux/if_alg.h>
1863 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
1866 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
1867 config_host_data.set('CONFIG_AF_ALG', have_afalg)
1869 config_host_data.set('CONFIG_AF_VSOCK', cc.compiles(gnu_source_prefix + '''
1871 #include <sys/types.h>
1872 #include <sys/socket.h>
1873 #if !defined(AF_VSOCK)
1874 # error missing AF_VSOCK flag
1876 #include <linux/vm_sockets.h>
1879 struct sockaddr_vm svm;
1880 socklen_t len = sizeof(svm);
1881 sock = socket(AF_VSOCK, SOCK_STREAM, 0);
1882 ret = getpeername(sock, (struct sockaddr *)&svm, &len);
1883 if ((ret == -1) && (errno == ENOTCONN)) {
1889 ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target
1891 arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1892 strings = ['CONFIG_IASL']
1893 foreach k, v: config_host
1894 if ignored.contains(k)
1896 elif arrays.contains(k)
1898 v = '"' + '", "'.join(v.split()) + '", '
1900 config_host_data.set(k, v)
1901 elif strings.contains(k)
1902 config_host_data.set_quoted(k, v)
1903 elif k.startswith('CONFIG_')
1904 config_host_data.set(k, v == 'y' ? 1 : v)
1908 ########################
1909 # Target configuration #
1910 ########################
1912 minikconf = find_program('scripts/minikconf.py')
1914 config_all_devices = {}
1915 config_all_disas = {}
1916 config_devices_mak_list = []
1917 config_devices_h = {}
1918 config_target_h = {}
1919 config_target_mak = {}
1922 'alpha' : ['CONFIG_ALPHA_DIS'],
1923 'arm' : ['CONFIG_ARM_DIS'],
1924 'avr' : ['CONFIG_AVR_DIS'],
1925 'cris' : ['CONFIG_CRIS_DIS'],
1926 'hexagon' : ['CONFIG_HEXAGON_DIS'],
1927 'hppa' : ['CONFIG_HPPA_DIS'],
1928 'i386' : ['CONFIG_I386_DIS'],
1929 'x86_64' : ['CONFIG_I386_DIS'],
1930 'm68k' : ['CONFIG_M68K_DIS'],
1931 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1932 'mips' : ['CONFIG_MIPS_DIS'],
1933 'nios2' : ['CONFIG_NIOS2_DIS'],
1934 'or1k' : ['CONFIG_OPENRISC_DIS'],
1935 'ppc' : ['CONFIG_PPC_DIS'],
1936 'riscv' : ['CONFIG_RISCV_DIS'],
1937 'rx' : ['CONFIG_RX_DIS'],
1938 's390' : ['CONFIG_S390_DIS'],
1939 'sh4' : ['CONFIG_SH4_DIS'],
1940 'sparc' : ['CONFIG_SPARC_DIS'],
1941 'xtensa' : ['CONFIG_XTENSA_DIS'],
1943 if link_language == 'cpp'
1945 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1946 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1947 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1951 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
1953 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
1954 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
1955 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
1956 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
1957 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1958 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1959 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1960 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1961 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1962 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1963 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1964 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1965 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1967 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1969 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1970 actual_target_dirs = []
1972 foreach target : target_dirs
1973 config_target = { 'TARGET_NAME': target.split('-')[0] }
1974 if target.endswith('linux-user')
1975 if targetos != 'linux'
1979 error('Target @0@ is only available on a Linux host'.format(target))
1981 config_target += { 'CONFIG_LINUX_USER': 'y' }
1982 elif target.endswith('bsd-user')
1983 if 'CONFIG_BSD' not in config_host
1987 error('Target @0@ is only available on a BSD host'.format(target))
1989 config_target += { 'CONFIG_BSD_USER': 'y' }
1990 elif target.endswith('softmmu')
1991 config_target += { 'CONFIG_SOFTMMU': 'y' }
1993 if target.endswith('-user')
1995 'CONFIG_USER_ONLY': 'y',
1996 'CONFIG_QEMU_INTERP_PREFIX':
1997 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
2002 foreach sym: accelerators
2003 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2004 config_target += { sym: 'y' }
2005 config_all += { sym: 'y' }
2006 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
2007 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
2008 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
2009 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
2011 if target in modular_tcg
2012 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2014 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2016 accel_kconfig += [ sym + '=y' ]
2019 if accel_kconfig.length() == 0
2023 error('No accelerator available for target @0@'.format(target))
2026 actual_target_dirs += target
2027 config_target += keyval.load('configs/targets' / target + '.mak')
2028 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
2030 if 'TARGET_NEED_FDT' in config_target
2031 fdt_required += target
2035 if 'TARGET_BASE_ARCH' not in config_target
2036 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2038 if 'TARGET_ABI_DIR' not in config_target
2039 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2042 foreach k, v: disassemblers
2043 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
2045 config_target += { sym: 'y' }
2046 config_all_disas += { sym: 'y' }
2051 config_target_data = configuration_data()
2052 foreach k, v: config_target
2053 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2055 elif ignored.contains(k)
2057 elif k == 'TARGET_BASE_ARCH'
2058 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2059 # not used to select files from sourcesets.
2060 config_target_data.set('TARGET_' + v.to_upper(), 1)
2061 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
2062 config_target_data.set_quoted(k, v)
2064 config_target_data.set(k, 1)
2066 config_target_data.set(k, v)
2069 config_target_data.set('QEMU_ARCH',
2070 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
2071 config_target_h += {target: configure_file(output: target + '-config-target.h',
2072 configuration: config_target_data)}
2074 if target.endswith('-softmmu')
2075 config_input = meson.get_external_property(target, 'default')
2076 config_devices_mak = target + '-config-devices.mak'
2077 config_devices_mak = configure_file(
2078 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2079 output: config_devices_mak,
2080 depfile: config_devices_mak + '.d',
2082 command: [minikconf,
2083 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2084 config_devices_mak, '@DEPFILE@', '@INPUT@',
2085 host_kconfig, accel_kconfig,
2086 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
2088 config_devices_data = configuration_data()
2089 config_devices = keyval.load(config_devices_mak)
2090 foreach k, v: config_devices
2091 config_devices_data.set(k, 1)
2093 config_devices_mak_list += config_devices_mak
2094 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2095 configuration: config_devices_data)}
2096 config_target += config_devices
2097 config_all_devices += config_devices
2099 config_target_mak += {target: config_target}
2101 target_dirs = actual_target_dirs
2103 # This configuration is used to build files that are shared by
2104 # multiple binaries, and then extracted out of the "common"
2105 # static_library target.
2107 # We do not use all_sources()/all_dependencies(), because it would
2108 # build literally all source files, including devices only used by
2109 # targets that are not built for this compilation. The CONFIG_ALL
2110 # pseudo symbol replaces it.
2112 config_all += config_all_devices
2113 config_all += config_host
2114 config_all += config_all_disas
2116 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
2117 'CONFIG_SOFTMMU': have_system,
2118 'CONFIG_USER_ONLY': have_user,
2122 target_configs_h = []
2123 foreach target: target_dirs
2124 target_configs_h += config_target_h[target]
2125 target_configs_h += config_devices_h.get(target, [])
2127 genh += custom_target('config-poison.h',
2128 input: [target_configs_h],
2129 output: 'config-poison.h',
2131 command: [find_program('scripts/make-config-poison.sh'),
2138 capstone = not_found
2139 capstone_opt = get_option('capstone')
2140 if capstone_opt in ['enabled', 'auto', 'system']
2141 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
2142 capstone = dependency('capstone', version: '>=4.0',
2143 kwargs: static_kwargs, method: 'pkg-config',
2144 required: capstone_opt == 'system' or
2145 capstone_opt == 'enabled' and not have_internal)
2147 # Some versions of capstone have broken pkg-config file
2148 # that reports a wrong -I path, causing the #include to
2149 # fail later. If the system has such a broken version
2151 if capstone.found() and not cc.compiles('#include <capstone.h>',
2152 dependencies: [capstone])
2153 capstone = not_found
2154 if capstone_opt == 'system'
2155 error('system capstone requested, it does not appear to work')
2160 capstone_opt = 'system'
2162 capstone_opt = 'internal'
2164 capstone_opt = 'disabled'
2167 if capstone_opt == 'internal'
2168 capstone_data = configuration_data()
2169 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
2171 capstone_files = files(
2173 'capstone/MCInst.c',
2174 'capstone/MCInstrDesc.c',
2175 'capstone/MCRegisterInfo.c',
2176 'capstone/SStream.c',
2180 if 'CONFIG_ARM_DIS' in config_all_disas
2181 capstone_data.set('CAPSTONE_HAS_ARM', '1')
2182 capstone_files += files(
2183 'capstone/arch/ARM/ARMDisassembler.c',
2184 'capstone/arch/ARM/ARMInstPrinter.c',
2185 'capstone/arch/ARM/ARMMapping.c',
2186 'capstone/arch/ARM/ARMModule.c'
2190 # FIXME: This config entry currently depends on a c++ compiler.
2191 # Which is needed for building libvixl, but not for capstone.
2192 if 'CONFIG_ARM_A64_DIS' in config_all_disas
2193 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
2194 capstone_files += files(
2195 'capstone/arch/AArch64/AArch64BaseInfo.c',
2196 'capstone/arch/AArch64/AArch64Disassembler.c',
2197 'capstone/arch/AArch64/AArch64InstPrinter.c',
2198 'capstone/arch/AArch64/AArch64Mapping.c',
2199 'capstone/arch/AArch64/AArch64Module.c'
2203 if 'CONFIG_PPC_DIS' in config_all_disas
2204 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
2205 capstone_files += files(
2206 'capstone/arch/PowerPC/PPCDisassembler.c',
2207 'capstone/arch/PowerPC/PPCInstPrinter.c',
2208 'capstone/arch/PowerPC/PPCMapping.c',
2209 'capstone/arch/PowerPC/PPCModule.c'
2213 if 'CONFIG_S390_DIS' in config_all_disas
2214 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
2215 capstone_files += files(
2216 'capstone/arch/SystemZ/SystemZDisassembler.c',
2217 'capstone/arch/SystemZ/SystemZInstPrinter.c',
2218 'capstone/arch/SystemZ/SystemZMapping.c',
2219 'capstone/arch/SystemZ/SystemZModule.c',
2220 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
2224 if 'CONFIG_I386_DIS' in config_all_disas
2225 capstone_data.set('CAPSTONE_HAS_X86', 1)
2226 capstone_files += files(
2227 'capstone/arch/X86/X86Disassembler.c',
2228 'capstone/arch/X86/X86DisassemblerDecoder.c',
2229 'capstone/arch/X86/X86ATTInstPrinter.c',
2230 'capstone/arch/X86/X86IntelInstPrinter.c',
2231 'capstone/arch/X86/X86InstPrinterCommon.c',
2232 'capstone/arch/X86/X86Mapping.c',
2233 'capstone/arch/X86/X86Module.c'
2237 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
2240 # FIXME: There does not seem to be a way to completely replace the c_args
2241 # that come from add_project_arguments() -- we can only add to them.
2242 # So: disable all warnings with a big hammer.
2245 # Include all configuration defines via a header file, which will wind up
2246 # as a dependency on the object file, and thus changes here will result
2248 '-include', 'capstone-defs.h'
2251 libcapstone = static_library('capstone',
2252 build_by_default: false,
2253 sources: capstone_files,
2254 c_args: capstone_cargs,
2255 include_directories: 'capstone/include')
2256 capstone = declare_dependency(link_with: libcapstone,
2257 include_directories: 'capstone/include/capstone')
2261 slirp_opt = 'disabled'
2263 slirp_opt = get_option('slirp')
2264 if slirp_opt in ['enabled', 'auto', 'system']
2265 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2266 slirp = dependency('slirp', kwargs: static_kwargs,
2267 method: 'pkg-config',
2268 required: slirp_opt == 'system' or
2269 slirp_opt == 'enabled' and not have_internal)
2271 slirp_opt = 'system'
2273 slirp_opt = 'internal'
2275 slirp_opt = 'disabled'
2278 if slirp_opt == 'internal'
2280 if targetos == 'windows'
2281 slirp_deps = cc.find_library('iphlpapi')
2282 elif targetos == 'darwin'
2283 slirp_deps = cc.find_library('resolv')
2285 slirp_conf = configuration_data()
2286 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2287 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2288 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2289 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2290 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2292 'slirp/src/arp_table.c',
2293 'slirp/src/bootp.c',
2294 'slirp/src/cksum.c',
2295 'slirp/src/dhcpv6.c',
2296 'slirp/src/dnssearch.c',
2298 'slirp/src/ip6_icmp.c',
2299 'slirp/src/ip6_input.c',
2300 'slirp/src/ip6_output.c',
2301 'slirp/src/ip_icmp.c',
2302 'slirp/src/ip_input.c',
2303 'slirp/src/ip_output.c',
2307 'slirp/src/ndp_table.c',
2309 'slirp/src/slirp.c',
2310 'slirp/src/socket.c',
2311 'slirp/src/state.c',
2312 'slirp/src/stream.c',
2313 'slirp/src/tcp_input.c',
2314 'slirp/src/tcp_output.c',
2315 'slirp/src/tcp_subr.c',
2316 'slirp/src/tcp_timer.c',
2321 'slirp/src/version.c',
2322 'slirp/src/vmstate.c',
2326 input : 'slirp/src/libslirp-version.h.in',
2327 output : 'libslirp-version.h',
2328 configuration: slirp_conf)
2330 slirp_inc = include_directories('slirp', 'slirp/src')
2331 libslirp = static_library('slirp',
2332 build_by_default: false,
2333 sources: slirp_files,
2334 c_args: slirp_cargs,
2335 include_directories: slirp_inc)
2336 slirp = declare_dependency(link_with: libslirp,
2337 dependencies: slirp_deps,
2338 include_directories: slirp_inc)
2342 # For CFI, we need to compile slirp as a static library together with qemu.
2343 # This is because we register slirp functions as callbacks for QEMU Timers.
2344 # When using a system-wide shared libslirp, the type information for the
2345 # callback is missing and the timer call produces a false positive with CFI.
2347 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2348 # with control-flow integrity.
2349 if get_option('cfi') and slirp_opt == 'system'
2350 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2351 + ' Please configure with --enable-slirp=git')
2355 fdt_opt = get_option('fdt')
2357 if fdt_opt in ['enabled', 'auto', 'system']
2358 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2359 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2360 required: fdt_opt == 'system' or
2361 fdt_opt == 'enabled' and not have_internal)
2362 if fdt.found() and cc.links('''
2364 #include <libfdt_env.h>
2365 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2368 elif fdt_opt == 'system'
2369 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2371 fdt_opt = 'internal'
2373 fdt_opt = 'disabled'
2377 if fdt_opt == 'internal'
2380 'dtc/libfdt/fdt_ro.c',
2381 'dtc/libfdt/fdt_wip.c',
2382 'dtc/libfdt/fdt_sw.c',
2383 'dtc/libfdt/fdt_rw.c',
2384 'dtc/libfdt/fdt_strerror.c',
2385 'dtc/libfdt/fdt_empty_tree.c',
2386 'dtc/libfdt/fdt_addresses.c',
2387 'dtc/libfdt/fdt_overlay.c',
2388 'dtc/libfdt/fdt_check.c',
2391 fdt_inc = include_directories('dtc/libfdt')
2392 libfdt = static_library('fdt',
2393 build_by_default: false,
2395 include_directories: fdt_inc)
2396 fdt = declare_dependency(link_with: libfdt,
2397 include_directories: fdt_inc)
2400 if not fdt.found() and fdt_required.length() > 0
2401 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2404 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2405 config_host_data.set('CONFIG_FDT', fdt.found())
2406 config_host_data.set('CONFIG_SLIRP', slirp.found())
2408 #####################
2409 # Generated sources #
2410 #####################
2412 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2414 hxtool = find_program('scripts/hxtool')
2415 shaderinclude = find_program('scripts/shaderinclude.pl')
2416 qapi_gen = find_program('scripts/qapi-gen.py')
2417 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2418 meson.current_source_dir() / 'scripts/qapi/commands.py',
2419 meson.current_source_dir() / 'scripts/qapi/common.py',
2420 meson.current_source_dir() / 'scripts/qapi/error.py',
2421 meson.current_source_dir() / 'scripts/qapi/events.py',
2422 meson.current_source_dir() / 'scripts/qapi/expr.py',
2423 meson.current_source_dir() / 'scripts/qapi/gen.py',
2424 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2425 meson.current_source_dir() / 'scripts/qapi/parser.py',
2426 meson.current_source_dir() / 'scripts/qapi/schema.py',
2427 meson.current_source_dir() / 'scripts/qapi/source.py',
2428 meson.current_source_dir() / 'scripts/qapi/types.py',
2429 meson.current_source_dir() / 'scripts/qapi/visit.py',
2430 meson.current_source_dir() / 'scripts/qapi/common.py',
2431 meson.current_source_dir() / 'scripts/qapi-gen.py'
2435 python, files('scripts/tracetool.py'),
2436 '--backend=' + ','.join(get_option('trace_backends'))
2438 tracetool_depends = files(
2439 'scripts/tracetool/backend/log.py',
2440 'scripts/tracetool/backend/__init__.py',
2441 'scripts/tracetool/backend/dtrace.py',
2442 'scripts/tracetool/backend/ftrace.py',
2443 'scripts/tracetool/backend/simple.py',
2444 'scripts/tracetool/backend/syslog.py',
2445 'scripts/tracetool/backend/ust.py',
2446 'scripts/tracetool/format/ust_events_c.py',
2447 'scripts/tracetool/format/ust_events_h.py',
2448 'scripts/tracetool/format/__init__.py',
2449 'scripts/tracetool/format/d.py',
2450 'scripts/tracetool/format/simpletrace_stap.py',
2451 'scripts/tracetool/format/c.py',
2452 'scripts/tracetool/format/h.py',
2453 'scripts/tracetool/format/log_stap.py',
2454 'scripts/tracetool/format/stap.py',
2455 'scripts/tracetool/__init__.py',
2456 'scripts/tracetool/transform.py',
2457 'scripts/tracetool/vcpu.py'
2460 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2461 meson.current_source_dir(),
2462 config_host['PKGVERSION'], meson.project_version()]
2463 qemu_version = custom_target('qemu-version.h',
2464 output: 'qemu-version.h',
2465 command: qemu_version_cmd,
2467 build_by_default: true,
2468 build_always_stale: true)
2469 genh += qemu_version
2473 ['qemu-options.hx', 'qemu-options.def'],
2474 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2478 ['hmp-commands.hx', 'hmp-commands.h'],
2479 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2482 foreach d : hx_headers
2483 hxdep += custom_target(d[1],
2487 build_by_default: true, # to be removed when added to a target
2488 command: [hxtool, '-h', '@INPUT0@'])
2496 authz_ss = ss.source_set()
2497 blockdev_ss = ss.source_set()
2498 block_ss = ss.source_set()
2499 chardev_ss = ss.source_set()
2500 common_ss = ss.source_set()
2501 crypto_ss = ss.source_set()
2502 hwcore_ss = ss.source_set()
2503 io_ss = ss.source_set()
2504 qmp_ss = ss.source_set()
2505 qom_ss = ss.source_set()
2506 softmmu_ss = ss.source_set()
2507 specific_fuzz_ss = ss.source_set()
2508 specific_ss = ss.source_set()
2509 stub_ss = ss.source_set()
2510 trace_ss = ss.source_set()
2511 user_ss = ss.source_set()
2512 util_ss = ss.source_set()
2515 qtest_module_ss = ss.source_set()
2516 tcg_module_ss = ss.source_set()
2522 target_softmmu_arch = {}
2523 target_user_arch = {}
2529 # TODO: add each directory to the subdirs from its own meson.build, once
2531 trace_events_subdirs = [
2539 trace_events_subdirs += [ 'linux-user' ]
2542 trace_events_subdirs += [ 'bsd-user' ]
2545 trace_events_subdirs += [
2554 trace_events_subdirs += [
2568 'hw/block/dataplane',
2618 if have_system or have_user
2619 trace_events_subdirs += [
2636 vhost_user = not_found
2637 if 'CONFIG_VHOST_USER' in config_host
2638 libvhost_user = subproject('libvhost-user')
2639 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2642 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
2643 # that is filled in by qapi/.
2656 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2657 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2660 stub_ss = stub_ss.apply(config_all, strict: false)
2662 util_ss.add_all(trace_ss)
2663 util_ss = util_ss.apply(config_all, strict: false)
2664 libqemuutil = static_library('qemuutil',
2665 sources: util_ss.sources() + stub_ss.sources() + genh,
2666 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2667 qemuutil = declare_dependency(link_with: libqemuutil,
2668 sources: genh + version_res)
2670 if have_system or have_user
2671 decodetree = generator(find_program('scripts/decodetree.py'),
2672 output: 'decode-@BASENAME@.c.inc',
2673 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2674 subdir('libdecnumber')
2691 if config_host_data.get('CONFIG_REPLICATION')
2692 block_ss.add(files('replication.c'))
2699 blockdev_ss.add(files(
2706 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2707 # os-win32.c does not
2708 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2709 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2712 common_ss.add(files('cpus-common.c'))
2716 common_ss.add(capstone)
2717 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2719 # Work around a gcc bug/misfeature wherein constant propagation looks
2721 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2722 # to guess that a const variable is always zero. Without lto, this is
2723 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2724 # without lto, not even the alias is required -- we simply use different
2725 # declarations in different compilation units.
2726 pagevary = files('page-vary-common.c')
2727 if get_option('b_lto')
2728 pagevary_flags = ['-fno-lto']
2729 if get_option('cfi')
2730 pagevary_flags += '-fno-sanitize=cfi-icall'
2732 pagevary = static_library('page-vary-common', sources: pagevary,
2733 c_args: pagevary_flags)
2734 pagevary = declare_dependency(link_with: pagevary)
2736 common_ss.add(pagevary)
2737 specific_ss.add(files('page-vary.c'))
2745 subdir('semihosting')
2753 common_user_inc = []
2755 subdir('common-user')
2757 subdir('linux-user')
2759 # needed for fuzzing binaries
2760 subdir('tests/qtest/libqos')
2761 subdir('tests/qtest/fuzz')
2764 tcg_real_module_ss = ss.source_set()
2765 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
2766 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
2767 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
2768 'tcg': tcg_real_module_ss }}
2770 ########################
2771 # Library dependencies #
2772 ########################
2774 modinfo_collect = find_program('scripts/modinfo-collect.py')
2775 modinfo_generate = find_program('scripts/modinfo-generate.py')
2780 foreach d, list : modules
2781 foreach m, module_ss : list
2782 if enable_modules and targetos != 'windows'
2783 module_ss = module_ss.apply(config_all, strict: false)
2784 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2785 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2791 if module_ss.sources() != []
2792 # FIXME: Should use sl.extract_all_objects(recursive: true) as
2793 # input. Sources can be used multiple times but objects are
2794 # unique when it comes to lookup in compile_commands.json.
2795 # Depnds on a mesion version with
2796 # https://github.com/mesonbuild/meson/pull/8900
2797 modinfo_files += custom_target(d + '-' + m + '.modinfo',
2798 output: d + '-' + m + '.modinfo',
2799 input: module_ss.sources() + genh,
2801 command: [modinfo_collect, module_ss.sources()])
2805 block_ss.add_all(module_ss)
2807 softmmu_ss.add_all(module_ss)
2813 foreach d, list : target_modules
2814 foreach m, module_ss : list
2815 if enable_modules and targetos != 'windows'
2816 foreach target : target_dirs
2817 if target.endswith('-softmmu')
2818 config_target = config_target_mak[target]
2819 config_target += config_host
2820 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2821 c_args = ['-DNEED_CPU_H',
2822 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2823 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2824 target_module_ss = module_ss.apply(config_target, strict: false)
2825 if target_module_ss.sources() != []
2826 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
2827 sl = static_library(module_name,
2828 [genh, target_module_ss.sources()],
2829 dependencies: [modulecommon, target_module_ss.dependencies()],
2830 include_directories: target_inc,
2834 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
2835 modinfo_files += custom_target(module_name + '.modinfo',
2836 output: module_name + '.modinfo',
2837 input: target_module_ss.sources() + genh,
2839 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
2844 specific_ss.add_all(module_ss)
2850 modinfo_src = custom_target('modinfo.c',
2851 output: 'modinfo.c',
2852 input: modinfo_files,
2853 command: [modinfo_generate, '@INPUT@'],
2855 modinfo_lib = static_library('modinfo', modinfo_src)
2856 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
2857 softmmu_ss.add(modinfo_dep)
2860 nm = find_program('nm')
2861 undefsym = find_program('scripts/undefsym.py')
2862 block_syms = custom_target('block.syms', output: 'block.syms',
2863 input: [libqemuutil, block_mods],
2865 command: [undefsym, nm, '@INPUT@'])
2866 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2867 input: [libqemuutil, softmmu_mods],
2869 command: [undefsym, nm, '@INPUT@'])
2871 qom_ss = qom_ss.apply(config_host, strict: false)
2872 libqom = static_library('qom', qom_ss.sources() + genh,
2873 dependencies: [qom_ss.dependencies()],
2876 qom = declare_dependency(link_whole: libqom)
2878 authz_ss = authz_ss.apply(config_host, strict: false)
2879 libauthz = static_library('authz', authz_ss.sources() + genh,
2880 dependencies: [authz_ss.dependencies()],
2882 build_by_default: false)
2884 authz = declare_dependency(link_whole: libauthz,
2887 crypto_ss = crypto_ss.apply(config_host, strict: false)
2888 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2889 dependencies: [crypto_ss.dependencies()],
2891 build_by_default: false)
2893 crypto = declare_dependency(link_whole: libcrypto,
2894 dependencies: [authz, qom])
2896 io_ss = io_ss.apply(config_host, strict: false)
2897 libio = static_library('io', io_ss.sources() + genh,
2898 dependencies: [io_ss.dependencies()],
2899 link_with: libqemuutil,
2901 build_by_default: false)
2903 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2905 libmigration = static_library('migration', sources: migration_files + genh,
2907 build_by_default: false)
2908 migration = declare_dependency(link_with: libmigration,
2909 dependencies: [zlib, qom, io])
2910 softmmu_ss.add(migration)
2912 block_ss = block_ss.apply(config_host, strict: false)
2913 libblock = static_library('block', block_ss.sources() + genh,
2914 dependencies: block_ss.dependencies(),
2915 link_depends: block_syms,
2917 build_by_default: false)
2919 block = declare_dependency(link_whole: [libblock],
2920 link_args: '@block.syms',
2921 dependencies: [crypto, io])
2923 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2924 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2925 dependencies: blockdev_ss.dependencies(),
2927 build_by_default: false)
2929 blockdev = declare_dependency(link_whole: [libblockdev],
2930 dependencies: [block])
2932 qmp_ss = qmp_ss.apply(config_host, strict: false)
2933 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2934 dependencies: qmp_ss.dependencies(),
2936 build_by_default: false)
2938 qmp = declare_dependency(link_whole: [libqmp])
2940 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2942 dependencies: [gnutls],
2943 build_by_default: false)
2945 chardev = declare_dependency(link_whole: libchardev)
2947 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
2948 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
2950 build_by_default: false)
2951 hwcore = declare_dependency(link_whole: libhwcore)
2952 common_ss.add(hwcore)
2958 emulator_modules = []
2959 foreach m : block_mods + softmmu_mods
2960 emulator_modules += shared_module(m.name(),
2961 build_by_default: true,
2965 install_dir: qemu_moddir)
2968 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2969 common_ss.add(qom, qemuutil)
2971 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2972 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2974 common_all = common_ss.apply(config_all, strict: false)
2975 common_all = static_library('common',
2976 build_by_default: false,
2977 sources: common_all.sources() + genh,
2978 include_directories: common_user_inc,
2979 implicit_include_directories: false,
2980 dependencies: common_all.dependencies(),
2983 feature_to_c = find_program('scripts/feature_to_c.sh')
2986 foreach target : target_dirs
2987 config_target = config_target_mak[target]
2988 target_name = config_target['TARGET_NAME']
2989 target_base_arch = config_target['TARGET_BASE_ARCH']
2990 arch_srcs = [config_target_h[target]]
2992 c_args = ['-DNEED_CPU_H',
2993 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2994 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2995 link_args = emulator_link_args
2997 config_target += config_host
2998 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2999 if targetos == 'linux'
3000 target_inc += include_directories('linux-headers', is_system: true)
3002 if target.endswith('-softmmu')
3003 qemu_target_name = 'qemu-system-' + target_name
3004 target_type='system'
3005 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3006 arch_srcs += t.sources()
3007 arch_deps += t.dependencies()
3009 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3010 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3011 arch_srcs += hw.sources()
3012 arch_deps += hw.dependencies()
3014 arch_srcs += config_devices_h[target]
3015 link_args += ['@block.syms', '@qemu.syms']
3017 abi = config_target['TARGET_ABI_DIR']
3019 target_inc += common_user_inc
3020 qemu_target_name = 'qemu-' + target_name
3021 if target_base_arch in target_user_arch
3022 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3023 arch_srcs += t.sources()
3024 arch_deps += t.dependencies()
3026 if 'CONFIG_LINUX_USER' in config_target
3027 base_dir = 'linux-user'
3029 if 'CONFIG_BSD_USER' in config_target
3030 base_dir = 'bsd-user'
3031 target_inc += include_directories('bsd-user/' / targetos)
3032 target_inc += include_directories('bsd-user/host/' / host_arch)
3033 dir = base_dir / abi
3034 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3036 target_inc += include_directories(
3040 if 'CONFIG_LINUX_USER' in config_target
3041 dir = base_dir / abi
3042 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3043 if config_target.has_key('TARGET_SYSTBL_ABI')
3045 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3046 extra_args : config_target['TARGET_SYSTBL_ABI'])
3051 if 'TARGET_XML_FILES' in config_target
3052 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3053 output: target + '-gdbstub-xml.c',
3054 input: files(config_target['TARGET_XML_FILES'].split()),
3055 command: [feature_to_c, '@INPUT@'],
3057 arch_srcs += gdbstub_xml
3060 t = target_arch[target_base_arch].apply(config_target, strict: false)
3061 arch_srcs += t.sources()
3062 arch_deps += t.dependencies()
3064 target_common = common_ss.apply(config_target, strict: false)
3065 objects = common_all.extract_objects(target_common.sources())
3066 deps = target_common.dependencies()
3068 target_specific = specific_ss.apply(config_target, strict: false)
3069 arch_srcs += target_specific.sources()
3070 arch_deps += target_specific.dependencies()
3072 lib = static_library('qemu-' + target,
3073 sources: arch_srcs + genh,
3074 dependencies: arch_deps,
3076 include_directories: target_inc,
3078 build_by_default: false,
3081 if target.endswith('-softmmu')
3083 'name': 'qemu-system-' + target_name,
3084 'win_subsystem': 'console',
3085 'sources': files('softmmu/main.c'),
3088 if targetos == 'windows' and (sdl.found() or gtk.found())
3090 'name': 'qemu-system-' + target_name + 'w',
3091 'win_subsystem': 'windows',
3092 'sources': files('softmmu/main.c'),
3096 if get_option('fuzzing')
3097 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3099 'name': 'qemu-fuzz-' + target_name,
3100 'win_subsystem': 'console',
3101 'sources': specific_fuzz.sources(),
3102 'dependencies': specific_fuzz.dependencies(),
3107 'name': 'qemu-' + target_name,
3108 'win_subsystem': 'console',
3114 exe_name = exe['name']
3115 if targetos == 'darwin'
3116 exe_name += '-unsigned'
3119 emulator = executable(exe_name, exe['sources'],
3122 dependencies: arch_deps + deps + exe['dependencies'],
3123 objects: lib.extract_all_objects(recursive: true),
3124 link_language: link_language,
3125 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3126 link_args: link_args,
3127 win_subsystem: exe['win_subsystem'])
3129 if targetos == 'darwin'
3130 icon = 'pc-bios/qemu.rsrc'
3131 build_input = [emulator, files(icon)]
3133 get_option('bindir') / exe_name,
3134 meson.current_source_dir() / icon
3136 if 'CONFIG_HVF' in config_target
3137 entitlements = 'accel/hvf/entitlements.plist'
3138 build_input += files(entitlements)
3139 install_input += meson.current_source_dir() / entitlements
3142 entitlement = find_program('scripts/entitlement.sh')
3143 emulators += {exe['name'] : custom_target(exe['name'],
3145 output: exe['name'],
3146 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3149 meson.add_install_script(entitlement, '--install',
3150 get_option('bindir') / exe['name'],
3153 emulators += {exe['name']: emulator}
3158 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3159 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3160 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3161 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3163 custom_target(exe['name'] + stp['ext'],
3164 input: trace_events_all,
3165 output: exe['name'] + stp['ext'],
3166 install: stp['install'],
3167 install_dir: get_option('datadir') / 'systemtap/tapset',
3169 tracetool, '--group=all', '--format=' + stp['fmt'],
3170 '--binary=' + stp['bin'],
3171 '--target-name=' + target_name,
3172 '--target-type=' + target_type,
3173 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3174 '@INPUT@', '@OUTPUT@'
3176 depend_files: tracetool_depends)
3182 # Other build targets
3184 if 'CONFIG_PLUGIN' in config_host
3185 install_headers('include/qemu/qemu-plugin.h')
3188 if 'CONFIG_GUEST_AGENT' in config_host
3190 elif get_option('guest_agent_msi').enabled()
3191 error('Guest agent MSI requested, but the guest agent is not being built')
3194 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3195 # when we don't build tools or system
3196 if xkbcommon.found()
3197 # used for the update-keymaps target, so include rules even if !have_tools
3198 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3199 dependencies: [qemuutil, xkbcommon], install: have_tools)
3203 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3204 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3205 qemu_io = executable('qemu-io', files('qemu-io.c'),
3206 dependencies: [block, qemuutil], install: true)
3207 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3208 dependencies: [blockdev, qemuutil, gnutls, selinux],
3211 subdir('storage-daemon')
3212 subdir('contrib/rdmacm-mux')
3213 subdir('contrib/elf2dmp')
3215 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3216 dependencies: qemuutil,
3219 if 'CONFIG_VHOST_USER' in config_host
3220 subdir('contrib/vhost-user-blk')
3221 subdir('contrib/vhost-user-gpu')
3222 subdir('contrib/vhost-user-input')
3223 subdir('contrib/vhost-user-scsi')
3226 if targetos == 'linux'
3227 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3228 dependencies: [qemuutil, libcap_ng],
3230 install_dir: get_option('libexecdir'))
3232 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3233 dependencies: [authz, crypto, io, qom, qemuutil,
3234 libcap_ng, mpathpersist],
3239 subdir('contrib/ivshmem-client')
3240 subdir('contrib/ivshmem-server')
3253 if host_machine.system() == 'windows'
3255 find_program('scripts/nsis.py'),
3257 get_option('prefix'),
3258 meson.current_source_dir(),
3261 '-DDISPLAYVERSION=' + meson.project_version(),
3264 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3267 nsis_cmd += '-DCONFIG_GTK=y'
3270 nsis = custom_target('nsis',
3271 output: 'qemu-setup-' + meson.project_version() + '.exe',
3272 input: files('qemu.nsi'),
3273 build_always_stale: true,
3274 command: nsis_cmd + ['@INPUT@'])
3275 alias_target('installer', nsis)
3278 #########################
3279 # Configuration summary #
3280 #########################
3284 summary_info += {'Install prefix': get_option('prefix')}
3285 summary_info += {'BIOS directory': qemu_datadir}
3286 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
3287 summary_info += {'binary directory': get_option('bindir')}
3288 summary_info += {'library directory': get_option('libdir')}
3289 summary_info += {'module directory': qemu_moddir}
3290 summary_info += {'libexec directory': get_option('libexecdir')}
3291 summary_info += {'include directory': get_option('includedir')}
3292 summary_info += {'config directory': get_option('sysconfdir')}
3293 if targetos != 'windows'
3294 summary_info += {'local state directory': get_option('localstatedir')}
3295 summary_info += {'Manual directory': get_option('mandir')}
3297 summary_info += {'local state directory': 'queried at runtime'}
3299 summary_info += {'Doc directory': get_option('docdir')}
3300 summary_info += {'Build directory': meson.current_build_dir()}
3301 summary_info += {'Source path': meson.current_source_dir()}
3302 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3303 summary(summary_info, bool_yn: true, section: 'Directories')
3307 summary_info += {'git': config_host['GIT']}
3308 summary_info += {'make': config_host['MAKE']}
3309 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3310 summary_info += {'sphinx-build': sphinx_build}
3311 if config_host.has_key('HAVE_GDB_BIN')
3312 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3314 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3315 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
3316 summary_info += {'wixl': wixl}
3318 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
3319 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
3321 summary(summary_info, bool_yn: true, section: 'Host binaries')
3323 # Configurable features
3325 summary_info += {'Documentation': build_docs}
3326 summary_info += {'system-mode emulation': have_system}
3327 summary_info += {'user-mode emulation': have_user}
3328 summary_info += {'block layer': have_block}
3329 summary_info += {'Install blobs': get_option('install_blobs')}
3330 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3331 if config_host.has_key('CONFIG_MODULES')
3332 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
3334 summary_info += {'fuzzing support': get_option('fuzzing')}
3336 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3338 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3339 if 'simple' in get_option('trace_backends')
3340 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3342 summary_info += {'D-Bus display': dbus_display}
3343 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
3344 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
3345 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
3346 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
3347 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
3348 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
3349 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
3350 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3351 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
3352 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
3353 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
3354 summary(summary_info, bool_yn: true, section: 'Configurable features')
3356 # Compilation information
3358 summary_info += {'host CPU': cpu}
3359 summary_info += {'host endianness': build_machine.endian()}
3360 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3361 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3362 if link_language == 'cpp'
3363 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3365 summary_info += {'C++ compiler': false}
3367 if targetos == 'darwin'
3368 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3370 if targetos == 'windows'
3371 if 'WIN_SDK' in config_host
3372 summary_info += {'Windows SDK': config_host['WIN_SDK']}
3375 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3376 + ['-O' + get_option('optimization')]
3377 + (get_option('debug') ? ['-g'] : []))}
3378 if link_language == 'cpp'
3379 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3380 + ['-O' + get_option('optimization')]
3381 + (get_option('debug') ? ['-g'] : []))}
3383 link_args = get_option(link_language + '_link_args')
3384 if link_args.length() > 0
3385 summary_info += {'LDFLAGS': ' '.join(link_args)}
3387 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
3388 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
3389 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
3390 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3391 summary_info += {'PIE': get_option('b_pie')}
3392 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3393 summary_info += {'malloc trim support': has_malloc_trim}
3394 summary_info += {'membarrier': have_membarrier}
3395 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
3396 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
3397 summary_info += {'memory allocator': get_option('malloc')}
3398 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
3399 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
3400 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
3401 summary_info += {'gcov': get_option('b_coverage')}
3402 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3403 summary_info += {'CFI support': get_option('cfi')}
3404 if get_option('cfi')
3405 summary_info += {'CFI debug support': get_option('cfi_debug')}
3407 summary_info += {'strip binaries': get_option('strip')}
3408 summary_info += {'sparse': sparse}
3409 summary_info += {'mingw32 support': targetos == 'windows'}
3411 # snarf the cross-compilation information for tests
3412 foreach target: target_dirs
3413 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3414 if fs.exists(tcg_mak)
3415 config_cross_tcg = keyval.load(tcg_mak)
3416 target = config_cross_tcg['TARGET_NAME']
3418 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3419 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3420 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3421 elif 'CROSS_CC_GUEST' in config_cross_tcg
3422 summary_info += {target + ' tests'
3423 : config_cross_tcg['CROSS_CC_GUEST'] }
3428 summary(summary_info, bool_yn: true, section: 'Compilation')
3430 # Targets and accelerators
3433 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3434 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3435 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3436 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3437 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3438 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
3439 if config_host.has_key('CONFIG_XEN_BACKEND')
3440 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
3443 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3444 if config_all.has_key('CONFIG_TCG')
3445 if get_option('tcg_interpreter')
3446 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
3448 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3450 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3451 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3453 summary_info += {'target list': ' '.join(target_dirs)}
3455 summary_info += {'default devices': get_option('default_devices')}
3456 summary_info += {'out of process emulation': multiprocess_allowed}
3458 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3462 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3463 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
3465 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3466 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3467 summary_info += {'Use block whitelist in tools': config_host.has_key('CONFIG_BDRV_WHITELIST_TOOLS')}
3468 summary_info += {'VirtFS support': have_virtfs}
3469 summary_info += {'build virtiofs daemon': have_virtiofsd}
3470 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
3471 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
3472 summary_info += {'bochs support': get_option('bochs').allowed()}
3473 summary_info += {'cloop support': get_option('cloop').allowed()}
3474 summary_info += {'dmg support': get_option('dmg').allowed()}
3475 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
3476 summary_info += {'vdi support': get_option('vdi').allowed()}
3477 summary_info += {'vvfat support': get_option('vvfat').allowed()}
3478 summary_info += {'qed support': get_option('qed').allowed()}
3479 summary_info += {'parallels support': get_option('parallels').allowed()}
3480 summary_info += {'FUSE exports': fuse}
3482 summary(summary_info, bool_yn: true, section: 'Block layer support')
3486 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
3487 summary_info += {'GNUTLS support': gnutls}
3489 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3491 summary_info += {'libgcrypt': gcrypt}
3492 summary_info += {'nettle': nettle}
3494 summary_info += {' XTS': xts != 'private'}
3496 summary_info += {'AF_ALG support': have_afalg}
3497 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
3498 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
3499 summary(summary_info, bool_yn: true, section: 'Crypto')
3503 if targetos == 'darwin'
3504 summary_info += {'Cocoa support': cocoa}
3506 summary_info += {'SDL support': sdl}
3507 summary_info += {'SDL image support': sdl_image}
3508 summary_info += {'GTK support': gtk}
3509 summary_info += {'pixman': pixman}
3510 summary_info += {'VTE support': vte}
3511 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3512 summary_info += {'libtasn1': tasn1}
3513 summary_info += {'PAM': pam}
3514 summary_info += {'iconv support': iconv}
3515 summary_info += {'curses support': curses}
3516 summary_info += {'virgl support': virgl}
3517 summary_info += {'curl support': curl}
3518 summary_info += {'Multipath support': mpathpersist}
3519 summary_info += {'VNC support': vnc}
3521 summary_info += {'VNC SASL support': sasl}
3522 summary_info += {'VNC JPEG support': jpeg}
3523 summary_info += {'VNC PNG support': png}
3525 if targetos not in ['darwin', 'haiku', 'windows']
3526 summary_info += {'OSS support': oss}
3527 elif targetos == 'darwin'
3528 summary_info += {'CoreAudio support': coreaudio}
3529 elif targetos == 'windows'
3530 summary_info += {'DirectSound support': dsound}
3532 if targetos == 'linux'
3533 summary_info += {'ALSA support': alsa}
3534 summary_info += {'PulseAudio support': pulse}
3536 summary_info += {'JACK support': jack}
3537 summary_info += {'brlapi support': brlapi}
3538 summary_info += {'vde support': vde}
3539 summary_info += {'netmap support': have_netmap}
3540 summary_info += {'l2tpv3 support': have_l2tpv3}
3541 summary_info += {'Linux AIO support': libaio}
3542 summary_info += {'Linux io_uring support': linux_io_uring}
3543 summary_info += {'ATTR/XATTR support': libattr}
3544 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
3545 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
3546 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3547 summary_info += {'libcap-ng support': libcap_ng}
3548 summary_info += {'bpf support': libbpf}
3549 summary_info += {'spice protocol support': spice_protocol}
3550 if spice_protocol.found()
3551 summary_info += {' spice server support': spice}
3553 summary_info += {'rbd support': rbd}
3554 summary_info += {'smartcard support': cacard}
3555 summary_info += {'U2F support': u2f}
3556 summary_info += {'libusb': libusb}
3557 summary_info += {'usb net redir': usbredir}
3558 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
3559 summary_info += {'GBM': gbm}
3560 summary_info += {'libiscsi support': libiscsi}
3561 summary_info += {'libnfs support': libnfs}
3562 if targetos == 'windows'
3563 if config_host.has_key('CONFIG_GUEST_AGENT')
3564 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
3565 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
3568 summary_info += {'seccomp support': seccomp}
3569 summary_info += {'GlusterFS support': glusterfs}
3570 summary_info += {'TPM support': have_tpm}
3571 summary_info += {'libssh support': libssh}
3572 summary_info += {'lzo support': lzo}
3573 summary_info += {'snappy support': snappy}
3574 summary_info += {'bzip2 support': libbzip2}
3575 summary_info += {'lzfse support': liblzfse}
3576 summary_info += {'zstd support': zstd}
3577 summary_info += {'NUMA host support': numa}
3578 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3579 summary_info += {'libpmem support': libpmem}
3580 summary_info += {'libdaxctl support': libdaxctl}
3581 summary_info += {'libudev': libudev}
3582 # Dummy dependency, keep .found()
3583 summary_info += {'FUSE lseek': fuse_lseek.found()}
3584 summary_info += {'selinux': selinux}
3585 summary(summary_info, bool_yn: true, section: 'Dependencies')
3587 if not supported_cpus.contains(cpu)
3589 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3591 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3592 message('The QEMU project intends to remove support for this host CPU in')
3593 message('a future release if nobody volunteers to maintain it and to')
3594 message('provide a build host for our continuous integration setup.')
3595 message('configure has succeeded and you can continue to build, but')
3596 message('if you care about QEMU on this platform you should contact')
3597 message('us upstream at qemu-devel@nongnu.org.')
3600 if not supported_oses.contains(targetos)
3602 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3604 message('Host OS ' + targetos + 'support is not currently maintained.')
3605 message('The QEMU project intends to remove support for this host OS in')
3606 message('a future release if nobody volunteers to maintain it and to')
3607 message('provide a build host for our continuous integration setup.')
3608 message('configure has succeeded and you can continue to build, but')
3609 message('if you care about QEMU on this platform you should contact')
3610 message('us upstream at qemu-devel@nongnu.org.')