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 in ['x86', 'x86_64']
71 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
73 kvm_targets = ['aarch64-softmmu']
75 kvm_targets = ['s390x-softmmu']
76 elif cpu in ['ppc', 'ppc64']
77 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
78 elif cpu in ['mips', 'mips64']
79 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
85 if not get_option('kvm').disabled() and targetos == 'linux'
86 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
88 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
90 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
93 accelerator_targets += {
94 'CONFIG_HVF': ['aarch64-softmmu']
98 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
99 # i386 emulator provides xenpv machine type for multiple architectures
100 accelerator_targets += {
101 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
104 if cpu in ['x86', 'x86_64']
105 accelerator_targets += {
106 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
107 'CONFIG_HVF': ['x86_64-softmmu'],
108 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
109 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
114 # Darwin does not support references to thread-local variables in modules
115 if targetos != 'darwin'
116 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
119 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
120 unpack_edk2_blobs = false
121 foreach target : edk2_targets
122 if target in target_dirs
123 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
124 unpack_edk2_blobs = bzip2.found()
131 if 'dtrace' in get_option('trace_backends')
132 dtrace = find_program('dtrace', required: true)
133 stap = find_program('stap', required: false)
135 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
136 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
137 # instead. QEMU --enable-modules depends on this because the SystemTap
138 # semaphores are linked into the main binary and not the module's shared
140 add_global_arguments('-DSTAP_SDT_V2',
141 native: false, language: ['c', 'cpp', 'objc'])
149 # Specify linker-script with add_project_link_arguments so that it is not placed
150 # within a linker --start-group/--end-group pair
151 if get_option('fuzzing')
152 add_project_link_arguments(['-Wl,-T,',
153 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
154 native: false, language: ['c', 'cpp', 'objc'])
156 # Specify a filter to only instrument code that is directly related to
158 configure_file(output: 'instrumentation-filter',
159 input: 'scripts/oss-fuzz/instrumentation-filter-template',
161 add_global_arguments(
162 cc.get_supported_arguments('-fsanitize-coverage-allowlist=instrumentation-filter'),
163 native: false, language: ['c', 'cpp', 'objc'])
165 if get_option('fuzzing_engine') == ''
166 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
167 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
168 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
169 # unable to bind the fuzzer-related callbacks added by instrumentation.
170 add_global_arguments('-fsanitize=fuzzer-no-link',
171 native: false, language: ['c', 'cpp', 'objc'])
172 add_global_link_arguments('-fsanitize=fuzzer-no-link',
173 native: false, language: ['c', 'cpp', 'objc'])
174 # For the actual fuzzer binaries, we need to link against the libfuzzer
175 # library. They need to be configurable, to support OSS-Fuzz
176 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
178 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
179 # the needed CFLAGS have already been provided
180 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
184 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
185 native: false, language: ['c', 'objc'])
186 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
187 native: false, language: 'cpp')
188 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
189 native: false, language: ['c', 'cpp', 'objc'])
191 if targetos == 'linux'
192 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
193 '-isystem', 'linux-headers',
194 language: ['c', 'cpp'])
197 add_project_arguments('-iquote', '.',
198 '-iquote', meson.current_source_dir(),
199 '-iquote', meson.current_source_dir() / 'include',
200 '-iquote', meson.current_source_dir() / 'disas/libvixl',
201 language: ['c', 'cpp', 'objc'])
203 link_language = meson.get_external_property('link_language', 'cpp')
204 if link_language == 'cpp'
205 add_languages('cpp', required: true, native: false)
206 cxx = meson.get_compiler('cpp')
211 if host_machine.system() == 'darwin'
212 add_languages('objc', required: false, native: false)
215 sparse = find_program('cgcc', required: get_option('sparse'))
218 command: [find_program('scripts/check_sparse.py'),
219 'compile_commands.json', sparse.full_path(), '-Wbitwise',
220 '-Wno-transparent-union', '-Wno-old-initializer',
221 '-Wno-non-pointer-null'])
224 ###########################################
225 # Target-specific checks and dependencies #
226 ###########################################
228 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
231 #include <sys/types.h>
232 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
233 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
235 args: ['-Werror', '-fsanitize=fuzzer'])
236 error('Your compiler does not support -fsanitize=fuzzer')
239 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
240 error('ftrace is supported only on Linux')
242 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
245 openlog("qemu", LOG_PID, LOG_DAEMON);
246 syslog(LOG_INFO, "configure");
249 error('syslog is not supported on this system')
252 if targetos != 'linux' and get_option('mpath').enabled()
253 error('Multipath is supported only on Linux')
256 if targetos != 'linux' and get_option('multiprocess').enabled()
257 error('Multiprocess QEMU is supported only on Linux')
259 multiprocess_allowed = targetos == 'linux' and not get_option('multiprocess').disabled()
261 libm = cc.find_library('m', required: false)
262 threads = dependency('threads')
263 util = cc.find_library('util', required: false)
269 emulator_link_args = []
273 if targetos == 'windows'
274 socket = cc.find_library('ws2_32')
275 winmm = cc.find_library('winmm')
277 win = import('windows')
278 version_res = win.compile_resources('version.rc',
279 depend_files: files('pc-bios/qemu-nsis.ico'),
280 include_directories: include_directories('.'))
282 elif targetos == 'darwin'
283 coref = dependency('appleframeworks', modules: 'CoreFoundation')
284 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
285 host_dsosuf = '.dylib'
286 elif targetos == 'sunos'
287 socket = [cc.find_library('socket'),
288 cc.find_library('nsl'),
289 cc.find_library('resolv')]
290 elif targetos == 'haiku'
291 socket = [cc.find_library('posix_error_mapper'),
292 cc.find_library('network'),
293 cc.find_library('bsd')]
294 elif targetos == 'openbsd'
295 if not get_option('tcg').disabled() and target_dirs.length() > 0
296 # Disable OpenBSD W^X if available
297 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
302 if not get_option('kvm').disabled() and targetos == 'linux'
303 accelerators += 'CONFIG_KVM'
305 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
306 accelerators += 'CONFIG_XEN'
307 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
309 have_xen_pci_passthrough = false
311 if not get_option('whpx').disabled() and targetos == 'windows'
312 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
313 error('WHPX requires 64-bit host')
314 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
315 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
316 accelerators += 'CONFIG_WHPX'
319 if not get_option('hvf').disabled()
320 hvf = dependency('appleframeworks', modules: 'Hypervisor',
321 required: get_option('hvf'))
323 accelerators += 'CONFIG_HVF'
326 if not get_option('hax').disabled()
327 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
328 accelerators += 'CONFIG_HAX'
331 if targetos == 'netbsd'
332 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
334 accelerators += 'CONFIG_NVMM'
338 tcg_arch = config_host['ARCH']
339 if not get_option('tcg').disabled()
340 if cpu not in supported_cpus
341 if get_option('tcg_interpreter')
342 warning('Unsupported CPU @0@, will use TCG with TCI (slow)'.format(cpu))
344 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
346 elif get_option('tcg_interpreter')
347 warning('Use of the TCG interpreter is not recommended on this host')
348 warning('architecture. There is a native TCG execution backend available')
349 warning('which provides substantially better performance and reliability.')
350 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
351 warning('configuration option on this architecture to use the native')
354 if get_option('tcg_interpreter')
356 elif config_host['ARCH'] == 'sparc64'
358 elif config_host['ARCH'] in ['x86_64', 'x32']
360 elif config_host['ARCH'] == 'ppc64'
363 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
364 language: ['c', 'cpp', 'objc'])
366 accelerators += 'CONFIG_TCG'
367 config_host += { 'CONFIG_TCG': 'y' }
370 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
371 error('KVM not available on this platform')
373 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
374 error('HVF not available on this platform')
376 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
377 error('NVMM not available on this platform')
379 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
380 error('WHPX not available on this platform')
382 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
383 if 'CONFIG_XEN' in accelerators
384 error('Xen PCI passthrough not available on this platform')
386 error('Xen PCI passthrough requested but Xen not enabled')
394 # The path to glib.h is added to all compilation commands. This was
395 # grandfathered in from the QEMU Makefiles.
396 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
397 native: false, language: ['c', 'cpp', 'objc'])
398 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
399 link_args: config_host['GLIB_LIBS'].split())
400 # override glib dep with the configure results (for subprojects)
401 meson.override_dependency('glib-2.0', glib)
404 if 'CONFIG_GIO' in config_host
405 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
406 link_args: config_host['GIO_LIBS'].split())
409 if 'ust' in get_option('trace_backends')
410 lttng = dependency('lttng-ust', required: true, method: 'pkg-config',
411 kwargs: static_kwargs)
414 if have_system or have_tools
415 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
416 method: 'pkg-config', kwargs: static_kwargs)
418 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
421 if not get_option('linux_aio').auto() or have_block
422 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
423 required: get_option('linux_aio'),
424 kwargs: static_kwargs)
426 linux_io_uring = not_found
427 if not get_option('linux_io_uring').auto() or have_block
428 linux_io_uring = dependency('liburing', required: get_option('linux_io_uring'),
429 method: 'pkg-config', kwargs: static_kwargs)
432 if not get_option('libxml2').auto() or have_block
433 libxml2 = dependency('libxml-2.0', required: get_option('libxml2'),
434 method: 'pkg-config', kwargs: static_kwargs)
437 if not get_option('libnfs').auto() or have_block
438 libnfs = dependency('libnfs', version: '>=1.9.3',
439 required: get_option('libnfs'),
440 method: 'pkg-config', kwargs: static_kwargs)
445 #include <sys/types.h>
446 #ifdef CONFIG_LIBATTR
447 #include <attr/xattr.h>
449 #include <sys/xattr.h>
451 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
454 have_old_libattr = false
455 if not get_option('attr').disabled()
456 if cc.links(libattr_test)
457 libattr = declare_dependency()
459 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
460 required: get_option('attr'),
461 kwargs: static_kwargs)
462 if libattr.found() and not \
463 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
465 if get_option('attr').enabled()
466 error('could not link libattr')
468 warning('could not link libattr, disabling')
471 have_old_libattr = libattr.found()
476 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
477 if cocoa.found() and get_option('sdl').enabled()
478 error('Cocoa and SDL cannot be enabled at the same time')
480 if cocoa.found() and get_option('gtk').enabled()
481 error('Cocoa and GTK+ cannot be enabled at the same time')
485 if not get_option('seccomp').auto() or have_system or have_tools
486 seccomp = dependency('libseccomp', version: '>=2.3.0',
487 required: get_option('seccomp'),
488 method: 'pkg-config', kwargs: static_kwargs)
491 libcap_ng = not_found
492 if not get_option('cap_ng').auto() or have_system or have_tools
493 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
494 required: get_option('cap_ng'),
495 kwargs: static_kwargs)
497 if libcap_ng.found() and not cc.links('''
501 capng_capability_to_name(CAPNG_EFFECTIVE);
503 }''', dependencies: libcap_ng)
504 libcap_ng = not_found
505 if get_option('cap_ng').enabled()
506 error('could not link libcap-ng')
508 warning('could not link libcap-ng, disabling')
512 if get_option('xkbcommon').auto() and not have_system and not have_tools
513 xkbcommon = not_found
515 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
516 method: 'pkg-config', kwargs: static_kwargs)
520 if not get_option('vde').auto() or have_system or have_tools
521 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
522 required: get_option('vde'),
523 kwargs: static_kwargs)
525 if vde.found() and not cc.links('''
526 #include <libvdeplug.h>
529 struct vde_open_args a = {0, 0, 0};
533 }''', dependencies: vde)
535 if get_option('cap_ng').enabled()
536 error('could not link libvdeplug')
538 warning('could not link libvdeplug, disabling')
543 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
544 pulse = dependency('libpulse', required: get_option('pa'),
545 method: 'pkg-config', kwargs: static_kwargs)
548 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
549 alsa = dependency('alsa', required: get_option('alsa'),
550 method: 'pkg-config', kwargs: static_kwargs)
553 if not get_option('jack').auto() or have_system
554 jack = dependency('jack', required: get_option('jack'),
555 method: 'pkg-config', kwargs: static_kwargs)
558 spice_protocol = not_found
559 if not get_option('spice_protocol').auto() or have_system
560 spice_protocol = dependency('spice-protocol', version: '>=0.12.3',
561 required: get_option('spice_protocol'),
562 method: 'pkg-config', kwargs: static_kwargs)
565 if not get_option('spice').auto() or have_system
566 spice = dependency('spice-server', version: '>=0.12.5',
567 required: get_option('spice'),
568 method: 'pkg-config', kwargs: static_kwargs)
570 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
572 rt = cc.find_library('rt', required: false)
575 if not get_option('libiscsi').auto() or have_block
576 libiscsi = dependency('libiscsi', version: '>=1.9.0',
577 required: get_option('libiscsi'),
578 method: 'pkg-config', kwargs: static_kwargs)
581 if not get_option('zstd').auto() or have_block
582 zstd = dependency('libzstd', version: '>=1.4.0',
583 required: get_option('zstd'),
584 method: 'pkg-config', kwargs: static_kwargs)
587 if not get_option('virglrenderer').auto() or have_system
588 virgl = dependency('virglrenderer',
589 method: 'pkg-config',
590 required: get_option('virglrenderer'),
591 kwargs: static_kwargs)
594 if not get_option('curl').auto() or have_block
595 curl = dependency('libcurl', version: '>=7.29.0',
596 method: 'pkg-config',
597 required: get_option('curl'),
598 kwargs: static_kwargs)
601 if targetos == 'linux' and (have_system or have_tools)
602 libudev = dependency('libudev',
603 method: 'pkg-config',
604 required: get_option('libudev'),
605 kwargs: static_kwargs)
608 mpathlibs = [libudev]
609 mpathpersist = not_found
610 mpathpersist_new_api = false
611 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
612 mpath_test_source_new = '''
614 #include <mpath_persist.h>
615 unsigned mpath_mx_alloc_len = 1024;
617 static struct config *multipath_conf;
618 extern struct udev *udev;
619 extern struct config *get_multipath_config(void);
620 extern void put_multipath_config(struct config *conf);
622 struct config *get_multipath_config(void) { return multipath_conf; }
623 void put_multipath_config(struct config *conf) { }
626 multipath_conf = mpath_lib_init();
629 mpath_test_source_old = '''
631 #include <mpath_persist.h>
632 unsigned mpath_mx_alloc_len = 1024;
635 struct udev *udev = udev_new();
636 mpath_lib_init(udev);
639 libmpathpersist = cc.find_library('mpathpersist',
640 required: get_option('mpath'),
641 kwargs: static_kwargs)
642 if libmpathpersist.found()
643 mpathlibs += libmpathpersist
645 mpathlibs += cc.find_library('devmapper',
646 required: get_option('mpath'),
647 kwargs: static_kwargs)
649 mpathlibs += cc.find_library('multipath',
650 required: get_option('mpath'),
651 kwargs: static_kwargs)
652 foreach lib: mpathlibs
658 if mpathlibs.length() == 0
659 msg = 'Dependencies missing for libmpathpersist'
660 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
661 mpathpersist = declare_dependency(dependencies: mpathlibs)
662 mpathpersist_new_api = true
663 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
664 mpathpersist = declare_dependency(dependencies: mpathlibs)
666 msg = 'Cannot detect libmpathpersist API'
668 if not mpathpersist.found()
669 if get_option('mpath').enabled()
672 warning(msg + ', disabling')
680 if have_system and not get_option('curses').disabled()
682 #if defined(__APPLE__) || defined(__OpenBSD__)
683 #define _XOPEN_SOURCE_EXTENDED 1
690 setlocale(LC_ALL, "");
692 addwstr(L"wide chars\n");
694 add_wch(WACS_DEGREE);
698 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
699 foreach curses_dep : curses_dep_list
700 if not curses.found()
701 curses = dependency(curses_dep,
703 method: 'pkg-config',
704 kwargs: static_kwargs)
707 msg = get_option('curses').enabled() ? 'curses library not found' : ''
708 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
710 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
711 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
713 msg = 'curses package not usable'
717 if not curses.found()
718 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
719 if targetos != 'windows' and not has_curses_h
720 message('Trying with /usr/include/ncursesw')
721 curses_compile_args += ['-I/usr/include/ncursesw']
722 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
725 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
726 foreach curses_libname : curses_libname_list
727 libcurses = cc.find_library(curses_libname,
729 kwargs: static_kwargs)
731 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
732 curses = declare_dependency(compile_args: curses_compile_args,
733 dependencies: [libcurses])
736 msg = 'curses library not usable'
742 if not get_option('iconv').disabled()
743 foreach link_args : [ ['-liconv'], [] ]
744 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
745 # We need to use libiconv if available because mixing libiconv's headers with
746 # the system libc does not work.
747 # However, without adding glib to the dependencies -L/usr/local/lib will not be
748 # included in the command line and libiconv will not be found.
752 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
753 return conv != (iconv_t) -1;
754 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
755 iconv = declare_dependency(link_args: link_args, dependencies: glib)
760 if curses.found() and not iconv.found()
761 if get_option('iconv').enabled()
762 error('iconv not available')
764 msg = 'iconv required for curses UI but not available'
767 if not curses.found() and msg != ''
768 if get_option('curses').enabled()
771 warning(msg + ', disabling')
777 if not get_option('brlapi').auto() or have_system
778 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
779 required: get_option('brlapi'),
780 kwargs: static_kwargs)
781 if brlapi.found() and not cc.links('''
784 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
786 if get_option('brlapi').enabled()
787 error('could not link brlapi')
789 warning('could not link brlapi, disabling')
795 if not get_option('sdl').auto() or (have_system and not cocoa.found())
796 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
797 sdl_image = not_found
800 # work around 2.0.8 bug
801 sdl = declare_dependency(compile_args: '-Wno-undef',
803 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
804 method: 'pkg-config', kwargs: static_kwargs)
806 if get_option('sdl_image').enabled()
807 error('sdl-image required, but SDL was @0@'.format(
808 get_option('sdl').disabled() ? 'disabled' : 'not found'))
810 sdl_image = not_found
814 if not get_option('rbd').auto() or have_block
815 librados = cc.find_library('rados', required: get_option('rbd'),
816 kwargs: static_kwargs)
817 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
818 required: get_option('rbd'),
819 kwargs: static_kwargs)
820 if librados.found() and librbd.found()
823 #include <rbd/librbd.h>
826 rados_create(&cluster, NULL);
827 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
831 }''', dependencies: [librbd, librados])
832 rbd = declare_dependency(dependencies: [librbd, librados])
833 elif get_option('rbd').enabled()
834 error('librbd >= 1.12.0 required')
836 warning('librbd >= 1.12.0 not found, disabling')
841 glusterfs = not_found
842 glusterfs_ftruncate_has_stat = false
843 glusterfs_iocb_has_stat = false
844 if not get_option('glusterfs').auto() or have_block
845 glusterfs = dependency('glusterfs-api', version: '>=3',
846 required: get_option('glusterfs'),
847 method: 'pkg-config', kwargs: static_kwargs)
849 glusterfs_ftruncate_has_stat = cc.links('''
850 #include <glusterfs/api/glfs.h>
855 /* new glfs_ftruncate() passes two additional args */
856 return glfs_ftruncate(NULL, 0, NULL, NULL);
858 ''', dependencies: glusterfs)
859 glusterfs_iocb_has_stat = cc.links('''
860 #include <glusterfs/api/glfs.h>
862 /* new glfs_io_cbk() passes two additional glfs_stat structs */
864 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
870 glfs_io_cbk iocb = &glusterfs_iocb;
871 iocb(NULL, 0 , NULL, NULL, NULL);
874 ''', dependencies: glusterfs)
878 if 'CONFIG_LIBSSH' in config_host
879 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
880 link_args: config_host['LIBSSH_LIBS'].split())
883 if not get_option('bzip2').auto() or have_block
884 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
885 required: get_option('bzip2'),
886 kwargs: static_kwargs)
887 if libbzip2.found() and not cc.links('''
889 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
891 if get_option('bzip2').enabled()
892 error('could not link libbzip2')
894 warning('could not link libbzip2, disabling')
900 if not get_option('lzfse').auto() or have_block
901 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
902 required: get_option('lzfse'),
903 kwargs: static_kwargs)
905 if liblzfse.found() and not cc.links('''
907 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
909 if get_option('lzfse').enabled()
910 error('could not link liblzfse')
912 warning('could not link liblzfse, disabling')
917 if have_system and not get_option('oss').disabled()
918 if not cc.has_header('sys/soundcard.h')
920 elif targetos == 'netbsd'
921 oss = cc.find_library('ossaudio', required: get_option('oss'),
922 kwargs: static_kwargs)
924 oss = declare_dependency()
928 if get_option('oss').enabled()
929 error('OSS not found')
934 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
935 if cc.has_header('dsound.h')
936 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
939 if not dsound.found()
940 if get_option('dsound').enabled()
941 error('DirectSound not found')
946 coreaudio = not_found
947 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
948 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
949 required: get_option('coreaudio'))
953 if 'CONFIG_OPENGL' in config_host
954 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
955 link_args: config_host['OPENGL_LIBS'].split())
958 if (have_system or have_tools) and (virgl.found() or opengl.found())
959 gbm = dependency('gbm', method: 'pkg-config', required: false,
960 kwargs: static_kwargs)
964 gnutls_crypto = not_found
965 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
966 # For general TLS support our min gnutls matches
967 # that implied by our platform support matrix
969 # For the crypto backends, we look for a newer
972 # Version 3.6.8 is needed to get XTS
973 # Version 3.6.13 is needed to get PBKDF
974 # Version 3.6.14 is needed to get HW accelerated XTS
976 # If newer enough gnutls isn't available, we can
977 # still use a different crypto backend to satisfy
978 # the platform support requirements
979 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
980 method: 'pkg-config',
982 kwargs: static_kwargs)
983 if gnutls_crypto.found()
984 gnutls = gnutls_crypto
986 # Our min version if all we need is TLS
987 gnutls = dependency('gnutls', version: '>=3.5.18',
988 method: 'pkg-config',
989 required: get_option('gnutls'),
990 kwargs: static_kwargs)
994 # We prefer use of gnutls for crypto, unless the options
995 # explicitly asked for nettle or gcrypt.
997 # If gnutls isn't available for crypto, then we'll prefer
998 # gcrypt over nettle for performance reasons.
1003 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1004 error('Only one of gcrypt & nettle can be enabled')
1007 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1008 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1009 gnutls_crypto = not_found
1012 if not gnutls_crypto.found()
1013 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1014 gcrypt = dependency('libgcrypt', version: '>=1.8',
1015 method: 'config-tool',
1016 required: get_option('gcrypt'),
1017 kwargs: static_kwargs)
1018 # Debian has removed -lgpg-error from libgcrypt-config
1019 # as it "spreads unnecessary dependencies" which in
1020 # turn breaks static builds...
1021 if gcrypt.found() and enable_static
1022 gcrypt = declare_dependency(dependencies: [
1024 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
1027 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1028 nettle = dependency('nettle', version: '>=3.4',
1029 method: 'pkg-config',
1030 required: get_option('nettle'),
1031 kwargs: static_kwargs)
1032 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1041 if not get_option('gtk').auto() or (have_system and not cocoa.found())
1042 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1043 method: 'pkg-config',
1044 required: get_option('gtk'),
1045 kwargs: static_kwargs)
1047 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1048 method: 'pkg-config',
1050 kwargs: static_kwargs)
1051 gtk = declare_dependency(dependencies: [gtk, gtkx11])
1053 if not get_option('vte').auto() or have_system
1054 vte = dependency('vte-2.91',
1055 method: 'pkg-config',
1056 required: get_option('vte'),
1057 kwargs: static_kwargs)
1064 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
1065 kwargs: static_kwargs)
1071 if have_system and not get_option('vnc').disabled()
1072 vnc = declare_dependency() # dummy dependency
1073 png = dependency('libpng', required: get_option('vnc_png'),
1074 method: 'pkg-config', kwargs: static_kwargs)
1075 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1076 method: 'pkg-config', kwargs: static_kwargs)
1077 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1078 required: get_option('vnc_sasl'),
1079 kwargs: static_kwargs)
1081 sasl = declare_dependency(dependencies: sasl,
1082 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1087 if not get_option('auth_pam').auto() or have_system
1088 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1089 required: get_option('auth_pam'),
1090 kwargs: static_kwargs)
1092 if pam.found() and not cc.links('''
1094 #include <security/pam_appl.h>
1096 const char *service_name = "qemu";
1097 const char *user = "frank";
1098 const struct pam_conv pam_conv = { 0 };
1099 pam_handle_t *pamh = NULL;
1100 pam_start(service_name, user, &pam_conv, &pamh);
1102 }''', dependencies: pam)
1104 if get_option('auth_pam').enabled()
1105 error('could not link libpam')
1107 warning('could not link libpam, disabling')
1112 if not get_option('snappy').auto() or have_system
1113 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1114 required: get_option('snappy'),
1115 kwargs: static_kwargs)
1117 if snappy.found() and not linker.links('''
1118 #include <snappy-c.h>
1119 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1121 if get_option('snappy').enabled()
1122 error('could not link libsnappy')
1124 warning('could not link libsnappy, disabling')
1129 if not get_option('lzo').auto() or have_system
1130 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1131 required: get_option('lzo'),
1132 kwargs: static_kwargs)
1134 if lzo.found() and not cc.links('''
1135 #include <lzo/lzo1x.h>
1136 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1138 if get_option('lzo').enabled()
1139 error('could not link liblzo2')
1141 warning('could not link liblzo2, disabling')
1146 if 'CONFIG_RDMA' in config_host
1147 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
1150 if 'CONFIG_NUMA' in config_host
1151 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
1154 if 'CONFIG_XEN_BACKEND' in config_host
1155 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
1156 link_args: config_host['XEN_LIBS'].split())
1159 if not get_option('smartcard').auto() or have_system
1160 cacard = dependency('libcacard', required: get_option('smartcard'),
1161 version: '>=2.5.1', method: 'pkg-config',
1162 kwargs: static_kwargs)
1166 u2f = dependency('u2f-emu', required: get_option('u2f'),
1167 method: 'pkg-config',
1168 kwargs: static_kwargs)
1170 usbredir = not_found
1171 if not get_option('usb_redir').auto() or have_system
1172 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1173 version: '>=0.6', method: 'pkg-config',
1174 kwargs: static_kwargs)
1177 if not get_option('libusb').auto() or have_system
1178 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1179 version: '>=1.0.13', method: 'pkg-config',
1180 kwargs: static_kwargs)
1184 if not get_option('libpmem').auto() or have_system
1185 libpmem = dependency('libpmem', required: get_option('libpmem'),
1186 method: 'pkg-config', kwargs: static_kwargs)
1188 libdaxctl = not_found
1189 if not get_option('libdaxctl').auto() or have_system
1190 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1191 version: '>=57', method: 'pkg-config',
1192 kwargs: static_kwargs)
1196 tasn1 = dependency('libtasn1',
1197 method: 'pkg-config',
1198 kwargs: static_kwargs)
1200 keyutils = dependency('libkeyutils', required: false,
1201 method: 'pkg-config', kwargs: static_kwargs)
1203 has_gettid = cc.has_function('gettid')
1206 selinux = dependency('libselinux',
1207 required: get_option('selinux'),
1208 method: 'pkg-config', kwargs: static_kwargs)
1213 if get_option('malloc') == 'system'
1215 not get_option('malloc_trim').disabled() and \
1216 cc.links('''#include <malloc.h>
1217 int main(void) { malloc_trim(0); return 0; }''')
1219 has_malloc_trim = false
1220 malloc = cc.find_library(get_option('malloc'), required: true)
1222 if not has_malloc_trim and get_option('malloc_trim').enabled()
1223 if get_option('malloc') == 'system'
1224 error('malloc_trim not available on this platform.')
1226 error('malloc_trim not available with non-libc memory allocator')
1230 # Check whether the glibc provides statx()
1232 gnu_source_prefix = '''
1237 statx_test = gnu_source_prefix + '''
1238 #include <sys/stat.h>
1240 struct statx statxbuf;
1241 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1245 has_statx = cc.links(statx_test)
1247 have_vhost_user_blk_server = (targetos == 'linux' and
1248 'CONFIG_VHOST_USER' in config_host)
1250 if get_option('vhost_user_blk_server').enabled()
1251 if targetos != 'linux'
1252 error('vhost_user_blk_server requires linux')
1253 elif 'CONFIG_VHOST_USER' not in config_host
1254 error('vhost_user_blk_server requires vhost-user support')
1256 elif get_option('vhost_user_blk_server').disabled() or not have_system
1257 have_vhost_user_blk_server = false
1261 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1262 error('Cannot enable fuse-lseek while fuse is disabled')
1265 fuse = dependency('fuse3', required: get_option('fuse'),
1266 version: '>=3.1', method: 'pkg-config',
1267 kwargs: static_kwargs)
1269 fuse_lseek = not_found
1270 if not get_option('fuse_lseek').disabled()
1271 if fuse.version().version_compare('>=3.8')
1273 fuse_lseek = declare_dependency()
1274 elif get_option('fuse_lseek').enabled()
1276 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1278 error('fuse-lseek requires libfuse, which was not found')
1284 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1285 if libbpf.found() and not cc.links('''
1286 #include <bpf/libbpf.h>
1289 bpf_object__destroy_skeleton(NULL);
1291 }''', dependencies: libbpf)
1293 if get_option('bpf').enabled()
1294 error('libbpf skeleton test failed')
1296 warning('libbpf skeleton test failed, disabling')
1304 audio_drivers_selected = []
1306 audio_drivers_available = {
1307 'alsa': alsa.found(),
1308 'coreaudio': coreaudio.found(),
1309 'dsound': dsound.found(),
1310 'jack': jack.found(),
1312 'pa': pulse.found(),
1315 foreach k, v: audio_drivers_available
1316 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1319 # Default to native drivers first, OSS second, SDL third
1320 audio_drivers_priority = \
1321 [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
1322 (targetos == 'linux' ? [] : [ 'sdl' ])
1323 audio_drivers_default = []
1324 foreach k: audio_drivers_priority
1325 if audio_drivers_available[k]
1326 audio_drivers_default += k
1330 foreach k: get_option('audio_drv_list')
1332 audio_drivers_selected += audio_drivers_default
1333 elif not audio_drivers_available[k]
1334 error('Audio driver "@0@" not available.'.format(k))
1336 audio_drivers_selected += k
1340 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1341 '"' + '", "'.join(audio_drivers_selected) + '", ')
1343 if get_option('cfi')
1345 # Check for dependency on LTO
1346 if not get_option('b_lto')
1347 error('Selected Control-Flow Integrity but LTO is disabled')
1349 if config_host.has_key('CONFIG_MODULES')
1350 error('Selected Control-Flow Integrity is not compatible with modules')
1352 # Check for cfi flags. CFI requires LTO so we can't use
1353 # get_supported_arguments, but need a more complex "compiles" which allows
1355 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1356 args: ['-flto', '-fsanitize=cfi-icall'] )
1357 cfi_flags += '-fsanitize=cfi-icall'
1359 error('-fsanitize=cfi-icall is not supported by the compiler')
1361 if cc.compiles('int main () { return 0; }',
1362 name: '-fsanitize-cfi-icall-generalize-pointers',
1363 args: ['-flto', '-fsanitize=cfi-icall',
1364 '-fsanitize-cfi-icall-generalize-pointers'] )
1365 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1367 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1369 if get_option('cfi_debug')
1370 if cc.compiles('int main () { return 0; }',
1371 name: '-fno-sanitize-trap=cfi-icall',
1372 args: ['-flto', '-fsanitize=cfi-icall',
1373 '-fno-sanitize-trap=cfi-icall'] )
1374 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1376 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1379 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1380 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1383 have_host_block_device = (targetos != 'darwin' or
1384 cc.has_header('IOKit/storage/IOMedia.h'))
1386 have_virtfs = (targetos == 'linux' and
1391 have_virtfs_proxy_helper = have_virtfs and have_tools
1393 if get_option('virtfs').enabled()
1395 if targetos != 'linux'
1396 error('virtio-9p (virtfs) requires Linux')
1397 elif not libcap_ng.found() or not libattr.found()
1398 error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1399 elif not have_system
1400 error('virtio-9p (virtfs) needs system emulation support')
1403 elif get_option('virtfs').disabled()
1407 foreach k : get_option('trace_backends')
1408 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1410 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1412 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1413 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1414 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1415 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1416 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1417 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1418 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1419 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1420 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1421 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1422 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1423 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1425 config_host_data.set('CONFIG_ATTR', libattr.found())
1426 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1427 config_host_data.set('CONFIG_COCOA', cocoa.found())
1428 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1429 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1430 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1431 config_host_data.set('CONFIG_LZO', lzo.found())
1432 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1433 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1434 config_host_data.set('CONFIG_CURL', curl.found())
1435 config_host_data.set('CONFIG_CURSES', curses.found())
1436 config_host_data.set('CONFIG_GBM', gbm.found())
1437 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1438 if glusterfs.found()
1439 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1440 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1441 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1442 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1443 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1444 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1446 config_host_data.set('CONFIG_GTK', gtk.found())
1447 config_host_data.set('CONFIG_VTE', vte.found())
1448 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1449 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1450 config_host_data.set('CONFIG_EBPF', libbpf.found())
1451 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1452 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1453 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1454 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1455 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1456 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1457 config_host_data.set('CONFIG_RBD', rbd.found())
1458 config_host_data.set('CONFIG_SDL', sdl.found())
1459 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1460 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1461 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1462 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1463 config_host_data.set('CONFIG_VDE', vde.found())
1464 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1465 config_host_data.set('CONFIG_VNC', vnc.found())
1466 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1467 config_host_data.set('CONFIG_VNC_PNG', png.found())
1468 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1469 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1470 config_host_data.set('CONFIG_VTE', vte.found())
1471 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1472 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1473 config_host_data.set('CONFIG_GETTID', has_gettid)
1474 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1475 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1476 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1477 config_host_data.set('CONFIG_NETTLE', nettle.found())
1478 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1479 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1480 config_host_data.set('CONFIG_STATX', has_statx)
1481 config_host_data.set('CONFIG_ZSTD', zstd.found())
1482 config_host_data.set('CONFIG_FUSE', fuse.found())
1483 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1484 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1485 config_host_data.set('CONFIG_SPICE', spice.found())
1486 config_host_data.set('CONFIG_X11', x11.found())
1487 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1488 config_host_data.set('CONFIG_SELINUX', selinux.found())
1489 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1490 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1491 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1492 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1494 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1495 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1496 config_host_data.set('HOST_WORDS_BIGENDIAN', host_machine.endian() == 'big')
1499 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1500 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1501 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1502 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1503 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1504 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1505 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1506 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1507 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1510 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1511 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1512 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1513 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1514 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1515 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
1516 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1517 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1518 config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
1519 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1520 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1521 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1522 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1523 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1524 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1525 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1526 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1527 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1529 config_host_data.set('HAVE_IBV_ADVISE_MR',
1530 cc.has_function('ibv_advise_mr',
1531 args: config_host['RDMA_LIBS'].split(),
1532 prefix: '#include <infiniband/verbs.h>'))
1536 config_host_data.set('CONFIG_BYTESWAP_H',
1537 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1538 config_host_data.set('CONFIG_EPOLL_CREATE1',
1539 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1540 config_host_data.set('CONFIG_HAS_ENVIRON',
1541 cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix))
1542 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1543 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1544 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1545 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1546 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1547 config_host_data.set('CONFIG_FIEMAP',
1548 cc.has_header('linux/fiemap.h') and
1549 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1550 config_host_data.set('CONFIG_GETRANDOM',
1551 cc.has_function('getrandom') and
1552 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1553 config_host_data.set('CONFIG_INOTIFY',
1554 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1555 config_host_data.set('CONFIG_INOTIFY1',
1556 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1557 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1558 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1559 prefix: '''#include <sys/endian.h>
1560 #include <sys/types.h>'''))
1561 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1562 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1563 config_host_data.set('CONFIG_RTNETLINK',
1564 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1565 config_host_data.set('CONFIG_SYSMACROS',
1566 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1567 config_host_data.set('HAVE_OPTRESET',
1568 cc.has_header_symbol('getopt.h', 'optreset'))
1569 config_host_data.set('HAVE_IPPROTO_MPTCP',
1570 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1573 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1574 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1575 prefix: '#include <signal.h>'))
1576 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1577 cc.has_member('struct stat', 'st_atim',
1578 prefix: '#include <sys/stat.h>'))
1581 config_host_data.set('CONFIG_IOVEC',
1582 cc.has_type('struct iovec',
1583 prefix: '#include <sys/uio.h>'))
1584 config_host_data.set('HAVE_UTMPX',
1585 cc.has_type('struct utmpx',
1586 prefix: '#include <utmpx.h>'))
1588 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1589 #include <sys/eventfd.h>
1590 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1591 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1594 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1595 return fdatasync(0);
1597 #error Not supported
1600 config_host_data.set('CONFIG_MADVISE', cc.links(gnu_source_prefix + '''
1601 #include <sys/types.h>
1602 #include <sys/mman.h>
1604 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }'''))
1605 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1606 #include <sys/mman.h>
1607 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1608 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1610 #if !defined(AT_EMPTY_PATH)
1611 # error missing definition
1613 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1615 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1622 return pipe2(pipefd, O_CLOEXEC);
1624 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1625 #include <sys/mman.h>
1627 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1629 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
1630 #include <pthread.h>
1632 static void *f(void *p) { return NULL; }
1636 pthread_create(&thread, 0, f, 0);
1637 pthread_setname_np(thread, "QEMU");
1639 }''', dependencies: threads))
1640 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
1641 #include <pthread.h>
1643 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
1647 pthread_create(&thread, 0, f, 0);
1649 }''', dependencies: threads))
1651 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1652 #include <sys/signalfd.h>
1654 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1655 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1663 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1664 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1668 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
1669 #include <sys/mman.h>
1670 int main(int argc, char *argv[]) {
1671 return mlockall(MCL_FUTURE);
1675 if not get_option('l2tpv3').disabled() and have_system
1676 have_l2tpv3 = cc.has_type('struct mmsghdr',
1677 prefix: gnu_source_prefix + '''
1678 #include <sys/socket.h>
1679 #include <linux/ip.h>''')
1681 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
1684 if not get_option('netmap').disabled() and have_system
1685 have_netmap = cc.compiles('''
1686 #include <inttypes.h>
1688 #include <net/netmap.h>
1689 #include <net/netmap_user.h>
1690 #if (NETMAP_API < 11) || (NETMAP_API > 15)
1693 int main(void) { return 0; }''')
1694 if not have_netmap and get_option('netmap').enabled()
1695 error('Netmap headers not available')
1698 config_host_data.set('CONFIG_NETMAP', have_netmap)
1700 # Work around a system header bug with some kernel/XFS header
1701 # versions where they both try to define 'struct fsxattr':
1702 # xfs headers will not try to redefine structs from linux headers
1703 # if this macro is set.
1704 config_host_data.set('HAVE_FSXATTR', cc.links('''
1705 #include <linux/fs.h>
1711 # Some versions of Mac OS X incorrectly define SIZE_MAX
1712 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1715 int main(int argc, char *argv[]) {
1716 return printf("%zu", SIZE_MAX);
1717 }''', args: ['-Werror']))
1719 # See if 64-bit atomic operations are supported.
1720 # Note that without __atomic builtins, we can only
1721 # assume atomic loads/stores max at pointer size.
1722 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
1726 uint64_t x = 0, y = 0;
1727 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
1728 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
1729 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
1730 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
1731 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
1735 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
1736 #include <sys/auxv.h>
1738 return getauxval(AT_HWCAP) == 0;
1741 config_host_data.set('CONFIG_AF_VSOCK', cc.compiles(gnu_source_prefix + '''
1743 #include <sys/types.h>
1744 #include <sys/socket.h>
1745 #if !defined(AF_VSOCK)
1746 # error missing AF_VSOCK flag
1748 #include <linux/vm_sockets.h>
1751 struct sockaddr_vm svm;
1752 socklen_t len = sizeof(svm);
1753 sock = socket(AF_VSOCK, SOCK_STREAM, 0);
1754 ret = getpeername(sock, (struct sockaddr *)&svm, &len);
1755 if ((ret == -1) && (errno == ENOTCONN)) {
1761 ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target
1763 arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1764 strings = ['CONFIG_IASL']
1765 foreach k, v: config_host
1766 if ignored.contains(k)
1768 elif arrays.contains(k)
1770 v = '"' + '", "'.join(v.split()) + '", '
1772 config_host_data.set(k, v)
1774 config_host_data.set('HOST_' + v.to_upper(), 1)
1775 elif strings.contains(k)
1776 config_host_data.set_quoted(k, v)
1777 elif k.startswith('CONFIG_')
1778 config_host_data.set(k, v == 'y' ? 1 : v)
1782 ########################
1783 # Target configuration #
1784 ########################
1786 minikconf = find_program('scripts/minikconf.py')
1788 config_all_devices = {}
1789 config_all_disas = {}
1790 config_devices_mak_list = []
1791 config_devices_h = {}
1792 config_target_h = {}
1793 config_target_mak = {}
1796 'alpha' : ['CONFIG_ALPHA_DIS'],
1797 'arm' : ['CONFIG_ARM_DIS'],
1798 'avr' : ['CONFIG_AVR_DIS'],
1799 'cris' : ['CONFIG_CRIS_DIS'],
1800 'hexagon' : ['CONFIG_HEXAGON_DIS'],
1801 'hppa' : ['CONFIG_HPPA_DIS'],
1802 'i386' : ['CONFIG_I386_DIS'],
1803 'x86_64' : ['CONFIG_I386_DIS'],
1804 'x32' : ['CONFIG_I386_DIS'],
1805 'm68k' : ['CONFIG_M68K_DIS'],
1806 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1807 'mips' : ['CONFIG_MIPS_DIS'],
1808 'nios2' : ['CONFIG_NIOS2_DIS'],
1809 'or1k' : ['CONFIG_OPENRISC_DIS'],
1810 'ppc' : ['CONFIG_PPC_DIS'],
1811 'riscv' : ['CONFIG_RISCV_DIS'],
1812 'rx' : ['CONFIG_RX_DIS'],
1813 's390' : ['CONFIG_S390_DIS'],
1814 'sh4' : ['CONFIG_SH4_DIS'],
1815 'sparc' : ['CONFIG_SPARC_DIS'],
1816 'xtensa' : ['CONFIG_XTENSA_DIS'],
1818 if link_language == 'cpp'
1820 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1821 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1822 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1826 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
1828 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
1829 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1830 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
1831 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
1832 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1833 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1834 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1835 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1836 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1837 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1838 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1839 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1840 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1842 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1844 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1845 actual_target_dirs = []
1847 foreach target : target_dirs
1848 config_target = { 'TARGET_NAME': target.split('-')[0] }
1849 if target.endswith('linux-user')
1850 if targetos != 'linux'
1854 error('Target @0@ is only available on a Linux host'.format(target))
1856 config_target += { 'CONFIG_LINUX_USER': 'y' }
1857 elif target.endswith('bsd-user')
1858 if 'CONFIG_BSD' not in config_host
1862 error('Target @0@ is only available on a BSD host'.format(target))
1864 config_target += { 'CONFIG_BSD_USER': 'y' }
1865 elif target.endswith('softmmu')
1866 config_target += { 'CONFIG_SOFTMMU': 'y' }
1868 if target.endswith('-user')
1870 'CONFIG_USER_ONLY': 'y',
1871 'CONFIG_QEMU_INTERP_PREFIX':
1872 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1877 foreach sym: accelerators
1878 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1879 config_target += { sym: 'y' }
1880 config_all += { sym: 'y' }
1881 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1882 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1883 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1884 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1886 if target in modular_tcg
1887 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
1889 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
1891 accel_kconfig += [ sym + '=y' ]
1894 if accel_kconfig.length() == 0
1898 error('No accelerator available for target @0@'.format(target))
1901 actual_target_dirs += target
1902 config_target += keyval.load('configs/targets' / target + '.mak')
1903 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1905 if 'TARGET_NEED_FDT' in config_target
1906 fdt_required += target
1910 if 'TARGET_BASE_ARCH' not in config_target
1911 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1913 if 'TARGET_ABI_DIR' not in config_target
1914 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1917 foreach k, v: disassemblers
1918 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1920 config_target += { sym: 'y' }
1921 config_all_disas += { sym: 'y' }
1926 config_target_data = configuration_data()
1927 foreach k, v: config_target
1928 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1930 elif ignored.contains(k)
1932 elif k == 'TARGET_BASE_ARCH'
1933 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1934 # not used to select files from sourcesets.
1935 config_target_data.set('TARGET_' + v.to_upper(), 1)
1936 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1937 config_target_data.set_quoted(k, v)
1939 config_target_data.set(k, 1)
1941 config_target_data.set(k, v)
1944 config_target_data.set('QEMU_ARCH',
1945 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
1946 config_target_h += {target: configure_file(output: target + '-config-target.h',
1947 configuration: config_target_data)}
1949 if target.endswith('-softmmu')
1950 config_input = meson.get_external_property(target, 'default')
1951 config_devices_mak = target + '-config-devices.mak'
1952 config_devices_mak = configure_file(
1953 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
1954 output: config_devices_mak,
1955 depfile: config_devices_mak + '.d',
1957 command: [minikconf,
1958 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1959 config_devices_mak, '@DEPFILE@', '@INPUT@',
1960 host_kconfig, accel_kconfig,
1961 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
1963 config_devices_data = configuration_data()
1964 config_devices = keyval.load(config_devices_mak)
1965 foreach k, v: config_devices
1966 config_devices_data.set(k, 1)
1968 config_devices_mak_list += config_devices_mak
1969 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1970 configuration: config_devices_data)}
1971 config_target += config_devices
1972 config_all_devices += config_devices
1974 config_target_mak += {target: config_target}
1976 target_dirs = actual_target_dirs
1978 # This configuration is used to build files that are shared by
1979 # multiple binaries, and then extracted out of the "common"
1980 # static_library target.
1982 # We do not use all_sources()/all_dependencies(), because it would
1983 # build literally all source files, including devices only used by
1984 # targets that are not built for this compilation. The CONFIG_ALL
1985 # pseudo symbol replaces it.
1987 config_all += config_all_devices
1988 config_all += config_host
1989 config_all += config_all_disas
1991 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1992 'CONFIG_SOFTMMU': have_system,
1993 'CONFIG_USER_ONLY': have_user,
2001 capstone = not_found
2002 capstone_opt = get_option('capstone')
2003 if capstone_opt in ['enabled', 'auto', 'system']
2004 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
2005 capstone = dependency('capstone', version: '>=4.0',
2006 kwargs: static_kwargs, method: 'pkg-config',
2007 required: capstone_opt == 'system' or
2008 capstone_opt == 'enabled' and not have_internal)
2010 # Some versions of capstone have broken pkg-config file
2011 # that reports a wrong -I path, causing the #include to
2012 # fail later. If the system has such a broken version
2014 if capstone.found() and not cc.compiles('#include <capstone.h>',
2015 dependencies: [capstone])
2016 capstone = not_found
2017 if capstone_opt == 'system'
2018 error('system capstone requested, it does not appear to work')
2023 capstone_opt = 'system'
2025 capstone_opt = 'internal'
2027 capstone_opt = 'disabled'
2030 if capstone_opt == 'internal'
2031 capstone_data = configuration_data()
2032 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
2034 capstone_files = files(
2036 'capstone/MCInst.c',
2037 'capstone/MCInstrDesc.c',
2038 'capstone/MCRegisterInfo.c',
2039 'capstone/SStream.c',
2043 if 'CONFIG_ARM_DIS' in config_all_disas
2044 capstone_data.set('CAPSTONE_HAS_ARM', '1')
2045 capstone_files += files(
2046 'capstone/arch/ARM/ARMDisassembler.c',
2047 'capstone/arch/ARM/ARMInstPrinter.c',
2048 'capstone/arch/ARM/ARMMapping.c',
2049 'capstone/arch/ARM/ARMModule.c'
2053 # FIXME: This config entry currently depends on a c++ compiler.
2054 # Which is needed for building libvixl, but not for capstone.
2055 if 'CONFIG_ARM_A64_DIS' in config_all_disas
2056 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
2057 capstone_files += files(
2058 'capstone/arch/AArch64/AArch64BaseInfo.c',
2059 'capstone/arch/AArch64/AArch64Disassembler.c',
2060 'capstone/arch/AArch64/AArch64InstPrinter.c',
2061 'capstone/arch/AArch64/AArch64Mapping.c',
2062 'capstone/arch/AArch64/AArch64Module.c'
2066 if 'CONFIG_PPC_DIS' in config_all_disas
2067 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
2068 capstone_files += files(
2069 'capstone/arch/PowerPC/PPCDisassembler.c',
2070 'capstone/arch/PowerPC/PPCInstPrinter.c',
2071 'capstone/arch/PowerPC/PPCMapping.c',
2072 'capstone/arch/PowerPC/PPCModule.c'
2076 if 'CONFIG_S390_DIS' in config_all_disas
2077 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
2078 capstone_files += files(
2079 'capstone/arch/SystemZ/SystemZDisassembler.c',
2080 'capstone/arch/SystemZ/SystemZInstPrinter.c',
2081 'capstone/arch/SystemZ/SystemZMapping.c',
2082 'capstone/arch/SystemZ/SystemZModule.c',
2083 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
2087 if 'CONFIG_I386_DIS' in config_all_disas
2088 capstone_data.set('CAPSTONE_HAS_X86', 1)
2089 capstone_files += files(
2090 'capstone/arch/X86/X86Disassembler.c',
2091 'capstone/arch/X86/X86DisassemblerDecoder.c',
2092 'capstone/arch/X86/X86ATTInstPrinter.c',
2093 'capstone/arch/X86/X86IntelInstPrinter.c',
2094 'capstone/arch/X86/X86InstPrinterCommon.c',
2095 'capstone/arch/X86/X86Mapping.c',
2096 'capstone/arch/X86/X86Module.c'
2100 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
2103 # FIXME: There does not seem to be a way to completely replace the c_args
2104 # that come from add_project_arguments() -- we can only add to them.
2105 # So: disable all warnings with a big hammer.
2108 # Include all configuration defines via a header file, which will wind up
2109 # as a dependency on the object file, and thus changes here will result
2111 '-include', 'capstone-defs.h'
2114 libcapstone = static_library('capstone',
2115 build_by_default: false,
2116 sources: capstone_files,
2117 c_args: capstone_cargs,
2118 include_directories: 'capstone/include')
2119 capstone = declare_dependency(link_with: libcapstone,
2120 include_directories: 'capstone/include/capstone')
2124 slirp_opt = 'disabled'
2126 slirp_opt = get_option('slirp')
2127 if slirp_opt in ['enabled', 'auto', 'system']
2128 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2129 slirp = dependency('slirp', kwargs: static_kwargs,
2130 method: 'pkg-config',
2131 required: slirp_opt == 'system' or
2132 slirp_opt == 'enabled' and not have_internal)
2134 slirp_opt = 'system'
2136 slirp_opt = 'internal'
2138 slirp_opt = 'disabled'
2141 if slirp_opt == 'internal'
2143 if targetos == 'windows'
2144 slirp_deps = cc.find_library('iphlpapi')
2145 elif targetos == 'darwin'
2146 slirp_deps = cc.find_library('resolv')
2148 slirp_conf = configuration_data()
2149 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2150 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2151 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2152 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2153 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2155 'slirp/src/arp_table.c',
2156 'slirp/src/bootp.c',
2157 'slirp/src/cksum.c',
2158 'slirp/src/dhcpv6.c',
2159 'slirp/src/dnssearch.c',
2161 'slirp/src/ip6_icmp.c',
2162 'slirp/src/ip6_input.c',
2163 'slirp/src/ip6_output.c',
2164 'slirp/src/ip_icmp.c',
2165 'slirp/src/ip_input.c',
2166 'slirp/src/ip_output.c',
2170 'slirp/src/ndp_table.c',
2172 'slirp/src/slirp.c',
2173 'slirp/src/socket.c',
2174 'slirp/src/state.c',
2175 'slirp/src/stream.c',
2176 'slirp/src/tcp_input.c',
2177 'slirp/src/tcp_output.c',
2178 'slirp/src/tcp_subr.c',
2179 'slirp/src/tcp_timer.c',
2184 'slirp/src/version.c',
2185 'slirp/src/vmstate.c',
2189 input : 'slirp/src/libslirp-version.h.in',
2190 output : 'libslirp-version.h',
2191 configuration: slirp_conf)
2193 slirp_inc = include_directories('slirp', 'slirp/src')
2194 libslirp = static_library('slirp',
2195 build_by_default: false,
2196 sources: slirp_files,
2197 c_args: slirp_cargs,
2198 include_directories: slirp_inc)
2199 slirp = declare_dependency(link_with: libslirp,
2200 dependencies: slirp_deps,
2201 include_directories: slirp_inc)
2205 # For CFI, we need to compile slirp as a static library together with qemu.
2206 # This is because we register slirp functions as callbacks for QEMU Timers.
2207 # When using a system-wide shared libslirp, the type information for the
2208 # callback is missing and the timer call produces a false positive with CFI.
2210 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2211 # with control-flow integrity.
2212 if get_option('cfi') and slirp_opt == 'system'
2213 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2214 + ' Please configure with --enable-slirp=git')
2218 fdt_opt = get_option('fdt')
2220 if fdt_opt in ['enabled', 'auto', 'system']
2221 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2222 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2223 required: fdt_opt == 'system' or
2224 fdt_opt == 'enabled' and not have_internal)
2225 if fdt.found() and cc.links('''
2227 #include <libfdt_env.h>
2228 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
2231 elif fdt_opt == 'system'
2232 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2234 fdt_opt = 'internal'
2236 fdt_opt = 'disabled'
2240 if fdt_opt == 'internal'
2243 'dtc/libfdt/fdt_ro.c',
2244 'dtc/libfdt/fdt_wip.c',
2245 'dtc/libfdt/fdt_sw.c',
2246 'dtc/libfdt/fdt_rw.c',
2247 'dtc/libfdt/fdt_strerror.c',
2248 'dtc/libfdt/fdt_empty_tree.c',
2249 'dtc/libfdt/fdt_addresses.c',
2250 'dtc/libfdt/fdt_overlay.c',
2251 'dtc/libfdt/fdt_check.c',
2254 fdt_inc = include_directories('dtc/libfdt')
2255 libfdt = static_library('fdt',
2256 build_by_default: false,
2258 include_directories: fdt_inc)
2259 fdt = declare_dependency(link_with: libfdt,
2260 include_directories: fdt_inc)
2263 if not fdt.found() and fdt_required.length() > 0
2264 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2267 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2268 config_host_data.set('CONFIG_FDT', fdt.found())
2269 config_host_data.set('CONFIG_SLIRP', slirp.found())
2271 #####################
2272 # Generated sources #
2273 #####################
2275 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2277 hxtool = find_program('scripts/hxtool')
2278 shaderinclude = find_program('scripts/shaderinclude.pl')
2279 qapi_gen = find_program('scripts/qapi-gen.py')
2280 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2281 meson.current_source_dir() / 'scripts/qapi/commands.py',
2282 meson.current_source_dir() / 'scripts/qapi/common.py',
2283 meson.current_source_dir() / 'scripts/qapi/error.py',
2284 meson.current_source_dir() / 'scripts/qapi/events.py',
2285 meson.current_source_dir() / 'scripts/qapi/expr.py',
2286 meson.current_source_dir() / 'scripts/qapi/gen.py',
2287 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2288 meson.current_source_dir() / 'scripts/qapi/parser.py',
2289 meson.current_source_dir() / 'scripts/qapi/schema.py',
2290 meson.current_source_dir() / 'scripts/qapi/source.py',
2291 meson.current_source_dir() / 'scripts/qapi/types.py',
2292 meson.current_source_dir() / 'scripts/qapi/visit.py',
2293 meson.current_source_dir() / 'scripts/qapi/common.py',
2294 meson.current_source_dir() / 'scripts/qapi-gen.py'
2298 python, files('scripts/tracetool.py'),
2299 '--backend=' + ','.join(get_option('trace_backends'))
2301 tracetool_depends = files(
2302 'scripts/tracetool/backend/log.py',
2303 'scripts/tracetool/backend/__init__.py',
2304 'scripts/tracetool/backend/dtrace.py',
2305 'scripts/tracetool/backend/ftrace.py',
2306 'scripts/tracetool/backend/simple.py',
2307 'scripts/tracetool/backend/syslog.py',
2308 'scripts/tracetool/backend/ust.py',
2309 'scripts/tracetool/format/tcg_h.py',
2310 'scripts/tracetool/format/ust_events_c.py',
2311 'scripts/tracetool/format/ust_events_h.py',
2312 'scripts/tracetool/format/__init__.py',
2313 'scripts/tracetool/format/d.py',
2314 'scripts/tracetool/format/tcg_helper_c.py',
2315 'scripts/tracetool/format/simpletrace_stap.py',
2316 'scripts/tracetool/format/c.py',
2317 'scripts/tracetool/format/h.py',
2318 'scripts/tracetool/format/tcg_helper_h.py',
2319 'scripts/tracetool/format/log_stap.py',
2320 'scripts/tracetool/format/stap.py',
2321 'scripts/tracetool/format/tcg_helper_wrapper_h.py',
2322 'scripts/tracetool/__init__.py',
2323 'scripts/tracetool/transform.py',
2324 'scripts/tracetool/vcpu.py'
2327 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2328 meson.current_source_dir(),
2329 config_host['PKGVERSION'], meson.project_version()]
2330 qemu_version = custom_target('qemu-version.h',
2331 output: 'qemu-version.h',
2332 command: qemu_version_cmd,
2334 build_by_default: true,
2335 build_always_stale: true)
2336 genh += qemu_version
2340 ['qemu-options.hx', 'qemu-options.def'],
2341 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2345 ['hmp-commands.hx', 'hmp-commands.h'],
2346 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2349 foreach d : hx_headers
2350 hxdep += custom_target(d[1],
2354 build_by_default: true, # to be removed when added to a target
2355 command: [hxtool, '-h', '@INPUT0@'])
2363 authz_ss = ss.source_set()
2364 blockdev_ss = ss.source_set()
2365 block_ss = ss.source_set()
2366 bsd_user_ss = ss.source_set()
2367 chardev_ss = ss.source_set()
2368 common_ss = ss.source_set()
2369 crypto_ss = ss.source_set()
2370 hwcore_ss = ss.source_set()
2371 io_ss = ss.source_set()
2372 linux_user_ss = ss.source_set()
2373 qmp_ss = ss.source_set()
2374 qom_ss = ss.source_set()
2375 softmmu_ss = ss.source_set()
2376 specific_fuzz_ss = ss.source_set()
2377 specific_ss = ss.source_set()
2378 stub_ss = ss.source_set()
2379 trace_ss = ss.source_set()
2380 user_ss = ss.source_set()
2381 util_ss = ss.source_set()
2384 qtest_module_ss = ss.source_set()
2385 tcg_module_ss = ss.source_set()
2391 target_softmmu_arch = {}
2392 target_user_arch = {}
2398 # TODO: add each directory to the subdirs from its own meson.build, once
2400 trace_events_subdirs = [
2408 trace_events_subdirs += [ 'linux-user' ]
2411 trace_events_subdirs += [
2420 trace_events_subdirs += [
2434 'hw/block/dataplane',
2484 if have_system or have_user
2485 trace_events_subdirs += [
2502 vhost_user = not_found
2503 if 'CONFIG_VHOST_USER' in config_host
2504 libvhost_user = subproject('libvhost-user')
2505 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2520 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2521 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2524 stub_ss = stub_ss.apply(config_all, strict: false)
2526 util_ss.add_all(trace_ss)
2527 util_ss = util_ss.apply(config_all, strict: false)
2528 libqemuutil = static_library('qemuutil',
2529 sources: util_ss.sources() + stub_ss.sources() + genh,
2530 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2531 qemuutil = declare_dependency(link_with: libqemuutil,
2532 sources: genh + version_res)
2534 if have_system or have_user
2535 decodetree = generator(find_program('scripts/decodetree.py'),
2536 output: 'decode-@BASENAME@.c.inc',
2537 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2538 subdir('libdecnumber')
2555 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
2561 blockdev_ss.add(files(
2568 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2569 # os-win32.c does not
2570 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2571 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2574 common_ss.add(files('cpus-common.c'))
2578 common_ss.add(capstone)
2579 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2581 # Work around a gcc bug/misfeature wherein constant propagation looks
2583 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2584 # to guess that a const variable is always zero. Without lto, this is
2585 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2586 # without lto, not even the alias is required -- we simply use different
2587 # declarations in different compilation units.
2588 pagevary = files('page-vary-common.c')
2589 if get_option('b_lto')
2590 pagevary_flags = ['-fno-lto']
2591 if get_option('cfi')
2592 pagevary_flags += '-fno-sanitize=cfi-icall'
2594 pagevary = static_library('page-vary-common', sources: pagevary,
2595 c_args: pagevary_flags)
2596 pagevary = declare_dependency(link_with: pagevary)
2598 common_ss.add(pagevary)
2599 specific_ss.add(files('page-vary.c'))
2607 subdir('semihosting')
2614 subdir('linux-user')
2617 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
2619 linux_user_ss.add(files('thunk.c'))
2620 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
2622 # needed for fuzzing binaries
2623 subdir('tests/qtest/libqos')
2624 subdir('tests/qtest/fuzz')
2627 tcg_real_module_ss = ss.source_set()
2628 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
2629 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
2630 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
2631 'tcg': tcg_real_module_ss }}
2633 ########################
2634 # Library dependencies #
2635 ########################
2637 modinfo_collect = find_program('scripts/modinfo-collect.py')
2638 modinfo_generate = find_program('scripts/modinfo-generate.py')
2643 foreach d, list : modules
2644 foreach m, module_ss : list
2645 if enable_modules and targetos != 'windows'
2646 module_ss = module_ss.apply(config_all, strict: false)
2647 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2648 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2654 if module_ss.sources() != []
2655 # FIXME: Should use sl.extract_all_objects(recursive: true) as
2656 # input. Sources can be used multiple times but objects are
2657 # unique when it comes to lookup in compile_commands.json.
2658 # Depnds on a mesion version with
2659 # https://github.com/mesonbuild/meson/pull/8900
2660 modinfo_files += custom_target(d + '-' + m + '.modinfo',
2661 output: d + '-' + m + '.modinfo',
2662 input: module_ss.sources() + genh,
2664 command: [modinfo_collect, module_ss.sources()])
2668 block_ss.add_all(module_ss)
2670 softmmu_ss.add_all(module_ss)
2676 foreach d, list : target_modules
2677 foreach m, module_ss : list
2678 if enable_modules and targetos != 'windows'
2679 foreach target : target_dirs
2680 if target.endswith('-softmmu')
2681 config_target = config_target_mak[target]
2682 config_target += config_host
2683 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2684 c_args = ['-DNEED_CPU_H',
2685 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2686 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2687 target_module_ss = module_ss.apply(config_target, strict: false)
2688 if target_module_ss.sources() != []
2689 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
2690 sl = static_library(module_name,
2691 [genh, target_module_ss.sources()],
2692 dependencies: [modulecommon, target_module_ss.dependencies()],
2693 include_directories: target_inc,
2697 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
2698 modinfo_files += custom_target(module_name + '.modinfo',
2699 output: module_name + '.modinfo',
2700 input: target_module_ss.sources() + genh,
2702 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
2707 specific_ss.add_all(module_ss)
2713 modinfo_src = custom_target('modinfo.c',
2714 output: 'modinfo.c',
2715 input: modinfo_files,
2716 command: [modinfo_generate, '@INPUT@'],
2718 modinfo_lib = static_library('modinfo', modinfo_src)
2719 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
2720 softmmu_ss.add(modinfo_dep)
2723 nm = find_program('nm')
2724 undefsym = find_program('scripts/undefsym.py')
2725 block_syms = custom_target('block.syms', output: 'block.syms',
2726 input: [libqemuutil, block_mods],
2728 command: [undefsym, nm, '@INPUT@'])
2729 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2730 input: [libqemuutil, softmmu_mods],
2732 command: [undefsym, nm, '@INPUT@'])
2734 qom_ss = qom_ss.apply(config_host, strict: false)
2735 libqom = static_library('qom', qom_ss.sources() + genh,
2736 dependencies: [qom_ss.dependencies()],
2739 qom = declare_dependency(link_whole: libqom)
2741 authz_ss = authz_ss.apply(config_host, strict: false)
2742 libauthz = static_library('authz', authz_ss.sources() + genh,
2743 dependencies: [authz_ss.dependencies()],
2745 build_by_default: false)
2747 authz = declare_dependency(link_whole: libauthz,
2750 crypto_ss = crypto_ss.apply(config_host, strict: false)
2751 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2752 dependencies: [crypto_ss.dependencies()],
2754 build_by_default: false)
2756 crypto = declare_dependency(link_whole: libcrypto,
2757 dependencies: [authz, qom])
2759 io_ss = io_ss.apply(config_host, strict: false)
2760 libio = static_library('io', io_ss.sources() + genh,
2761 dependencies: [io_ss.dependencies()],
2762 link_with: libqemuutil,
2764 build_by_default: false)
2766 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2768 libmigration = static_library('migration', sources: migration_files + genh,
2770 build_by_default: false)
2771 migration = declare_dependency(link_with: libmigration,
2772 dependencies: [zlib, qom, io])
2773 softmmu_ss.add(migration)
2775 block_ss = block_ss.apply(config_host, strict: false)
2776 libblock = static_library('block', block_ss.sources() + genh,
2777 dependencies: block_ss.dependencies(),
2778 link_depends: block_syms,
2780 build_by_default: false)
2782 block = declare_dependency(link_whole: [libblock],
2783 link_args: '@block.syms',
2784 dependencies: [crypto, io])
2786 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2787 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2788 dependencies: blockdev_ss.dependencies(),
2790 build_by_default: false)
2792 blockdev = declare_dependency(link_whole: [libblockdev],
2793 dependencies: [block])
2795 qmp_ss = qmp_ss.apply(config_host, strict: false)
2796 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2797 dependencies: qmp_ss.dependencies(),
2799 build_by_default: false)
2801 qmp = declare_dependency(link_whole: [libqmp])
2803 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2805 dependencies: [gnutls],
2806 build_by_default: false)
2808 chardev = declare_dependency(link_whole: libchardev)
2810 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
2811 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
2813 build_by_default: false)
2814 hwcore = declare_dependency(link_whole: libhwcore)
2815 common_ss.add(hwcore)
2821 foreach m : block_mods + softmmu_mods
2822 shared_module(m.name(),
2826 install_dir: qemu_moddir)
2829 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2830 common_ss.add(qom, qemuutil)
2832 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2833 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2835 common_all = common_ss.apply(config_all, strict: false)
2836 common_all = static_library('common',
2837 build_by_default: false,
2838 sources: common_all.sources() + genh,
2839 implicit_include_directories: false,
2840 dependencies: common_all.dependencies(),
2843 feature_to_c = find_program('scripts/feature_to_c.sh')
2846 foreach target : target_dirs
2847 config_target = config_target_mak[target]
2848 target_name = config_target['TARGET_NAME']
2849 arch = config_target['TARGET_BASE_ARCH']
2850 arch_srcs = [config_target_h[target]]
2852 c_args = ['-DNEED_CPU_H',
2853 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2854 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2855 link_args = emulator_link_args
2857 config_target += config_host
2858 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2859 if targetos == 'linux'
2860 target_inc += include_directories('linux-headers', is_system: true)
2862 if target.endswith('-softmmu')
2863 qemu_target_name = 'qemu-system-' + target_name
2864 target_type='system'
2865 t = target_softmmu_arch[arch].apply(config_target, strict: false)
2866 arch_srcs += t.sources()
2867 arch_deps += t.dependencies()
2869 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2870 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2871 arch_srcs += hw.sources()
2872 arch_deps += hw.dependencies()
2874 arch_srcs += config_devices_h[target]
2875 link_args += ['@block.syms', '@qemu.syms']
2877 abi = config_target['TARGET_ABI_DIR']
2879 qemu_target_name = 'qemu-' + target_name
2880 if arch in target_user_arch
2881 t = target_user_arch[arch].apply(config_target, strict: false)
2882 arch_srcs += t.sources()
2883 arch_deps += t.dependencies()
2885 if 'CONFIG_LINUX_USER' in config_target
2886 base_dir = 'linux-user'
2887 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2889 if 'CONFIG_BSD_USER' in config_target
2890 base_dir = 'bsd-user'
2891 target_inc += include_directories('bsd-user/' / targetos)
2892 dir = base_dir / abi
2893 arch_srcs += files(dir / 'target_arch_cpu.c')
2895 target_inc += include_directories(
2899 if 'CONFIG_LINUX_USER' in config_target
2900 dir = base_dir / abi
2901 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2902 if config_target.has_key('TARGET_SYSTBL_ABI')
2904 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2905 extra_args : config_target['TARGET_SYSTBL_ABI'])
2910 if 'TARGET_XML_FILES' in config_target
2911 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2912 output: target + '-gdbstub-xml.c',
2913 input: files(config_target['TARGET_XML_FILES'].split()),
2914 command: [feature_to_c, '@INPUT@'],
2916 arch_srcs += gdbstub_xml
2919 t = target_arch[arch].apply(config_target, strict: false)
2920 arch_srcs += t.sources()
2921 arch_deps += t.dependencies()
2923 target_common = common_ss.apply(config_target, strict: false)
2924 objects = common_all.extract_objects(target_common.sources())
2925 deps = target_common.dependencies()
2927 target_specific = specific_ss.apply(config_target, strict: false)
2928 arch_srcs += target_specific.sources()
2929 arch_deps += target_specific.dependencies()
2931 lib = static_library('qemu-' + target,
2932 sources: arch_srcs + genh,
2933 dependencies: arch_deps,
2935 include_directories: target_inc,
2937 build_by_default: false,
2940 if target.endswith('-softmmu')
2942 'name': 'qemu-system-' + target_name,
2943 'win_subsystem': 'console',
2944 'sources': files('softmmu/main.c'),
2947 if targetos == 'windows' and (sdl.found() or gtk.found())
2949 'name': 'qemu-system-' + target_name + 'w',
2950 'win_subsystem': 'windows',
2951 'sources': files('softmmu/main.c'),
2955 if get_option('fuzzing')
2956 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2958 'name': 'qemu-fuzz-' + target_name,
2959 'win_subsystem': 'console',
2960 'sources': specific_fuzz.sources(),
2961 'dependencies': specific_fuzz.dependencies(),
2966 'name': 'qemu-' + target_name,
2967 'win_subsystem': 'console',
2973 exe_name = exe['name']
2974 if targetos == 'darwin'
2975 exe_name += '-unsigned'
2978 emulator = executable(exe_name, exe['sources'],
2981 dependencies: arch_deps + deps + exe['dependencies'],
2982 objects: lib.extract_all_objects(recursive: true),
2983 link_language: link_language,
2984 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2985 link_args: link_args,
2986 win_subsystem: exe['win_subsystem'])
2988 if targetos == 'darwin'
2989 icon = 'pc-bios/qemu.rsrc'
2990 build_input = [emulator, files(icon)]
2992 get_option('bindir') / exe_name,
2993 meson.current_source_dir() / icon
2995 if 'CONFIG_HVF' in config_target
2996 entitlements = 'accel/hvf/entitlements.plist'
2997 build_input += files(entitlements)
2998 install_input += meson.current_source_dir() / entitlements
3001 emulators += {exe['name'] : custom_target(exe['name'],
3003 output: exe['name'],
3005 files('scripts/entitlement.sh'),
3011 meson.add_install_script('scripts/entitlement.sh', '--install',
3012 get_option('bindir') / exe['name'],
3015 emulators += {exe['name']: emulator}
3020 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3021 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3022 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3023 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3025 custom_target(exe['name'] + stp['ext'],
3026 input: trace_events_all,
3027 output: exe['name'] + stp['ext'],
3028 install: stp['install'],
3029 install_dir: get_option('datadir') / 'systemtap/tapset',
3031 tracetool, '--group=all', '--format=' + stp['fmt'],
3032 '--binary=' + stp['bin'],
3033 '--target-name=' + target_name,
3034 '--target-type=' + target_type,
3035 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3036 '@INPUT@', '@OUTPUT@'
3038 depend_files: tracetool_depends)
3044 # Other build targets
3046 if 'CONFIG_PLUGIN' in config_host
3047 install_headers('include/qemu/qemu-plugin.h')
3050 if 'CONFIG_GUEST_AGENT' in config_host
3052 elif get_option('guest_agent_msi').enabled()
3053 error('Guest agent MSI requested, but the guest agent is not being built')
3056 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3057 # when we don't build tools or system
3058 if xkbcommon.found()
3059 # used for the update-keymaps target, so include rules even if !have_tools
3060 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3061 dependencies: [qemuutil, xkbcommon], install: have_tools)
3065 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3066 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3067 qemu_io = executable('qemu-io', files('qemu-io.c'),
3068 dependencies: [block, qemuutil], install: true)
3069 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3070 dependencies: [blockdev, qemuutil, gnutls, selinux],
3073 subdir('storage-daemon')
3074 subdir('contrib/rdmacm-mux')
3075 subdir('contrib/elf2dmp')
3077 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3078 dependencies: qemuutil,
3081 if 'CONFIG_VHOST_USER' in config_host
3082 subdir('contrib/vhost-user-blk')
3083 subdir('contrib/vhost-user-gpu')
3084 subdir('contrib/vhost-user-input')
3085 subdir('contrib/vhost-user-scsi')
3088 if targetos == 'linux'
3089 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3090 dependencies: [qemuutil, libcap_ng],
3092 install_dir: get_option('libexecdir'))
3094 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3095 dependencies: [authz, crypto, io, qom, qemuutil,
3096 libcap_ng, mpathpersist],
3101 subdir('contrib/ivshmem-client')
3102 subdir('contrib/ivshmem-server')
3115 if host_machine.system() == 'windows'
3117 find_program('scripts/nsis.py'),
3119 get_option('prefix'),
3120 meson.current_source_dir(),
3123 '-DDISPLAYVERSION=' + meson.project_version(),
3126 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3129 nsis_cmd += '-DCONFIG_GTK=y'
3132 nsis = custom_target('nsis',
3133 output: 'qemu-setup-' + meson.project_version() + '.exe',
3134 input: files('qemu.nsi'),
3135 build_always_stale: true,
3136 command: nsis_cmd + ['@INPUT@'])
3137 alias_target('installer', nsis)
3140 #########################
3141 # Configuration summary #
3142 #########################
3146 summary_info += {'Install prefix': get_option('prefix')}
3147 summary_info += {'BIOS directory': qemu_datadir}
3148 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
3149 summary_info += {'binary directory': get_option('bindir')}
3150 summary_info += {'library directory': get_option('libdir')}
3151 summary_info += {'module directory': qemu_moddir}
3152 summary_info += {'libexec directory': get_option('libexecdir')}
3153 summary_info += {'include directory': get_option('includedir')}
3154 summary_info += {'config directory': get_option('sysconfdir')}
3155 if targetos != 'windows'
3156 summary_info += {'local state directory': get_option('localstatedir')}
3157 summary_info += {'Manual directory': get_option('mandir')}
3159 summary_info += {'local state directory': 'queried at runtime'}
3161 summary_info += {'Doc directory': get_option('docdir')}
3162 summary_info += {'Build directory': meson.current_build_dir()}
3163 summary_info += {'Source path': meson.current_source_dir()}
3164 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3165 summary(summary_info, bool_yn: true, section: 'Directories')
3169 summary_info += {'git': config_host['GIT']}
3170 summary_info += {'make': config_host['MAKE']}
3171 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3172 summary_info += {'sphinx-build': sphinx_build}
3173 if config_host.has_key('HAVE_GDB_BIN')
3174 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3176 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3177 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
3178 summary_info += {'wixl': wixl}
3180 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
3181 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
3183 summary(summary_info, bool_yn: true, section: 'Host binaries')
3185 # Configurable features
3187 summary_info += {'Documentation': build_docs}
3188 summary_info += {'system-mode emulation': have_system}
3189 summary_info += {'user-mode emulation': have_user}
3190 summary_info += {'block layer': have_block}
3191 summary_info += {'Install blobs': get_option('install_blobs')}
3192 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3193 if config_host.has_key('CONFIG_MODULES')
3194 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
3196 summary_info += {'fuzzing support': get_option('fuzzing')}
3198 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3200 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3201 if 'simple' in get_option('trace_backends')
3202 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3204 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
3205 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
3206 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
3207 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
3208 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
3209 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
3210 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
3211 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3212 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
3213 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
3214 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
3215 summary(summary_info, bool_yn: true, section: 'Configurable features')
3217 # Compilation information
3219 summary_info += {'host CPU': cpu}
3220 summary_info += {'host endianness': build_machine.endian()}
3221 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3222 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3223 if link_language == 'cpp'
3224 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3226 summary_info += {'C++ compiler': false}
3228 if targetos == 'darwin'
3229 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3231 if targetos == 'windows'
3232 if 'WIN_SDK' in config_host
3233 summary_info += {'Windows SDK': config_host['WIN_SDK']}
3236 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3237 + ['-O' + get_option('optimization')]
3238 + (get_option('debug') ? ['-g'] : []))}
3239 if link_language == 'cpp'
3240 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3241 + ['-O' + get_option('optimization')]
3242 + (get_option('debug') ? ['-g'] : []))}
3244 link_args = get_option(link_language + '_link_args')
3245 if link_args.length() > 0
3246 summary_info += {'LDFLAGS': ' '.join(link_args)}
3248 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
3249 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
3250 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
3251 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3252 summary_info += {'PIE': get_option('b_pie')}
3253 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3254 summary_info += {'malloc trim support': has_malloc_trim}
3255 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
3256 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
3257 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
3258 summary_info += {'memory allocator': get_option('malloc')}
3259 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
3260 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
3261 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
3262 summary_info += {'gcov': get_option('b_coverage')}
3263 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3264 summary_info += {'CFI support': get_option('cfi')}
3265 if get_option('cfi')
3266 summary_info += {'CFI debug support': get_option('cfi_debug')}
3268 summary_info += {'strip binaries': get_option('strip')}
3269 summary_info += {'sparse': sparse}
3270 summary_info += {'mingw32 support': targetos == 'windows'}
3272 # snarf the cross-compilation information for tests
3273 foreach target: target_dirs
3274 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3275 if fs.exists(tcg_mak)
3276 config_cross_tcg = keyval.load(tcg_mak)
3277 target = config_cross_tcg['TARGET_NAME']
3279 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3280 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3281 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3282 elif 'CROSS_CC_GUEST' in config_cross_tcg
3283 summary_info += {target + ' tests'
3284 : config_cross_tcg['CROSS_CC_GUEST'] }
3289 summary(summary_info, bool_yn: true, section: 'Compilation')
3291 # Targets and accelerators
3294 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3295 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3296 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3297 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3298 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3299 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
3300 if config_host.has_key('CONFIG_XEN_BACKEND')
3301 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
3304 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3305 if config_all.has_key('CONFIG_TCG')
3306 if get_option('tcg_interpreter')
3307 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
3309 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3311 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3312 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3314 summary_info += {'target list': ' '.join(target_dirs)}
3316 summary_info += {'default devices': get_option('default_devices')}
3317 summary_info += {'out of process emulation': multiprocess_allowed}
3319 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3323 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3324 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
3326 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3327 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3328 summary_info += {'Use block whitelist in tools': config_host.has_key('CONFIG_BDRV_WHITELIST_TOOLS')}
3329 summary_info += {'VirtFS support': have_virtfs}
3330 summary_info += {'build virtiofs daemon': have_virtiofsd}
3331 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
3332 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
3333 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
3334 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
3335 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
3336 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
3337 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
3338 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
3339 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
3340 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
3341 summary_info += {'FUSE exports': fuse}
3343 summary(summary_info, bool_yn: true, section: 'Block layer support')
3347 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
3348 summary_info += {'GNUTLS support': gnutls}
3350 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3352 summary_info += {'libgcrypt': gcrypt}
3353 summary_info += {'nettle': nettle}
3355 summary_info += {' XTS': xts != 'private'}
3357 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
3358 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
3359 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
3360 summary(summary_info, bool_yn: true, section: 'Crypto')
3364 if targetos == 'darwin'
3365 summary_info += {'Cocoa support': cocoa}
3367 summary_info += {'SDL support': sdl}
3368 summary_info += {'SDL image support': sdl_image}
3369 summary_info += {'GTK support': gtk}
3370 summary_info += {'pixman': pixman}
3371 summary_info += {'VTE support': vte}
3372 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3373 summary_info += {'libtasn1': tasn1}
3374 summary_info += {'PAM': pam}
3375 summary_info += {'iconv support': iconv}
3376 summary_info += {'curses support': curses}
3377 summary_info += {'virgl support': virgl}
3378 summary_info += {'curl support': curl}
3379 summary_info += {'Multipath support': mpathpersist}
3380 summary_info += {'VNC support': vnc}
3382 summary_info += {'VNC SASL support': sasl}
3383 summary_info += {'VNC JPEG support': jpeg}
3384 summary_info += {'VNC PNG support': png}
3386 if targetos not in ['darwin', 'haiku', 'windows']
3387 summary_info += {'OSS support': oss}
3388 elif targetos == 'darwin'
3389 summary_info += {'CoreAudio support': coreaudio}
3390 elif targetos == 'windows'
3391 summary_info += {'DirectSound support': dsound}
3393 if targetos == 'linux'
3394 summary_info += {'ALSA support': alsa}
3395 summary_info += {'PulseAudio support': pulse}
3397 summary_info += {'JACK support': jack}
3398 summary_info += {'brlapi support': brlapi}
3399 summary_info += {'vde support': vde}
3400 summary_info += {'netmap support': have_netmap}
3401 summary_info += {'l2tpv3 support': have_l2tpv3}
3402 summary_info += {'Linux AIO support': libaio}
3403 summary_info += {'Linux io_uring support': linux_io_uring}
3404 summary_info += {'ATTR/XATTR support': libattr}
3405 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
3406 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
3407 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3408 summary_info += {'libcap-ng support': libcap_ng}
3409 summary_info += {'bpf support': libbpf}
3410 summary_info += {'spice protocol support': spice_protocol}
3411 if spice_protocol.found()
3412 summary_info += {' spice server support': spice}
3414 summary_info += {'rbd support': rbd}
3415 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
3416 summary_info += {'smartcard support': cacard}
3417 summary_info += {'U2F support': u2f}
3418 summary_info += {'libusb': libusb}
3419 summary_info += {'usb net redir': usbredir}
3420 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
3421 summary_info += {'GBM': gbm}
3422 summary_info += {'libiscsi support': libiscsi}
3423 summary_info += {'libnfs support': libnfs}
3424 if targetos == 'windows'
3425 if config_host.has_key('CONFIG_GUEST_AGENT')
3426 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
3427 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
3430 summary_info += {'seccomp support': seccomp}
3431 summary_info += {'GlusterFS support': glusterfs}
3432 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
3433 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
3434 summary_info += {'lzo support': lzo}
3435 summary_info += {'snappy support': snappy}
3436 summary_info += {'bzip2 support': libbzip2}
3437 summary_info += {'lzfse support': liblzfse}
3438 summary_info += {'zstd support': zstd}
3439 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
3440 summary_info += {'libxml2': libxml2}
3441 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3442 summary_info += {'libpmem support': libpmem}
3443 summary_info += {'libdaxctl support': libdaxctl}
3444 summary_info += {'libudev': libudev}
3445 # Dummy dependency, keep .found()
3446 summary_info += {'FUSE lseek': fuse_lseek.found()}
3447 summary_info += {'selinux': selinux}
3448 summary(summary_info, bool_yn: true, section: 'Dependencies')
3450 if not supported_cpus.contains(cpu)
3452 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3454 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3455 message('The QEMU project intends to remove support for this host CPU in')
3456 message('a future release if nobody volunteers to maintain it and to')
3457 message('provide a build host for our continuous integration setup.')
3458 message('configure has succeeded and you can continue to build, but')
3459 message('if you care about QEMU on this platform you should contact')
3460 message('us upstream at qemu-devel@nongnu.org.')
3463 if not supported_oses.contains(targetos)
3465 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3467 message('Host OS ' + targetos + 'support is not currently maintained.')
3468 message('The QEMU project intends to remove support for this host OS in')
3469 message('a future release if nobody volunteers to maintain it and to')
3470 message('provide a build host for our continuous integration setup.')
3471 message('configure has succeeded and you can continue to build, but')
3472 message('if you care about QEMU on this platform you should contact')
3473 message('us upstream at qemu-devel@nongnu.org.')