1 project('qemu', ['c'], meson_version: '>=0.58.2',
2 default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
4 version: files('VERSION'))
6 not_found = dependency('', required: false)
7 keyval = import('keyval')
8 ss = import('sourceset')
11 sh = find_program('sh')
12 cc = meson.get_compiler('c')
13 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
14 enable_modules = 'CONFIG_MODULES' in config_host
15 enable_static = 'CONFIG_STATIC' in config_host
17 # Allow both shared and static libraries unless --enable-static
18 static_kwargs = enable_static ? {'static': true} : {}
20 # Temporary directory used for files created while
21 # configure runs. Since it is in the build directory
22 # we can safely blow away any previous version of it
23 # (and we need not jump through hoops to try to delete
24 # it when configure exits.)
25 tmpdir = meson.current_build_dir() / 'meson-private/temp'
27 if get_option('qemu_suffix').startswith('/')
28 error('qemu_suffix cannot start with a /')
31 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
32 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
33 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
34 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
36 qemu_desktopdir = get_option('datadir') / 'applications'
37 qemu_icondir = get_option('datadir') / 'icons'
39 config_host_data = configuration_data()
42 target_dirs = config_host['TARGET_DIRS'].split()
43 have_linux_user = false
46 foreach target : target_dirs
47 have_linux_user = have_linux_user or target.endswith('linux-user')
48 have_bsd_user = have_bsd_user or target.endswith('bsd-user')
49 have_system = have_system or target.endswith('-softmmu')
51 have_user = have_linux_user or have_bsd_user
52 have_tools = 'CONFIG_TOOLS' in config_host
53 have_block = have_system or have_tools
55 python = import('python').find_installation()
57 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
58 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
59 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
61 cpu = host_machine.cpu_family()
62 targetos = host_machine.system()
64 if cpu in ['x86', 'x86_64']
65 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
67 kvm_targets = ['aarch64-softmmu']
69 kvm_targets = ['s390x-softmmu']
70 elif cpu in ['ppc', 'ppc64']
71 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
72 elif cpu in ['mips', 'mips64']
73 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
79 if not get_option('kvm').disabled() and targetos == 'linux'
80 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
82 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
84 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
87 accelerator_targets += {
88 'CONFIG_HVF': ['aarch64-softmmu']
92 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
93 # i386 emulator provides xenpv machine type for multiple architectures
94 accelerator_targets += {
95 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
98 if cpu in ['x86', 'x86_64']
99 accelerator_targets += {
100 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
101 'CONFIG_HVF': ['x86_64-softmmu'],
102 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
103 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
108 # Darwin does not support references to thread-local variables in modules
109 if targetos != 'darwin'
110 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
113 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
114 unpack_edk2_blobs = false
115 foreach target : edk2_targets
116 if target in target_dirs
117 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
118 unpack_edk2_blobs = bzip2.found()
125 if 'dtrace' in get_option('trace_backends')
126 dtrace = find_program('dtrace', required: true)
127 stap = find_program('stap', required: false)
129 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
130 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
131 # instead. QEMU --enable-modules depends on this because the SystemTap
132 # semaphores are linked into the main binary and not the module's shared
134 add_global_arguments('-DSTAP_SDT_V2',
135 native: false, language: ['c', 'cpp', 'objc'])
143 # Specify linker-script with add_project_link_arguments so that it is not placed
144 # within a linker --start-group/--end-group pair
145 if get_option('fuzzing')
146 add_project_link_arguments(['-Wl,-T,',
147 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
148 native: false, language: ['c', 'cpp', 'objc'])
150 # Specify a filter to only instrument code that is directly related to
152 configure_file(output: 'instrumentation-filter',
153 input: 'scripts/oss-fuzz/instrumentation-filter-template',
155 add_global_arguments(
156 cc.get_supported_arguments('-fsanitize-coverage-allowlist=instrumentation-filter'),
157 native: false, language: ['c', 'cpp', 'objc'])
159 if get_option('fuzzing_engine') == ''
160 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
161 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
162 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
163 # unable to bind the fuzzer-related callbacks added by instrumentation.
164 add_global_arguments('-fsanitize=fuzzer-no-link',
165 native: false, language: ['c', 'cpp', 'objc'])
166 add_global_link_arguments('-fsanitize=fuzzer-no-link',
167 native: false, language: ['c', 'cpp', 'objc'])
168 # For the actual fuzzer binaries, we need to link against the libfuzzer
169 # library. They need to be configurable, to support OSS-Fuzz
170 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
172 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
173 # the needed CFLAGS have already been provided
174 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
178 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
179 native: false, language: ['c', 'objc'])
180 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
181 native: false, language: 'cpp')
182 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
183 native: false, language: ['c', 'cpp', 'objc'])
185 if targetos == 'linux'
186 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
187 '-isystem', 'linux-headers',
188 language: ['c', 'cpp'])
191 add_project_arguments('-iquote', '.',
192 '-iquote', meson.current_source_dir(),
193 '-iquote', meson.current_source_dir() / 'include',
194 '-iquote', meson.current_source_dir() / 'disas/libvixl',
195 language: ['c', 'cpp', 'objc'])
197 link_language = meson.get_external_property('link_language', 'cpp')
198 if link_language == 'cpp'
199 add_languages('cpp', required: true, native: false)
201 if host_machine.system() == 'darwin'
202 add_languages('objc', required: false, native: false)
205 sparse = find_program('cgcc', required: get_option('sparse'))
208 command: [find_program('scripts/check_sparse.py'),
209 'compile_commands.json', sparse.full_path(), '-Wbitwise',
210 '-Wno-transparent-union', '-Wno-old-initializer',
211 '-Wno-non-pointer-null'])
214 ###########################################
215 # Target-specific checks and dependencies #
216 ###########################################
218 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
221 #include <sys/types.h>
222 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
223 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
225 args: ['-Werror', '-fsanitize=fuzzer'])
226 error('Your compiler does not support -fsanitize=fuzzer')
229 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
230 error('ftrace is supported only on Linux')
232 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
235 openlog("qemu", LOG_PID, LOG_DAEMON);
236 syslog(LOG_INFO, "configure");
239 error('syslog is not supported on this system')
242 if targetos != 'linux' and get_option('mpath').enabled()
243 error('Multipath is supported only on Linux')
246 if targetos != 'linux' and get_option('multiprocess').enabled()
247 error('Multiprocess QEMU is supported only on Linux')
249 multiprocess_allowed = targetos == 'linux' and not get_option('multiprocess').disabled()
251 libm = cc.find_library('m', required: false)
252 threads = dependency('threads')
253 util = cc.find_library('util', required: false)
259 emulator_link_args = []
263 if targetos == 'windows'
264 socket = cc.find_library('ws2_32')
265 winmm = cc.find_library('winmm')
267 win = import('windows')
268 version_res = win.compile_resources('version.rc',
269 depend_files: files('pc-bios/qemu-nsis.ico'),
270 include_directories: include_directories('.'))
272 elif targetos == 'darwin'
273 coref = dependency('appleframeworks', modules: 'CoreFoundation')
274 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
275 host_dsosuf = '.dylib'
276 elif targetos == 'sunos'
277 socket = [cc.find_library('socket'),
278 cc.find_library('nsl'),
279 cc.find_library('resolv')]
280 elif targetos == 'haiku'
281 socket = [cc.find_library('posix_error_mapper'),
282 cc.find_library('network'),
283 cc.find_library('bsd')]
284 elif targetos == 'openbsd'
285 if not get_option('tcg').disabled() and target_dirs.length() > 0
286 # Disable OpenBSD W^X if available
287 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
292 if not get_option('kvm').disabled() and targetos == 'linux'
293 accelerators += 'CONFIG_KVM'
295 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
296 accelerators += 'CONFIG_XEN'
297 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
299 have_xen_pci_passthrough = false
301 if not get_option('whpx').disabled() and targetos == 'windows'
302 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
303 error('WHPX requires 64-bit host')
304 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
305 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
306 accelerators += 'CONFIG_WHPX'
309 if not get_option('hvf').disabled()
310 hvf = dependency('appleframeworks', modules: 'Hypervisor',
311 required: get_option('hvf'))
313 accelerators += 'CONFIG_HVF'
316 if not get_option('hax').disabled()
317 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
318 accelerators += 'CONFIG_HAX'
321 if targetos == 'netbsd'
322 if cc.has_header_symbol('nvmm.h', 'nvmm_cpu_stop', required: get_option('nvmm'))
323 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
326 accelerators += 'CONFIG_NVMM'
330 tcg_arch = config_host['ARCH']
331 if not get_option('tcg').disabled()
332 if cpu not in supported_cpus
333 if get_option('tcg_interpreter')
334 warning('Unsupported CPU @0@, will use TCG with TCI (experimental and slow)'.format(cpu))
336 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
338 elif get_option('tcg_interpreter')
339 warning('Use of the TCG interpretor is not recommended on this host')
340 warning('architecture. There is a native TCG execution backend available')
341 warning('which provides substantially better performance and reliability.')
342 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
343 warning('configuration option on this architecture to use the native')
346 if get_option('tcg_interpreter')
348 elif config_host['ARCH'] == 'sparc64'
350 elif config_host['ARCH'] in ['x86_64', 'x32']
352 elif config_host['ARCH'] == 'ppc64'
354 elif config_host['ARCH'] in ['riscv32', 'riscv64']
357 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
358 language: ['c', 'cpp', 'objc'])
360 accelerators += 'CONFIG_TCG'
361 config_host += { 'CONFIG_TCG': 'y' }
364 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
365 error('KVM not available on this platform')
367 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
368 error('HVF not available on this platform')
370 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
371 error('NVMM not available on this platform')
373 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
374 error('WHPX not available on this platform')
376 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
377 if 'CONFIG_XEN' in accelerators
378 error('Xen PCI passthrough not available on this platform')
380 error('Xen PCI passthrough requested but Xen not enabled')
388 # The path to glib.h is added to all compilation commands. This was
389 # grandfathered in from the QEMU Makefiles.
390 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
391 native: false, language: ['c', 'cpp', 'objc'])
392 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
393 link_args: config_host['GLIB_LIBS'].split())
394 # override glib dep with the configure results (for subprojects)
395 meson.override_dependency('glib-2.0', glib)
398 if 'CONFIG_GIO' in config_host
399 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
400 link_args: config_host['GIO_LIBS'].split())
403 if 'ust' in get_option('trace_backends')
404 lttng = dependency('lttng-ust', required: true, method: 'pkg-config',
405 kwargs: static_kwargs)
408 if have_system or have_tools
409 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
410 method: 'pkg-config', kwargs: static_kwargs)
412 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
415 if not get_option('linux_aio').auto() or have_block
416 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
417 required: get_option('linux_aio'),
418 kwargs: static_kwargs)
420 linux_io_uring = not_found
421 if not get_option('linux_io_uring').auto() or have_block
422 linux_io_uring = dependency('liburing', required: get_option('linux_io_uring'),
423 method: 'pkg-config', kwargs: static_kwargs)
426 if not get_option('libxml2').auto() or have_block
427 libxml2 = dependency('libxml-2.0', required: get_option('libxml2'),
428 method: 'pkg-config', kwargs: static_kwargs)
431 if not get_option('libnfs').auto() or have_block
432 libnfs = dependency('libnfs', version: '>=1.9.3',
433 required: get_option('libnfs'),
434 method: 'pkg-config', kwargs: static_kwargs)
439 #include <sys/types.h>
440 #ifdef CONFIG_LIBATTR
441 #include <attr/xattr.h>
443 #include <sys/xattr.h>
445 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
448 have_old_libattr = false
449 if not get_option('attr').disabled()
450 if cc.links(libattr_test)
451 libattr = declare_dependency()
453 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
454 required: get_option('attr'),
455 kwargs: static_kwargs)
456 if libattr.found() and not \
457 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
459 if get_option('attr').enabled()
460 error('could not link libattr')
462 warning('could not link libattr, disabling')
465 have_old_libattr = libattr.found()
470 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
471 if cocoa.found() and get_option('sdl').enabled()
472 error('Cocoa and SDL cannot be enabled at the same time')
474 if cocoa.found() and get_option('gtk').enabled()
475 error('Cocoa and GTK+ cannot be enabled at the same time')
479 if not get_option('seccomp').auto() or have_system or have_tools
480 seccomp = dependency('libseccomp', version: '>=2.3.0',
481 required: get_option('seccomp'),
482 method: 'pkg-config', kwargs: static_kwargs)
485 libcap_ng = not_found
486 if not get_option('cap_ng').auto() or have_system or have_tools
487 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
488 required: get_option('cap_ng'),
489 kwargs: static_kwargs)
491 if libcap_ng.found() and not cc.links('''
495 capng_capability_to_name(CAPNG_EFFECTIVE);
497 }''', dependencies: libcap_ng)
498 libcap_ng = not_found
499 if get_option('cap_ng').enabled()
500 error('could not link libcap-ng')
502 warning('could not link libcap-ng, disabling')
506 if get_option('xkbcommon').auto() and not have_system and not have_tools
507 xkbcommon = not_found
509 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
510 method: 'pkg-config', kwargs: static_kwargs)
514 if not get_option('vde').auto() or have_system or have_tools
515 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
516 required: get_option('vde'),
517 kwargs: static_kwargs)
519 if vde.found() and not cc.links('''
520 #include <libvdeplug.h>
523 struct vde_open_args a = {0, 0, 0};
527 }''', dependencies: vde)
529 if get_option('cap_ng').enabled()
530 error('could not link libvdeplug')
532 warning('could not link libvdeplug, disabling')
537 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
538 pulse = dependency('libpulse', required: get_option('pa'),
539 method: 'pkg-config', kwargs: static_kwargs)
542 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
543 alsa = dependency('alsa', required: get_option('alsa'),
544 method: 'pkg-config', kwargs: static_kwargs)
547 if not get_option('jack').auto() or have_system
548 jack = dependency('jack', required: get_option('jack'),
549 method: 'pkg-config', kwargs: static_kwargs)
552 spice_protocol = not_found
553 if not get_option('spice_protocol').auto() or have_system
554 spice_protocol = dependency('spice-protocol', version: '>=0.12.3',
555 required: get_option('spice_protocol'),
556 method: 'pkg-config', kwargs: static_kwargs)
559 if not get_option('spice').auto() or have_system
560 spice = dependency('spice-server', version: '>=0.12.5',
561 required: get_option('spice'),
562 method: 'pkg-config', kwargs: static_kwargs)
564 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
566 rt = cc.find_library('rt', required: false)
568 if 'CONFIG_PLUGIN' in config_host
569 libdl = cc.find_library('dl', required: false)
570 if not cc.has_function('dlopen', dependencies: libdl)
571 error('dlopen not found')
575 if not get_option('libiscsi').auto() or have_block
576 libiscsi = dependency('libiscsi', version: '>=1.9.0',
577 required: get_option('libiscsi'),
578 method: 'pkg-config', kwargs: static_kwargs)
581 if not get_option('zstd').auto() or have_block
582 zstd = dependency('libzstd', version: '>=1.4.0',
583 required: get_option('zstd'),
584 method: 'pkg-config', kwargs: static_kwargs)
587 if not get_option('virglrenderer').auto() or have_system
588 virgl = dependency('virglrenderer',
589 method: 'pkg-config',
590 required: get_option('virglrenderer'),
591 kwargs: static_kwargs)
594 if not get_option('curl').auto() or have_block
595 curl = dependency('libcurl', version: '>=7.29.0',
596 method: 'pkg-config',
597 required: get_option('curl'),
598 kwargs: static_kwargs)
601 if targetos == 'linux' and (have_system or have_tools)
602 libudev = dependency('libudev',
603 method: 'pkg-config',
604 required: get_option('libudev'),
605 kwargs: static_kwargs)
608 mpathlibs = [libudev]
609 mpathpersist = not_found
610 mpathpersist_new_api = false
611 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
612 mpath_test_source_new = '''
614 #include <mpath_persist.h>
615 unsigned mpath_mx_alloc_len = 1024;
617 static struct config *multipath_conf;
618 extern struct udev *udev;
619 extern struct config *get_multipath_config(void);
620 extern void put_multipath_config(struct config *conf);
622 struct config *get_multipath_config(void) { return multipath_conf; }
623 void put_multipath_config(struct config *conf) { }
626 multipath_conf = mpath_lib_init();
629 mpath_test_source_old = '''
631 #include <mpath_persist.h>
632 unsigned mpath_mx_alloc_len = 1024;
635 struct udev *udev = udev_new();
636 mpath_lib_init(udev);
639 libmpathpersist = cc.find_library('mpathpersist',
640 required: get_option('mpath'),
641 kwargs: static_kwargs)
642 if libmpathpersist.found()
643 mpathlibs += libmpathpersist
645 mpathlibs += cc.find_library('devmapper',
646 required: get_option('mpath'),
647 kwargs: static_kwargs)
649 mpathlibs += cc.find_library('multipath',
650 required: get_option('mpath'),
651 kwargs: static_kwargs)
652 foreach lib: mpathlibs
658 if mpathlibs.length() == 0
659 msg = 'Dependencies missing for libmpathpersist'
660 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
661 mpathpersist = declare_dependency(dependencies: mpathlibs)
662 mpathpersist_new_api = true
663 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
664 mpathpersist = declare_dependency(dependencies: mpathlibs)
666 msg = 'Cannot detect libmpathpersist API'
668 if not mpathpersist.found()
669 if get_option('mpath').enabled()
672 warning(msg + ', disabling')
680 if have_system and not get_option('curses').disabled()
687 setlocale(LC_ALL, "");
689 addwstr(L"wide chars\n");
691 add_wch(WACS_DEGREE);
695 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
696 foreach curses_dep : curses_dep_list
697 if not curses.found()
698 curses = dependency(curses_dep,
700 method: 'pkg-config',
701 kwargs: static_kwargs)
704 msg = get_option('curses').enabled() ? 'curses library not found' : ''
705 curses_compile_args = ['-DNCURSES_WIDECHAR']
707 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
708 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
710 msg = 'curses package not usable'
714 if not curses.found()
715 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
716 if targetos != 'windows' and not has_curses_h
717 message('Trying with /usr/include/ncursesw')
718 curses_compile_args += ['-I/usr/include/ncursesw']
719 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
722 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
723 foreach curses_libname : curses_libname_list
724 libcurses = cc.find_library(curses_libname,
726 kwargs: static_kwargs)
728 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
729 curses = declare_dependency(compile_args: curses_compile_args,
730 dependencies: [libcurses])
733 msg = 'curses library not usable'
739 if not get_option('iconv').disabled()
740 foreach link_args : [ ['-liconv'], [] ]
741 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
742 # We need to use libiconv if available because mixing libiconv's headers with
743 # the system libc does not work.
744 # However, without adding glib to the dependencies -L/usr/local/lib will not be
745 # included in the command line and libiconv will not be found.
749 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
750 return conv != (iconv_t) -1;
751 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
752 iconv = declare_dependency(link_args: link_args, dependencies: glib)
757 if curses.found() and not iconv.found()
758 if get_option('iconv').enabled()
759 error('iconv not available')
761 msg = 'iconv required for curses UI but not available'
764 if not curses.found() and msg != ''
765 if get_option('curses').enabled()
768 warning(msg + ', disabling')
774 if not get_option('brlapi').auto() or have_system
775 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
776 required: get_option('brlapi'),
777 kwargs: static_kwargs)
778 if brlapi.found() and not cc.links('''
781 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
783 if get_option('brlapi').enabled()
784 error('could not link brlapi')
786 warning('could not link brlapi, disabling')
792 if not get_option('sdl').auto() or (have_system and not cocoa.found())
793 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
794 sdl_image = not_found
797 # work around 2.0.8 bug
798 sdl = declare_dependency(compile_args: '-Wno-undef',
800 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
801 method: 'pkg-config', kwargs: static_kwargs)
803 if get_option('sdl_image').enabled()
804 error('sdl-image required, but SDL was @0@'.format(
805 get_option('sdl').disabled() ? 'disabled' : 'not found'))
807 sdl_image = not_found
811 if not get_option('rbd').auto() or have_block
812 librados = cc.find_library('rados', required: get_option('rbd'),
813 kwargs: static_kwargs)
814 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
815 required: get_option('rbd'),
816 kwargs: static_kwargs)
817 if librados.found() and librbd.found()
820 #include <rbd/librbd.h>
823 rados_create(&cluster, NULL);
824 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
828 }''', dependencies: [librbd, librados])
829 rbd = declare_dependency(dependencies: [librbd, librados])
830 elif get_option('rbd').enabled()
831 error('librbd >= 1.12.0 required')
833 warning('librbd >= 1.12.0 not found, disabling')
838 glusterfs = not_found
839 glusterfs_ftruncate_has_stat = false
840 glusterfs_iocb_has_stat = false
841 if not get_option('glusterfs').auto() or have_block
842 glusterfs = dependency('glusterfs-api', version: '>=3',
843 required: get_option('glusterfs'),
844 method: 'pkg-config', kwargs: static_kwargs)
846 glusterfs_ftruncate_has_stat = cc.links('''
847 #include <glusterfs/api/glfs.h>
852 /* new glfs_ftruncate() passes two additional args */
853 return glfs_ftruncate(NULL, 0, NULL, NULL);
855 ''', dependencies: glusterfs)
856 glusterfs_iocb_has_stat = cc.links('''
857 #include <glusterfs/api/glfs.h>
859 /* new glfs_io_cbk() passes two additional glfs_stat structs */
861 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
867 glfs_io_cbk iocb = &glusterfs_iocb;
868 iocb(NULL, 0 , NULL, NULL, NULL);
871 ''', dependencies: glusterfs)
875 if 'CONFIG_LIBSSH' in config_host
876 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
877 link_args: config_host['LIBSSH_LIBS'].split())
880 if not get_option('bzip2').auto() or have_block
881 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
882 required: get_option('bzip2'),
883 kwargs: static_kwargs)
884 if libbzip2.found() and not cc.links('''
886 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
888 if get_option('bzip2').enabled()
889 error('could not link libbzip2')
891 warning('could not link libbzip2, disabling')
897 if not get_option('lzfse').auto() or have_block
898 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
899 required: get_option('lzfse'),
900 kwargs: static_kwargs)
902 if liblzfse.found() and not cc.links('''
904 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
906 if get_option('lzfse').enabled()
907 error('could not link liblzfse')
909 warning('could not link liblzfse, disabling')
914 if not get_option('oss').auto() or have_system
915 if not cc.has_header('sys/soundcard.h')
917 elif targetos == 'netbsd'
918 oss = cc.find_library('ossaudio', required: get_option('oss'),
919 kwargs: static_kwargs)
921 oss = declare_dependency()
925 if get_option('oss').enabled()
926 error('OSS not found')
928 warning('OSS not found, disabling')
933 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
934 if cc.has_header('dsound.h')
935 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
938 if not dsound.found()
939 if get_option('dsound').enabled()
940 error('DirectSound not found')
942 warning('DirectSound not found, disabling')
947 coreaudio = not_found
948 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
949 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
950 required: get_option('coreaudio'))
951 if coreaudio.found() and not cc.links('''
952 #include <CoreAudio/CoreAudio.h>
955 return (int)AudioGetCurrentHostTime();
957 coreaudio = not_found
960 if not coreaudio.found()
961 if get_option('coreaudio').enabled()
962 error('CoreAudio not found')
964 warning('CoreAudio not found, disabling')
970 if 'CONFIG_OPENGL' in config_host
971 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
972 link_args: config_host['OPENGL_LIBS'].split())
975 if (have_system or have_tools) and (virgl.found() or opengl.found())
976 gbm = dependency('gbm', method: 'pkg-config', required: false,
977 kwargs: static_kwargs)
981 gnutls_crypto = not_found
982 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
983 # For general TLS support our min gnutls matches
984 # that implied by our platform support matrix
986 # For the crypto backends, we look for a newer
989 # Version 3.6.8 is needed to get XTS
990 # Version 3.6.13 is needed to get PBKDF
991 # Version 3.6.14 is needed to get HW accelerated XTS
993 # If newer enough gnutls isn't available, we can
994 # still use a different crypto backend to satisfy
995 # the platform support requirements
996 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
997 method: 'pkg-config',
999 kwargs: static_kwargs)
1000 if gnutls_crypto.found()
1001 gnutls = gnutls_crypto
1003 # Our min version if all we need is TLS
1004 gnutls = dependency('gnutls', version: '>=3.5.18',
1005 method: 'pkg-config',
1006 required: get_option('gnutls'),
1007 kwargs: static_kwargs)
1011 # We prefer use of gnutls for crypto, unless the options
1012 # explicitly asked for nettle or gcrypt.
1014 # If gnutls isn't available for crypto, then we'll prefer
1015 # gcrypt over nettle for performance reasons.
1020 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1021 error('Only one of gcrypt & nettle can be enabled')
1024 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1025 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1026 gnutls_crypto = not_found
1029 if not gnutls_crypto.found()
1030 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1031 gcrypt = dependency('libgcrypt', version: '>=1.8',
1032 method: 'config-tool',
1033 required: get_option('gcrypt'),
1034 kwargs: static_kwargs)
1035 # Debian has removed -lgpg-error from libgcrypt-config
1036 # as it "spreads unnecessary dependencies" which in
1037 # turn breaks static builds...
1038 if gcrypt.found() and enable_static
1039 gcrypt = declare_dependency(dependencies: [
1041 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
1044 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1045 nettle = dependency('nettle', version: '>=3.4',
1046 method: 'pkg-config',
1047 required: get_option('nettle'),
1048 kwargs: static_kwargs)
1049 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1058 if not get_option('gtk').auto() or (have_system and not cocoa.found())
1059 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1060 method: 'pkg-config',
1061 required: get_option('gtk'),
1062 kwargs: static_kwargs)
1064 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1065 method: 'pkg-config',
1067 kwargs: static_kwargs)
1068 gtk = declare_dependency(dependencies: [gtk, gtkx11])
1070 if not get_option('vte').auto() or have_system
1071 vte = dependency('vte-2.91',
1072 method: 'pkg-config',
1073 required: get_option('vte'),
1074 kwargs: static_kwargs)
1081 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
1082 kwargs: static_kwargs)
1088 if have_system and not get_option('vnc').disabled()
1089 vnc = declare_dependency() # dummy dependency
1090 png = dependency('libpng', required: get_option('vnc_png'),
1091 method: 'pkg-config', kwargs: static_kwargs)
1092 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1093 method: 'pkg-config', kwargs: static_kwargs)
1094 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1095 required: get_option('vnc_sasl'),
1096 kwargs: static_kwargs)
1098 sasl = declare_dependency(dependencies: sasl,
1099 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1104 if not get_option('auth_pam').auto() or have_system
1105 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1106 required: get_option('auth_pam'),
1107 kwargs: static_kwargs)
1109 if pam.found() and not cc.links('''
1111 #include <security/pam_appl.h>
1113 const char *service_name = "qemu";
1114 const char *user = "frank";
1115 const struct pam_conv pam_conv = { 0 };
1116 pam_handle_t *pamh = NULL;
1117 pam_start(service_name, user, &pam_conv, &pamh);
1119 }''', dependencies: pam)
1121 if get_option('auth_pam').enabled()
1122 error('could not link libpam')
1124 warning('could not link libpam, disabling')
1129 if not get_option('snappy').auto() or have_system
1130 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1131 required: get_option('snappy'),
1132 kwargs: static_kwargs)
1134 if snappy.found() and not cc.links('''
1135 #include <snappy-c.h>
1136 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1138 if get_option('snappy').enabled()
1139 error('could not link libsnappy')
1141 warning('could not link libsnappy, disabling')
1146 if not get_option('lzo').auto() or have_system
1147 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1148 required: get_option('lzo'),
1149 kwargs: static_kwargs)
1151 if lzo.found() and not cc.links('''
1152 #include <lzo/lzo1x.h>
1153 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1155 if get_option('lzo').enabled()
1156 error('could not link liblzo2')
1158 warning('could not link liblzo2, disabling')
1163 if 'CONFIG_RDMA' in config_host
1164 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
1167 if 'CONFIG_NUMA' in config_host
1168 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
1171 if 'CONFIG_XEN_BACKEND' in config_host
1172 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
1173 link_args: config_host['XEN_LIBS'].split())
1176 if not get_option('smartcard').auto() or have_system
1177 cacard = dependency('libcacard', required: get_option('smartcard'),
1178 version: '>=2.5.1', method: 'pkg-config',
1179 kwargs: static_kwargs)
1183 u2f = dependency('u2f-emu', required: get_option('u2f'),
1184 method: 'pkg-config',
1185 kwargs: static_kwargs)
1187 usbredir = not_found
1188 if not get_option('usb_redir').auto() or have_system
1189 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1190 version: '>=0.6', method: 'pkg-config',
1191 kwargs: static_kwargs)
1194 if not get_option('libusb').auto() or have_system
1195 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1196 version: '>=1.0.13', method: 'pkg-config',
1197 kwargs: static_kwargs)
1201 if not get_option('libpmem').auto() or have_system
1202 libpmem = dependency('libpmem', required: get_option('libpmem'),
1203 method: 'pkg-config', kwargs: static_kwargs)
1205 libdaxctl = not_found
1206 if not get_option('libdaxctl').auto() or have_system
1207 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1208 version: '>=57', method: 'pkg-config',
1209 kwargs: static_kwargs)
1213 tasn1 = dependency('libtasn1',
1214 method: 'pkg-config',
1215 kwargs: static_kwargs)
1217 keyutils = dependency('libkeyutils', required: false,
1218 method: 'pkg-config', kwargs: static_kwargs)
1220 has_gettid = cc.has_function('gettid')
1225 if get_option('malloc') == 'system'
1227 not get_option('malloc_trim').disabled() and \
1228 cc.links('''#include <malloc.h>
1229 int main(void) { malloc_trim(0); return 0; }''')
1231 has_malloc_trim = false
1232 malloc = cc.find_library(get_option('malloc'), required: true)
1234 if not has_malloc_trim and get_option('malloc_trim').enabled()
1235 if get_option('malloc') == 'system'
1236 error('malloc_trim not available on this platform.')
1238 error('malloc_trim not available with non-libc memory allocator')
1242 # Check whether the glibc provides statx()
1244 gnu_source_prefix = '''
1249 statx_test = gnu_source_prefix + '''
1250 #include <sys/stat.h>
1252 struct statx statxbuf;
1253 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1257 has_statx = cc.links(statx_test)
1259 have_vhost_user_blk_server = (targetos == 'linux' and
1260 'CONFIG_VHOST_USER' in config_host)
1262 if get_option('vhost_user_blk_server').enabled()
1263 if targetos != 'linux'
1264 error('vhost_user_blk_server requires linux')
1265 elif 'CONFIG_VHOST_USER' not in config_host
1266 error('vhost_user_blk_server requires vhost-user support')
1268 elif get_option('vhost_user_blk_server').disabled() or not have_system
1269 have_vhost_user_blk_server = false
1273 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1274 error('Cannot enable fuse-lseek while fuse is disabled')
1277 fuse = dependency('fuse3', required: get_option('fuse'),
1278 version: '>=3.1', method: 'pkg-config',
1279 kwargs: static_kwargs)
1281 fuse_lseek = not_found
1282 if not get_option('fuse_lseek').disabled()
1283 if fuse.version().version_compare('>=3.8')
1285 fuse_lseek = declare_dependency()
1286 elif get_option('fuse_lseek').enabled()
1288 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1290 error('fuse-lseek requires libfuse, which was not found')
1296 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1297 if libbpf.found() and not cc.links('''
1298 #include <bpf/libbpf.h>
1301 bpf_object__destroy_skeleton(NULL);
1303 }''', dependencies: libbpf)
1305 if get_option('bpf').enabled()
1306 error('libbpf skeleton test failed')
1308 warning('libbpf skeleton test failed, disabling')
1316 audio_drivers_selected = []
1318 audio_drivers_available = {
1319 'alsa': alsa.found(),
1320 'coreaudio': coreaudio.found(),
1321 'dsound': dsound.found(),
1322 'jack': jack.found(),
1324 'pa': pulse.found(),
1327 foreach k, v: audio_drivers_available
1328 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1331 # Default to native drivers first, OSS second, SDL third
1332 audio_drivers_priority = \
1333 [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
1334 (targetos == 'linux' ? [] : [ 'sdl' ])
1335 audio_drivers_default = []
1336 foreach k: audio_drivers_priority
1337 if audio_drivers_available[k]
1338 audio_drivers_default += k
1342 foreach k: get_option('audio_drv_list')
1344 audio_drivers_selected += audio_drivers_default
1345 elif not audio_drivers_available[k]
1346 error('Audio driver "@0@" not available.'.format(k))
1348 audio_drivers_selected += k
1352 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1353 '"' + '", "'.join(audio_drivers_selected) + '", ')
1355 if get_option('cfi')
1357 # Check for dependency on LTO
1358 if not get_option('b_lto')
1359 error('Selected Control-Flow Integrity but LTO is disabled')
1361 if config_host.has_key('CONFIG_MODULES')
1362 error('Selected Control-Flow Integrity is not compatible with modules')
1364 # Check for cfi flags. CFI requires LTO so we can't use
1365 # get_supported_arguments, but need a more complex "compiles" which allows
1367 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1368 args: ['-flto', '-fsanitize=cfi-icall'] )
1369 cfi_flags += '-fsanitize=cfi-icall'
1371 error('-fsanitize=cfi-icall is not supported by the compiler')
1373 if cc.compiles('int main () { return 0; }',
1374 name: '-fsanitize-cfi-icall-generalize-pointers',
1375 args: ['-flto', '-fsanitize=cfi-icall',
1376 '-fsanitize-cfi-icall-generalize-pointers'] )
1377 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1379 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1381 if get_option('cfi_debug')
1382 if cc.compiles('int main () { return 0; }',
1383 name: '-fno-sanitize-trap=cfi-icall',
1384 args: ['-flto', '-fsanitize=cfi-icall',
1385 '-fno-sanitize-trap=cfi-icall'] )
1386 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1388 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1391 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1392 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1395 have_host_block_device = (targetos != 'darwin' or
1396 cc.has_header('IOKit/storage/IOMedia.h'))
1398 have_virtfs = (targetos == 'linux' and
1403 have_virtfs_proxy_helper = have_virtfs and have_tools
1405 if get_option('virtfs').enabled()
1407 if targetos != 'linux'
1408 error('virtio-9p (virtfs) requires Linux')
1409 elif not libcap_ng.found() or not libattr.found()
1410 error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1411 elif not have_system
1412 error('virtio-9p (virtfs) needs system emulation support')
1415 elif get_option('virtfs').disabled()
1419 foreach k : get_option('trace_backends')
1420 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1422 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1424 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1425 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1426 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1427 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1428 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1429 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1430 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1431 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1432 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1433 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1434 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1435 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1437 config_host_data.set('CONFIG_ATTR', libattr.found())
1438 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1439 config_host_data.set('CONFIG_COCOA', cocoa.found())
1440 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1441 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1442 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1443 config_host_data.set('CONFIG_LZO', lzo.found())
1444 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1445 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1446 config_host_data.set('CONFIG_CURL', curl.found())
1447 config_host_data.set('CONFIG_CURSES', curses.found())
1448 config_host_data.set('CONFIG_GBM', gbm.found())
1449 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1450 if glusterfs.found()
1451 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1452 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1453 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1454 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1455 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1456 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1458 config_host_data.set('CONFIG_GTK', gtk.found())
1459 config_host_data.set('CONFIG_VTE', vte.found())
1460 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1461 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1462 config_host_data.set('CONFIG_EBPF', libbpf.found())
1463 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1464 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1465 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1466 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1467 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1468 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1469 config_host_data.set('CONFIG_RBD', rbd.found())
1470 config_host_data.set('CONFIG_SDL', sdl.found())
1471 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1472 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1473 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1474 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1475 config_host_data.set('CONFIG_VDE', vde.found())
1476 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1477 config_host_data.set('CONFIG_VNC', vnc.found())
1478 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1479 config_host_data.set('CONFIG_VNC_PNG', png.found())
1480 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1481 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1482 config_host_data.set('CONFIG_VTE', vte.found())
1483 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1484 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1485 config_host_data.set('CONFIG_GETTID', has_gettid)
1486 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1487 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1488 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1489 config_host_data.set('CONFIG_NETTLE', nettle.found())
1490 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1491 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1492 config_host_data.set('CONFIG_STATX', has_statx)
1493 config_host_data.set('CONFIG_ZSTD', zstd.found())
1494 config_host_data.set('CONFIG_FUSE', fuse.found())
1495 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1496 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1497 config_host_data.set('CONFIG_SPICE', spice.found())
1498 config_host_data.set('CONFIG_X11', x11.found())
1499 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1500 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1501 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1502 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1503 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1505 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1506 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1507 config_host_data.set('HOST_WORDS_BIGENDIAN', host_machine.endian() == 'big')
1510 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1511 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1512 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1513 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1514 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1515 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1516 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1517 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1518 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1521 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1522 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1523 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1524 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1525 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1526 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
1527 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1528 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1529 config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
1530 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1531 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1532 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1533 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1534 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1535 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1536 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1537 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1538 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1540 config_host_data.set('HAVE_IBV_ADVISE_MR',
1541 cc.has_function('ibv_advise_mr',
1542 args: config_host['RDMA_LIBS'].split(),
1543 prefix: '#include <infiniband/verbs.h>'))
1547 config_host_data.set('CONFIG_BYTESWAP_H',
1548 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1549 config_host_data.set('CONFIG_EPOLL_CREATE1',
1550 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1551 config_host_data.set('CONFIG_HAS_ENVIRON',
1552 cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix))
1553 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1554 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1555 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1556 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1557 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1558 config_host_data.set('CONFIG_FIEMAP',
1559 cc.has_header('linux/fiemap.h') and
1560 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1561 config_host_data.set('CONFIG_GETRANDOM',
1562 cc.has_function('getrandom') and
1563 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1564 config_host_data.set('CONFIG_INOTIFY',
1565 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1566 config_host_data.set('CONFIG_INOTIFY1',
1567 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1568 config_host_data.set('CONFIG_IOVEC',
1569 cc.has_header_symbol('sys/uio.h', 'struct iovec'))
1570 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1571 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1572 prefix: '''#include <sys/endian.h>
1573 #include <sys/types.h>'''))
1574 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1575 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1576 config_host_data.set('CONFIG_RTNETLINK',
1577 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1578 config_host_data.set('CONFIG_SYSMACROS',
1579 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1580 config_host_data.set('HAVE_OPTRESET',
1581 cc.has_header_symbol('getopt.h', 'optreset'))
1582 config_host_data.set('HAVE_UTMPX',
1583 cc.has_header_symbol('utmpx.h', 'struct utmpx'))
1584 config_host_data.set('HAVE_IPPROTO_MPTCP',
1585 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1588 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1589 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1590 prefix: '#include <signal.h>'))
1591 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1592 cc.has_member('struct stat', 'st_atim',
1593 prefix: '#include <sys/stat.h>'))
1595 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1596 #include <sys/eventfd.h>
1597 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1598 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1601 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1602 return fdatasync(0);
1604 #error Not supported
1607 config_host_data.set('CONFIG_MADVISE', cc.links(gnu_source_prefix + '''
1608 #include <sys/types.h>
1609 #include <sys/mman.h>
1611 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }'''))
1612 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1613 #include <sys/mman.h>
1614 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1615 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1617 #if !defined(AT_EMPTY_PATH)
1618 # error missing definition
1620 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1622 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1629 return pipe2(pipefd, O_CLOEXEC);
1631 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1632 #include <sys/mman.h>
1634 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1636 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links('''
1637 #include <pthread.h>
1639 static void *f(void *p) { return NULL; }
1643 pthread_create(&thread, 0, f, 0);
1644 pthread_setname_np(thread, "QEMU");
1646 }''', dependencies: threads))
1647 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links('''
1648 #include <pthread.h>
1650 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
1654 pthread_create(&thread, 0, f, 0);
1656 }''', dependencies: threads))
1658 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1659 #include <sys/signalfd.h>
1661 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1662 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1670 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1671 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1675 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
1676 #include <sys/mman.h>
1677 int main(int argc, char *argv[]) {
1678 return mlockall(MCL_FUTURE);
1682 if not get_option('netmap').disabled() and have_system
1683 have_netmap = cc.compiles('''
1684 #include <inttypes.h>
1686 #include <net/netmap.h>
1687 #include <net/netmap_user.h>
1688 #if (NETMAP_API < 11) || (NETMAP_API > 15)
1691 int main(void) { return 0; }''')
1692 if not have_netmap and get_option('netmap').enabled()
1693 error('Netmap headers not available')
1696 config_host_data.set('CONFIG_NETMAP', have_netmap)
1698 # Work around a system header bug with some kernel/XFS header
1699 # versions where they both try to define 'struct fsxattr':
1700 # xfs headers will not try to redefine structs from linux headers
1701 # if this macro is set.
1702 config_host_data.set('HAVE_FSXATTR', cc.links('''
1703 #include <linux/fs.h>'
1709 # Some versions of Mac OS X incorrectly define SIZE_MAX
1710 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1713 int main(int argc, char *argv[]) {
1714 return printf("%zu", SIZE_MAX);
1715 }''', args: ['-Werror']))
1717 # See if 64-bit atomic operations are supported.
1718 # Note that without __atomic builtins, we can only
1719 # assume atomic loads/stores max at pointer size.
1720 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
1724 uint64_t x = 0, y = 0;
1725 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
1726 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
1727 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
1728 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
1729 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
1733 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
1734 #include <sys/auxv.h>
1736 return getauxval(AT_HWCAP) == 0;
1739 config_host_data.set('CONFIG_AF_VSOCK', cc.compiles(gnu_source_prefix + '''
1741 #include <sys/types.h>
1742 #include <sys/socket.h>
1743 #if !defined(AF_VSOCK)
1744 # error missing AF_VSOCK flag
1746 #include <linux/vm_sockets.h>
1749 struct sockaddr_vm svm;
1750 socklen_t len = sizeof(svm);
1751 sock = socket(AF_VSOCK, SOCK_STREAM, 0);
1752 ret = getpeername(sock, (struct sockaddr *)&svm, &len);
1753 if ((ret == -1) && (errno == ENOTCONN)) {
1759 ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target
1761 arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1762 strings = ['CONFIG_IASL']
1763 foreach k, v: config_host
1764 if ignored.contains(k)
1766 elif arrays.contains(k)
1768 v = '"' + '", "'.join(v.split()) + '", '
1770 config_host_data.set(k, v)
1772 config_host_data.set('HOST_' + v.to_upper(), 1)
1773 elif strings.contains(k)
1774 config_host_data.set_quoted(k, v)
1775 elif k.startswith('CONFIG_')
1776 config_host_data.set(k, v == 'y' ? 1 : v)
1780 ########################
1781 # Target configuration #
1782 ########################
1784 minikconf = find_program('scripts/minikconf.py')
1786 config_all_devices = {}
1787 config_all_disas = {}
1788 config_devices_mak_list = []
1789 config_devices_h = {}
1790 config_target_h = {}
1791 config_target_mak = {}
1794 'alpha' : ['CONFIG_ALPHA_DIS'],
1795 'arm' : ['CONFIG_ARM_DIS'],
1796 'avr' : ['CONFIG_AVR_DIS'],
1797 'cris' : ['CONFIG_CRIS_DIS'],
1798 'hexagon' : ['CONFIG_HEXAGON_DIS'],
1799 'hppa' : ['CONFIG_HPPA_DIS'],
1800 'i386' : ['CONFIG_I386_DIS'],
1801 'x86_64' : ['CONFIG_I386_DIS'],
1802 'x32' : ['CONFIG_I386_DIS'],
1803 'm68k' : ['CONFIG_M68K_DIS'],
1804 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1805 'mips' : ['CONFIG_MIPS_DIS'],
1806 'nios2' : ['CONFIG_NIOS2_DIS'],
1807 'or1k' : ['CONFIG_OPENRISC_DIS'],
1808 'ppc' : ['CONFIG_PPC_DIS'],
1809 'riscv' : ['CONFIG_RISCV_DIS'],
1810 'rx' : ['CONFIG_RX_DIS'],
1811 's390' : ['CONFIG_S390_DIS'],
1812 'sh4' : ['CONFIG_SH4_DIS'],
1813 'sparc' : ['CONFIG_SPARC_DIS'],
1814 'xtensa' : ['CONFIG_XTENSA_DIS'],
1816 if link_language == 'cpp'
1818 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1819 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1820 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1824 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
1826 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
1827 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1828 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
1829 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
1830 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1831 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1832 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1833 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1834 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1835 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1836 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1837 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1838 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1840 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1842 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1843 actual_target_dirs = []
1845 foreach target : target_dirs
1846 config_target = { 'TARGET_NAME': target.split('-')[0] }
1847 if target.endswith('linux-user')
1848 if targetos != 'linux'
1852 error('Target @0@ is only available on a Linux host'.format(target))
1854 config_target += { 'CONFIG_LINUX_USER': 'y' }
1855 elif target.endswith('bsd-user')
1856 if 'CONFIG_BSD' not in config_host
1860 error('Target @0@ is only available on a BSD host'.format(target))
1862 config_target += { 'CONFIG_BSD_USER': 'y' }
1863 elif target.endswith('softmmu')
1864 config_target += { 'CONFIG_SOFTMMU': 'y' }
1866 if target.endswith('-user')
1868 'CONFIG_USER_ONLY': 'y',
1869 'CONFIG_QEMU_INTERP_PREFIX':
1870 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1875 foreach sym: accelerators
1876 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1877 config_target += { sym: 'y' }
1878 config_all += { sym: 'y' }
1879 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1880 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1881 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1882 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1884 if target in modular_tcg
1885 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
1887 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
1889 accel_kconfig += [ sym + '=y' ]
1892 if accel_kconfig.length() == 0
1896 error('No accelerator available for target @0@'.format(target))
1899 actual_target_dirs += target
1900 config_target += keyval.load('configs/targets' / target + '.mak')
1901 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1903 if 'TARGET_NEED_FDT' in config_target
1904 fdt_required += target
1908 if 'TARGET_BASE_ARCH' not in config_target
1909 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1911 if 'TARGET_ABI_DIR' not in config_target
1912 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1915 foreach k, v: disassemblers
1916 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1918 config_target += { sym: 'y' }
1919 config_all_disas += { sym: 'y' }
1924 config_target_data = configuration_data()
1925 foreach k, v: config_target
1926 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1928 elif ignored.contains(k)
1930 elif k == 'TARGET_BASE_ARCH'
1931 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1932 # not used to select files from sourcesets.
1933 config_target_data.set('TARGET_' + v.to_upper(), 1)
1934 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1935 config_target_data.set_quoted(k, v)
1937 config_target_data.set(k, 1)
1939 config_target_data.set(k, v)
1942 config_target_data.set('QEMU_ARCH',
1943 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
1944 config_target_h += {target: configure_file(output: target + '-config-target.h',
1945 configuration: config_target_data)}
1947 if target.endswith('-softmmu')
1948 config_input = meson.get_external_property(target, 'default')
1949 config_devices_mak = target + '-config-devices.mak'
1950 config_devices_mak = configure_file(
1951 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
1952 output: config_devices_mak,
1953 depfile: config_devices_mak + '.d',
1955 command: [minikconf,
1956 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1957 config_devices_mak, '@DEPFILE@', '@INPUT@',
1958 host_kconfig, accel_kconfig,
1959 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
1961 config_devices_data = configuration_data()
1962 config_devices = keyval.load(config_devices_mak)
1963 foreach k, v: config_devices
1964 config_devices_data.set(k, 1)
1966 config_devices_mak_list += config_devices_mak
1967 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1968 configuration: config_devices_data)}
1969 config_target += config_devices
1970 config_all_devices += config_devices
1972 config_target_mak += {target: config_target}
1974 target_dirs = actual_target_dirs
1976 # This configuration is used to build files that are shared by
1977 # multiple binaries, and then extracted out of the "common"
1978 # static_library target.
1980 # We do not use all_sources()/all_dependencies(), because it would
1981 # build literally all source files, including devices only used by
1982 # targets that are not built for this compilation. The CONFIG_ALL
1983 # pseudo symbol replaces it.
1985 config_all += config_all_devices
1986 config_all += config_host
1987 config_all += config_all_disas
1989 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1990 'CONFIG_SOFTMMU': have_system,
1991 'CONFIG_USER_ONLY': have_user,
1999 capstone = not_found
2000 capstone_opt = get_option('capstone')
2001 if capstone_opt in ['enabled', 'auto', 'system']
2002 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
2003 capstone = dependency('capstone', version: '>=4.0',
2004 kwargs: static_kwargs, method: 'pkg-config',
2005 required: capstone_opt == 'system' or
2006 capstone_opt == 'enabled' and not have_internal)
2008 # Some versions of capstone have broken pkg-config file
2009 # that reports a wrong -I path, causing the #include to
2010 # fail later. If the system has such a broken version
2012 if capstone.found() and not cc.compiles('#include <capstone.h>',
2013 dependencies: [capstone])
2014 capstone = not_found
2015 if capstone_opt == 'system'
2016 error('system capstone requested, it does not appear to work')
2021 capstone_opt = 'system'
2023 capstone_opt = 'internal'
2025 capstone_opt = 'disabled'
2028 if capstone_opt == 'internal'
2029 capstone_data = configuration_data()
2030 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
2032 capstone_files = files(
2034 'capstone/MCInst.c',
2035 'capstone/MCInstrDesc.c',
2036 'capstone/MCRegisterInfo.c',
2037 'capstone/SStream.c',
2041 if 'CONFIG_ARM_DIS' in config_all_disas
2042 capstone_data.set('CAPSTONE_HAS_ARM', '1')
2043 capstone_files += files(
2044 'capstone/arch/ARM/ARMDisassembler.c',
2045 'capstone/arch/ARM/ARMInstPrinter.c',
2046 'capstone/arch/ARM/ARMMapping.c',
2047 'capstone/arch/ARM/ARMModule.c'
2051 # FIXME: This config entry currently depends on a c++ compiler.
2052 # Which is needed for building libvixl, but not for capstone.
2053 if 'CONFIG_ARM_A64_DIS' in config_all_disas
2054 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
2055 capstone_files += files(
2056 'capstone/arch/AArch64/AArch64BaseInfo.c',
2057 'capstone/arch/AArch64/AArch64Disassembler.c',
2058 'capstone/arch/AArch64/AArch64InstPrinter.c',
2059 'capstone/arch/AArch64/AArch64Mapping.c',
2060 'capstone/arch/AArch64/AArch64Module.c'
2064 if 'CONFIG_PPC_DIS' in config_all_disas
2065 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
2066 capstone_files += files(
2067 'capstone/arch/PowerPC/PPCDisassembler.c',
2068 'capstone/arch/PowerPC/PPCInstPrinter.c',
2069 'capstone/arch/PowerPC/PPCMapping.c',
2070 'capstone/arch/PowerPC/PPCModule.c'
2074 if 'CONFIG_S390_DIS' in config_all_disas
2075 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
2076 capstone_files += files(
2077 'capstone/arch/SystemZ/SystemZDisassembler.c',
2078 'capstone/arch/SystemZ/SystemZInstPrinter.c',
2079 'capstone/arch/SystemZ/SystemZMapping.c',
2080 'capstone/arch/SystemZ/SystemZModule.c',
2081 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
2085 if 'CONFIG_I386_DIS' in config_all_disas
2086 capstone_data.set('CAPSTONE_HAS_X86', 1)
2087 capstone_files += files(
2088 'capstone/arch/X86/X86Disassembler.c',
2089 'capstone/arch/X86/X86DisassemblerDecoder.c',
2090 'capstone/arch/X86/X86ATTInstPrinter.c',
2091 'capstone/arch/X86/X86IntelInstPrinter.c',
2092 'capstone/arch/X86/X86InstPrinterCommon.c',
2093 'capstone/arch/X86/X86Mapping.c',
2094 'capstone/arch/X86/X86Module.c'
2098 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
2101 # FIXME: There does not seem to be a way to completely replace the c_args
2102 # that come from add_project_arguments() -- we can only add to them.
2103 # So: disable all warnings with a big hammer.
2106 # Include all configuration defines via a header file, which will wind up
2107 # as a dependency on the object file, and thus changes here will result
2109 '-include', 'capstone-defs.h'
2112 libcapstone = static_library('capstone',
2113 build_by_default: false,
2114 sources: capstone_files,
2115 c_args: capstone_cargs,
2116 include_directories: 'capstone/include')
2117 capstone = declare_dependency(link_with: libcapstone,
2118 include_directories: 'capstone/include/capstone')
2122 slirp_opt = 'disabled'
2124 slirp_opt = get_option('slirp')
2125 if slirp_opt in ['enabled', 'auto', 'system']
2126 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2127 slirp = dependency('slirp', kwargs: static_kwargs,
2128 method: 'pkg-config',
2129 required: slirp_opt == 'system' or
2130 slirp_opt == 'enabled' and not have_internal)
2132 slirp_opt = 'system'
2134 slirp_opt = 'internal'
2136 slirp_opt = 'disabled'
2139 if slirp_opt == 'internal'
2141 if targetos == 'windows'
2142 slirp_deps = cc.find_library('iphlpapi')
2143 elif targetos == 'darwin'
2144 slirp_deps = cc.find_library('resolv')
2146 slirp_conf = configuration_data()
2147 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2148 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2149 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2150 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2151 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2153 'slirp/src/arp_table.c',
2154 'slirp/src/bootp.c',
2155 'slirp/src/cksum.c',
2156 'slirp/src/dhcpv6.c',
2157 'slirp/src/dnssearch.c',
2159 'slirp/src/ip6_icmp.c',
2160 'slirp/src/ip6_input.c',
2161 'slirp/src/ip6_output.c',
2162 'slirp/src/ip_icmp.c',
2163 'slirp/src/ip_input.c',
2164 'slirp/src/ip_output.c',
2168 'slirp/src/ndp_table.c',
2170 'slirp/src/slirp.c',
2171 'slirp/src/socket.c',
2172 'slirp/src/state.c',
2173 'slirp/src/stream.c',
2174 'slirp/src/tcp_input.c',
2175 'slirp/src/tcp_output.c',
2176 'slirp/src/tcp_subr.c',
2177 'slirp/src/tcp_timer.c',
2182 'slirp/src/version.c',
2183 'slirp/src/vmstate.c',
2187 input : 'slirp/src/libslirp-version.h.in',
2188 output : 'libslirp-version.h',
2189 configuration: slirp_conf)
2191 slirp_inc = include_directories('slirp', 'slirp/src')
2192 libslirp = static_library('slirp',
2193 build_by_default: false,
2194 sources: slirp_files,
2195 c_args: slirp_cargs,
2196 include_directories: slirp_inc)
2197 slirp = declare_dependency(link_with: libslirp,
2198 dependencies: slirp_deps,
2199 include_directories: slirp_inc)
2203 # For CFI, we need to compile slirp as a static library together with qemu.
2204 # This is because we register slirp functions as callbacks for QEMU Timers.
2205 # When using a system-wide shared libslirp, the type information for the
2206 # callback is missing and the timer call produces a false positive with CFI.
2208 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2209 # with control-flow integrity.
2210 if get_option('cfi') and slirp_opt == 'system'
2211 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2212 + ' Please configure with --enable-slirp=git')
2216 fdt_opt = get_option('fdt')
2218 if fdt_opt in ['enabled', 'auto', 'system']
2219 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2220 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2221 required: fdt_opt == 'system' or
2222 fdt_opt == 'enabled' and not have_internal)
2223 if fdt.found() and cc.links('''
2225 #include <libfdt_env.h>
2226 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
2229 elif fdt_opt == 'system'
2230 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2232 fdt_opt = 'internal'
2234 fdt_opt = 'disabled'
2238 if fdt_opt == 'internal'
2241 'dtc/libfdt/fdt_ro.c',
2242 'dtc/libfdt/fdt_wip.c',
2243 'dtc/libfdt/fdt_sw.c',
2244 'dtc/libfdt/fdt_rw.c',
2245 'dtc/libfdt/fdt_strerror.c',
2246 'dtc/libfdt/fdt_empty_tree.c',
2247 'dtc/libfdt/fdt_addresses.c',
2248 'dtc/libfdt/fdt_overlay.c',
2249 'dtc/libfdt/fdt_check.c',
2252 fdt_inc = include_directories('dtc/libfdt')
2253 libfdt = static_library('fdt',
2254 build_by_default: false,
2256 include_directories: fdt_inc)
2257 fdt = declare_dependency(link_with: libfdt,
2258 include_directories: fdt_inc)
2261 if not fdt.found() and fdt_required.length() > 0
2262 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2265 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2266 config_host_data.set('CONFIG_FDT', fdt.found())
2267 config_host_data.set('CONFIG_SLIRP', slirp.found())
2269 #####################
2270 # Generated sources #
2271 #####################
2273 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2275 hxtool = find_program('scripts/hxtool')
2276 shaderinclude = find_program('scripts/shaderinclude.pl')
2277 qapi_gen = find_program('scripts/qapi-gen.py')
2278 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2279 meson.current_source_dir() / 'scripts/qapi/commands.py',
2280 meson.current_source_dir() / 'scripts/qapi/common.py',
2281 meson.current_source_dir() / 'scripts/qapi/error.py',
2282 meson.current_source_dir() / 'scripts/qapi/events.py',
2283 meson.current_source_dir() / 'scripts/qapi/expr.py',
2284 meson.current_source_dir() / 'scripts/qapi/gen.py',
2285 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2286 meson.current_source_dir() / 'scripts/qapi/parser.py',
2287 meson.current_source_dir() / 'scripts/qapi/schema.py',
2288 meson.current_source_dir() / 'scripts/qapi/source.py',
2289 meson.current_source_dir() / 'scripts/qapi/types.py',
2290 meson.current_source_dir() / 'scripts/qapi/visit.py',
2291 meson.current_source_dir() / 'scripts/qapi/common.py',
2292 meson.current_source_dir() / 'scripts/qapi-gen.py'
2296 python, files('scripts/tracetool.py'),
2297 '--backend=' + ','.join(get_option('trace_backends'))
2299 tracetool_depends = files(
2300 'scripts/tracetool/backend/log.py',
2301 'scripts/tracetool/backend/__init__.py',
2302 'scripts/tracetool/backend/dtrace.py',
2303 'scripts/tracetool/backend/ftrace.py',
2304 'scripts/tracetool/backend/simple.py',
2305 'scripts/tracetool/backend/syslog.py',
2306 'scripts/tracetool/backend/ust.py',
2307 'scripts/tracetool/format/tcg_h.py',
2308 'scripts/tracetool/format/ust_events_c.py',
2309 'scripts/tracetool/format/ust_events_h.py',
2310 'scripts/tracetool/format/__init__.py',
2311 'scripts/tracetool/format/d.py',
2312 'scripts/tracetool/format/tcg_helper_c.py',
2313 'scripts/tracetool/format/simpletrace_stap.py',
2314 'scripts/tracetool/format/c.py',
2315 'scripts/tracetool/format/h.py',
2316 'scripts/tracetool/format/tcg_helper_h.py',
2317 'scripts/tracetool/format/log_stap.py',
2318 'scripts/tracetool/format/stap.py',
2319 'scripts/tracetool/format/tcg_helper_wrapper_h.py',
2320 'scripts/tracetool/__init__.py',
2321 'scripts/tracetool/transform.py',
2322 'scripts/tracetool/vcpu.py'
2325 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2326 meson.current_source_dir(),
2327 config_host['PKGVERSION'], meson.project_version()]
2328 qemu_version = custom_target('qemu-version.h',
2329 output: 'qemu-version.h',
2330 command: qemu_version_cmd,
2332 build_by_default: true,
2333 build_always_stale: true)
2334 genh += qemu_version
2338 ['qemu-options.hx', 'qemu-options.def'],
2339 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2343 ['hmp-commands.hx', 'hmp-commands.h'],
2344 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2347 foreach d : hx_headers
2348 hxdep += custom_target(d[1],
2352 build_by_default: true, # to be removed when added to a target
2353 command: [hxtool, '-h', '@INPUT0@'])
2361 authz_ss = ss.source_set()
2362 blockdev_ss = ss.source_set()
2363 block_ss = ss.source_set()
2364 bsd_user_ss = ss.source_set()
2365 chardev_ss = ss.source_set()
2366 common_ss = ss.source_set()
2367 crypto_ss = ss.source_set()
2368 hwcore_ss = ss.source_set()
2369 io_ss = ss.source_set()
2370 linux_user_ss = ss.source_set()
2371 qmp_ss = ss.source_set()
2372 qom_ss = ss.source_set()
2373 softmmu_ss = ss.source_set()
2374 specific_fuzz_ss = ss.source_set()
2375 specific_ss = ss.source_set()
2376 stub_ss = ss.source_set()
2377 trace_ss = ss.source_set()
2378 user_ss = ss.source_set()
2379 util_ss = ss.source_set()
2382 qtest_module_ss = ss.source_set()
2383 tcg_module_ss = ss.source_set()
2389 target_softmmu_arch = {}
2390 target_user_arch = {}
2396 # TODO: add each directory to the subdirs from its own meson.build, once
2398 trace_events_subdirs = [
2406 trace_events_subdirs += [ 'linux-user' ]
2409 trace_events_subdirs += [
2418 trace_events_subdirs += [
2432 'hw/block/dataplane',
2482 if have_system or have_user
2483 trace_events_subdirs += [
2500 vhost_user = not_found
2501 if 'CONFIG_VHOST_USER' in config_host
2502 libvhost_user = subproject('libvhost-user')
2503 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2518 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2519 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2522 stub_ss = stub_ss.apply(config_all, strict: false)
2524 util_ss.add_all(trace_ss)
2525 util_ss = util_ss.apply(config_all, strict: false)
2526 libqemuutil = static_library('qemuutil',
2527 sources: util_ss.sources() + stub_ss.sources() + genh,
2528 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2529 qemuutil = declare_dependency(link_with: libqemuutil,
2530 sources: genh + version_res)
2532 if have_system or have_user
2533 decodetree = generator(find_program('scripts/decodetree.py'),
2534 output: 'decode-@BASENAME@.c.inc',
2535 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2536 subdir('libdecnumber')
2553 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
2559 blockdev_ss.add(files(
2566 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2567 # os-win32.c does not
2568 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2569 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2572 common_ss.add(files('cpus-common.c'))
2576 common_ss.add(capstone)
2577 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2579 # Work around a gcc bug/misfeature wherein constant propagation looks
2581 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2582 # to guess that a const variable is always zero. Without lto, this is
2583 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2584 # without lto, not even the alias is required -- we simply use different
2585 # declarations in different compilation units.
2586 pagevary = files('page-vary-common.c')
2587 if get_option('b_lto')
2588 pagevary_flags = ['-fno-lto']
2589 if get_option('cfi')
2590 pagevary_flags += '-fno-sanitize=cfi-icall'
2592 pagevary = static_library('page-vary-common', sources: pagevary,
2593 c_args: pagevary_flags)
2594 pagevary = declare_dependency(link_with: pagevary)
2596 common_ss.add(pagevary)
2597 specific_ss.add(files('page-vary.c'))
2605 subdir('semihosting')
2612 subdir('linux-user')
2615 common_ss.add(libbpf)
2617 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
2619 linux_user_ss.add(files('thunk.c'))
2620 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
2622 # needed for fuzzing binaries
2623 subdir('tests/qtest/libqos')
2624 subdir('tests/qtest/fuzz')
2627 tcg_real_module_ss = ss.source_set()
2628 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
2629 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
2630 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
2631 'tcg': tcg_real_module_ss }}
2633 ########################
2634 # Library dependencies #
2635 ########################
2637 modinfo_collect = find_program('scripts/modinfo-collect.py')
2638 modinfo_generate = find_program('scripts/modinfo-generate.py')
2643 foreach d, list : modules
2644 foreach m, module_ss : list
2645 if enable_modules and targetos != 'windows'
2646 module_ss = module_ss.apply(config_all, strict: false)
2647 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2648 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2654 if module_ss.sources() != []
2655 # FIXME: Should use sl.extract_all_objects(recursive: true) as
2656 # input. Sources can be used multiple times but objects are
2657 # unique when it comes to lookup in compile_commands.json.
2658 # Depnds on a mesion version with
2659 # https://github.com/mesonbuild/meson/pull/8900
2660 modinfo_files += custom_target(d + '-' + m + '.modinfo',
2661 output: d + '-' + m + '.modinfo',
2662 input: module_ss.sources() + genh,
2664 command: [modinfo_collect, module_ss.sources()])
2668 block_ss.add_all(module_ss)
2670 softmmu_ss.add_all(module_ss)
2676 foreach d, list : target_modules
2677 foreach m, module_ss : list
2678 if enable_modules and targetos != 'windows'
2679 foreach target : target_dirs
2680 if target.endswith('-softmmu')
2681 config_target = config_target_mak[target]
2682 config_target += config_host
2683 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2684 c_args = ['-DNEED_CPU_H',
2685 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2686 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2687 target_module_ss = module_ss.apply(config_target, strict: false)
2688 if target_module_ss.sources() != []
2689 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
2690 sl = static_library(module_name,
2691 [genh, target_module_ss.sources()],
2692 dependencies: [modulecommon, target_module_ss.dependencies()],
2693 include_directories: target_inc,
2697 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
2698 modinfo_files += custom_target(module_name + '.modinfo',
2699 output: module_name + '.modinfo',
2700 input: target_module_ss.sources() + genh,
2702 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
2707 specific_ss.add_all(module_ss)
2713 modinfo_src = custom_target('modinfo.c',
2714 output: 'modinfo.c',
2715 input: modinfo_files,
2716 command: [modinfo_generate, '@INPUT@'],
2718 modinfo_lib = static_library('modinfo', modinfo_src)
2719 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
2720 softmmu_ss.add(modinfo_dep)
2723 nm = find_program('nm')
2724 undefsym = find_program('scripts/undefsym.py')
2725 block_syms = custom_target('block.syms', output: 'block.syms',
2726 input: [libqemuutil, block_mods],
2728 command: [undefsym, nm, '@INPUT@'])
2729 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2730 input: [libqemuutil, softmmu_mods],
2732 command: [undefsym, nm, '@INPUT@'])
2734 qom_ss = qom_ss.apply(config_host, strict: false)
2735 libqom = static_library('qom', qom_ss.sources() + genh,
2736 dependencies: [qom_ss.dependencies()],
2739 qom = declare_dependency(link_whole: libqom)
2741 authz_ss = authz_ss.apply(config_host, strict: false)
2742 libauthz = static_library('authz', authz_ss.sources() + genh,
2743 dependencies: [authz_ss.dependencies()],
2745 build_by_default: false)
2747 authz = declare_dependency(link_whole: libauthz,
2750 crypto_ss = crypto_ss.apply(config_host, strict: false)
2751 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2752 dependencies: [crypto_ss.dependencies()],
2754 build_by_default: false)
2756 crypto = declare_dependency(link_whole: libcrypto,
2757 dependencies: [authz, qom])
2759 io_ss = io_ss.apply(config_host, strict: false)
2760 libio = static_library('io', io_ss.sources() + genh,
2761 dependencies: [io_ss.dependencies()],
2762 link_with: libqemuutil,
2764 build_by_default: false)
2766 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2768 libmigration = static_library('migration', sources: migration_files + genh,
2770 build_by_default: false)
2771 migration = declare_dependency(link_with: libmigration,
2772 dependencies: [zlib, qom, io])
2773 softmmu_ss.add(migration)
2775 block_ss = block_ss.apply(config_host, strict: false)
2776 libblock = static_library('block', block_ss.sources() + genh,
2777 dependencies: block_ss.dependencies(),
2778 link_depends: block_syms,
2780 build_by_default: false)
2782 block = declare_dependency(link_whole: [libblock],
2783 link_args: '@block.syms',
2784 dependencies: [crypto, io])
2786 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2787 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2788 dependencies: blockdev_ss.dependencies(),
2790 build_by_default: false)
2792 blockdev = declare_dependency(link_whole: [libblockdev],
2793 dependencies: [block])
2795 qmp_ss = qmp_ss.apply(config_host, strict: false)
2796 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2797 dependencies: qmp_ss.dependencies(),
2799 build_by_default: false)
2801 qmp = declare_dependency(link_whole: [libqmp])
2803 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2805 dependencies: [gnutls],
2806 build_by_default: false)
2808 chardev = declare_dependency(link_whole: libchardev)
2810 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
2811 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
2813 build_by_default: false)
2814 hwcore = declare_dependency(link_whole: libhwcore)
2815 common_ss.add(hwcore)
2821 foreach m : block_mods + softmmu_mods
2822 shared_module(m.name(),
2826 install_dir: qemu_moddir)
2829 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2830 common_ss.add(qom, qemuutil)
2832 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2833 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2835 common_all = common_ss.apply(config_all, strict: false)
2836 common_all = static_library('common',
2837 build_by_default: false,
2838 sources: common_all.sources() + genh,
2839 implicit_include_directories: false,
2840 dependencies: common_all.dependencies(),
2843 feature_to_c = find_program('scripts/feature_to_c.sh')
2846 foreach target : target_dirs
2847 config_target = config_target_mak[target]
2848 target_name = config_target['TARGET_NAME']
2849 arch = config_target['TARGET_BASE_ARCH']
2850 arch_srcs = [config_target_h[target]]
2852 c_args = ['-DNEED_CPU_H',
2853 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2854 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2855 link_args = emulator_link_args
2857 config_target += config_host
2858 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2859 if targetos == 'linux'
2860 target_inc += include_directories('linux-headers', is_system: true)
2862 if target.endswith('-softmmu')
2863 qemu_target_name = 'qemu-system-' + target_name
2864 target_type='system'
2865 t = target_softmmu_arch[arch].apply(config_target, strict: false)
2866 arch_srcs += t.sources()
2867 arch_deps += t.dependencies()
2869 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2870 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2871 arch_srcs += hw.sources()
2872 arch_deps += hw.dependencies()
2874 arch_srcs += config_devices_h[target]
2875 link_args += ['@block.syms', '@qemu.syms']
2877 abi = config_target['TARGET_ABI_DIR']
2879 qemu_target_name = 'qemu-' + target_name
2880 if arch in target_user_arch
2881 t = target_user_arch[arch].apply(config_target, strict: false)
2882 arch_srcs += t.sources()
2883 arch_deps += t.dependencies()
2885 if 'CONFIG_LINUX_USER' in config_target
2886 base_dir = 'linux-user'
2887 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2889 if 'CONFIG_BSD_USER' in config_target
2890 base_dir = 'bsd-user'
2891 target_inc += include_directories('bsd-user/' / targetos)
2892 dir = base_dir / abi
2893 arch_srcs += files(dir / 'target_arch_cpu.c')
2895 target_inc += include_directories(
2899 if 'CONFIG_LINUX_USER' in config_target
2900 dir = base_dir / abi
2901 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2902 if config_target.has_key('TARGET_SYSTBL_ABI')
2904 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2905 extra_args : config_target['TARGET_SYSTBL_ABI'])
2910 if 'TARGET_XML_FILES' in config_target
2911 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2912 output: target + '-gdbstub-xml.c',
2913 input: files(config_target['TARGET_XML_FILES'].split()),
2914 command: [feature_to_c, '@INPUT@'],
2916 arch_srcs += gdbstub_xml
2919 t = target_arch[arch].apply(config_target, strict: false)
2920 arch_srcs += t.sources()
2921 arch_deps += t.dependencies()
2923 target_common = common_ss.apply(config_target, strict: false)
2924 objects = common_all.extract_objects(target_common.sources())
2925 deps = target_common.dependencies()
2927 target_specific = specific_ss.apply(config_target, strict: false)
2928 arch_srcs += target_specific.sources()
2929 arch_deps += target_specific.dependencies()
2931 lib = static_library('qemu-' + target,
2932 sources: arch_srcs + genh,
2933 dependencies: arch_deps,
2935 include_directories: target_inc,
2937 build_by_default: false,
2940 if target.endswith('-softmmu')
2942 'name': 'qemu-system-' + target_name,
2943 'win_subsystem': 'console',
2944 'sources': files('softmmu/main.c'),
2947 if targetos == 'windows' and (sdl.found() or gtk.found())
2949 'name': 'qemu-system-' + target_name + 'w',
2950 'win_subsystem': 'windows',
2951 'sources': files('softmmu/main.c'),
2955 if get_option('fuzzing')
2956 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2958 'name': 'qemu-fuzz-' + target_name,
2959 'win_subsystem': 'console',
2960 'sources': specific_fuzz.sources(),
2961 'dependencies': specific_fuzz.dependencies(),
2966 'name': 'qemu-' + target_name,
2967 'win_subsystem': 'console',
2973 exe_name = exe['name']
2974 if targetos == 'darwin'
2975 exe_name += '-unsigned'
2978 emulator = executable(exe_name, exe['sources'],
2981 dependencies: arch_deps + deps + exe['dependencies'],
2982 objects: lib.extract_all_objects(recursive: true),
2983 link_language: link_language,
2984 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2985 link_args: link_args,
2986 win_subsystem: exe['win_subsystem'])
2988 if targetos == 'darwin'
2989 icon = 'pc-bios/qemu.rsrc'
2990 build_input = [emulator, files(icon)]
2992 get_option('bindir') / exe_name,
2993 meson.current_source_dir() / icon
2995 if 'CONFIG_HVF' in config_target
2996 entitlements = 'accel/hvf/entitlements.plist'
2997 build_input += files(entitlements)
2998 install_input += meson.current_source_dir() / entitlements
3001 emulators += {exe['name'] : custom_target(exe['name'],
3003 output: exe['name'],
3005 files('scripts/entitlement.sh'),
3011 meson.add_install_script('scripts/entitlement.sh', '--install',
3012 get_option('bindir') / exe['name'],
3015 emulators += {exe['name']: emulator}
3020 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3021 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3022 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3023 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3025 custom_target(exe['name'] + stp['ext'],
3026 input: trace_events_all,
3027 output: exe['name'] + stp['ext'],
3028 install: stp['install'],
3029 install_dir: get_option('datadir') / 'systemtap/tapset',
3031 tracetool, '--group=all', '--format=' + stp['fmt'],
3032 '--binary=' + stp['bin'],
3033 '--target-name=' + target_name,
3034 '--target-type=' + target_type,
3035 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3036 '@INPUT@', '@OUTPUT@'
3038 depend_files: tracetool_depends)
3044 # Other build targets
3046 if 'CONFIG_PLUGIN' in config_host
3047 install_headers('include/qemu/qemu-plugin.h')
3050 if 'CONFIG_GUEST_AGENT' in config_host
3052 elif get_option('guest_agent_msi').enabled()
3053 error('Guest agent MSI requested, but the guest agent is not being built')
3056 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3057 # when we don't build tools or system
3058 if xkbcommon.found()
3059 # used for the update-keymaps target, so include rules even if !have_tools
3060 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3061 dependencies: [qemuutil, xkbcommon], install: have_tools)
3065 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3066 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3067 qemu_io = executable('qemu-io', files('qemu-io.c'),
3068 dependencies: [block, qemuutil], install: true)
3069 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3070 dependencies: [blockdev, qemuutil, gnutls], install: true)
3072 subdir('storage-daemon')
3073 subdir('contrib/rdmacm-mux')
3074 subdir('contrib/elf2dmp')
3076 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3077 dependencies: qemuutil,
3080 if 'CONFIG_VHOST_USER' in config_host
3081 subdir('contrib/vhost-user-blk')
3082 subdir('contrib/vhost-user-gpu')
3083 subdir('contrib/vhost-user-input')
3084 subdir('contrib/vhost-user-scsi')
3087 if targetos == 'linux'
3088 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3089 dependencies: [qemuutil, libcap_ng],
3091 install_dir: get_option('libexecdir'))
3093 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3094 dependencies: [authz, crypto, io, qom, qemuutil,
3095 libcap_ng, mpathpersist],
3100 subdir('contrib/ivshmem-client')
3101 subdir('contrib/ivshmem-server')
3114 if host_machine.system() == 'windows'
3116 find_program('scripts/nsis.py'),
3118 get_option('prefix'),
3119 meson.current_source_dir(),
3122 '-DDISPLAYVERSION=' + meson.project_version(),
3125 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3128 nsis_cmd += '-DCONFIG_GTK=y'
3131 nsis = custom_target('nsis',
3132 output: 'qemu-setup-' + meson.project_version() + '.exe',
3133 input: files('qemu.nsi'),
3134 build_always_stale: true,
3135 command: nsis_cmd + ['@INPUT@'])
3136 alias_target('installer', nsis)
3139 #########################
3140 # Configuration summary #
3141 #########################
3145 summary_info += {'Install prefix': get_option('prefix')}
3146 summary_info += {'BIOS directory': qemu_datadir}
3147 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
3148 summary_info += {'binary directory': get_option('bindir')}
3149 summary_info += {'library directory': get_option('libdir')}
3150 summary_info += {'module directory': qemu_moddir}
3151 summary_info += {'libexec directory': get_option('libexecdir')}
3152 summary_info += {'include directory': get_option('includedir')}
3153 summary_info += {'config directory': get_option('sysconfdir')}
3154 if targetos != 'windows'
3155 summary_info += {'local state directory': get_option('localstatedir')}
3156 summary_info += {'Manual directory': get_option('mandir')}
3158 summary_info += {'local state directory': 'queried at runtime'}
3160 summary_info += {'Doc directory': get_option('docdir')}
3161 summary_info += {'Build directory': meson.current_build_dir()}
3162 summary_info += {'Source path': meson.current_source_dir()}
3163 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3164 summary(summary_info, bool_yn: true, section: 'Directories')
3168 summary_info += {'git': config_host['GIT']}
3169 summary_info += {'make': config_host['MAKE']}
3170 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3171 summary_info += {'sphinx-build': sphinx_build}
3172 if config_host.has_key('HAVE_GDB_BIN')
3173 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3175 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3176 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
3177 summary_info += {'wixl': wixl}
3179 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
3180 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
3182 summary(summary_info, bool_yn: true, section: 'Host binaries')
3184 # Configurable features
3186 summary_info += {'Documentation': build_docs}
3187 summary_info += {'system-mode emulation': have_system}
3188 summary_info += {'user-mode emulation': have_user}
3189 summary_info += {'block layer': have_block}
3190 summary_info += {'Install blobs': get_option('install_blobs')}
3191 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3192 if config_host.has_key('CONFIG_MODULES')
3193 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
3195 summary_info += {'fuzzing support': get_option('fuzzing')}
3197 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3199 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3200 if 'simple' in get_option('trace_backends')
3201 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3203 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
3204 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
3205 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
3206 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
3207 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
3208 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
3209 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
3210 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3211 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
3212 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
3213 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
3214 summary(summary_info, bool_yn: true, section: 'Configurable features')
3216 # Compilation information
3218 summary_info += {'host CPU': cpu}
3219 summary_info += {'host endianness': build_machine.endian()}
3220 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3221 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3222 if link_language == 'cpp'
3223 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3225 summary_info += {'C++ compiler': false}
3227 if targetos == 'darwin'
3228 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3230 if targetos == 'windows'
3231 if 'WIN_SDK' in config_host
3232 summary_info += {'Windows SDK': config_host['WIN_SDK']}
3235 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3236 + ['-O' + get_option('optimization')]
3237 + (get_option('debug') ? ['-g'] : []))}
3238 if link_language == 'cpp'
3239 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3240 + ['-O' + get_option('optimization')]
3241 + (get_option('debug') ? ['-g'] : []))}
3243 link_args = get_option(link_language + '_link_args')
3244 if link_args.length() > 0
3245 summary_info += {'LDFLAGS': ' '.join(link_args)}
3247 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
3248 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
3249 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
3250 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3251 summary_info += {'PIE': get_option('b_pie')}
3252 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3253 summary_info += {'malloc trim support': has_malloc_trim}
3254 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
3255 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
3256 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
3257 summary_info += {'memory allocator': get_option('malloc')}
3258 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
3259 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
3260 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
3261 summary_info += {'gcov': get_option('b_coverage')}
3262 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3263 summary_info += {'CFI support': get_option('cfi')}
3264 if get_option('cfi')
3265 summary_info += {'CFI debug support': get_option('cfi_debug')}
3267 summary_info += {'strip binaries': get_option('strip')}
3268 summary_info += {'sparse': sparse}
3269 summary_info += {'mingw32 support': targetos == 'windows'}
3271 # snarf the cross-compilation information for tests
3272 foreach target: target_dirs
3273 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3274 if fs.exists(tcg_mak)
3275 config_cross_tcg = keyval.load(tcg_mak)
3276 target = config_cross_tcg['TARGET_NAME']
3278 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3279 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3280 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3281 elif 'CROSS_CC_GUEST' in config_cross_tcg
3282 summary_info += {target + ' tests'
3283 : config_cross_tcg['CROSS_CC_GUEST'] }
3288 summary(summary_info, bool_yn: true, section: 'Compilation')
3290 # Targets and accelerators
3293 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3294 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3295 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3296 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3297 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3298 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
3299 if config_host.has_key('CONFIG_XEN_BACKEND')
3300 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
3303 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3304 if config_all.has_key('CONFIG_TCG')
3305 if get_option('tcg_interpreter')
3306 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, experimental and slow)'}
3308 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3310 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3311 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3313 summary_info += {'target list': ' '.join(target_dirs)}
3315 summary_info += {'default devices': get_option('default_devices')}
3316 summary_info += {'out of process emulation': multiprocess_allowed}
3318 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3322 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3323 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
3325 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3326 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3327 summary_info += {'Use block whitelist in tools': config_host.has_key('CONFIG_BDRV_WHITELIST_TOOLS')}
3328 summary_info += {'VirtFS support': have_virtfs}
3329 summary_info += {'build virtiofs daemon': have_virtiofsd}
3330 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
3331 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
3332 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
3333 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
3334 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
3335 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
3336 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
3337 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
3338 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
3339 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
3340 summary_info += {'FUSE exports': fuse}
3342 summary(summary_info, bool_yn: true, section: 'Block layer support')
3346 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
3347 summary_info += {'GNUTLS support': gnutls}
3349 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3351 summary_info += {'libgcrypt': gcrypt}
3352 summary_info += {'nettle': nettle}
3354 summary_info += {' XTS': xts != 'private'}
3356 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
3357 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
3358 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
3359 summary(summary_info, bool_yn: true, section: 'Crypto')
3363 if targetos == 'darwin'
3364 summary_info += {'Cocoa support': cocoa}
3366 summary_info += {'SDL support': sdl}
3367 summary_info += {'SDL image support': sdl_image}
3368 summary_info += {'GTK support': gtk}
3369 summary_info += {'pixman': pixman}
3370 summary_info += {'VTE support': vte}
3371 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3372 summary_info += {'libtasn1': tasn1}
3373 summary_info += {'PAM': pam}
3374 summary_info += {'iconv support': iconv}
3375 summary_info += {'curses support': curses}
3376 summary_info += {'virgl support': virgl}
3377 summary_info += {'curl support': curl}
3378 summary_info += {'Multipath support': mpathpersist}
3379 summary_info += {'VNC support': vnc}
3381 summary_info += {'VNC SASL support': sasl}
3382 summary_info += {'VNC JPEG support': jpeg}
3383 summary_info += {'VNC PNG support': png}
3385 if targetos not in ['darwin', 'haiku', 'windows']
3386 summary_info += {'OSS support': oss}
3387 elif targetos == 'darwin'
3388 summary_info += {'CoreAudio support': coreaudio}
3389 elif targetos == 'windows'
3390 summary_info += {'DirectSound support': dsound}
3392 if targetos == 'linux'
3393 summary_info += {'ALSA support': alsa}
3394 summary_info += {'PulseAudio support': pulse}
3396 summary_info += {'JACK support': jack}
3397 summary_info += {'brlapi support': brlapi}
3398 summary_info += {'vde support': vde}
3399 summary_info += {'netmap support': have_netmap}
3400 summary_info += {'Linux AIO support': libaio}
3401 summary_info += {'Linux io_uring support': linux_io_uring}
3402 summary_info += {'ATTR/XATTR support': libattr}
3403 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
3404 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
3405 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3406 summary_info += {'libcap-ng support': libcap_ng}
3407 summary_info += {'bpf support': libbpf}
3408 summary_info += {'spice protocol support': spice_protocol}
3409 if spice_protocol.found()
3410 summary_info += {' spice server support': spice}
3412 summary_info += {'rbd support': rbd}
3413 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
3414 summary_info += {'smartcard support': cacard}
3415 summary_info += {'U2F support': u2f}
3416 summary_info += {'libusb': libusb}
3417 summary_info += {'usb net redir': usbredir}
3418 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
3419 summary_info += {'GBM': gbm}
3420 summary_info += {'libiscsi support': libiscsi}
3421 summary_info += {'libnfs support': libnfs}
3422 if targetos == 'windows'
3423 if config_host.has_key('CONFIG_GUEST_AGENT')
3424 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
3425 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
3428 summary_info += {'seccomp support': seccomp}
3429 summary_info += {'GlusterFS support': glusterfs}
3430 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
3431 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
3432 summary_info += {'lzo support': lzo}
3433 summary_info += {'snappy support': snappy}
3434 summary_info += {'bzip2 support': libbzip2}
3435 summary_info += {'lzfse support': liblzfse}
3436 summary_info += {'zstd support': zstd}
3437 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
3438 summary_info += {'libxml2': libxml2}
3439 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3440 summary_info += {'libpmem support': libpmem}
3441 summary_info += {'libdaxctl support': libdaxctl}
3442 summary_info += {'libudev': libudev}
3443 # Dummy dependency, keep .found()
3444 summary_info += {'FUSE lseek': fuse_lseek.found()}
3445 summary(summary_info, bool_yn: true, section: 'Dependencies')
3447 if not supported_cpus.contains(cpu)
3449 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3451 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3452 message('The QEMU project intends to remove support for this host CPU in')
3453 message('a future release if nobody volunteers to maintain it and to')
3454 message('provide a build host for our continuous integration setup.')
3455 message('configure has succeeded and you can continue to build, but')
3456 message('if you care about QEMU on this platform you should contact')
3457 message('us upstream at qemu-devel@nongnu.org.')
3460 if not supported_oses.contains(targetos)
3462 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3464 message('Host OS ' + targetos + 'support is not currently maintained.')
3465 message('The QEMU project intends to remove support for this host OS in')
3466 message('a future release if nobody volunteers to maintain it and to')
3467 message('provide a build host for our continuous integration setup.')
3468 message('configure has succeeded and you can continue to build, but')
3469 message('if you care about QEMU on this platform you should contact')
3470 message('us upstream at qemu-devel@nongnu.org.')