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', 'riscv', 'x86', 'x86_64',
59 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
61 cpu = host_machine.cpu_family()
63 # Unify riscv* to a single family.
64 if cpu in ['riscv32', 'riscv64']
68 targetos = host_machine.system()
70 if cpu not in supported_cpus
78 if cpu in ['x86', 'x86_64']
79 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
81 kvm_targets = ['aarch64-softmmu']
83 kvm_targets = ['s390x-softmmu']
84 elif cpu in ['ppc', 'ppc64']
85 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
86 elif cpu in ['mips', 'mips64']
87 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
93 if not get_option('kvm').disabled() and targetos == 'linux'
94 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
96 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
98 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
100 if cpu in ['aarch64']
101 accelerator_targets += {
102 'CONFIG_HVF': ['aarch64-softmmu']
106 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
107 # i386 emulator provides xenpv machine type for multiple architectures
108 accelerator_targets += {
109 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
112 if cpu in ['x86', 'x86_64']
113 accelerator_targets += {
114 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
115 'CONFIG_HVF': ['x86_64-softmmu'],
116 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
117 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
122 # Darwin does not support references to thread-local variables in modules
123 if targetos != 'darwin'
124 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
127 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
128 unpack_edk2_blobs = false
129 foreach target : edk2_targets
130 if target in target_dirs
131 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
132 unpack_edk2_blobs = bzip2.found()
139 if 'dtrace' in get_option('trace_backends')
140 dtrace = find_program('dtrace', required: true)
141 stap = find_program('stap', required: false)
143 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
144 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
145 # instead. QEMU --enable-modules depends on this because the SystemTap
146 # semaphores are linked into the main binary and not the module's shared
148 add_global_arguments('-DSTAP_SDT_V2',
149 native: false, language: ['c', 'cpp', 'objc'])
157 # Specify linker-script with add_project_link_arguments so that it is not placed
158 # within a linker --start-group/--end-group pair
159 if get_option('fuzzing')
160 add_project_link_arguments(['-Wl,-T,',
161 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
162 native: false, language: ['c', 'cpp', 'objc'])
164 # Specify a filter to only instrument code that is directly related to
166 configure_file(output: 'instrumentation-filter',
167 input: 'scripts/oss-fuzz/instrumentation-filter-template',
169 add_global_arguments(
170 cc.get_supported_arguments('-fsanitize-coverage-allowlist=instrumentation-filter'),
171 native: false, language: ['c', 'cpp', 'objc'])
173 if get_option('fuzzing_engine') == ''
174 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
175 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
176 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
177 # unable to bind the fuzzer-related callbacks added by instrumentation.
178 add_global_arguments('-fsanitize=fuzzer-no-link',
179 native: false, language: ['c', 'cpp', 'objc'])
180 add_global_link_arguments('-fsanitize=fuzzer-no-link',
181 native: false, language: ['c', 'cpp', 'objc'])
182 # For the actual fuzzer binaries, we need to link against the libfuzzer
183 # library. They need to be configurable, to support OSS-Fuzz
184 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
186 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
187 # the needed CFLAGS have already been provided
188 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
192 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
193 native: false, language: ['c', 'objc'])
194 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
195 native: false, language: 'cpp')
196 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
197 native: false, language: ['c', 'cpp', 'objc'])
199 if targetos == 'linux'
200 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
201 '-isystem', 'linux-headers',
202 language: ['c', 'cpp'])
205 add_project_arguments('-iquote', '.',
206 '-iquote', meson.current_source_dir(),
207 '-iquote', meson.current_source_dir() / 'include',
208 '-iquote', meson.current_source_dir() / 'disas/libvixl',
209 language: ['c', 'cpp', 'objc'])
211 link_language = meson.get_external_property('link_language', 'cpp')
212 if link_language == 'cpp'
213 add_languages('cpp', required: true, native: false)
214 cxx = meson.get_compiler('cpp')
219 if host_machine.system() == 'darwin'
220 add_languages('objc', required: false, native: false)
223 sparse = find_program('cgcc', required: get_option('sparse'))
226 command: [find_program('scripts/check_sparse.py'),
227 'compile_commands.json', sparse.full_path(), '-Wbitwise',
228 '-Wno-transparent-union', '-Wno-old-initializer',
229 '-Wno-non-pointer-null'])
232 ###########################################
233 # Target-specific checks and dependencies #
234 ###########################################
236 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
239 #include <sys/types.h>
240 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
241 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
243 args: ['-Werror', '-fsanitize=fuzzer'])
244 error('Your compiler does not support -fsanitize=fuzzer')
247 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
248 error('ftrace is supported only on Linux')
250 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
253 openlog("qemu", LOG_PID, LOG_DAEMON);
254 syslog(LOG_INFO, "configure");
257 error('syslog is not supported on this system')
260 if targetos != 'linux' and get_option('mpath').enabled()
261 error('Multipath is supported only on Linux')
264 if targetos != 'linux' and get_option('multiprocess').enabled()
265 error('Multiprocess QEMU is supported only on Linux')
267 multiprocess_allowed = targetos == 'linux' and not get_option('multiprocess').disabled()
269 libm = cc.find_library('m', required: false)
270 threads = dependency('threads')
271 util = cc.find_library('util', required: false)
277 emulator_link_args = []
281 if targetos == 'windows'
282 socket = cc.find_library('ws2_32')
283 winmm = cc.find_library('winmm')
285 win = import('windows')
286 version_res = win.compile_resources('version.rc',
287 depend_files: files('pc-bios/qemu-nsis.ico'),
288 include_directories: include_directories('.'))
290 elif targetos == 'darwin'
291 coref = dependency('appleframeworks', modules: 'CoreFoundation')
292 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
293 host_dsosuf = '.dylib'
294 elif targetos == 'sunos'
295 socket = [cc.find_library('socket'),
296 cc.find_library('nsl'),
297 cc.find_library('resolv')]
298 elif targetos == 'haiku'
299 socket = [cc.find_library('posix_error_mapper'),
300 cc.find_library('network'),
301 cc.find_library('bsd')]
302 elif targetos == 'openbsd'
303 if not get_option('tcg').disabled() and target_dirs.length() > 0
304 # Disable OpenBSD W^X if available
305 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
310 if not get_option('kvm').disabled() and targetos == 'linux'
311 accelerators += 'CONFIG_KVM'
313 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
314 accelerators += 'CONFIG_XEN'
315 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
317 have_xen_pci_passthrough = false
319 if not get_option('whpx').disabled() and targetos == 'windows'
320 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
321 error('WHPX requires 64-bit host')
322 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
323 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
324 accelerators += 'CONFIG_WHPX'
327 if not get_option('hvf').disabled()
328 hvf = dependency('appleframeworks', modules: 'Hypervisor',
329 required: get_option('hvf'))
331 accelerators += 'CONFIG_HVF'
334 if not get_option('hax').disabled()
335 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
336 accelerators += 'CONFIG_HAX'
339 if targetos == 'netbsd'
340 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
342 accelerators += 'CONFIG_NVMM'
347 if not get_option('tcg').disabled()
348 if host_arch == 'unknown'
349 if get_option('tcg_interpreter')
350 warning('Unsupported CPU @0@, will use TCG with TCI (slow)'.format(cpu))
352 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
354 elif get_option('tcg_interpreter')
355 warning('Use of the TCG interpreter is not recommended on this host')
356 warning('architecture. There is a native TCG execution backend available')
357 warning('which provides substantially better performance and reliability.')
358 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
359 warning('configuration option on this architecture to use the native')
362 if get_option('tcg_interpreter')
364 elif host_arch == 'sparc64'
366 elif host_arch == 'x86_64'
368 elif host_arch == 'ppc64'
371 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
372 language: ['c', 'cpp', 'objc'])
374 accelerators += 'CONFIG_TCG'
375 config_host += { 'CONFIG_TCG': 'y' }
378 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
379 error('KVM not available on this platform')
381 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
382 error('HVF not available on this platform')
384 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
385 error('NVMM not available on this platform')
387 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
388 error('WHPX not available on this platform')
390 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
391 if 'CONFIG_XEN' in accelerators
392 error('Xen PCI passthrough not available on this platform')
394 error('Xen PCI passthrough requested but Xen not enabled')
402 # The path to glib.h is added to all compilation commands. This was
403 # grandfathered in from the QEMU Makefiles.
404 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
405 native: false, language: ['c', 'cpp', 'objc'])
406 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
407 link_args: config_host['GLIB_LIBS'].split())
408 # override glib dep with the configure results (for subprojects)
409 meson.override_dependency('glib-2.0', glib)
412 if 'CONFIG_GIO' in config_host
413 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
414 link_args: config_host['GIO_LIBS'].split())
417 if 'ust' in get_option('trace_backends')
418 lttng = dependency('lttng-ust', required: true, method: 'pkg-config',
419 kwargs: static_kwargs)
422 if have_system or have_tools
423 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
424 method: 'pkg-config', kwargs: static_kwargs)
426 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
429 if not get_option('linux_aio').auto() or have_block
430 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
431 required: get_option('linux_aio'),
432 kwargs: static_kwargs)
434 linux_io_uring = not_found
435 if not get_option('linux_io_uring').auto() or have_block
436 linux_io_uring = dependency('liburing', required: get_option('linux_io_uring'),
437 method: 'pkg-config', kwargs: static_kwargs)
440 if not get_option('libxml2').auto() or have_block
441 libxml2 = dependency('libxml-2.0', required: get_option('libxml2'),
442 method: 'pkg-config', kwargs: static_kwargs)
445 if not get_option('libnfs').auto() or have_block
446 libnfs = dependency('libnfs', version: '>=1.9.3',
447 required: get_option('libnfs'),
448 method: 'pkg-config', kwargs: static_kwargs)
453 #include <sys/types.h>
454 #ifdef CONFIG_LIBATTR
455 #include <attr/xattr.h>
457 #include <sys/xattr.h>
459 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
462 have_old_libattr = false
463 if not get_option('attr').disabled()
464 if cc.links(libattr_test)
465 libattr = declare_dependency()
467 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
468 required: get_option('attr'),
469 kwargs: static_kwargs)
470 if libattr.found() and not \
471 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
473 if get_option('attr').enabled()
474 error('could not link libattr')
476 warning('could not link libattr, disabling')
479 have_old_libattr = libattr.found()
484 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
485 if cocoa.found() and get_option('sdl').enabled()
486 error('Cocoa and SDL cannot be enabled at the same time')
488 if cocoa.found() and get_option('gtk').enabled()
489 error('Cocoa and GTK+ cannot be enabled at the same time')
493 if not get_option('seccomp').auto() or have_system or have_tools
494 seccomp = dependency('libseccomp', version: '>=2.3.0',
495 required: get_option('seccomp'),
496 method: 'pkg-config', kwargs: static_kwargs)
499 libcap_ng = not_found
500 if not get_option('cap_ng').auto() or have_system or have_tools
501 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
502 required: get_option('cap_ng'),
503 kwargs: static_kwargs)
505 if libcap_ng.found() and not cc.links('''
509 capng_capability_to_name(CAPNG_EFFECTIVE);
511 }''', dependencies: libcap_ng)
512 libcap_ng = not_found
513 if get_option('cap_ng').enabled()
514 error('could not link libcap-ng')
516 warning('could not link libcap-ng, disabling')
520 if get_option('xkbcommon').auto() and not have_system and not have_tools
521 xkbcommon = not_found
523 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
524 method: 'pkg-config', kwargs: static_kwargs)
528 if not get_option('vde').auto() or have_system or have_tools
529 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
530 required: get_option('vde'),
531 kwargs: static_kwargs)
533 if vde.found() and not cc.links('''
534 #include <libvdeplug.h>
537 struct vde_open_args a = {0, 0, 0};
541 }''', dependencies: vde)
543 if get_option('cap_ng').enabled()
544 error('could not link libvdeplug')
546 warning('could not link libvdeplug, disabling')
551 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
552 pulse = dependency('libpulse', required: get_option('pa'),
553 method: 'pkg-config', kwargs: static_kwargs)
556 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
557 alsa = dependency('alsa', required: get_option('alsa'),
558 method: 'pkg-config', kwargs: static_kwargs)
561 if not get_option('jack').auto() or have_system
562 jack = dependency('jack', required: get_option('jack'),
563 method: 'pkg-config', kwargs: static_kwargs)
566 spice_protocol = not_found
567 if not get_option('spice_protocol').auto() or have_system
568 spice_protocol = dependency('spice-protocol', version: '>=0.12.3',
569 required: get_option('spice_protocol'),
570 method: 'pkg-config', kwargs: static_kwargs)
573 if not get_option('spice').auto() or have_system
574 spice = dependency('spice-server', version: '>=0.12.5',
575 required: get_option('spice'),
576 method: 'pkg-config', kwargs: static_kwargs)
578 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
580 rt = cc.find_library('rt', required: false)
583 if not get_option('libiscsi').auto() or have_block
584 libiscsi = dependency('libiscsi', version: '>=1.9.0',
585 required: get_option('libiscsi'),
586 method: 'pkg-config', kwargs: static_kwargs)
589 if not get_option('zstd').auto() or have_block
590 zstd = dependency('libzstd', version: '>=1.4.0',
591 required: get_option('zstd'),
592 method: 'pkg-config', kwargs: static_kwargs)
595 if not get_option('virglrenderer').auto() or have_system
596 virgl = dependency('virglrenderer',
597 method: 'pkg-config',
598 required: get_option('virglrenderer'),
599 kwargs: static_kwargs)
602 if not get_option('curl').auto() or have_block
603 curl = dependency('libcurl', version: '>=7.29.0',
604 method: 'pkg-config',
605 required: get_option('curl'),
606 kwargs: static_kwargs)
609 if targetos == 'linux' and (have_system or have_tools)
610 libudev = dependency('libudev',
611 method: 'pkg-config',
612 required: get_option('libudev'),
613 kwargs: static_kwargs)
616 mpathlibs = [libudev]
617 mpathpersist = not_found
618 mpathpersist_new_api = false
619 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
620 mpath_test_source_new = '''
622 #include <mpath_persist.h>
623 unsigned mpath_mx_alloc_len = 1024;
625 static struct config *multipath_conf;
626 extern struct udev *udev;
627 extern struct config *get_multipath_config(void);
628 extern void put_multipath_config(struct config *conf);
630 struct config *get_multipath_config(void) { return multipath_conf; }
631 void put_multipath_config(struct config *conf) { }
634 multipath_conf = mpath_lib_init();
637 mpath_test_source_old = '''
639 #include <mpath_persist.h>
640 unsigned mpath_mx_alloc_len = 1024;
643 struct udev *udev = udev_new();
644 mpath_lib_init(udev);
647 libmpathpersist = cc.find_library('mpathpersist',
648 required: get_option('mpath'),
649 kwargs: static_kwargs)
650 if libmpathpersist.found()
651 mpathlibs += libmpathpersist
653 mpathlibs += cc.find_library('devmapper',
654 required: get_option('mpath'),
655 kwargs: static_kwargs)
657 mpathlibs += cc.find_library('multipath',
658 required: get_option('mpath'),
659 kwargs: static_kwargs)
660 foreach lib: mpathlibs
666 if mpathlibs.length() == 0
667 msg = 'Dependencies missing for libmpathpersist'
668 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
669 mpathpersist = declare_dependency(dependencies: mpathlibs)
670 mpathpersist_new_api = true
671 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
672 mpathpersist = declare_dependency(dependencies: mpathlibs)
674 msg = 'Cannot detect libmpathpersist API'
676 if not mpathpersist.found()
677 if get_option('mpath').enabled()
680 warning(msg + ', disabling')
688 if have_system and not get_option('curses').disabled()
690 #if defined(__APPLE__) || defined(__OpenBSD__)
691 #define _XOPEN_SOURCE_EXTENDED 1
698 setlocale(LC_ALL, "");
700 addwstr(L"wide chars\n");
702 add_wch(WACS_DEGREE);
706 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
707 foreach curses_dep : curses_dep_list
708 if not curses.found()
709 curses = dependency(curses_dep,
711 method: 'pkg-config',
712 kwargs: static_kwargs)
715 msg = get_option('curses').enabled() ? 'curses library not found' : ''
716 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
718 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
719 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
721 msg = 'curses package not usable'
725 if not curses.found()
726 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
727 if targetos != 'windows' and not has_curses_h
728 message('Trying with /usr/include/ncursesw')
729 curses_compile_args += ['-I/usr/include/ncursesw']
730 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
733 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
734 foreach curses_libname : curses_libname_list
735 libcurses = cc.find_library(curses_libname,
737 kwargs: static_kwargs)
739 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
740 curses = declare_dependency(compile_args: curses_compile_args,
741 dependencies: [libcurses])
744 msg = 'curses library not usable'
750 if not get_option('iconv').disabled()
751 foreach link_args : [ ['-liconv'], [] ]
752 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
753 # We need to use libiconv if available because mixing libiconv's headers with
754 # the system libc does not work.
755 # However, without adding glib to the dependencies -L/usr/local/lib will not be
756 # included in the command line and libiconv will not be found.
760 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
761 return conv != (iconv_t) -1;
762 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
763 iconv = declare_dependency(link_args: link_args, dependencies: glib)
768 if curses.found() and not iconv.found()
769 if get_option('iconv').enabled()
770 error('iconv not available')
772 msg = 'iconv required for curses UI but not available'
775 if not curses.found() and msg != ''
776 if get_option('curses').enabled()
779 warning(msg + ', disabling')
785 if not get_option('brlapi').auto() or have_system
786 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
787 required: get_option('brlapi'),
788 kwargs: static_kwargs)
789 if brlapi.found() and not cc.links('''
792 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
794 if get_option('brlapi').enabled()
795 error('could not link brlapi')
797 warning('could not link brlapi, disabling')
803 if not get_option('sdl').auto() or (have_system and not cocoa.found())
804 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
805 sdl_image = not_found
808 # work around 2.0.8 bug
809 sdl = declare_dependency(compile_args: '-Wno-undef',
811 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
812 method: 'pkg-config', kwargs: static_kwargs)
814 if get_option('sdl_image').enabled()
815 error('sdl-image required, but SDL was @0@'.format(
816 get_option('sdl').disabled() ? 'disabled' : 'not found'))
818 sdl_image = not_found
822 if not get_option('rbd').auto() or have_block
823 librados = cc.find_library('rados', required: get_option('rbd'),
824 kwargs: static_kwargs)
825 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
826 required: get_option('rbd'),
827 kwargs: static_kwargs)
828 if librados.found() and librbd.found()
831 #include <rbd/librbd.h>
834 rados_create(&cluster, NULL);
835 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
839 }''', dependencies: [librbd, librados])
840 rbd = declare_dependency(dependencies: [librbd, librados])
841 elif get_option('rbd').enabled()
842 error('librbd >= 1.12.0 required')
844 warning('librbd >= 1.12.0 not found, disabling')
849 glusterfs = not_found
850 glusterfs_ftruncate_has_stat = false
851 glusterfs_iocb_has_stat = false
852 if not get_option('glusterfs').auto() or have_block
853 glusterfs = dependency('glusterfs-api', version: '>=3',
854 required: get_option('glusterfs'),
855 method: 'pkg-config', kwargs: static_kwargs)
857 glusterfs_ftruncate_has_stat = cc.links('''
858 #include <glusterfs/api/glfs.h>
863 /* new glfs_ftruncate() passes two additional args */
864 return glfs_ftruncate(NULL, 0, NULL, NULL);
866 ''', dependencies: glusterfs)
867 glusterfs_iocb_has_stat = cc.links('''
868 #include <glusterfs/api/glfs.h>
870 /* new glfs_io_cbk() passes two additional glfs_stat structs */
872 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
878 glfs_io_cbk iocb = &glusterfs_iocb;
879 iocb(NULL, 0 , NULL, NULL, NULL);
882 ''', dependencies: glusterfs)
887 if not get_option('libssh').auto() or have_block
888 libssh = dependency('libssh', version: '>=0.8.7',
889 method: 'pkg-config',
890 required: get_option('libssh'),
891 kwargs: static_kwargs)
895 if not get_option('bzip2').auto() or have_block
896 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
897 required: get_option('bzip2'),
898 kwargs: static_kwargs)
899 if libbzip2.found() and not cc.links('''
901 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
903 if get_option('bzip2').enabled()
904 error('could not link libbzip2')
906 warning('could not link libbzip2, disabling')
912 if not get_option('lzfse').auto() or have_block
913 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
914 required: get_option('lzfse'),
915 kwargs: static_kwargs)
917 if liblzfse.found() and not cc.links('''
919 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
921 if get_option('lzfse').enabled()
922 error('could not link liblzfse')
924 warning('could not link liblzfse, disabling')
929 if have_system and not get_option('oss').disabled()
930 if not cc.has_header('sys/soundcard.h')
932 elif targetos == 'netbsd'
933 oss = cc.find_library('ossaudio', required: get_option('oss'),
934 kwargs: static_kwargs)
936 oss = declare_dependency()
940 if get_option('oss').enabled()
941 error('OSS not found')
946 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
947 if cc.has_header('dsound.h')
948 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
951 if not dsound.found()
952 if get_option('dsound').enabled()
953 error('DirectSound not found')
958 coreaudio = not_found
959 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
960 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
961 required: get_option('coreaudio'))
965 if 'CONFIG_OPENGL' in config_host
966 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
967 link_args: config_host['OPENGL_LIBS'].split())
970 if (have_system or have_tools) and (virgl.found() or opengl.found())
971 gbm = dependency('gbm', method: 'pkg-config', required: false,
972 kwargs: static_kwargs)
976 gnutls_crypto = not_found
977 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
978 # For general TLS support our min gnutls matches
979 # that implied by our platform support matrix
981 # For the crypto backends, we look for a newer
984 # Version 3.6.8 is needed to get XTS
985 # Version 3.6.13 is needed to get PBKDF
986 # Version 3.6.14 is needed to get HW accelerated XTS
988 # If newer enough gnutls isn't available, we can
989 # still use a different crypto backend to satisfy
990 # the platform support requirements
991 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
992 method: 'pkg-config',
994 kwargs: static_kwargs)
995 if gnutls_crypto.found()
996 gnutls = gnutls_crypto
998 # Our min version if all we need is TLS
999 gnutls = dependency('gnutls', version: '>=3.5.18',
1000 method: 'pkg-config',
1001 required: get_option('gnutls'),
1002 kwargs: static_kwargs)
1006 # We prefer use of gnutls for crypto, unless the options
1007 # explicitly asked for nettle or gcrypt.
1009 # If gnutls isn't available for crypto, then we'll prefer
1010 # gcrypt over nettle for performance reasons.
1015 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1016 error('Only one of gcrypt & nettle can be enabled')
1019 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1020 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1021 gnutls_crypto = not_found
1024 if not gnutls_crypto.found()
1025 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1026 gcrypt = dependency('libgcrypt', version: '>=1.8',
1027 method: 'config-tool',
1028 required: get_option('gcrypt'),
1029 kwargs: static_kwargs)
1030 # Debian has removed -lgpg-error from libgcrypt-config
1031 # as it "spreads unnecessary dependencies" which in
1032 # turn breaks static builds...
1033 if gcrypt.found() and enable_static
1034 gcrypt = declare_dependency(dependencies: [
1036 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
1039 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1040 nettle = dependency('nettle', version: '>=3.4',
1041 method: 'pkg-config',
1042 required: get_option('nettle'),
1043 kwargs: static_kwargs)
1044 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1053 if not get_option('gtk').auto() or (have_system and not cocoa.found())
1054 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1055 method: 'pkg-config',
1056 required: get_option('gtk'),
1057 kwargs: static_kwargs)
1059 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1060 method: 'pkg-config',
1062 kwargs: static_kwargs)
1063 gtk = declare_dependency(dependencies: [gtk, gtkx11])
1065 if not get_option('vte').auto() or have_system
1066 vte = dependency('vte-2.91',
1067 method: 'pkg-config',
1068 required: get_option('vte'),
1069 kwargs: static_kwargs)
1076 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
1077 kwargs: static_kwargs)
1083 if have_system and not get_option('vnc').disabled()
1084 vnc = declare_dependency() # dummy dependency
1085 png = dependency('libpng', required: get_option('vnc_png'),
1086 method: 'pkg-config', kwargs: static_kwargs)
1087 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1088 method: 'pkg-config', kwargs: static_kwargs)
1089 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1090 required: get_option('vnc_sasl'),
1091 kwargs: static_kwargs)
1093 sasl = declare_dependency(dependencies: sasl,
1094 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1099 if not get_option('auth_pam').auto() or have_system
1100 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1101 required: get_option('auth_pam'),
1102 kwargs: static_kwargs)
1104 if pam.found() and not cc.links('''
1106 #include <security/pam_appl.h>
1108 const char *service_name = "qemu";
1109 const char *user = "frank";
1110 const struct pam_conv pam_conv = { 0 };
1111 pam_handle_t *pamh = NULL;
1112 pam_start(service_name, user, &pam_conv, &pamh);
1114 }''', dependencies: pam)
1116 if get_option('auth_pam').enabled()
1117 error('could not link libpam')
1119 warning('could not link libpam, disabling')
1124 if not get_option('snappy').auto() or have_system
1125 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1126 required: get_option('snappy'),
1127 kwargs: static_kwargs)
1129 if snappy.found() and not linker.links('''
1130 #include <snappy-c.h>
1131 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1133 if get_option('snappy').enabled()
1134 error('could not link libsnappy')
1136 warning('could not link libsnappy, disabling')
1141 if not get_option('lzo').auto() or have_system
1142 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1143 required: get_option('lzo'),
1144 kwargs: static_kwargs)
1146 if lzo.found() and not cc.links('''
1147 #include <lzo/lzo1x.h>
1148 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1150 if get_option('lzo').enabled()
1151 error('could not link liblzo2')
1153 warning('could not link liblzo2, disabling')
1158 if 'CONFIG_RDMA' in config_host
1159 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
1162 if 'CONFIG_NUMA' in config_host
1163 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
1166 if 'CONFIG_XEN_BACKEND' in config_host
1167 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
1168 link_args: config_host['XEN_LIBS'].split())
1171 if not get_option('smartcard').auto() or have_system
1172 cacard = dependency('libcacard', required: get_option('smartcard'),
1173 version: '>=2.5.1', method: 'pkg-config',
1174 kwargs: static_kwargs)
1178 u2f = dependency('u2f-emu', required: get_option('u2f'),
1179 method: 'pkg-config',
1180 kwargs: static_kwargs)
1182 usbredir = not_found
1183 if not get_option('usb_redir').auto() or have_system
1184 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1185 version: '>=0.6', method: 'pkg-config',
1186 kwargs: static_kwargs)
1189 if not get_option('libusb').auto() or have_system
1190 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1191 version: '>=1.0.13', method: 'pkg-config',
1192 kwargs: static_kwargs)
1196 if not get_option('libpmem').auto() or have_system
1197 libpmem = dependency('libpmem', required: get_option('libpmem'),
1198 method: 'pkg-config', kwargs: static_kwargs)
1200 libdaxctl = not_found
1201 if not get_option('libdaxctl').auto() or have_system
1202 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1203 version: '>=57', method: 'pkg-config',
1204 kwargs: static_kwargs)
1208 tasn1 = dependency('libtasn1',
1209 method: 'pkg-config',
1210 kwargs: static_kwargs)
1212 keyutils = dependency('libkeyutils', required: false,
1213 method: 'pkg-config', kwargs: static_kwargs)
1215 has_gettid = cc.has_function('gettid')
1218 selinux = dependency('libselinux',
1219 required: get_option('selinux'),
1220 method: 'pkg-config', kwargs: static_kwargs)
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('HOST_' + host_arch.to_upper(), 1)
1439 config_host_data.set('CONFIG_ATTR', libattr.found())
1440 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1441 config_host_data.set('CONFIG_COCOA', cocoa.found())
1442 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1443 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1444 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1445 config_host_data.set('CONFIG_LZO', lzo.found())
1446 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1447 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1448 config_host_data.set('CONFIG_CURL', curl.found())
1449 config_host_data.set('CONFIG_CURSES', curses.found())
1450 config_host_data.set('CONFIG_GBM', gbm.found())
1451 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1452 if glusterfs.found()
1453 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1454 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1455 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1456 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1457 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1458 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1460 config_host_data.set('CONFIG_GTK', gtk.found())
1461 config_host_data.set('CONFIG_VTE', vte.found())
1462 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1463 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1464 config_host_data.set('CONFIG_EBPF', libbpf.found())
1465 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1466 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1467 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1468 config_host_data.set('CONFIG_LIBSSH', libssh.found())
1469 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1470 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1471 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1472 config_host_data.set('CONFIG_RBD', rbd.found())
1473 config_host_data.set('CONFIG_SDL', sdl.found())
1474 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1475 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1476 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1477 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1478 config_host_data.set('CONFIG_VDE', vde.found())
1479 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1480 config_host_data.set('CONFIG_VNC', vnc.found())
1481 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1482 config_host_data.set('CONFIG_VNC_PNG', png.found())
1483 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1484 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1485 config_host_data.set('CONFIG_VTE', vte.found())
1486 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1487 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1488 config_host_data.set('CONFIG_GETTID', has_gettid)
1489 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1490 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1491 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1492 config_host_data.set('CONFIG_NETTLE', nettle.found())
1493 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1494 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1495 config_host_data.set('CONFIG_STATX', has_statx)
1496 config_host_data.set('CONFIG_ZSTD', zstd.found())
1497 config_host_data.set('CONFIG_FUSE', fuse.found())
1498 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1499 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1500 config_host_data.set('CONFIG_SPICE', spice.found())
1501 config_host_data.set('CONFIG_X11', x11.found())
1502 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1503 config_host_data.set('CONFIG_SELINUX', selinux.found())
1504 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1505 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1506 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1507 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1509 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1510 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1511 config_host_data.set('HOST_WORDS_BIGENDIAN', host_machine.endian() == 'big')
1514 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1515 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1516 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1517 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1518 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1519 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1520 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1521 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1522 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1525 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1526 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1527 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1528 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1529 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1530 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
1531 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1532 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1533 config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
1534 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1535 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1536 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1537 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1538 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1539 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1540 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1541 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1542 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1544 config_host_data.set('HAVE_IBV_ADVISE_MR',
1545 cc.has_function('ibv_advise_mr',
1546 args: config_host['RDMA_LIBS'].split(),
1547 prefix: '#include <infiniband/verbs.h>'))
1551 config_host_data.set('CONFIG_BYTESWAP_H',
1552 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1553 config_host_data.set('CONFIG_EPOLL_CREATE1',
1554 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1555 config_host_data.set('CONFIG_HAS_ENVIRON',
1556 cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix))
1557 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1558 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1559 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1560 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1561 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1562 config_host_data.set('CONFIG_FIEMAP',
1563 cc.has_header('linux/fiemap.h') and
1564 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1565 config_host_data.set('CONFIG_GETRANDOM',
1566 cc.has_function('getrandom') and
1567 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1568 config_host_data.set('CONFIG_INOTIFY',
1569 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1570 config_host_data.set('CONFIG_INOTIFY1',
1571 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1572 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1573 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1574 prefix: '''#include <sys/endian.h>
1575 #include <sys/types.h>'''))
1576 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1577 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1578 config_host_data.set('CONFIG_RTNETLINK',
1579 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1580 config_host_data.set('CONFIG_SYSMACROS',
1581 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1582 config_host_data.set('HAVE_OPTRESET',
1583 cc.has_header_symbol('getopt.h', 'optreset'))
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>'))
1596 config_host_data.set('CONFIG_IOVEC',
1597 cc.has_type('struct iovec',
1598 prefix: '#include <sys/uio.h>'))
1599 config_host_data.set('HAVE_UTMPX',
1600 cc.has_type('struct utmpx',
1601 prefix: '#include <utmpx.h>'))
1603 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1604 #include <sys/eventfd.h>
1605 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1606 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1609 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1610 return fdatasync(0);
1612 #error Not supported
1615 config_host_data.set('CONFIG_MADVISE', cc.links(gnu_source_prefix + '''
1616 #include <sys/types.h>
1617 #include <sys/mman.h>
1619 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }'''))
1620 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1621 #include <sys/mman.h>
1622 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1623 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1625 #if !defined(AT_EMPTY_PATH)
1626 # error missing definition
1628 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1630 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1637 return pipe2(pipefd, O_CLOEXEC);
1639 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1640 #include <sys/mman.h>
1642 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1644 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
1645 #include <pthread.h>
1647 static void *f(void *p) { return NULL; }
1651 pthread_create(&thread, 0, f, 0);
1652 pthread_setname_np(thread, "QEMU");
1654 }''', dependencies: threads))
1655 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
1656 #include <pthread.h>
1658 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
1662 pthread_create(&thread, 0, f, 0);
1664 }''', dependencies: threads))
1666 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1667 #include <sys/signalfd.h>
1669 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1670 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1678 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1679 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1683 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
1684 #include <sys/mman.h>
1685 int main(int argc, char *argv[]) {
1686 return mlockall(MCL_FUTURE);
1690 if not get_option('l2tpv3').disabled() and have_system
1691 have_l2tpv3 = cc.has_type('struct mmsghdr',
1692 prefix: gnu_source_prefix + '''
1693 #include <sys/socket.h>
1694 #include <linux/ip.h>''')
1696 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
1699 if not get_option('netmap').disabled() and have_system
1700 have_netmap = cc.compiles('''
1701 #include <inttypes.h>
1703 #include <net/netmap.h>
1704 #include <net/netmap_user.h>
1705 #if (NETMAP_API < 11) || (NETMAP_API > 15)
1708 int main(void) { return 0; }''')
1709 if not have_netmap and get_option('netmap').enabled()
1710 error('Netmap headers not available')
1713 config_host_data.set('CONFIG_NETMAP', have_netmap)
1715 # Work around a system header bug with some kernel/XFS header
1716 # versions where they both try to define 'struct fsxattr':
1717 # xfs headers will not try to redefine structs from linux headers
1718 # if this macro is set.
1719 config_host_data.set('HAVE_FSXATTR', cc.links('''
1720 #include <linux/fs.h>
1726 # Some versions of Mac OS X incorrectly define SIZE_MAX
1727 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1730 int main(int argc, char *argv[]) {
1731 return printf("%zu", SIZE_MAX);
1732 }''', args: ['-Werror']))
1734 # See if 64-bit atomic operations are supported.
1735 # Note that without __atomic builtins, we can only
1736 # assume atomic loads/stores max at pointer size.
1737 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
1741 uint64_t x = 0, y = 0;
1742 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
1743 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
1744 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
1745 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
1746 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
1750 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
1751 #include <sys/auxv.h>
1753 return getauxval(AT_HWCAP) == 0;
1756 config_host_data.set('CONFIG_AF_VSOCK', cc.compiles(gnu_source_prefix + '''
1758 #include <sys/types.h>
1759 #include <sys/socket.h>
1760 #if !defined(AF_VSOCK)
1761 # error missing AF_VSOCK flag
1763 #include <linux/vm_sockets.h>
1766 struct sockaddr_vm svm;
1767 socklen_t len = sizeof(svm);
1768 sock = socket(AF_VSOCK, SOCK_STREAM, 0);
1769 ret = getpeername(sock, (struct sockaddr *)&svm, &len);
1770 if ((ret == -1) && (errno == ENOTCONN)) {
1776 ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target
1778 arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1779 strings = ['CONFIG_IASL']
1780 foreach k, v: config_host
1781 if ignored.contains(k)
1783 elif arrays.contains(k)
1785 v = '"' + '", "'.join(v.split()) + '", '
1787 config_host_data.set(k, v)
1788 elif strings.contains(k)
1789 config_host_data.set_quoted(k, v)
1790 elif k.startswith('CONFIG_')
1791 config_host_data.set(k, v == 'y' ? 1 : v)
1795 ########################
1796 # Target configuration #
1797 ########################
1799 minikconf = find_program('scripts/minikconf.py')
1801 config_all_devices = {}
1802 config_all_disas = {}
1803 config_devices_mak_list = []
1804 config_devices_h = {}
1805 config_target_h = {}
1806 config_target_mak = {}
1809 'alpha' : ['CONFIG_ALPHA_DIS'],
1810 'arm' : ['CONFIG_ARM_DIS'],
1811 'avr' : ['CONFIG_AVR_DIS'],
1812 'cris' : ['CONFIG_CRIS_DIS'],
1813 'hexagon' : ['CONFIG_HEXAGON_DIS'],
1814 'hppa' : ['CONFIG_HPPA_DIS'],
1815 'i386' : ['CONFIG_I386_DIS'],
1816 'x86_64' : ['CONFIG_I386_DIS'],
1817 'm68k' : ['CONFIG_M68K_DIS'],
1818 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1819 'mips' : ['CONFIG_MIPS_DIS'],
1820 'nios2' : ['CONFIG_NIOS2_DIS'],
1821 'or1k' : ['CONFIG_OPENRISC_DIS'],
1822 'ppc' : ['CONFIG_PPC_DIS'],
1823 'riscv' : ['CONFIG_RISCV_DIS'],
1824 'rx' : ['CONFIG_RX_DIS'],
1825 's390' : ['CONFIG_S390_DIS'],
1826 'sh4' : ['CONFIG_SH4_DIS'],
1827 'sparc' : ['CONFIG_SPARC_DIS'],
1828 'xtensa' : ['CONFIG_XTENSA_DIS'],
1830 if link_language == 'cpp'
1832 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1833 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1834 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1838 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
1840 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
1841 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1842 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
1843 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
1844 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1845 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1846 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1847 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1848 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1849 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1850 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1851 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1852 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1854 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1856 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1857 actual_target_dirs = []
1859 foreach target : target_dirs
1860 config_target = { 'TARGET_NAME': target.split('-')[0] }
1861 if target.endswith('linux-user')
1862 if targetos != 'linux'
1866 error('Target @0@ is only available on a Linux host'.format(target))
1868 config_target += { 'CONFIG_LINUX_USER': 'y' }
1869 elif target.endswith('bsd-user')
1870 if 'CONFIG_BSD' not in config_host
1874 error('Target @0@ is only available on a BSD host'.format(target))
1876 config_target += { 'CONFIG_BSD_USER': 'y' }
1877 elif target.endswith('softmmu')
1878 config_target += { 'CONFIG_SOFTMMU': 'y' }
1880 if target.endswith('-user')
1882 'CONFIG_USER_ONLY': 'y',
1883 'CONFIG_QEMU_INTERP_PREFIX':
1884 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1889 foreach sym: accelerators
1890 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1891 config_target += { sym: 'y' }
1892 config_all += { sym: 'y' }
1893 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1894 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1895 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1896 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1898 if target in modular_tcg
1899 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
1901 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
1903 accel_kconfig += [ sym + '=y' ]
1906 if accel_kconfig.length() == 0
1910 error('No accelerator available for target @0@'.format(target))
1913 actual_target_dirs += target
1914 config_target += keyval.load('configs/targets' / target + '.mak')
1915 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1917 if 'TARGET_NEED_FDT' in config_target
1918 fdt_required += target
1922 if 'TARGET_BASE_ARCH' not in config_target
1923 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1925 if 'TARGET_ABI_DIR' not in config_target
1926 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1929 foreach k, v: disassemblers
1930 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1932 config_target += { sym: 'y' }
1933 config_all_disas += { sym: 'y' }
1938 config_target_data = configuration_data()
1939 foreach k, v: config_target
1940 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1942 elif ignored.contains(k)
1944 elif k == 'TARGET_BASE_ARCH'
1945 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1946 # not used to select files from sourcesets.
1947 config_target_data.set('TARGET_' + v.to_upper(), 1)
1948 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1949 config_target_data.set_quoted(k, v)
1951 config_target_data.set(k, 1)
1953 config_target_data.set(k, v)
1956 config_target_data.set('QEMU_ARCH',
1957 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
1958 config_target_h += {target: configure_file(output: target + '-config-target.h',
1959 configuration: config_target_data)}
1961 if target.endswith('-softmmu')
1962 config_input = meson.get_external_property(target, 'default')
1963 config_devices_mak = target + '-config-devices.mak'
1964 config_devices_mak = configure_file(
1965 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
1966 output: config_devices_mak,
1967 depfile: config_devices_mak + '.d',
1969 command: [minikconf,
1970 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1971 config_devices_mak, '@DEPFILE@', '@INPUT@',
1972 host_kconfig, accel_kconfig,
1973 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
1975 config_devices_data = configuration_data()
1976 config_devices = keyval.load(config_devices_mak)
1977 foreach k, v: config_devices
1978 config_devices_data.set(k, 1)
1980 config_devices_mak_list += config_devices_mak
1981 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1982 configuration: config_devices_data)}
1983 config_target += config_devices
1984 config_all_devices += config_devices
1986 config_target_mak += {target: config_target}
1988 target_dirs = actual_target_dirs
1990 # This configuration is used to build files that are shared by
1991 # multiple binaries, and then extracted out of the "common"
1992 # static_library target.
1994 # We do not use all_sources()/all_dependencies(), because it would
1995 # build literally all source files, including devices only used by
1996 # targets that are not built for this compilation. The CONFIG_ALL
1997 # pseudo symbol replaces it.
1999 config_all += config_all_devices
2000 config_all += config_host
2001 config_all += config_all_disas
2003 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
2004 'CONFIG_SOFTMMU': have_system,
2005 'CONFIG_USER_ONLY': have_user,
2013 capstone = not_found
2014 capstone_opt = get_option('capstone')
2015 if capstone_opt in ['enabled', 'auto', 'system']
2016 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
2017 capstone = dependency('capstone', version: '>=4.0',
2018 kwargs: static_kwargs, method: 'pkg-config',
2019 required: capstone_opt == 'system' or
2020 capstone_opt == 'enabled' and not have_internal)
2022 # Some versions of capstone have broken pkg-config file
2023 # that reports a wrong -I path, causing the #include to
2024 # fail later. If the system has such a broken version
2026 if capstone.found() and not cc.compiles('#include <capstone.h>',
2027 dependencies: [capstone])
2028 capstone = not_found
2029 if capstone_opt == 'system'
2030 error('system capstone requested, it does not appear to work')
2035 capstone_opt = 'system'
2037 capstone_opt = 'internal'
2039 capstone_opt = 'disabled'
2042 if capstone_opt == 'internal'
2043 capstone_data = configuration_data()
2044 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
2046 capstone_files = files(
2048 'capstone/MCInst.c',
2049 'capstone/MCInstrDesc.c',
2050 'capstone/MCRegisterInfo.c',
2051 'capstone/SStream.c',
2055 if 'CONFIG_ARM_DIS' in config_all_disas
2056 capstone_data.set('CAPSTONE_HAS_ARM', '1')
2057 capstone_files += files(
2058 'capstone/arch/ARM/ARMDisassembler.c',
2059 'capstone/arch/ARM/ARMInstPrinter.c',
2060 'capstone/arch/ARM/ARMMapping.c',
2061 'capstone/arch/ARM/ARMModule.c'
2065 # FIXME: This config entry currently depends on a c++ compiler.
2066 # Which is needed for building libvixl, but not for capstone.
2067 if 'CONFIG_ARM_A64_DIS' in config_all_disas
2068 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
2069 capstone_files += files(
2070 'capstone/arch/AArch64/AArch64BaseInfo.c',
2071 'capstone/arch/AArch64/AArch64Disassembler.c',
2072 'capstone/arch/AArch64/AArch64InstPrinter.c',
2073 'capstone/arch/AArch64/AArch64Mapping.c',
2074 'capstone/arch/AArch64/AArch64Module.c'
2078 if 'CONFIG_PPC_DIS' in config_all_disas
2079 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
2080 capstone_files += files(
2081 'capstone/arch/PowerPC/PPCDisassembler.c',
2082 'capstone/arch/PowerPC/PPCInstPrinter.c',
2083 'capstone/arch/PowerPC/PPCMapping.c',
2084 'capstone/arch/PowerPC/PPCModule.c'
2088 if 'CONFIG_S390_DIS' in config_all_disas
2089 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
2090 capstone_files += files(
2091 'capstone/arch/SystemZ/SystemZDisassembler.c',
2092 'capstone/arch/SystemZ/SystemZInstPrinter.c',
2093 'capstone/arch/SystemZ/SystemZMapping.c',
2094 'capstone/arch/SystemZ/SystemZModule.c',
2095 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
2099 if 'CONFIG_I386_DIS' in config_all_disas
2100 capstone_data.set('CAPSTONE_HAS_X86', 1)
2101 capstone_files += files(
2102 'capstone/arch/X86/X86Disassembler.c',
2103 'capstone/arch/X86/X86DisassemblerDecoder.c',
2104 'capstone/arch/X86/X86ATTInstPrinter.c',
2105 'capstone/arch/X86/X86IntelInstPrinter.c',
2106 'capstone/arch/X86/X86InstPrinterCommon.c',
2107 'capstone/arch/X86/X86Mapping.c',
2108 'capstone/arch/X86/X86Module.c'
2112 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
2115 # FIXME: There does not seem to be a way to completely replace the c_args
2116 # that come from add_project_arguments() -- we can only add to them.
2117 # So: disable all warnings with a big hammer.
2120 # Include all configuration defines via a header file, which will wind up
2121 # as a dependency on the object file, and thus changes here will result
2123 '-include', 'capstone-defs.h'
2126 libcapstone = static_library('capstone',
2127 build_by_default: false,
2128 sources: capstone_files,
2129 c_args: capstone_cargs,
2130 include_directories: 'capstone/include')
2131 capstone = declare_dependency(link_with: libcapstone,
2132 include_directories: 'capstone/include/capstone')
2136 slirp_opt = 'disabled'
2138 slirp_opt = get_option('slirp')
2139 if slirp_opt in ['enabled', 'auto', 'system']
2140 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2141 slirp = dependency('slirp', kwargs: static_kwargs,
2142 method: 'pkg-config',
2143 required: slirp_opt == 'system' or
2144 slirp_opt == 'enabled' and not have_internal)
2146 slirp_opt = 'system'
2148 slirp_opt = 'internal'
2150 slirp_opt = 'disabled'
2153 if slirp_opt == 'internal'
2155 if targetos == 'windows'
2156 slirp_deps = cc.find_library('iphlpapi')
2157 elif targetos == 'darwin'
2158 slirp_deps = cc.find_library('resolv')
2160 slirp_conf = configuration_data()
2161 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2162 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2163 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2164 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2165 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2167 'slirp/src/arp_table.c',
2168 'slirp/src/bootp.c',
2169 'slirp/src/cksum.c',
2170 'slirp/src/dhcpv6.c',
2171 'slirp/src/dnssearch.c',
2173 'slirp/src/ip6_icmp.c',
2174 'slirp/src/ip6_input.c',
2175 'slirp/src/ip6_output.c',
2176 'slirp/src/ip_icmp.c',
2177 'slirp/src/ip_input.c',
2178 'slirp/src/ip_output.c',
2182 'slirp/src/ndp_table.c',
2184 'slirp/src/slirp.c',
2185 'slirp/src/socket.c',
2186 'slirp/src/state.c',
2187 'slirp/src/stream.c',
2188 'slirp/src/tcp_input.c',
2189 'slirp/src/tcp_output.c',
2190 'slirp/src/tcp_subr.c',
2191 'slirp/src/tcp_timer.c',
2196 'slirp/src/version.c',
2197 'slirp/src/vmstate.c',
2201 input : 'slirp/src/libslirp-version.h.in',
2202 output : 'libslirp-version.h',
2203 configuration: slirp_conf)
2205 slirp_inc = include_directories('slirp', 'slirp/src')
2206 libslirp = static_library('slirp',
2207 build_by_default: false,
2208 sources: slirp_files,
2209 c_args: slirp_cargs,
2210 include_directories: slirp_inc)
2211 slirp = declare_dependency(link_with: libslirp,
2212 dependencies: slirp_deps,
2213 include_directories: slirp_inc)
2217 # For CFI, we need to compile slirp as a static library together with qemu.
2218 # This is because we register slirp functions as callbacks for QEMU Timers.
2219 # When using a system-wide shared libslirp, the type information for the
2220 # callback is missing and the timer call produces a false positive with CFI.
2222 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2223 # with control-flow integrity.
2224 if get_option('cfi') and slirp_opt == 'system'
2225 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2226 + ' Please configure with --enable-slirp=git')
2230 fdt_opt = get_option('fdt')
2232 if fdt_opt in ['enabled', 'auto', 'system']
2233 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2234 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2235 required: fdt_opt == 'system' or
2236 fdt_opt == 'enabled' and not have_internal)
2237 if fdt.found() and cc.links('''
2239 #include <libfdt_env.h>
2240 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
2243 elif fdt_opt == 'system'
2244 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2246 fdt_opt = 'internal'
2248 fdt_opt = 'disabled'
2252 if fdt_opt == 'internal'
2255 'dtc/libfdt/fdt_ro.c',
2256 'dtc/libfdt/fdt_wip.c',
2257 'dtc/libfdt/fdt_sw.c',
2258 'dtc/libfdt/fdt_rw.c',
2259 'dtc/libfdt/fdt_strerror.c',
2260 'dtc/libfdt/fdt_empty_tree.c',
2261 'dtc/libfdt/fdt_addresses.c',
2262 'dtc/libfdt/fdt_overlay.c',
2263 'dtc/libfdt/fdt_check.c',
2266 fdt_inc = include_directories('dtc/libfdt')
2267 libfdt = static_library('fdt',
2268 build_by_default: false,
2270 include_directories: fdt_inc)
2271 fdt = declare_dependency(link_with: libfdt,
2272 include_directories: fdt_inc)
2275 if not fdt.found() and fdt_required.length() > 0
2276 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2279 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2280 config_host_data.set('CONFIG_FDT', fdt.found())
2281 config_host_data.set('CONFIG_SLIRP', slirp.found())
2283 #####################
2284 # Generated sources #
2285 #####################
2287 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2289 hxtool = find_program('scripts/hxtool')
2290 shaderinclude = find_program('scripts/shaderinclude.pl')
2291 qapi_gen = find_program('scripts/qapi-gen.py')
2292 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2293 meson.current_source_dir() / 'scripts/qapi/commands.py',
2294 meson.current_source_dir() / 'scripts/qapi/common.py',
2295 meson.current_source_dir() / 'scripts/qapi/error.py',
2296 meson.current_source_dir() / 'scripts/qapi/events.py',
2297 meson.current_source_dir() / 'scripts/qapi/expr.py',
2298 meson.current_source_dir() / 'scripts/qapi/gen.py',
2299 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2300 meson.current_source_dir() / 'scripts/qapi/parser.py',
2301 meson.current_source_dir() / 'scripts/qapi/schema.py',
2302 meson.current_source_dir() / 'scripts/qapi/source.py',
2303 meson.current_source_dir() / 'scripts/qapi/types.py',
2304 meson.current_source_dir() / 'scripts/qapi/visit.py',
2305 meson.current_source_dir() / 'scripts/qapi/common.py',
2306 meson.current_source_dir() / 'scripts/qapi-gen.py'
2310 python, files('scripts/tracetool.py'),
2311 '--backend=' + ','.join(get_option('trace_backends'))
2313 tracetool_depends = files(
2314 'scripts/tracetool/backend/log.py',
2315 'scripts/tracetool/backend/__init__.py',
2316 'scripts/tracetool/backend/dtrace.py',
2317 'scripts/tracetool/backend/ftrace.py',
2318 'scripts/tracetool/backend/simple.py',
2319 'scripts/tracetool/backend/syslog.py',
2320 'scripts/tracetool/backend/ust.py',
2321 'scripts/tracetool/format/tcg_h.py',
2322 'scripts/tracetool/format/ust_events_c.py',
2323 'scripts/tracetool/format/ust_events_h.py',
2324 'scripts/tracetool/format/__init__.py',
2325 'scripts/tracetool/format/d.py',
2326 'scripts/tracetool/format/tcg_helper_c.py',
2327 'scripts/tracetool/format/simpletrace_stap.py',
2328 'scripts/tracetool/format/c.py',
2329 'scripts/tracetool/format/h.py',
2330 'scripts/tracetool/format/tcg_helper_h.py',
2331 'scripts/tracetool/format/log_stap.py',
2332 'scripts/tracetool/format/stap.py',
2333 'scripts/tracetool/format/tcg_helper_wrapper_h.py',
2334 'scripts/tracetool/__init__.py',
2335 'scripts/tracetool/transform.py',
2336 'scripts/tracetool/vcpu.py'
2339 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2340 meson.current_source_dir(),
2341 config_host['PKGVERSION'], meson.project_version()]
2342 qemu_version = custom_target('qemu-version.h',
2343 output: 'qemu-version.h',
2344 command: qemu_version_cmd,
2346 build_by_default: true,
2347 build_always_stale: true)
2348 genh += qemu_version
2352 ['qemu-options.hx', 'qemu-options.def'],
2353 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2357 ['hmp-commands.hx', 'hmp-commands.h'],
2358 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2361 foreach d : hx_headers
2362 hxdep += custom_target(d[1],
2366 build_by_default: true, # to be removed when added to a target
2367 command: [hxtool, '-h', '@INPUT0@'])
2375 authz_ss = ss.source_set()
2376 blockdev_ss = ss.source_set()
2377 block_ss = ss.source_set()
2378 bsd_user_ss = ss.source_set()
2379 chardev_ss = ss.source_set()
2380 common_ss = ss.source_set()
2381 crypto_ss = ss.source_set()
2382 hwcore_ss = ss.source_set()
2383 io_ss = ss.source_set()
2384 linux_user_ss = ss.source_set()
2385 qmp_ss = ss.source_set()
2386 qom_ss = ss.source_set()
2387 softmmu_ss = ss.source_set()
2388 specific_fuzz_ss = ss.source_set()
2389 specific_ss = ss.source_set()
2390 stub_ss = ss.source_set()
2391 trace_ss = ss.source_set()
2392 user_ss = ss.source_set()
2393 util_ss = ss.source_set()
2396 qtest_module_ss = ss.source_set()
2397 tcg_module_ss = ss.source_set()
2403 target_softmmu_arch = {}
2404 target_user_arch = {}
2410 # TODO: add each directory to the subdirs from its own meson.build, once
2412 trace_events_subdirs = [
2420 trace_events_subdirs += [ 'linux-user' ]
2423 trace_events_subdirs += [
2432 trace_events_subdirs += [
2446 'hw/block/dataplane',
2496 if have_system or have_user
2497 trace_events_subdirs += [
2514 vhost_user = not_found
2515 if 'CONFIG_VHOST_USER' in config_host
2516 libvhost_user = subproject('libvhost-user')
2517 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2532 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2533 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2536 stub_ss = stub_ss.apply(config_all, strict: false)
2538 util_ss.add_all(trace_ss)
2539 util_ss = util_ss.apply(config_all, strict: false)
2540 libqemuutil = static_library('qemuutil',
2541 sources: util_ss.sources() + stub_ss.sources() + genh,
2542 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2543 qemuutil = declare_dependency(link_with: libqemuutil,
2544 sources: genh + version_res)
2546 if have_system or have_user
2547 decodetree = generator(find_program('scripts/decodetree.py'),
2548 output: 'decode-@BASENAME@.c.inc',
2549 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2550 subdir('libdecnumber')
2567 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
2573 blockdev_ss.add(files(
2580 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2581 # os-win32.c does not
2582 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2583 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2586 common_ss.add(files('cpus-common.c'))
2590 common_ss.add(capstone)
2591 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2593 # Work around a gcc bug/misfeature wherein constant propagation looks
2595 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2596 # to guess that a const variable is always zero. Without lto, this is
2597 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2598 # without lto, not even the alias is required -- we simply use different
2599 # declarations in different compilation units.
2600 pagevary = files('page-vary-common.c')
2601 if get_option('b_lto')
2602 pagevary_flags = ['-fno-lto']
2603 if get_option('cfi')
2604 pagevary_flags += '-fno-sanitize=cfi-icall'
2606 pagevary = static_library('page-vary-common', sources: pagevary,
2607 c_args: pagevary_flags)
2608 pagevary = declare_dependency(link_with: pagevary)
2610 common_ss.add(pagevary)
2611 specific_ss.add(files('page-vary.c'))
2619 subdir('semihosting')
2626 subdir('linux-user')
2629 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
2631 linux_user_ss.add(files('thunk.c'))
2632 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
2634 # needed for fuzzing binaries
2635 subdir('tests/qtest/libqos')
2636 subdir('tests/qtest/fuzz')
2639 tcg_real_module_ss = ss.source_set()
2640 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
2641 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
2642 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
2643 'tcg': tcg_real_module_ss }}
2645 ########################
2646 # Library dependencies #
2647 ########################
2649 modinfo_collect = find_program('scripts/modinfo-collect.py')
2650 modinfo_generate = find_program('scripts/modinfo-generate.py')
2655 foreach d, list : modules
2656 foreach m, module_ss : list
2657 if enable_modules and targetos != 'windows'
2658 module_ss = module_ss.apply(config_all, strict: false)
2659 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2660 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2666 if module_ss.sources() != []
2667 # FIXME: Should use sl.extract_all_objects(recursive: true) as
2668 # input. Sources can be used multiple times but objects are
2669 # unique when it comes to lookup in compile_commands.json.
2670 # Depnds on a mesion version with
2671 # https://github.com/mesonbuild/meson/pull/8900
2672 modinfo_files += custom_target(d + '-' + m + '.modinfo',
2673 output: d + '-' + m + '.modinfo',
2674 input: module_ss.sources() + genh,
2676 command: [modinfo_collect, module_ss.sources()])
2680 block_ss.add_all(module_ss)
2682 softmmu_ss.add_all(module_ss)
2688 foreach d, list : target_modules
2689 foreach m, module_ss : list
2690 if enable_modules and targetos != 'windows'
2691 foreach target : target_dirs
2692 if target.endswith('-softmmu')
2693 config_target = config_target_mak[target]
2694 config_target += config_host
2695 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2696 c_args = ['-DNEED_CPU_H',
2697 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2698 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2699 target_module_ss = module_ss.apply(config_target, strict: false)
2700 if target_module_ss.sources() != []
2701 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
2702 sl = static_library(module_name,
2703 [genh, target_module_ss.sources()],
2704 dependencies: [modulecommon, target_module_ss.dependencies()],
2705 include_directories: target_inc,
2709 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
2710 modinfo_files += custom_target(module_name + '.modinfo',
2711 output: module_name + '.modinfo',
2712 input: target_module_ss.sources() + genh,
2714 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
2719 specific_ss.add_all(module_ss)
2725 modinfo_src = custom_target('modinfo.c',
2726 output: 'modinfo.c',
2727 input: modinfo_files,
2728 command: [modinfo_generate, '@INPUT@'],
2730 modinfo_lib = static_library('modinfo', modinfo_src)
2731 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
2732 softmmu_ss.add(modinfo_dep)
2735 nm = find_program('nm')
2736 undefsym = find_program('scripts/undefsym.py')
2737 block_syms = custom_target('block.syms', output: 'block.syms',
2738 input: [libqemuutil, block_mods],
2740 command: [undefsym, nm, '@INPUT@'])
2741 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2742 input: [libqemuutil, softmmu_mods],
2744 command: [undefsym, nm, '@INPUT@'])
2746 qom_ss = qom_ss.apply(config_host, strict: false)
2747 libqom = static_library('qom', qom_ss.sources() + genh,
2748 dependencies: [qom_ss.dependencies()],
2751 qom = declare_dependency(link_whole: libqom)
2753 authz_ss = authz_ss.apply(config_host, strict: false)
2754 libauthz = static_library('authz', authz_ss.sources() + genh,
2755 dependencies: [authz_ss.dependencies()],
2757 build_by_default: false)
2759 authz = declare_dependency(link_whole: libauthz,
2762 crypto_ss = crypto_ss.apply(config_host, strict: false)
2763 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2764 dependencies: [crypto_ss.dependencies()],
2766 build_by_default: false)
2768 crypto = declare_dependency(link_whole: libcrypto,
2769 dependencies: [authz, qom])
2771 io_ss = io_ss.apply(config_host, strict: false)
2772 libio = static_library('io', io_ss.sources() + genh,
2773 dependencies: [io_ss.dependencies()],
2774 link_with: libqemuutil,
2776 build_by_default: false)
2778 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2780 libmigration = static_library('migration', sources: migration_files + genh,
2782 build_by_default: false)
2783 migration = declare_dependency(link_with: libmigration,
2784 dependencies: [zlib, qom, io])
2785 softmmu_ss.add(migration)
2787 block_ss = block_ss.apply(config_host, strict: false)
2788 libblock = static_library('block', block_ss.sources() + genh,
2789 dependencies: block_ss.dependencies(),
2790 link_depends: block_syms,
2792 build_by_default: false)
2794 block = declare_dependency(link_whole: [libblock],
2795 link_args: '@block.syms',
2796 dependencies: [crypto, io])
2798 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2799 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2800 dependencies: blockdev_ss.dependencies(),
2802 build_by_default: false)
2804 blockdev = declare_dependency(link_whole: [libblockdev],
2805 dependencies: [block])
2807 qmp_ss = qmp_ss.apply(config_host, strict: false)
2808 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2809 dependencies: qmp_ss.dependencies(),
2811 build_by_default: false)
2813 qmp = declare_dependency(link_whole: [libqmp])
2815 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2817 dependencies: [gnutls],
2818 build_by_default: false)
2820 chardev = declare_dependency(link_whole: libchardev)
2822 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
2823 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
2825 build_by_default: false)
2826 hwcore = declare_dependency(link_whole: libhwcore)
2827 common_ss.add(hwcore)
2833 foreach m : block_mods + softmmu_mods
2834 shared_module(m.name(),
2838 install_dir: qemu_moddir)
2841 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2842 common_ss.add(qom, qemuutil)
2844 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2845 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2847 common_all = common_ss.apply(config_all, strict: false)
2848 common_all = static_library('common',
2849 build_by_default: false,
2850 sources: common_all.sources() + genh,
2851 implicit_include_directories: false,
2852 dependencies: common_all.dependencies(),
2855 feature_to_c = find_program('scripts/feature_to_c.sh')
2858 foreach target : target_dirs
2859 config_target = config_target_mak[target]
2860 target_name = config_target['TARGET_NAME']
2861 target_base_arch = config_target['TARGET_BASE_ARCH']
2862 arch_srcs = [config_target_h[target]]
2864 c_args = ['-DNEED_CPU_H',
2865 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2866 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2867 link_args = emulator_link_args
2869 config_target += config_host
2870 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2871 if targetos == 'linux'
2872 target_inc += include_directories('linux-headers', is_system: true)
2874 if target.endswith('-softmmu')
2875 qemu_target_name = 'qemu-system-' + target_name
2876 target_type='system'
2877 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
2878 arch_srcs += t.sources()
2879 arch_deps += t.dependencies()
2881 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
2882 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2883 arch_srcs += hw.sources()
2884 arch_deps += hw.dependencies()
2886 arch_srcs += config_devices_h[target]
2887 link_args += ['@block.syms', '@qemu.syms']
2889 abi = config_target['TARGET_ABI_DIR']
2891 qemu_target_name = 'qemu-' + target_name
2892 if target_base_arch in target_user_arch
2893 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
2894 arch_srcs += t.sources()
2895 arch_deps += t.dependencies()
2897 if 'CONFIG_LINUX_USER' in config_target
2898 base_dir = 'linux-user'
2899 target_inc += include_directories('linux-user/host/' / host_arch)
2901 if 'CONFIG_BSD_USER' in config_target
2902 base_dir = 'bsd-user'
2903 target_inc += include_directories('bsd-user/' / targetos)
2904 dir = base_dir / abi
2905 arch_srcs += files(dir / 'target_arch_cpu.c')
2907 target_inc += include_directories(
2911 if 'CONFIG_LINUX_USER' in config_target
2912 dir = base_dir / abi
2913 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2914 if config_target.has_key('TARGET_SYSTBL_ABI')
2916 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2917 extra_args : config_target['TARGET_SYSTBL_ABI'])
2922 if 'TARGET_XML_FILES' in config_target
2923 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2924 output: target + '-gdbstub-xml.c',
2925 input: files(config_target['TARGET_XML_FILES'].split()),
2926 command: [feature_to_c, '@INPUT@'],
2928 arch_srcs += gdbstub_xml
2931 t = target_arch[target_base_arch].apply(config_target, strict: false)
2932 arch_srcs += t.sources()
2933 arch_deps += t.dependencies()
2935 target_common = common_ss.apply(config_target, strict: false)
2936 objects = common_all.extract_objects(target_common.sources())
2937 deps = target_common.dependencies()
2939 target_specific = specific_ss.apply(config_target, strict: false)
2940 arch_srcs += target_specific.sources()
2941 arch_deps += target_specific.dependencies()
2943 lib = static_library('qemu-' + target,
2944 sources: arch_srcs + genh,
2945 dependencies: arch_deps,
2947 include_directories: target_inc,
2949 build_by_default: false,
2952 if target.endswith('-softmmu')
2954 'name': 'qemu-system-' + target_name,
2955 'win_subsystem': 'console',
2956 'sources': files('softmmu/main.c'),
2959 if targetos == 'windows' and (sdl.found() or gtk.found())
2961 'name': 'qemu-system-' + target_name + 'w',
2962 'win_subsystem': 'windows',
2963 'sources': files('softmmu/main.c'),
2967 if get_option('fuzzing')
2968 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2970 'name': 'qemu-fuzz-' + target_name,
2971 'win_subsystem': 'console',
2972 'sources': specific_fuzz.sources(),
2973 'dependencies': specific_fuzz.dependencies(),
2978 'name': 'qemu-' + target_name,
2979 'win_subsystem': 'console',
2985 exe_name = exe['name']
2986 if targetos == 'darwin'
2987 exe_name += '-unsigned'
2990 emulator = executable(exe_name, exe['sources'],
2993 dependencies: arch_deps + deps + exe['dependencies'],
2994 objects: lib.extract_all_objects(recursive: true),
2995 link_language: link_language,
2996 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2997 link_args: link_args,
2998 win_subsystem: exe['win_subsystem'])
3000 if targetos == 'darwin'
3001 icon = 'pc-bios/qemu.rsrc'
3002 build_input = [emulator, files(icon)]
3004 get_option('bindir') / exe_name,
3005 meson.current_source_dir() / icon
3007 if 'CONFIG_HVF' in config_target
3008 entitlements = 'accel/hvf/entitlements.plist'
3009 build_input += files(entitlements)
3010 install_input += meson.current_source_dir() / entitlements
3013 emulators += {exe['name'] : custom_target(exe['name'],
3015 output: exe['name'],
3017 files('scripts/entitlement.sh'),
3023 meson.add_install_script('scripts/entitlement.sh', '--install',
3024 get_option('bindir') / exe['name'],
3027 emulators += {exe['name']: emulator}
3032 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3033 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3034 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3035 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3037 custom_target(exe['name'] + stp['ext'],
3038 input: trace_events_all,
3039 output: exe['name'] + stp['ext'],
3040 install: stp['install'],
3041 install_dir: get_option('datadir') / 'systemtap/tapset',
3043 tracetool, '--group=all', '--format=' + stp['fmt'],
3044 '--binary=' + stp['bin'],
3045 '--target-name=' + target_name,
3046 '--target-type=' + target_type,
3047 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3048 '@INPUT@', '@OUTPUT@'
3050 depend_files: tracetool_depends)
3056 # Other build targets
3058 if 'CONFIG_PLUGIN' in config_host
3059 install_headers('include/qemu/qemu-plugin.h')
3062 if 'CONFIG_GUEST_AGENT' in config_host
3064 elif get_option('guest_agent_msi').enabled()
3065 error('Guest agent MSI requested, but the guest agent is not being built')
3068 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3069 # when we don't build tools or system
3070 if xkbcommon.found()
3071 # used for the update-keymaps target, so include rules even if !have_tools
3072 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3073 dependencies: [qemuutil, xkbcommon], install: have_tools)
3077 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3078 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3079 qemu_io = executable('qemu-io', files('qemu-io.c'),
3080 dependencies: [block, qemuutil], install: true)
3081 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3082 dependencies: [blockdev, qemuutil, gnutls, selinux],
3085 subdir('storage-daemon')
3086 subdir('contrib/rdmacm-mux')
3087 subdir('contrib/elf2dmp')
3089 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3090 dependencies: qemuutil,
3093 if 'CONFIG_VHOST_USER' in config_host
3094 subdir('contrib/vhost-user-blk')
3095 subdir('contrib/vhost-user-gpu')
3096 subdir('contrib/vhost-user-input')
3097 subdir('contrib/vhost-user-scsi')
3100 if targetos == 'linux'
3101 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3102 dependencies: [qemuutil, libcap_ng],
3104 install_dir: get_option('libexecdir'))
3106 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3107 dependencies: [authz, crypto, io, qom, qemuutil,
3108 libcap_ng, mpathpersist],
3113 subdir('contrib/ivshmem-client')
3114 subdir('contrib/ivshmem-server')
3127 if host_machine.system() == 'windows'
3129 find_program('scripts/nsis.py'),
3131 get_option('prefix'),
3132 meson.current_source_dir(),
3135 '-DDISPLAYVERSION=' + meson.project_version(),
3138 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3141 nsis_cmd += '-DCONFIG_GTK=y'
3144 nsis = custom_target('nsis',
3145 output: 'qemu-setup-' + meson.project_version() + '.exe',
3146 input: files('qemu.nsi'),
3147 build_always_stale: true,
3148 command: nsis_cmd + ['@INPUT@'])
3149 alias_target('installer', nsis)
3152 #########################
3153 # Configuration summary #
3154 #########################
3158 summary_info += {'Install prefix': get_option('prefix')}
3159 summary_info += {'BIOS directory': qemu_datadir}
3160 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
3161 summary_info += {'binary directory': get_option('bindir')}
3162 summary_info += {'library directory': get_option('libdir')}
3163 summary_info += {'module directory': qemu_moddir}
3164 summary_info += {'libexec directory': get_option('libexecdir')}
3165 summary_info += {'include directory': get_option('includedir')}
3166 summary_info += {'config directory': get_option('sysconfdir')}
3167 if targetos != 'windows'
3168 summary_info += {'local state directory': get_option('localstatedir')}
3169 summary_info += {'Manual directory': get_option('mandir')}
3171 summary_info += {'local state directory': 'queried at runtime'}
3173 summary_info += {'Doc directory': get_option('docdir')}
3174 summary_info += {'Build directory': meson.current_build_dir()}
3175 summary_info += {'Source path': meson.current_source_dir()}
3176 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3177 summary(summary_info, bool_yn: true, section: 'Directories')
3181 summary_info += {'git': config_host['GIT']}
3182 summary_info += {'make': config_host['MAKE']}
3183 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3184 summary_info += {'sphinx-build': sphinx_build}
3185 if config_host.has_key('HAVE_GDB_BIN')
3186 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3188 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3189 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
3190 summary_info += {'wixl': wixl}
3192 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
3193 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
3195 summary(summary_info, bool_yn: true, section: 'Host binaries')
3197 # Configurable features
3199 summary_info += {'Documentation': build_docs}
3200 summary_info += {'system-mode emulation': have_system}
3201 summary_info += {'user-mode emulation': have_user}
3202 summary_info += {'block layer': have_block}
3203 summary_info += {'Install blobs': get_option('install_blobs')}
3204 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3205 if config_host.has_key('CONFIG_MODULES')
3206 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
3208 summary_info += {'fuzzing support': get_option('fuzzing')}
3210 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3212 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3213 if 'simple' in get_option('trace_backends')
3214 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3216 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
3217 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
3218 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
3219 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
3220 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
3221 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
3222 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
3223 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3224 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
3225 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
3226 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
3227 summary(summary_info, bool_yn: true, section: 'Configurable features')
3229 # Compilation information
3231 summary_info += {'host CPU': cpu}
3232 summary_info += {'host endianness': build_machine.endian()}
3233 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3234 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3235 if link_language == 'cpp'
3236 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3238 summary_info += {'C++ compiler': false}
3240 if targetos == 'darwin'
3241 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3243 if targetos == 'windows'
3244 if 'WIN_SDK' in config_host
3245 summary_info += {'Windows SDK': config_host['WIN_SDK']}
3248 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3249 + ['-O' + get_option('optimization')]
3250 + (get_option('debug') ? ['-g'] : []))}
3251 if link_language == 'cpp'
3252 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3253 + ['-O' + get_option('optimization')]
3254 + (get_option('debug') ? ['-g'] : []))}
3256 link_args = get_option(link_language + '_link_args')
3257 if link_args.length() > 0
3258 summary_info += {'LDFLAGS': ' '.join(link_args)}
3260 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
3261 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
3262 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
3263 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3264 summary_info += {'PIE': get_option('b_pie')}
3265 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3266 summary_info += {'malloc trim support': has_malloc_trim}
3267 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
3268 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
3269 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
3270 summary_info += {'memory allocator': get_option('malloc')}
3271 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
3272 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
3273 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
3274 summary_info += {'gcov': get_option('b_coverage')}
3275 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3276 summary_info += {'CFI support': get_option('cfi')}
3277 if get_option('cfi')
3278 summary_info += {'CFI debug support': get_option('cfi_debug')}
3280 summary_info += {'strip binaries': get_option('strip')}
3281 summary_info += {'sparse': sparse}
3282 summary_info += {'mingw32 support': targetos == 'windows'}
3284 # snarf the cross-compilation information for tests
3285 foreach target: target_dirs
3286 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3287 if fs.exists(tcg_mak)
3288 config_cross_tcg = keyval.load(tcg_mak)
3289 target = config_cross_tcg['TARGET_NAME']
3291 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3292 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3293 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3294 elif 'CROSS_CC_GUEST' in config_cross_tcg
3295 summary_info += {target + ' tests'
3296 : config_cross_tcg['CROSS_CC_GUEST'] }
3301 summary(summary_info, bool_yn: true, section: 'Compilation')
3303 # Targets and accelerators
3306 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3307 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3308 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3309 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3310 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3311 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
3312 if config_host.has_key('CONFIG_XEN_BACKEND')
3313 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
3316 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3317 if config_all.has_key('CONFIG_TCG')
3318 if get_option('tcg_interpreter')
3319 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
3321 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3323 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3324 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3326 summary_info += {'target list': ' '.join(target_dirs)}
3328 summary_info += {'default devices': get_option('default_devices')}
3329 summary_info += {'out of process emulation': multiprocess_allowed}
3331 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3335 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3336 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
3338 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3339 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3340 summary_info += {'Use block whitelist in tools': config_host.has_key('CONFIG_BDRV_WHITELIST_TOOLS')}
3341 summary_info += {'VirtFS support': have_virtfs}
3342 summary_info += {'build virtiofs daemon': have_virtiofsd}
3343 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
3344 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
3345 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
3346 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
3347 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
3348 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
3349 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
3350 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
3351 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
3352 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
3353 summary_info += {'FUSE exports': fuse}
3355 summary(summary_info, bool_yn: true, section: 'Block layer support')
3359 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
3360 summary_info += {'GNUTLS support': gnutls}
3362 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3364 summary_info += {'libgcrypt': gcrypt}
3365 summary_info += {'nettle': nettle}
3367 summary_info += {' XTS': xts != 'private'}
3369 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
3370 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
3371 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
3372 summary(summary_info, bool_yn: true, section: 'Crypto')
3376 if targetos == 'darwin'
3377 summary_info += {'Cocoa support': cocoa}
3379 summary_info += {'SDL support': sdl}
3380 summary_info += {'SDL image support': sdl_image}
3381 summary_info += {'GTK support': gtk}
3382 summary_info += {'pixman': pixman}
3383 summary_info += {'VTE support': vte}
3384 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3385 summary_info += {'libtasn1': tasn1}
3386 summary_info += {'PAM': pam}
3387 summary_info += {'iconv support': iconv}
3388 summary_info += {'curses support': curses}
3389 summary_info += {'virgl support': virgl}
3390 summary_info += {'curl support': curl}
3391 summary_info += {'Multipath support': mpathpersist}
3392 summary_info += {'VNC support': vnc}
3394 summary_info += {'VNC SASL support': sasl}
3395 summary_info += {'VNC JPEG support': jpeg}
3396 summary_info += {'VNC PNG support': png}
3398 if targetos not in ['darwin', 'haiku', 'windows']
3399 summary_info += {'OSS support': oss}
3400 elif targetos == 'darwin'
3401 summary_info += {'CoreAudio support': coreaudio}
3402 elif targetos == 'windows'
3403 summary_info += {'DirectSound support': dsound}
3405 if targetos == 'linux'
3406 summary_info += {'ALSA support': alsa}
3407 summary_info += {'PulseAudio support': pulse}
3409 summary_info += {'JACK support': jack}
3410 summary_info += {'brlapi support': brlapi}
3411 summary_info += {'vde support': vde}
3412 summary_info += {'netmap support': have_netmap}
3413 summary_info += {'l2tpv3 support': have_l2tpv3}
3414 summary_info += {'Linux AIO support': libaio}
3415 summary_info += {'Linux io_uring support': linux_io_uring}
3416 summary_info += {'ATTR/XATTR support': libattr}
3417 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
3418 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
3419 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3420 summary_info += {'libcap-ng support': libcap_ng}
3421 summary_info += {'bpf support': libbpf}
3422 summary_info += {'spice protocol support': spice_protocol}
3423 if spice_protocol.found()
3424 summary_info += {' spice server support': spice}
3426 summary_info += {'rbd support': rbd}
3427 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
3428 summary_info += {'smartcard support': cacard}
3429 summary_info += {'U2F support': u2f}
3430 summary_info += {'libusb': libusb}
3431 summary_info += {'usb net redir': usbredir}
3432 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
3433 summary_info += {'GBM': gbm}
3434 summary_info += {'libiscsi support': libiscsi}
3435 summary_info += {'libnfs support': libnfs}
3436 if targetos == 'windows'
3437 if config_host.has_key('CONFIG_GUEST_AGENT')
3438 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
3439 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
3442 summary_info += {'seccomp support': seccomp}
3443 summary_info += {'GlusterFS support': glusterfs}
3444 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
3445 summary_info += {'libssh support': libssh}
3446 summary_info += {'lzo support': lzo}
3447 summary_info += {'snappy support': snappy}
3448 summary_info += {'bzip2 support': libbzip2}
3449 summary_info += {'lzfse support': liblzfse}
3450 summary_info += {'zstd support': zstd}
3451 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
3452 summary_info += {'libxml2': libxml2}
3453 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3454 summary_info += {'libpmem support': libpmem}
3455 summary_info += {'libdaxctl support': libdaxctl}
3456 summary_info += {'libudev': libudev}
3457 # Dummy dependency, keep .found()
3458 summary_info += {'FUSE lseek': fuse_lseek.found()}
3459 summary_info += {'selinux': selinux}
3460 summary(summary_info, bool_yn: true, section: 'Dependencies')
3462 if not supported_cpus.contains(cpu)
3464 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3466 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3467 message('The QEMU project intends to remove support for this host CPU in')
3468 message('a future release if nobody volunteers to maintain it and to')
3469 message('provide a build host for our continuous integration setup.')
3470 message('configure has succeeded and you can continue to build, but')
3471 message('if you care about QEMU on this platform you should contact')
3472 message('us upstream at qemu-devel@nongnu.org.')
3475 if not supported_oses.contains(targetos)
3477 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3479 message('Host OS ' + targetos + 'support is not currently maintained.')
3480 message('The QEMU project intends to remove support for this host OS in')
3481 message('a future release if nobody volunteers to maintain it and to')
3482 message('provide a build host for our continuous integration setup.')
3483 message('configure has succeeded and you can continue to build, but')
3484 message('if you care about QEMU on this platform you should contact')
3485 message('us upstream at qemu-devel@nongnu.org.')