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',
3 'b_staticpic=false', 'stdsplit=false'],
4 version: files('VERSION'))
6 add_test_setup('quick', exclude_suites: 'slow', is_default: true)
7 add_test_setup('slow', env: ['G_TEST_SLOW=1', 'SPEED=slow'])
9 not_found = dependency('', required: false)
10 keyval = import('keyval')
11 ss = import('sourceset')
14 sh = find_program('sh')
15 cc = meson.get_compiler('c')
16 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
17 enable_modules = 'CONFIG_MODULES' in config_host
18 enable_static = 'CONFIG_STATIC' in config_host
20 # Allow both shared and static libraries unless --enable-static
21 static_kwargs = enable_static ? {'static': true} : {}
23 # Temporary directory used for files created while
24 # configure runs. Since it is in the build directory
25 # we can safely blow away any previous version of it
26 # (and we need not jump through hoops to try to delete
27 # it when configure exits.)
28 tmpdir = meson.current_build_dir() / 'meson-private/temp'
30 if get_option('qemu_suffix').startswith('/')
31 error('qemu_suffix cannot start with a /')
34 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
35 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
36 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
37 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
39 qemu_desktopdir = get_option('datadir') / 'applications'
40 qemu_icondir = get_option('datadir') / 'icons'
42 config_host_data = configuration_data()
45 target_dirs = config_host['TARGET_DIRS'].split()
46 have_linux_user = false
49 foreach target : target_dirs
50 have_linux_user = have_linux_user or target.endswith('linux-user')
51 have_bsd_user = have_bsd_user or target.endswith('bsd-user')
52 have_system = have_system or target.endswith('-softmmu')
54 have_user = have_linux_user or have_bsd_user
55 have_tools = 'CONFIG_TOOLS' in config_host
56 have_block = have_system or have_tools
58 python = import('python').find_installation()
60 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
61 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
62 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc', 'sparc64']
64 cpu = host_machine.cpu_family()
66 # Unify riscv* to a single family.
67 if cpu in ['riscv32', 'riscv64']
71 targetos = host_machine.system()
73 if cpu not in supported_cpus
83 if cpu in ['x86', 'x86_64']
84 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
86 kvm_targets = ['aarch64-softmmu']
88 kvm_targets = ['s390x-softmmu']
89 elif cpu in ['ppc', 'ppc64']
90 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
91 elif cpu in ['mips', 'mips64']
92 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
98 if not get_option('kvm').disabled() and targetos == 'linux'
99 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
101 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
103 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
105 if cpu in ['aarch64']
106 accelerator_targets += {
107 'CONFIG_HVF': ['aarch64-softmmu']
111 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
112 # i386 emulator provides xenpv machine type for multiple architectures
113 accelerator_targets += {
114 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
117 if cpu in ['x86', 'x86_64']
118 accelerator_targets += {
119 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
120 'CONFIG_HVF': ['x86_64-softmmu'],
121 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
122 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
127 # Darwin does not support references to thread-local variables in modules
128 if targetos != 'darwin'
129 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
132 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
133 unpack_edk2_blobs = false
134 foreach target : edk2_targets
135 if target in target_dirs
136 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
137 unpack_edk2_blobs = bzip2.found()
144 if 'dtrace' in get_option('trace_backends')
145 dtrace = find_program('dtrace', required: true)
146 stap = find_program('stap', required: false)
148 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
149 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
150 # instead. QEMU --enable-modules depends on this because the SystemTap
151 # semaphores are linked into the main binary and not the module's shared
153 add_global_arguments('-DSTAP_SDT_V2',
154 native: false, language: ['c', 'cpp', 'objc'])
162 # Specify linker-script with add_project_link_arguments so that it is not placed
163 # within a linker --start-group/--end-group pair
164 if get_option('fuzzing')
165 add_project_link_arguments(['-Wl,-T,',
166 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
167 native: false, language: ['c', 'cpp', 'objc'])
169 # Specify a filter to only instrument code that is directly related to
171 configure_file(output: 'instrumentation-filter',
172 input: 'scripts/oss-fuzz/instrumentation-filter-template',
174 add_global_arguments(
175 cc.get_supported_arguments('-fsanitize-coverage-allowlist=instrumentation-filter'),
176 native: false, language: ['c', 'cpp', 'objc'])
178 if get_option('fuzzing_engine') == ''
179 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
180 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
181 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
182 # unable to bind the fuzzer-related callbacks added by instrumentation.
183 add_global_arguments('-fsanitize=fuzzer-no-link',
184 native: false, language: ['c', 'cpp', 'objc'])
185 add_global_link_arguments('-fsanitize=fuzzer-no-link',
186 native: false, language: ['c', 'cpp', 'objc'])
187 # For the actual fuzzer binaries, we need to link against the libfuzzer
188 # library. They need to be configurable, to support OSS-Fuzz
189 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
191 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
192 # the needed CFLAGS have already been provided
193 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
197 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
198 native: false, language: ['c', 'objc'])
199 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
200 native: false, language: 'cpp')
201 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
202 native: false, language: ['c', 'cpp', 'objc'])
204 if targetos == 'linux'
205 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
206 '-isystem', 'linux-headers',
207 language: ['c', 'cpp'])
210 add_project_arguments('-iquote', '.',
211 '-iquote', meson.current_source_dir(),
212 '-iquote', meson.current_source_dir() / 'include',
213 '-iquote', meson.current_source_dir() / 'disas/libvixl',
214 language: ['c', 'cpp', 'objc'])
216 link_language = meson.get_external_property('link_language', 'cpp')
217 if link_language == 'cpp'
218 add_languages('cpp', required: true, native: false)
219 cxx = meson.get_compiler('cpp')
224 if host_machine.system() == 'darwin'
225 add_languages('objc', required: false, native: false)
228 sparse = find_program('cgcc', required: get_option('sparse'))
231 command: [find_program('scripts/check_sparse.py'),
232 'compile_commands.json', sparse.full_path(), '-Wbitwise',
233 '-Wno-transparent-union', '-Wno-old-initializer',
234 '-Wno-non-pointer-null'])
237 ###########################################
238 # Target-specific checks and dependencies #
239 ###########################################
241 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
244 #include <sys/types.h>
245 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
246 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
248 args: ['-Werror', '-fsanitize=fuzzer'])
249 error('Your compiler does not support -fsanitize=fuzzer')
252 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
253 error('ftrace is supported only on Linux')
255 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
258 openlog("qemu", LOG_PID, LOG_DAEMON);
259 syslog(LOG_INFO, "configure");
262 error('syslog is not supported on this system')
265 if targetos != 'linux' and get_option('mpath').enabled()
266 error('Multipath is supported only on Linux')
269 if targetos != 'linux' and get_option('multiprocess').enabled()
270 error('Multiprocess QEMU is supported only on Linux')
272 multiprocess_allowed = targetos == 'linux' and not get_option('multiprocess').disabled()
274 libm = cc.find_library('m', required: false)
275 threads = dependency('threads')
276 util = cc.find_library('util', required: false)
282 emulator_link_args = []
286 if targetos == 'windows'
287 socket = cc.find_library('ws2_32')
288 winmm = cc.find_library('winmm')
290 win = import('windows')
291 version_res = win.compile_resources('version.rc',
292 depend_files: files('pc-bios/qemu-nsis.ico'),
293 include_directories: include_directories('.'))
295 elif targetos == 'darwin'
296 coref = dependency('appleframeworks', modules: 'CoreFoundation')
297 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
298 host_dsosuf = '.dylib'
299 elif targetos == 'sunos'
300 socket = [cc.find_library('socket'),
301 cc.find_library('nsl'),
302 cc.find_library('resolv')]
303 elif targetos == 'haiku'
304 socket = [cc.find_library('posix_error_mapper'),
305 cc.find_library('network'),
306 cc.find_library('bsd')]
307 elif targetos == 'openbsd'
308 if not get_option('tcg').disabled() and target_dirs.length() > 0
309 # Disable OpenBSD W^X if available
310 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
315 if not get_option('kvm').disabled() and targetos == 'linux'
316 accelerators += 'CONFIG_KVM'
318 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
319 accelerators += 'CONFIG_XEN'
320 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
322 have_xen_pci_passthrough = false
324 if not get_option('whpx').disabled() and targetos == 'windows'
325 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
326 error('WHPX requires 64-bit host')
327 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
328 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
329 accelerators += 'CONFIG_WHPX'
332 if not get_option('hvf').disabled()
333 hvf = dependency('appleframeworks', modules: 'Hypervisor',
334 required: get_option('hvf'))
336 accelerators += 'CONFIG_HVF'
339 if not get_option('hax').disabled()
340 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
341 accelerators += 'CONFIG_HAX'
344 if targetos == 'netbsd'
345 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
347 accelerators += 'CONFIG_NVMM'
352 if not get_option('tcg').disabled()
353 if host_arch == 'unknown'
354 if get_option('tcg_interpreter')
355 warning('Unsupported CPU @0@, will use TCG with TCI (slow)'.format(cpu))
357 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
359 elif get_option('tcg_interpreter')
360 warning('Use of the TCG interpreter is not recommended on this host')
361 warning('architecture. There is a native TCG execution backend available')
362 warning('which provides substantially better performance and reliability.')
363 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
364 warning('configuration option on this architecture to use the native')
367 if get_option('tcg_interpreter')
369 elif host_arch == 'sparc64'
371 elif host_arch == 'x86_64'
373 elif host_arch == 'ppc64'
376 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
377 language: ['c', 'cpp', 'objc'])
379 accelerators += 'CONFIG_TCG'
380 config_host += { 'CONFIG_TCG': 'y' }
383 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
384 error('KVM not available on this platform')
386 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
387 error('HVF not available on this platform')
389 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
390 error('NVMM not available on this platform')
392 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
393 error('WHPX not available on this platform')
395 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
396 if 'CONFIG_XEN' in accelerators
397 error('Xen PCI passthrough not available on this platform')
399 error('Xen PCI passthrough requested but Xen not enabled')
407 # The path to glib.h is added to all compilation commands. This was
408 # grandfathered in from the QEMU Makefiles.
409 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
410 native: false, language: ['c', 'cpp', 'objc'])
411 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
412 link_args: config_host['GLIB_LIBS'].split(),
413 version: config_host['GLIB_VERSION'])
414 # override glib dep with the configure results (for subprojects)
415 meson.override_dependency('glib-2.0', glib)
418 if 'CONFIG_GIO' in config_host
419 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
420 link_args: config_host['GIO_LIBS'].split(),
421 version: config_host['GLIB_VERSION'])
424 if 'ust' in get_option('trace_backends')
425 lttng = dependency('lttng-ust', required: true, method: 'pkg-config',
426 kwargs: static_kwargs)
429 if have_system or have_tools
430 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
431 method: 'pkg-config', kwargs: static_kwargs)
433 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
436 if not get_option('linux_aio').auto() or have_block
437 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
438 required: get_option('linux_aio'),
439 kwargs: static_kwargs)
441 linux_io_uring = not_found
442 if not get_option('linux_io_uring').auto() or have_block
443 linux_io_uring = dependency('liburing', required: get_option('linux_io_uring'),
444 method: 'pkg-config', kwargs: static_kwargs)
447 if not get_option('libxml2').auto() or have_block
448 libxml2 = dependency('libxml-2.0', required: get_option('libxml2'),
449 method: 'pkg-config', kwargs: static_kwargs)
452 if not get_option('libnfs').auto() or have_block
453 libnfs = dependency('libnfs', version: '>=1.9.3',
454 required: get_option('libnfs'),
455 method: 'pkg-config', kwargs: static_kwargs)
460 #include <sys/types.h>
461 #ifdef CONFIG_LIBATTR
462 #include <attr/xattr.h>
464 #include <sys/xattr.h>
466 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
469 have_old_libattr = false
470 if not get_option('attr').disabled()
471 if cc.links(libattr_test)
472 libattr = declare_dependency()
474 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
475 required: get_option('attr'),
476 kwargs: static_kwargs)
477 if libattr.found() and not \
478 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
480 if get_option('attr').enabled()
481 error('could not link libattr')
483 warning('could not link libattr, disabling')
486 have_old_libattr = libattr.found()
491 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
492 if cocoa.found() and get_option('sdl').enabled()
493 error('Cocoa and SDL cannot be enabled at the same time')
495 if cocoa.found() and get_option('gtk').enabled()
496 error('Cocoa and GTK+ cannot be enabled at the same time')
500 if not get_option('seccomp').auto() or have_system or have_tools
501 seccomp = dependency('libseccomp', version: '>=2.3.0',
502 required: get_option('seccomp'),
503 method: 'pkg-config', kwargs: static_kwargs)
506 libcap_ng = not_found
507 if not get_option('cap_ng').auto() or have_system or have_tools
508 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
509 required: get_option('cap_ng'),
510 kwargs: static_kwargs)
512 if libcap_ng.found() and not cc.links('''
516 capng_capability_to_name(CAPNG_EFFECTIVE);
518 }''', dependencies: libcap_ng)
519 libcap_ng = not_found
520 if get_option('cap_ng').enabled()
521 error('could not link libcap-ng')
523 warning('could not link libcap-ng, disabling')
527 if get_option('xkbcommon').auto() and not have_system and not have_tools
528 xkbcommon = not_found
530 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
531 method: 'pkg-config', kwargs: static_kwargs)
535 if not get_option('vde').auto() or have_system or have_tools
536 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
537 required: get_option('vde'),
538 kwargs: static_kwargs)
540 if vde.found() and not cc.links('''
541 #include <libvdeplug.h>
544 struct vde_open_args a = {0, 0, 0};
548 }''', dependencies: vde)
550 if get_option('cap_ng').enabled()
551 error('could not link libvdeplug')
553 warning('could not link libvdeplug, disabling')
558 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
559 pulse = dependency('libpulse', required: get_option('pa'),
560 method: 'pkg-config', kwargs: static_kwargs)
563 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
564 alsa = dependency('alsa', required: get_option('alsa'),
565 method: 'pkg-config', kwargs: static_kwargs)
568 if not get_option('jack').auto() or have_system
569 jack = dependency('jack', required: get_option('jack'),
570 method: 'pkg-config', kwargs: static_kwargs)
573 spice_protocol = not_found
574 if not get_option('spice_protocol').auto() or have_system
575 spice_protocol = dependency('spice-protocol', version: '>=0.12.3',
576 required: get_option('spice_protocol'),
577 method: 'pkg-config', kwargs: static_kwargs)
580 if not get_option('spice').auto() or have_system
581 spice = dependency('spice-server', version: '>=0.12.5',
582 required: get_option('spice'),
583 method: 'pkg-config', kwargs: static_kwargs)
585 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
587 rt = cc.find_library('rt', required: false)
590 if not get_option('libiscsi').auto() or have_block
591 libiscsi = dependency('libiscsi', version: '>=1.9.0',
592 required: get_option('libiscsi'),
593 method: 'pkg-config', kwargs: static_kwargs)
596 if not get_option('zstd').auto() or have_block
597 zstd = dependency('libzstd', version: '>=1.4.0',
598 required: get_option('zstd'),
599 method: 'pkg-config', kwargs: static_kwargs)
602 if not get_option('virglrenderer').auto() or have_system
603 virgl = dependency('virglrenderer',
604 method: 'pkg-config',
605 required: get_option('virglrenderer'),
606 kwargs: static_kwargs)
609 if not get_option('curl').auto() or have_block
610 curl = dependency('libcurl', version: '>=7.29.0',
611 method: 'pkg-config',
612 required: get_option('curl'),
613 kwargs: static_kwargs)
616 if targetos == 'linux' and (have_system or have_tools)
617 libudev = dependency('libudev',
618 method: 'pkg-config',
619 required: get_option('libudev'),
620 kwargs: static_kwargs)
623 mpathlibs = [libudev]
624 mpathpersist = not_found
625 mpathpersist_new_api = false
626 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
627 mpath_test_source_new = '''
629 #include <mpath_persist.h>
630 unsigned mpath_mx_alloc_len = 1024;
632 static struct config *multipath_conf;
633 extern struct udev *udev;
634 extern struct config *get_multipath_config(void);
635 extern void put_multipath_config(struct config *conf);
637 struct config *get_multipath_config(void) { return multipath_conf; }
638 void put_multipath_config(struct config *conf) { }
641 multipath_conf = mpath_lib_init();
644 mpath_test_source_old = '''
646 #include <mpath_persist.h>
647 unsigned mpath_mx_alloc_len = 1024;
650 struct udev *udev = udev_new();
651 mpath_lib_init(udev);
654 libmpathpersist = cc.find_library('mpathpersist',
655 required: get_option('mpath'),
656 kwargs: static_kwargs)
657 if libmpathpersist.found()
658 mpathlibs += libmpathpersist
660 mpathlibs += cc.find_library('devmapper',
661 required: get_option('mpath'),
662 kwargs: static_kwargs)
664 mpathlibs += cc.find_library('multipath',
665 required: get_option('mpath'),
666 kwargs: static_kwargs)
667 foreach lib: mpathlibs
673 if mpathlibs.length() == 0
674 msg = 'Dependencies missing for libmpathpersist'
675 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
676 mpathpersist = declare_dependency(dependencies: mpathlibs)
677 mpathpersist_new_api = true
678 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
679 mpathpersist = declare_dependency(dependencies: mpathlibs)
681 msg = 'Cannot detect libmpathpersist API'
683 if not mpathpersist.found()
684 if get_option('mpath').enabled()
687 warning(msg + ', disabling')
695 if have_system and not get_option('curses').disabled()
697 #if defined(__APPLE__) || defined(__OpenBSD__)
698 #define _XOPEN_SOURCE_EXTENDED 1
705 setlocale(LC_ALL, "");
707 addwstr(L"wide chars\n");
709 add_wch(WACS_DEGREE);
713 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
714 foreach curses_dep : curses_dep_list
715 if not curses.found()
716 curses = dependency(curses_dep,
718 method: 'pkg-config',
719 kwargs: static_kwargs)
722 msg = get_option('curses').enabled() ? 'curses library not found' : ''
723 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
725 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
726 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
728 msg = 'curses package not usable'
732 if not curses.found()
733 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
734 if targetos != 'windows' and not has_curses_h
735 message('Trying with /usr/include/ncursesw')
736 curses_compile_args += ['-I/usr/include/ncursesw']
737 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
740 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
741 foreach curses_libname : curses_libname_list
742 libcurses = cc.find_library(curses_libname,
744 kwargs: static_kwargs)
746 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
747 curses = declare_dependency(compile_args: curses_compile_args,
748 dependencies: [libcurses])
751 msg = 'curses library not usable'
757 if not get_option('iconv').disabled()
758 foreach link_args : [ ['-liconv'], [] ]
759 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
760 # We need to use libiconv if available because mixing libiconv's headers with
761 # the system libc does not work.
762 # However, without adding glib to the dependencies -L/usr/local/lib will not be
763 # included in the command line and libiconv will not be found.
767 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
768 return conv != (iconv_t) -1;
769 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
770 iconv = declare_dependency(link_args: link_args, dependencies: glib)
775 if curses.found() and not iconv.found()
776 if get_option('iconv').enabled()
777 error('iconv not available')
779 msg = 'iconv required for curses UI but not available'
782 if not curses.found() and msg != ''
783 if get_option('curses').enabled()
786 warning(msg + ', disabling')
792 if not get_option('brlapi').auto() or have_system
793 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
794 required: get_option('brlapi'),
795 kwargs: static_kwargs)
796 if brlapi.found() and not cc.links('''
799 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
801 if get_option('brlapi').enabled()
802 error('could not link brlapi')
804 warning('could not link brlapi, disabling')
810 if not get_option('sdl').auto() or (have_system and not cocoa.found())
811 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
812 sdl_image = not_found
815 # work around 2.0.8 bug
816 sdl = declare_dependency(compile_args: '-Wno-undef',
818 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
819 method: 'pkg-config', kwargs: static_kwargs)
821 if get_option('sdl_image').enabled()
822 error('sdl-image required, but SDL was @0@'.format(
823 get_option('sdl').disabled() ? 'disabled' : 'not found'))
825 sdl_image = not_found
829 if not get_option('rbd').auto() or have_block
830 librados = cc.find_library('rados', required: get_option('rbd'),
831 kwargs: static_kwargs)
832 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
833 required: get_option('rbd'),
834 kwargs: static_kwargs)
835 if librados.found() and librbd.found()
838 #include <rbd/librbd.h>
841 rados_create(&cluster, NULL);
842 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
846 }''', dependencies: [librbd, librados])
847 rbd = declare_dependency(dependencies: [librbd, librados])
848 elif get_option('rbd').enabled()
849 error('librbd >= 1.12.0 required')
851 warning('librbd >= 1.12.0 not found, disabling')
856 glusterfs = not_found
857 glusterfs_ftruncate_has_stat = false
858 glusterfs_iocb_has_stat = false
859 if not get_option('glusterfs').auto() or have_block
860 glusterfs = dependency('glusterfs-api', version: '>=3',
861 required: get_option('glusterfs'),
862 method: 'pkg-config', kwargs: static_kwargs)
864 glusterfs_ftruncate_has_stat = cc.links('''
865 #include <glusterfs/api/glfs.h>
870 /* new glfs_ftruncate() passes two additional args */
871 return glfs_ftruncate(NULL, 0, NULL, NULL);
873 ''', dependencies: glusterfs)
874 glusterfs_iocb_has_stat = cc.links('''
875 #include <glusterfs/api/glfs.h>
877 /* new glfs_io_cbk() passes two additional glfs_stat structs */
879 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
885 glfs_io_cbk iocb = &glusterfs_iocb;
886 iocb(NULL, 0 , NULL, NULL, NULL);
889 ''', dependencies: glusterfs)
894 if not get_option('libssh').auto() or have_block
895 libssh = dependency('libssh', version: '>=0.8.7',
896 method: 'pkg-config',
897 required: get_option('libssh'),
898 kwargs: static_kwargs)
902 if not get_option('bzip2').auto() or have_block
903 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
904 required: get_option('bzip2'),
905 kwargs: static_kwargs)
906 if libbzip2.found() and not cc.links('''
908 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
910 if get_option('bzip2').enabled()
911 error('could not link libbzip2')
913 warning('could not link libbzip2, disabling')
919 if not get_option('lzfse').auto() or have_block
920 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
921 required: get_option('lzfse'),
922 kwargs: static_kwargs)
924 if liblzfse.found() and not cc.links('''
926 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
928 if get_option('lzfse').enabled()
929 error('could not link liblzfse')
931 warning('could not link liblzfse, disabling')
936 if have_system and not get_option('oss').disabled()
937 if not cc.has_header('sys/soundcard.h')
939 elif targetos == 'netbsd'
940 oss = cc.find_library('ossaudio', required: get_option('oss'),
941 kwargs: static_kwargs)
943 oss = declare_dependency()
947 if get_option('oss').enabled()
948 error('OSS not found')
953 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
954 if cc.has_header('dsound.h')
955 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
958 if not dsound.found()
959 if get_option('dsound').enabled()
960 error('DirectSound not found')
965 coreaudio = not_found
966 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
967 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
968 required: get_option('coreaudio'))
972 if 'CONFIG_OPENGL' in config_host
973 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
974 link_args: config_host['OPENGL_LIBS'].split())
977 if (have_system or have_tools) and (virgl.found() or opengl.found())
978 gbm = dependency('gbm', method: 'pkg-config', required: false,
979 kwargs: static_kwargs)
983 gnutls_crypto = not_found
984 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
985 # For general TLS support our min gnutls matches
986 # that implied by our platform support matrix
988 # For the crypto backends, we look for a newer
991 # Version 3.6.8 is needed to get XTS
992 # Version 3.6.13 is needed to get PBKDF
993 # Version 3.6.14 is needed to get HW accelerated XTS
995 # If newer enough gnutls isn't available, we can
996 # still use a different crypto backend to satisfy
997 # the platform support requirements
998 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
999 method: 'pkg-config',
1001 kwargs: static_kwargs)
1002 if gnutls_crypto.found()
1003 gnutls = gnutls_crypto
1005 # Our min version if all we need is TLS
1006 gnutls = dependency('gnutls', version: '>=3.5.18',
1007 method: 'pkg-config',
1008 required: get_option('gnutls'),
1009 kwargs: static_kwargs)
1013 # We prefer use of gnutls for crypto, unless the options
1014 # explicitly asked for nettle or gcrypt.
1016 # If gnutls isn't available for crypto, then we'll prefer
1017 # gcrypt over nettle for performance reasons.
1022 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1023 error('Only one of gcrypt & nettle can be enabled')
1026 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1027 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1028 gnutls_crypto = not_found
1031 if not gnutls_crypto.found()
1032 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1033 gcrypt = dependency('libgcrypt', version: '>=1.8',
1034 method: 'config-tool',
1035 required: get_option('gcrypt'),
1036 kwargs: static_kwargs)
1037 # Debian has removed -lgpg-error from libgcrypt-config
1038 # as it "spreads unnecessary dependencies" which in
1039 # turn breaks static builds...
1040 if gcrypt.found() and enable_static
1041 gcrypt = declare_dependency(dependencies: [
1043 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
1046 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1047 nettle = dependency('nettle', version: '>=3.4',
1048 method: 'pkg-config',
1049 required: get_option('nettle'),
1050 kwargs: static_kwargs)
1051 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1060 if not get_option('gtk').auto() or (have_system and not cocoa.found())
1061 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1062 method: 'pkg-config',
1063 required: get_option('gtk'),
1064 kwargs: static_kwargs)
1066 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1067 method: 'pkg-config',
1069 kwargs: static_kwargs)
1070 gtk = declare_dependency(dependencies: [gtk, gtkx11])
1072 if not get_option('vte').auto() or have_system
1073 vte = dependency('vte-2.91',
1074 method: 'pkg-config',
1075 required: get_option('vte'),
1076 kwargs: static_kwargs)
1083 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
1084 kwargs: static_kwargs)
1090 if have_system and not get_option('vnc').disabled()
1091 vnc = declare_dependency() # dummy dependency
1092 png = dependency('libpng', required: get_option('vnc_png'),
1093 method: 'pkg-config', kwargs: static_kwargs)
1094 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1095 method: 'pkg-config', kwargs: static_kwargs)
1096 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1097 required: get_option('vnc_sasl'),
1098 kwargs: static_kwargs)
1100 sasl = declare_dependency(dependencies: sasl,
1101 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1106 if not get_option('auth_pam').auto() or have_system
1107 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1108 required: get_option('auth_pam'),
1109 kwargs: static_kwargs)
1111 if pam.found() and not cc.links('''
1113 #include <security/pam_appl.h>
1115 const char *service_name = "qemu";
1116 const char *user = "frank";
1117 const struct pam_conv pam_conv = { 0 };
1118 pam_handle_t *pamh = NULL;
1119 pam_start(service_name, user, &pam_conv, &pamh);
1121 }''', dependencies: pam)
1123 if get_option('auth_pam').enabled()
1124 error('could not link libpam')
1126 warning('could not link libpam, disabling')
1131 if not get_option('snappy').auto() or have_system
1132 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1133 required: get_option('snappy'),
1134 kwargs: static_kwargs)
1136 if snappy.found() and not linker.links('''
1137 #include <snappy-c.h>
1138 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1140 if get_option('snappy').enabled()
1141 error('could not link libsnappy')
1143 warning('could not link libsnappy, disabling')
1148 if not get_option('lzo').auto() or have_system
1149 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1150 required: get_option('lzo'),
1151 kwargs: static_kwargs)
1153 if lzo.found() and not cc.links('''
1154 #include <lzo/lzo1x.h>
1155 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1157 if get_option('lzo').enabled()
1158 error('could not link liblzo2')
1160 warning('could not link liblzo2, disabling')
1165 if 'CONFIG_RDMA' in config_host
1166 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
1169 if 'CONFIG_NUMA' in config_host
1170 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
1173 if 'CONFIG_XEN_BACKEND' in config_host
1174 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
1175 link_args: config_host['XEN_LIBS'].split())
1178 if not get_option('smartcard').auto() or have_system
1179 cacard = dependency('libcacard', required: get_option('smartcard'),
1180 version: '>=2.5.1', method: 'pkg-config',
1181 kwargs: static_kwargs)
1185 u2f = dependency('u2f-emu', required: get_option('u2f'),
1186 method: 'pkg-config',
1187 kwargs: static_kwargs)
1189 usbredir = not_found
1190 if not get_option('usb_redir').auto() or have_system
1191 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1192 version: '>=0.6', method: 'pkg-config',
1193 kwargs: static_kwargs)
1196 if not get_option('libusb').auto() or have_system
1197 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1198 version: '>=1.0.13', method: 'pkg-config',
1199 kwargs: static_kwargs)
1203 if not get_option('libpmem').auto() or have_system
1204 libpmem = dependency('libpmem', required: get_option('libpmem'),
1205 method: 'pkg-config', kwargs: static_kwargs)
1207 libdaxctl = not_found
1208 if not get_option('libdaxctl').auto() or have_system
1209 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1210 version: '>=57', method: 'pkg-config',
1211 kwargs: static_kwargs)
1215 tasn1 = dependency('libtasn1',
1216 method: 'pkg-config',
1217 kwargs: static_kwargs)
1219 keyutils = dependency('libkeyutils', required: false,
1220 method: 'pkg-config', kwargs: static_kwargs)
1222 has_gettid = cc.has_function('gettid')
1225 selinux = dependency('libselinux',
1226 required: get_option('selinux'),
1227 method: 'pkg-config', kwargs: static_kwargs)
1232 if get_option('malloc') == 'system'
1234 not get_option('malloc_trim').disabled() and \
1235 cc.links('''#include <malloc.h>
1236 int main(void) { malloc_trim(0); return 0; }''')
1238 has_malloc_trim = false
1239 malloc = cc.find_library(get_option('malloc'), required: true)
1241 if not has_malloc_trim and get_option('malloc_trim').enabled()
1242 if get_option('malloc') == 'system'
1243 error('malloc_trim not available on this platform.')
1245 error('malloc_trim not available with non-libc memory allocator')
1249 # Check whether the glibc provides statx()
1251 gnu_source_prefix = '''
1256 statx_test = gnu_source_prefix + '''
1257 #include <sys/stat.h>
1259 struct statx statxbuf;
1260 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1264 has_statx = cc.links(statx_test)
1266 have_vhost_user_blk_server = (targetos == 'linux' and
1267 'CONFIG_VHOST_USER' in config_host)
1269 if get_option('vhost_user_blk_server').enabled()
1270 if targetos != 'linux'
1271 error('vhost_user_blk_server requires linux')
1272 elif 'CONFIG_VHOST_USER' not in config_host
1273 error('vhost_user_blk_server requires vhost-user support')
1275 elif get_option('vhost_user_blk_server').disabled() or not have_system
1276 have_vhost_user_blk_server = false
1280 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1281 error('Cannot enable fuse-lseek while fuse is disabled')
1284 fuse = dependency('fuse3', required: get_option('fuse'),
1285 version: '>=3.1', method: 'pkg-config',
1286 kwargs: static_kwargs)
1288 fuse_lseek = not_found
1289 if not get_option('fuse_lseek').disabled()
1290 if fuse.version().version_compare('>=3.8')
1292 fuse_lseek = declare_dependency()
1293 elif get_option('fuse_lseek').enabled()
1295 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1297 error('fuse-lseek requires libfuse, which was not found')
1303 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1304 if libbpf.found() and not cc.links('''
1305 #include <bpf/libbpf.h>
1308 bpf_object__destroy_skeleton(NULL);
1310 }''', dependencies: libbpf)
1312 if get_option('bpf').enabled()
1313 error('libbpf skeleton test failed')
1315 warning('libbpf skeleton test failed, disabling')
1323 audio_drivers_selected = []
1325 audio_drivers_available = {
1326 'alsa': alsa.found(),
1327 'coreaudio': coreaudio.found(),
1328 'dsound': dsound.found(),
1329 'jack': jack.found(),
1331 'pa': pulse.found(),
1334 foreach k, v: audio_drivers_available
1335 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1338 # Default to native drivers first, OSS second, SDL third
1339 audio_drivers_priority = \
1340 [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
1341 (targetos == 'linux' ? [] : [ 'sdl' ])
1342 audio_drivers_default = []
1343 foreach k: audio_drivers_priority
1344 if audio_drivers_available[k]
1345 audio_drivers_default += k
1349 foreach k: get_option('audio_drv_list')
1351 audio_drivers_selected += audio_drivers_default
1352 elif not audio_drivers_available[k]
1353 error('Audio driver "@0@" not available.'.format(k))
1355 audio_drivers_selected += k
1359 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1360 '"' + '", "'.join(audio_drivers_selected) + '", ')
1362 if get_option('cfi')
1364 # Check for dependency on LTO
1365 if not get_option('b_lto')
1366 error('Selected Control-Flow Integrity but LTO is disabled')
1368 if config_host.has_key('CONFIG_MODULES')
1369 error('Selected Control-Flow Integrity is not compatible with modules')
1371 # Check for cfi flags. CFI requires LTO so we can't use
1372 # get_supported_arguments, but need a more complex "compiles" which allows
1374 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1375 args: ['-flto', '-fsanitize=cfi-icall'] )
1376 cfi_flags += '-fsanitize=cfi-icall'
1378 error('-fsanitize=cfi-icall is not supported by the compiler')
1380 if cc.compiles('int main () { return 0; }',
1381 name: '-fsanitize-cfi-icall-generalize-pointers',
1382 args: ['-flto', '-fsanitize=cfi-icall',
1383 '-fsanitize-cfi-icall-generalize-pointers'] )
1384 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1386 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1388 if get_option('cfi_debug')
1389 if cc.compiles('int main () { return 0; }',
1390 name: '-fno-sanitize-trap=cfi-icall',
1391 args: ['-flto', '-fsanitize=cfi-icall',
1392 '-fno-sanitize-trap=cfi-icall'] )
1393 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1395 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1398 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1399 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1402 have_host_block_device = (targetos != 'darwin' or
1403 cc.has_header('IOKit/storage/IOMedia.h'))
1405 dbus_display = false
1406 if not get_option('dbus_display').disabled()
1407 # FIXME enable_modules shouldn't be necessary, but: https://github.com/mesonbuild/meson/issues/8333
1408 dbus_display = gio.version().version_compare('>=2.64') and config_host.has_key('GDBUS_CODEGEN') and enable_modules
1409 if get_option('dbus_display').enabled() and not dbus_display
1410 error('Requirements missing to enable -display dbus (glib>=2.64 && --enable-modules)')
1414 have_virtfs = (targetos == 'linux' and
1419 have_virtfs_proxy_helper = have_virtfs and have_tools
1421 if get_option('virtfs').enabled()
1423 if targetos != 'linux'
1424 error('virtio-9p (virtfs) requires Linux')
1425 elif not libcap_ng.found() or not libattr.found()
1426 error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1427 elif not have_system
1428 error('virtio-9p (virtfs) needs system emulation support')
1431 elif get_option('virtfs').disabled()
1435 foreach k : get_option('trace_backends')
1436 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1438 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1440 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1441 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1442 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1443 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1444 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1445 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1446 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1447 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1448 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1449 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1450 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1451 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1453 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
1455 config_host_data.set('CONFIG_ATTR', libattr.found())
1456 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1457 config_host_data.set('CONFIG_COCOA', cocoa.found())
1458 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1459 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1460 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1461 config_host_data.set('CONFIG_LZO', lzo.found())
1462 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1463 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1464 config_host_data.set('CONFIG_CURL', curl.found())
1465 config_host_data.set('CONFIG_CURSES', curses.found())
1466 config_host_data.set('CONFIG_GBM', gbm.found())
1467 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1468 if glusterfs.found()
1469 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1470 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1471 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1472 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1473 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1474 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1476 config_host_data.set('CONFIG_GTK', gtk.found())
1477 config_host_data.set('CONFIG_VTE', vte.found())
1478 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1479 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1480 config_host_data.set('CONFIG_EBPF', libbpf.found())
1481 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1482 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1483 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1484 config_host_data.set('CONFIG_LIBSSH', libssh.found())
1485 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1486 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1487 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1488 config_host_data.set('CONFIG_RBD', rbd.found())
1489 config_host_data.set('CONFIG_SDL', sdl.found())
1490 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1491 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1492 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1493 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1494 config_host_data.set('CONFIG_VDE', vde.found())
1495 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1496 config_host_data.set('CONFIG_VNC', vnc.found())
1497 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1498 config_host_data.set('CONFIG_VNC_PNG', png.found())
1499 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1500 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1501 config_host_data.set('CONFIG_VTE', vte.found())
1502 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1503 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1504 config_host_data.set('CONFIG_GETTID', has_gettid)
1505 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1506 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1507 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1508 config_host_data.set('CONFIG_NETTLE', nettle.found())
1509 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1510 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1511 config_host_data.set('CONFIG_STATX', has_statx)
1512 config_host_data.set('CONFIG_ZSTD', zstd.found())
1513 config_host_data.set('CONFIG_FUSE', fuse.found())
1514 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1515 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1516 if spice_protocol.found()
1517 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
1518 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
1519 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
1521 config_host_data.set('CONFIG_SPICE', spice.found())
1522 config_host_data.set('CONFIG_X11', x11.found())
1523 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
1524 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1525 config_host_data.set('CONFIG_SELINUX', selinux.found())
1526 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1527 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1528 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1529 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1531 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1532 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1533 config_host_data.set('HOST_WORDS_BIGENDIAN', host_machine.endian() == 'big')
1536 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1537 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1538 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1539 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1540 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1541 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1542 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1543 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1544 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1547 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1548 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1549 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1550 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1551 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1552 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
1553 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1554 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1555 config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
1556 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1557 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1558 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1559 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1560 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1561 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1562 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1563 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1564 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1566 config_host_data.set('HAVE_IBV_ADVISE_MR',
1567 cc.has_function('ibv_advise_mr',
1568 args: config_host['RDMA_LIBS'].split(),
1569 prefix: '#include <infiniband/verbs.h>'))
1573 config_host_data.set('CONFIG_BYTESWAP_H',
1574 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1575 config_host_data.set('CONFIG_EPOLL_CREATE1',
1576 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1577 config_host_data.set('CONFIG_HAS_ENVIRON',
1578 cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix))
1579 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1580 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1581 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1582 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1583 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1584 config_host_data.set('CONFIG_FIEMAP',
1585 cc.has_header('linux/fiemap.h') and
1586 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1587 config_host_data.set('CONFIG_GETRANDOM',
1588 cc.has_function('getrandom') and
1589 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1590 config_host_data.set('CONFIG_INOTIFY',
1591 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1592 config_host_data.set('CONFIG_INOTIFY1',
1593 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1594 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1595 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1596 prefix: '''#include <sys/endian.h>
1597 #include <sys/types.h>'''))
1598 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1599 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1600 config_host_data.set('CONFIG_RTNETLINK',
1601 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1602 config_host_data.set('CONFIG_SYSMACROS',
1603 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1604 config_host_data.set('HAVE_OPTRESET',
1605 cc.has_header_symbol('getopt.h', 'optreset'))
1606 config_host_data.set('HAVE_IPPROTO_MPTCP',
1607 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1610 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1611 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1612 prefix: '#include <signal.h>'))
1613 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1614 cc.has_member('struct stat', 'st_atim',
1615 prefix: '#include <sys/stat.h>'))
1618 config_host_data.set('CONFIG_IOVEC',
1619 cc.has_type('struct iovec',
1620 prefix: '#include <sys/uio.h>'))
1621 config_host_data.set('HAVE_UTMPX',
1622 cc.has_type('struct utmpx',
1623 prefix: '#include <utmpx.h>'))
1625 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1626 #include <sys/eventfd.h>
1627 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1628 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1631 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1632 return fdatasync(0);
1634 #error Not supported
1637 config_host_data.set('CONFIG_MADVISE', cc.links(gnu_source_prefix + '''
1638 #include <sys/types.h>
1639 #include <sys/mman.h>
1641 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }'''))
1642 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1643 #include <sys/mman.h>
1644 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1645 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1647 #if !defined(AT_EMPTY_PATH)
1648 # error missing definition
1650 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1652 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1659 return pipe2(pipefd, O_CLOEXEC);
1661 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1662 #include <sys/mman.h>
1664 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1666 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
1667 #include <pthread.h>
1669 static void *f(void *p) { return NULL; }
1673 pthread_create(&thread, 0, f, 0);
1674 pthread_setname_np(thread, "QEMU");
1676 }''', dependencies: threads))
1677 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
1678 #include <pthread.h>
1680 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
1684 pthread_create(&thread, 0, f, 0);
1686 }''', dependencies: threads))
1688 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1689 #include <sys/signalfd.h>
1691 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1692 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1700 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1701 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1705 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
1706 #include <sys/mman.h>
1707 int main(int argc, char *argv[]) {
1708 return mlockall(MCL_FUTURE);
1712 if not get_option('l2tpv3').disabled() and have_system
1713 have_l2tpv3 = cc.has_type('struct mmsghdr',
1714 prefix: gnu_source_prefix + '''
1715 #include <sys/socket.h>
1716 #include <linux/ip.h>''')
1718 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
1721 if not get_option('netmap').disabled() and have_system
1722 have_netmap = cc.compiles('''
1723 #include <inttypes.h>
1725 #include <net/netmap.h>
1726 #include <net/netmap_user.h>
1727 #if (NETMAP_API < 11) || (NETMAP_API > 15)
1730 int main(void) { return 0; }''')
1731 if not have_netmap and get_option('netmap').enabled()
1732 error('Netmap headers not available')
1735 config_host_data.set('CONFIG_NETMAP', have_netmap)
1737 # Work around a system header bug with some kernel/XFS header
1738 # versions where they both try to define 'struct fsxattr':
1739 # xfs headers will not try to redefine structs from linux headers
1740 # if this macro is set.
1741 config_host_data.set('HAVE_FSXATTR', cc.links('''
1742 #include <linux/fs.h>
1748 # Some versions of Mac OS X incorrectly define SIZE_MAX
1749 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1752 int main(int argc, char *argv[]) {
1753 return printf("%zu", SIZE_MAX);
1754 }''', args: ['-Werror']))
1756 # See if 64-bit atomic operations are supported.
1757 # Note that without __atomic builtins, we can only
1758 # assume atomic loads/stores max at pointer size.
1759 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
1763 uint64_t x = 0, y = 0;
1764 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
1765 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
1766 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
1767 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
1768 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
1772 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
1773 #include <sys/auxv.h>
1775 return getauxval(AT_HWCAP) == 0;
1778 config_host_data.set('CONFIG_AF_VSOCK', cc.compiles(gnu_source_prefix + '''
1780 #include <sys/types.h>
1781 #include <sys/socket.h>
1782 #if !defined(AF_VSOCK)
1783 # error missing AF_VSOCK flag
1785 #include <linux/vm_sockets.h>
1788 struct sockaddr_vm svm;
1789 socklen_t len = sizeof(svm);
1790 sock = socket(AF_VSOCK, SOCK_STREAM, 0);
1791 ret = getpeername(sock, (struct sockaddr *)&svm, &len);
1792 if ((ret == -1) && (errno == ENOTCONN)) {
1798 ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target
1800 arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1801 strings = ['CONFIG_IASL']
1802 foreach k, v: config_host
1803 if ignored.contains(k)
1805 elif arrays.contains(k)
1807 v = '"' + '", "'.join(v.split()) + '", '
1809 config_host_data.set(k, v)
1810 elif strings.contains(k)
1811 config_host_data.set_quoted(k, v)
1812 elif k.startswith('CONFIG_')
1813 config_host_data.set(k, v == 'y' ? 1 : v)
1817 ########################
1818 # Target configuration #
1819 ########################
1821 minikconf = find_program('scripts/minikconf.py')
1823 config_all_devices = {}
1824 config_all_disas = {}
1825 config_devices_mak_list = []
1826 config_devices_h = {}
1827 config_target_h = {}
1828 config_target_mak = {}
1831 'alpha' : ['CONFIG_ALPHA_DIS'],
1832 'arm' : ['CONFIG_ARM_DIS'],
1833 'avr' : ['CONFIG_AVR_DIS'],
1834 'cris' : ['CONFIG_CRIS_DIS'],
1835 'hexagon' : ['CONFIG_HEXAGON_DIS'],
1836 'hppa' : ['CONFIG_HPPA_DIS'],
1837 'i386' : ['CONFIG_I386_DIS'],
1838 'x86_64' : ['CONFIG_I386_DIS'],
1839 'm68k' : ['CONFIG_M68K_DIS'],
1840 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1841 'mips' : ['CONFIG_MIPS_DIS'],
1842 'nios2' : ['CONFIG_NIOS2_DIS'],
1843 'or1k' : ['CONFIG_OPENRISC_DIS'],
1844 'ppc' : ['CONFIG_PPC_DIS'],
1845 'riscv' : ['CONFIG_RISCV_DIS'],
1846 'rx' : ['CONFIG_RX_DIS'],
1847 's390' : ['CONFIG_S390_DIS'],
1848 'sh4' : ['CONFIG_SH4_DIS'],
1849 'sparc' : ['CONFIG_SPARC_DIS'],
1850 'xtensa' : ['CONFIG_XTENSA_DIS'],
1852 if link_language == 'cpp'
1854 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1855 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1856 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1860 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
1862 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
1863 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1864 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
1865 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
1866 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1867 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1868 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1869 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1870 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1871 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1872 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1873 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1874 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1876 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1878 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1879 actual_target_dirs = []
1881 foreach target : target_dirs
1882 config_target = { 'TARGET_NAME': target.split('-')[0] }
1883 if target.endswith('linux-user')
1884 if targetos != 'linux'
1888 error('Target @0@ is only available on a Linux host'.format(target))
1890 config_target += { 'CONFIG_LINUX_USER': 'y' }
1891 elif target.endswith('bsd-user')
1892 if 'CONFIG_BSD' not in config_host
1896 error('Target @0@ is only available on a BSD host'.format(target))
1898 config_target += { 'CONFIG_BSD_USER': 'y' }
1899 elif target.endswith('softmmu')
1900 config_target += { 'CONFIG_SOFTMMU': 'y' }
1902 if target.endswith('-user')
1904 'CONFIG_USER_ONLY': 'y',
1905 'CONFIG_QEMU_INTERP_PREFIX':
1906 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1911 foreach sym: accelerators
1912 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1913 config_target += { sym: 'y' }
1914 config_all += { sym: 'y' }
1915 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1916 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1917 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1918 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1920 if target in modular_tcg
1921 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
1923 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
1925 accel_kconfig += [ sym + '=y' ]
1928 if accel_kconfig.length() == 0
1932 error('No accelerator available for target @0@'.format(target))
1935 actual_target_dirs += target
1936 config_target += keyval.load('configs/targets' / target + '.mak')
1937 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1939 if 'TARGET_NEED_FDT' in config_target
1940 fdt_required += target
1944 if 'TARGET_BASE_ARCH' not in config_target
1945 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1947 if 'TARGET_ABI_DIR' not in config_target
1948 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1951 foreach k, v: disassemblers
1952 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1954 config_target += { sym: 'y' }
1955 config_all_disas += { sym: 'y' }
1960 config_target_data = configuration_data()
1961 foreach k, v: config_target
1962 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1964 elif ignored.contains(k)
1966 elif k == 'TARGET_BASE_ARCH'
1967 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1968 # not used to select files from sourcesets.
1969 config_target_data.set('TARGET_' + v.to_upper(), 1)
1970 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1971 config_target_data.set_quoted(k, v)
1973 config_target_data.set(k, 1)
1975 config_target_data.set(k, v)
1978 config_target_data.set('QEMU_ARCH',
1979 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
1980 config_target_h += {target: configure_file(output: target + '-config-target.h',
1981 configuration: config_target_data)}
1983 if target.endswith('-softmmu')
1984 config_input = meson.get_external_property(target, 'default')
1985 config_devices_mak = target + '-config-devices.mak'
1986 config_devices_mak = configure_file(
1987 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
1988 output: config_devices_mak,
1989 depfile: config_devices_mak + '.d',
1991 command: [minikconf,
1992 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1993 config_devices_mak, '@DEPFILE@', '@INPUT@',
1994 host_kconfig, accel_kconfig,
1995 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
1997 config_devices_data = configuration_data()
1998 config_devices = keyval.load(config_devices_mak)
1999 foreach k, v: config_devices
2000 config_devices_data.set(k, 1)
2002 config_devices_mak_list += config_devices_mak
2003 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2004 configuration: config_devices_data)}
2005 config_target += config_devices
2006 config_all_devices += config_devices
2008 config_target_mak += {target: config_target}
2010 target_dirs = actual_target_dirs
2012 # This configuration is used to build files that are shared by
2013 # multiple binaries, and then extracted out of the "common"
2014 # static_library target.
2016 # We do not use all_sources()/all_dependencies(), because it would
2017 # build literally all source files, including devices only used by
2018 # targets that are not built for this compilation. The CONFIG_ALL
2019 # pseudo symbol replaces it.
2021 config_all += config_all_devices
2022 config_all += config_host
2023 config_all += config_all_disas
2025 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
2026 'CONFIG_SOFTMMU': have_system,
2027 'CONFIG_USER_ONLY': have_user,
2035 capstone = not_found
2036 capstone_opt = get_option('capstone')
2037 if capstone_opt in ['enabled', 'auto', 'system']
2038 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
2039 capstone = dependency('capstone', version: '>=4.0',
2040 kwargs: static_kwargs, method: 'pkg-config',
2041 required: capstone_opt == 'system' or
2042 capstone_opt == 'enabled' and not have_internal)
2044 # Some versions of capstone have broken pkg-config file
2045 # that reports a wrong -I path, causing the #include to
2046 # fail later. If the system has such a broken version
2048 if capstone.found() and not cc.compiles('#include <capstone.h>',
2049 dependencies: [capstone])
2050 capstone = not_found
2051 if capstone_opt == 'system'
2052 error('system capstone requested, it does not appear to work')
2057 capstone_opt = 'system'
2059 capstone_opt = 'internal'
2061 capstone_opt = 'disabled'
2064 if capstone_opt == 'internal'
2065 capstone_data = configuration_data()
2066 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
2068 capstone_files = files(
2070 'capstone/MCInst.c',
2071 'capstone/MCInstrDesc.c',
2072 'capstone/MCRegisterInfo.c',
2073 'capstone/SStream.c',
2077 if 'CONFIG_ARM_DIS' in config_all_disas
2078 capstone_data.set('CAPSTONE_HAS_ARM', '1')
2079 capstone_files += files(
2080 'capstone/arch/ARM/ARMDisassembler.c',
2081 'capstone/arch/ARM/ARMInstPrinter.c',
2082 'capstone/arch/ARM/ARMMapping.c',
2083 'capstone/arch/ARM/ARMModule.c'
2087 # FIXME: This config entry currently depends on a c++ compiler.
2088 # Which is needed for building libvixl, but not for capstone.
2089 if 'CONFIG_ARM_A64_DIS' in config_all_disas
2090 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
2091 capstone_files += files(
2092 'capstone/arch/AArch64/AArch64BaseInfo.c',
2093 'capstone/arch/AArch64/AArch64Disassembler.c',
2094 'capstone/arch/AArch64/AArch64InstPrinter.c',
2095 'capstone/arch/AArch64/AArch64Mapping.c',
2096 'capstone/arch/AArch64/AArch64Module.c'
2100 if 'CONFIG_PPC_DIS' in config_all_disas
2101 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
2102 capstone_files += files(
2103 'capstone/arch/PowerPC/PPCDisassembler.c',
2104 'capstone/arch/PowerPC/PPCInstPrinter.c',
2105 'capstone/arch/PowerPC/PPCMapping.c',
2106 'capstone/arch/PowerPC/PPCModule.c'
2110 if 'CONFIG_S390_DIS' in config_all_disas
2111 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
2112 capstone_files += files(
2113 'capstone/arch/SystemZ/SystemZDisassembler.c',
2114 'capstone/arch/SystemZ/SystemZInstPrinter.c',
2115 'capstone/arch/SystemZ/SystemZMapping.c',
2116 'capstone/arch/SystemZ/SystemZModule.c',
2117 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
2121 if 'CONFIG_I386_DIS' in config_all_disas
2122 capstone_data.set('CAPSTONE_HAS_X86', 1)
2123 capstone_files += files(
2124 'capstone/arch/X86/X86Disassembler.c',
2125 'capstone/arch/X86/X86DisassemblerDecoder.c',
2126 'capstone/arch/X86/X86ATTInstPrinter.c',
2127 'capstone/arch/X86/X86IntelInstPrinter.c',
2128 'capstone/arch/X86/X86InstPrinterCommon.c',
2129 'capstone/arch/X86/X86Mapping.c',
2130 'capstone/arch/X86/X86Module.c'
2134 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
2137 # FIXME: There does not seem to be a way to completely replace the c_args
2138 # that come from add_project_arguments() -- we can only add to them.
2139 # So: disable all warnings with a big hammer.
2142 # Include all configuration defines via a header file, which will wind up
2143 # as a dependency on the object file, and thus changes here will result
2145 '-include', 'capstone-defs.h'
2148 libcapstone = static_library('capstone',
2149 build_by_default: false,
2150 sources: capstone_files,
2151 c_args: capstone_cargs,
2152 include_directories: 'capstone/include')
2153 capstone = declare_dependency(link_with: libcapstone,
2154 include_directories: 'capstone/include/capstone')
2158 slirp_opt = 'disabled'
2160 slirp_opt = get_option('slirp')
2161 if slirp_opt in ['enabled', 'auto', 'system']
2162 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2163 slirp = dependency('slirp', kwargs: static_kwargs,
2164 method: 'pkg-config',
2165 required: slirp_opt == 'system' or
2166 slirp_opt == 'enabled' and not have_internal)
2168 slirp_opt = 'system'
2170 slirp_opt = 'internal'
2172 slirp_opt = 'disabled'
2175 if slirp_opt == 'internal'
2177 if targetos == 'windows'
2178 slirp_deps = cc.find_library('iphlpapi')
2179 elif targetos == 'darwin'
2180 slirp_deps = cc.find_library('resolv')
2182 slirp_conf = configuration_data()
2183 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2184 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2185 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2186 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2187 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2189 'slirp/src/arp_table.c',
2190 'slirp/src/bootp.c',
2191 'slirp/src/cksum.c',
2192 'slirp/src/dhcpv6.c',
2193 'slirp/src/dnssearch.c',
2195 'slirp/src/ip6_icmp.c',
2196 'slirp/src/ip6_input.c',
2197 'slirp/src/ip6_output.c',
2198 'slirp/src/ip_icmp.c',
2199 'slirp/src/ip_input.c',
2200 'slirp/src/ip_output.c',
2204 'slirp/src/ndp_table.c',
2206 'slirp/src/slirp.c',
2207 'slirp/src/socket.c',
2208 'slirp/src/state.c',
2209 'slirp/src/stream.c',
2210 'slirp/src/tcp_input.c',
2211 'slirp/src/tcp_output.c',
2212 'slirp/src/tcp_subr.c',
2213 'slirp/src/tcp_timer.c',
2218 'slirp/src/version.c',
2219 'slirp/src/vmstate.c',
2223 input : 'slirp/src/libslirp-version.h.in',
2224 output : 'libslirp-version.h',
2225 configuration: slirp_conf)
2227 slirp_inc = include_directories('slirp', 'slirp/src')
2228 libslirp = static_library('slirp',
2229 build_by_default: false,
2230 sources: slirp_files,
2231 c_args: slirp_cargs,
2232 include_directories: slirp_inc)
2233 slirp = declare_dependency(link_with: libslirp,
2234 dependencies: slirp_deps,
2235 include_directories: slirp_inc)
2239 # For CFI, we need to compile slirp as a static library together with qemu.
2240 # This is because we register slirp functions as callbacks for QEMU Timers.
2241 # When using a system-wide shared libslirp, the type information for the
2242 # callback is missing and the timer call produces a false positive with CFI.
2244 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2245 # with control-flow integrity.
2246 if get_option('cfi') and slirp_opt == 'system'
2247 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2248 + ' Please configure with --enable-slirp=git')
2252 fdt_opt = get_option('fdt')
2254 if fdt_opt in ['enabled', 'auto', 'system']
2255 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2256 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2257 required: fdt_opt == 'system' or
2258 fdt_opt == 'enabled' and not have_internal)
2259 if fdt.found() and cc.links('''
2261 #include <libfdt_env.h>
2262 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
2265 elif fdt_opt == 'system'
2266 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2268 fdt_opt = 'internal'
2270 fdt_opt = 'disabled'
2274 if fdt_opt == 'internal'
2277 'dtc/libfdt/fdt_ro.c',
2278 'dtc/libfdt/fdt_wip.c',
2279 'dtc/libfdt/fdt_sw.c',
2280 'dtc/libfdt/fdt_rw.c',
2281 'dtc/libfdt/fdt_strerror.c',
2282 'dtc/libfdt/fdt_empty_tree.c',
2283 'dtc/libfdt/fdt_addresses.c',
2284 'dtc/libfdt/fdt_overlay.c',
2285 'dtc/libfdt/fdt_check.c',
2288 fdt_inc = include_directories('dtc/libfdt')
2289 libfdt = static_library('fdt',
2290 build_by_default: false,
2292 include_directories: fdt_inc)
2293 fdt = declare_dependency(link_with: libfdt,
2294 include_directories: fdt_inc)
2297 if not fdt.found() and fdt_required.length() > 0
2298 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2301 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2302 config_host_data.set('CONFIG_FDT', fdt.found())
2303 config_host_data.set('CONFIG_SLIRP', slirp.found())
2305 #####################
2306 # Generated sources #
2307 #####################
2309 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2311 hxtool = find_program('scripts/hxtool')
2312 shaderinclude = find_program('scripts/shaderinclude.pl')
2313 qapi_gen = find_program('scripts/qapi-gen.py')
2314 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2315 meson.current_source_dir() / 'scripts/qapi/commands.py',
2316 meson.current_source_dir() / 'scripts/qapi/common.py',
2317 meson.current_source_dir() / 'scripts/qapi/error.py',
2318 meson.current_source_dir() / 'scripts/qapi/events.py',
2319 meson.current_source_dir() / 'scripts/qapi/expr.py',
2320 meson.current_source_dir() / 'scripts/qapi/gen.py',
2321 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2322 meson.current_source_dir() / 'scripts/qapi/parser.py',
2323 meson.current_source_dir() / 'scripts/qapi/schema.py',
2324 meson.current_source_dir() / 'scripts/qapi/source.py',
2325 meson.current_source_dir() / 'scripts/qapi/types.py',
2326 meson.current_source_dir() / 'scripts/qapi/visit.py',
2327 meson.current_source_dir() / 'scripts/qapi/common.py',
2328 meson.current_source_dir() / 'scripts/qapi-gen.py'
2332 python, files('scripts/tracetool.py'),
2333 '--backend=' + ','.join(get_option('trace_backends'))
2335 tracetool_depends = files(
2336 'scripts/tracetool/backend/log.py',
2337 'scripts/tracetool/backend/__init__.py',
2338 'scripts/tracetool/backend/dtrace.py',
2339 'scripts/tracetool/backend/ftrace.py',
2340 'scripts/tracetool/backend/simple.py',
2341 'scripts/tracetool/backend/syslog.py',
2342 'scripts/tracetool/backend/ust.py',
2343 'scripts/tracetool/format/tcg_h.py',
2344 'scripts/tracetool/format/ust_events_c.py',
2345 'scripts/tracetool/format/ust_events_h.py',
2346 'scripts/tracetool/format/__init__.py',
2347 'scripts/tracetool/format/d.py',
2348 'scripts/tracetool/format/tcg_helper_c.py',
2349 'scripts/tracetool/format/simpletrace_stap.py',
2350 'scripts/tracetool/format/c.py',
2351 'scripts/tracetool/format/h.py',
2352 'scripts/tracetool/format/tcg_helper_h.py',
2353 'scripts/tracetool/format/log_stap.py',
2354 'scripts/tracetool/format/stap.py',
2355 'scripts/tracetool/format/tcg_helper_wrapper_h.py',
2356 'scripts/tracetool/__init__.py',
2357 'scripts/tracetool/transform.py',
2358 'scripts/tracetool/vcpu.py'
2361 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2362 meson.current_source_dir(),
2363 config_host['PKGVERSION'], meson.project_version()]
2364 qemu_version = custom_target('qemu-version.h',
2365 output: 'qemu-version.h',
2366 command: qemu_version_cmd,
2368 build_by_default: true,
2369 build_always_stale: true)
2370 genh += qemu_version
2374 ['qemu-options.hx', 'qemu-options.def'],
2375 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2379 ['hmp-commands.hx', 'hmp-commands.h'],
2380 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2383 foreach d : hx_headers
2384 hxdep += custom_target(d[1],
2388 build_by_default: true, # to be removed when added to a target
2389 command: [hxtool, '-h', '@INPUT0@'])
2397 authz_ss = ss.source_set()
2398 blockdev_ss = ss.source_set()
2399 block_ss = ss.source_set()
2400 chardev_ss = ss.source_set()
2401 common_ss = ss.source_set()
2402 common_user_ss = ss.source_set()
2403 crypto_ss = ss.source_set()
2404 hwcore_ss = ss.source_set()
2405 io_ss = ss.source_set()
2406 qmp_ss = ss.source_set()
2407 qom_ss = ss.source_set()
2408 softmmu_ss = ss.source_set()
2409 specific_fuzz_ss = ss.source_set()
2410 specific_ss = ss.source_set()
2411 stub_ss = ss.source_set()
2412 trace_ss = ss.source_set()
2413 user_ss = ss.source_set()
2414 util_ss = ss.source_set()
2417 qtest_module_ss = ss.source_set()
2418 tcg_module_ss = ss.source_set()
2424 target_softmmu_arch = {}
2425 target_user_arch = {}
2431 # TODO: add each directory to the subdirs from its own meson.build, once
2433 trace_events_subdirs = [
2441 trace_events_subdirs += [ 'linux-user' ]
2444 trace_events_subdirs += [
2453 trace_events_subdirs += [
2467 'hw/block/dataplane',
2517 if have_system or have_user
2518 trace_events_subdirs += [
2535 vhost_user = not_found
2536 if 'CONFIG_VHOST_USER' in config_host
2537 libvhost_user = subproject('libvhost-user')
2538 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2553 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2554 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2557 stub_ss = stub_ss.apply(config_all, strict: false)
2559 util_ss.add_all(trace_ss)
2560 util_ss = util_ss.apply(config_all, strict: false)
2561 libqemuutil = static_library('qemuutil',
2562 sources: util_ss.sources() + stub_ss.sources() + genh,
2563 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2564 qemuutil = declare_dependency(link_with: libqemuutil,
2565 sources: genh + version_res)
2567 if have_system or have_user
2568 decodetree = generator(find_program('scripts/decodetree.py'),
2569 output: 'decode-@BASENAME@.c.inc',
2570 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2571 subdir('libdecnumber')
2588 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
2594 blockdev_ss.add(files(
2601 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2602 # os-win32.c does not
2603 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2604 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2607 common_ss.add(files('cpus-common.c'))
2611 common_ss.add(capstone)
2612 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2614 # Work around a gcc bug/misfeature wherein constant propagation looks
2616 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2617 # to guess that a const variable is always zero. Without lto, this is
2618 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2619 # without lto, not even the alias is required -- we simply use different
2620 # declarations in different compilation units.
2621 pagevary = files('page-vary-common.c')
2622 if get_option('b_lto')
2623 pagevary_flags = ['-fno-lto']
2624 if get_option('cfi')
2625 pagevary_flags += '-fno-sanitize=cfi-icall'
2627 pagevary = static_library('page-vary-common', sources: pagevary,
2628 c_args: pagevary_flags)
2629 pagevary = declare_dependency(link_with: pagevary)
2631 common_ss.add(pagevary)
2632 specific_ss.add(files('page-vary.c'))
2640 subdir('semihosting')
2648 common_user_inc = []
2650 subdir('common-user')
2652 subdir('linux-user')
2654 common_user_ss = common_user_ss.apply(config_all, strict: false)
2655 common_user = static_library('common-user',
2656 sources: common_user_ss.sources(),
2657 dependencies: common_user_ss.dependencies(),
2658 include_directories: common_user_inc,
2660 build_by_default: false)
2661 common_user = declare_dependency(link_with: common_user)
2663 user_ss.add(common_user)
2665 # needed for fuzzing binaries
2666 subdir('tests/qtest/libqos')
2667 subdir('tests/qtest/fuzz')
2670 tcg_real_module_ss = ss.source_set()
2671 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
2672 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
2673 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
2674 'tcg': tcg_real_module_ss }}
2676 ########################
2677 # Library dependencies #
2678 ########################
2680 modinfo_collect = find_program('scripts/modinfo-collect.py')
2681 modinfo_generate = find_program('scripts/modinfo-generate.py')
2686 foreach d, list : modules
2687 foreach m, module_ss : list
2688 if enable_modules and targetos != 'windows'
2689 module_ss = module_ss.apply(config_all, strict: false)
2690 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2691 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2697 if module_ss.sources() != []
2698 # FIXME: Should use sl.extract_all_objects(recursive: true) as
2699 # input. Sources can be used multiple times but objects are
2700 # unique when it comes to lookup in compile_commands.json.
2701 # Depnds on a mesion version with
2702 # https://github.com/mesonbuild/meson/pull/8900
2703 modinfo_files += custom_target(d + '-' + m + '.modinfo',
2704 output: d + '-' + m + '.modinfo',
2705 input: module_ss.sources() + genh,
2707 command: [modinfo_collect, module_ss.sources()])
2711 block_ss.add_all(module_ss)
2713 softmmu_ss.add_all(module_ss)
2719 foreach d, list : target_modules
2720 foreach m, module_ss : list
2721 if enable_modules and targetos != 'windows'
2722 foreach target : target_dirs
2723 if target.endswith('-softmmu')
2724 config_target = config_target_mak[target]
2725 config_target += config_host
2726 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2727 c_args = ['-DNEED_CPU_H',
2728 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2729 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2730 target_module_ss = module_ss.apply(config_target, strict: false)
2731 if target_module_ss.sources() != []
2732 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
2733 sl = static_library(module_name,
2734 [genh, target_module_ss.sources()],
2735 dependencies: [modulecommon, target_module_ss.dependencies()],
2736 include_directories: target_inc,
2740 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
2741 modinfo_files += custom_target(module_name + '.modinfo',
2742 output: module_name + '.modinfo',
2743 input: target_module_ss.sources() + genh,
2745 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
2750 specific_ss.add_all(module_ss)
2756 modinfo_src = custom_target('modinfo.c',
2757 output: 'modinfo.c',
2758 input: modinfo_files,
2759 command: [modinfo_generate, '@INPUT@'],
2761 modinfo_lib = static_library('modinfo', modinfo_src)
2762 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
2763 softmmu_ss.add(modinfo_dep)
2766 nm = find_program('nm')
2767 undefsym = find_program('scripts/undefsym.py')
2768 block_syms = custom_target('block.syms', output: 'block.syms',
2769 input: [libqemuutil, block_mods],
2771 command: [undefsym, nm, '@INPUT@'])
2772 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2773 input: [libqemuutil, softmmu_mods],
2775 command: [undefsym, nm, '@INPUT@'])
2777 qom_ss = qom_ss.apply(config_host, strict: false)
2778 libqom = static_library('qom', qom_ss.sources() + genh,
2779 dependencies: [qom_ss.dependencies()],
2782 qom = declare_dependency(link_whole: libqom)
2784 authz_ss = authz_ss.apply(config_host, strict: false)
2785 libauthz = static_library('authz', authz_ss.sources() + genh,
2786 dependencies: [authz_ss.dependencies()],
2788 build_by_default: false)
2790 authz = declare_dependency(link_whole: libauthz,
2793 crypto_ss = crypto_ss.apply(config_host, strict: false)
2794 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2795 dependencies: [crypto_ss.dependencies()],
2797 build_by_default: false)
2799 crypto = declare_dependency(link_whole: libcrypto,
2800 dependencies: [authz, qom])
2802 io_ss = io_ss.apply(config_host, strict: false)
2803 libio = static_library('io', io_ss.sources() + genh,
2804 dependencies: [io_ss.dependencies()],
2805 link_with: libqemuutil,
2807 build_by_default: false)
2809 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2811 libmigration = static_library('migration', sources: migration_files + genh,
2813 build_by_default: false)
2814 migration = declare_dependency(link_with: libmigration,
2815 dependencies: [zlib, qom, io])
2816 softmmu_ss.add(migration)
2818 block_ss = block_ss.apply(config_host, strict: false)
2819 libblock = static_library('block', block_ss.sources() + genh,
2820 dependencies: block_ss.dependencies(),
2821 link_depends: block_syms,
2823 build_by_default: false)
2825 block = declare_dependency(link_whole: [libblock],
2826 link_args: '@block.syms',
2827 dependencies: [crypto, io])
2829 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2830 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2831 dependencies: blockdev_ss.dependencies(),
2833 build_by_default: false)
2835 blockdev = declare_dependency(link_whole: [libblockdev],
2836 dependencies: [block])
2838 qmp_ss = qmp_ss.apply(config_host, strict: false)
2839 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2840 dependencies: qmp_ss.dependencies(),
2842 build_by_default: false)
2844 qmp = declare_dependency(link_whole: [libqmp])
2846 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2848 dependencies: [gnutls],
2849 build_by_default: false)
2851 chardev = declare_dependency(link_whole: libchardev)
2853 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
2854 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
2856 build_by_default: false)
2857 hwcore = declare_dependency(link_whole: libhwcore)
2858 common_ss.add(hwcore)
2864 foreach m : block_mods + softmmu_mods
2865 shared_module(m.name(),
2869 install_dir: qemu_moddir)
2872 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2873 common_ss.add(qom, qemuutil)
2875 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2876 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2878 common_all = common_ss.apply(config_all, strict: false)
2879 common_all = static_library('common',
2880 build_by_default: false,
2881 sources: common_all.sources() + genh,
2882 implicit_include_directories: false,
2883 dependencies: common_all.dependencies(),
2886 feature_to_c = find_program('scripts/feature_to_c.sh')
2889 foreach target : target_dirs
2890 config_target = config_target_mak[target]
2891 target_name = config_target['TARGET_NAME']
2892 target_base_arch = config_target['TARGET_BASE_ARCH']
2893 arch_srcs = [config_target_h[target]]
2895 c_args = ['-DNEED_CPU_H',
2896 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2897 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2898 link_args = emulator_link_args
2900 config_target += config_host
2901 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2902 if targetos == 'linux'
2903 target_inc += include_directories('linux-headers', is_system: true)
2905 if target.endswith('-softmmu')
2906 qemu_target_name = 'qemu-system-' + target_name
2907 target_type='system'
2908 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
2909 arch_srcs += t.sources()
2910 arch_deps += t.dependencies()
2912 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
2913 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2914 arch_srcs += hw.sources()
2915 arch_deps += hw.dependencies()
2917 arch_srcs += config_devices_h[target]
2918 link_args += ['@block.syms', '@qemu.syms']
2920 abi = config_target['TARGET_ABI_DIR']
2922 qemu_target_name = 'qemu-' + target_name
2923 if target_base_arch in target_user_arch
2924 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
2925 arch_srcs += t.sources()
2926 arch_deps += t.dependencies()
2928 if 'CONFIG_LINUX_USER' in config_target
2929 base_dir = 'linux-user'
2930 target_inc += include_directories('linux-user/host/' / host_arch)
2932 if 'CONFIG_BSD_USER' in config_target
2933 base_dir = 'bsd-user'
2934 target_inc += include_directories('bsd-user/' / targetos)
2935 dir = base_dir / abi
2936 arch_srcs += files(dir / 'target_arch_cpu.c')
2938 target_inc += include_directories(
2942 if 'CONFIG_LINUX_USER' in config_target
2943 dir = base_dir / abi
2944 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2945 if config_target.has_key('TARGET_SYSTBL_ABI')
2947 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2948 extra_args : config_target['TARGET_SYSTBL_ABI'])
2953 if 'TARGET_XML_FILES' in config_target
2954 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2955 output: target + '-gdbstub-xml.c',
2956 input: files(config_target['TARGET_XML_FILES'].split()),
2957 command: [feature_to_c, '@INPUT@'],
2959 arch_srcs += gdbstub_xml
2962 t = target_arch[target_base_arch].apply(config_target, strict: false)
2963 arch_srcs += t.sources()
2964 arch_deps += t.dependencies()
2966 target_common = common_ss.apply(config_target, strict: false)
2967 objects = common_all.extract_objects(target_common.sources())
2968 deps = target_common.dependencies()
2970 target_specific = specific_ss.apply(config_target, strict: false)
2971 arch_srcs += target_specific.sources()
2972 arch_deps += target_specific.dependencies()
2974 lib = static_library('qemu-' + target,
2975 sources: arch_srcs + genh,
2976 dependencies: arch_deps,
2978 include_directories: target_inc,
2980 build_by_default: false,
2983 if target.endswith('-softmmu')
2985 'name': 'qemu-system-' + target_name,
2986 'win_subsystem': 'console',
2987 'sources': files('softmmu/main.c'),
2990 if targetos == 'windows' and (sdl.found() or gtk.found())
2992 'name': 'qemu-system-' + target_name + 'w',
2993 'win_subsystem': 'windows',
2994 'sources': files('softmmu/main.c'),
2998 if get_option('fuzzing')
2999 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3001 'name': 'qemu-fuzz-' + target_name,
3002 'win_subsystem': 'console',
3003 'sources': specific_fuzz.sources(),
3004 'dependencies': specific_fuzz.dependencies(),
3009 'name': 'qemu-' + target_name,
3010 'win_subsystem': 'console',
3016 exe_name = exe['name']
3017 if targetos == 'darwin'
3018 exe_name += '-unsigned'
3021 emulator = executable(exe_name, exe['sources'],
3024 dependencies: arch_deps + deps + exe['dependencies'],
3025 objects: lib.extract_all_objects(recursive: true),
3026 link_language: link_language,
3027 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3028 link_args: link_args,
3029 win_subsystem: exe['win_subsystem'])
3031 if targetos == 'darwin'
3032 icon = 'pc-bios/qemu.rsrc'
3033 build_input = [emulator, files(icon)]
3035 get_option('bindir') / exe_name,
3036 meson.current_source_dir() / icon
3038 if 'CONFIG_HVF' in config_target
3039 entitlements = 'accel/hvf/entitlements.plist'
3040 build_input += files(entitlements)
3041 install_input += meson.current_source_dir() / entitlements
3044 emulators += {exe['name'] : custom_target(exe['name'],
3046 output: exe['name'],
3048 files('scripts/entitlement.sh'),
3054 meson.add_install_script('scripts/entitlement.sh', '--install',
3055 get_option('bindir') / exe['name'],
3058 emulators += {exe['name']: emulator}
3063 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3064 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3065 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3066 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3068 custom_target(exe['name'] + stp['ext'],
3069 input: trace_events_all,
3070 output: exe['name'] + stp['ext'],
3071 install: stp['install'],
3072 install_dir: get_option('datadir') / 'systemtap/tapset',
3074 tracetool, '--group=all', '--format=' + stp['fmt'],
3075 '--binary=' + stp['bin'],
3076 '--target-name=' + target_name,
3077 '--target-type=' + target_type,
3078 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3079 '@INPUT@', '@OUTPUT@'
3081 depend_files: tracetool_depends)
3087 # Other build targets
3089 if 'CONFIG_PLUGIN' in config_host
3090 install_headers('include/qemu/qemu-plugin.h')
3093 if 'CONFIG_GUEST_AGENT' in config_host
3095 elif get_option('guest_agent_msi').enabled()
3096 error('Guest agent MSI requested, but the guest agent is not being built')
3099 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3100 # when we don't build tools or system
3101 if xkbcommon.found()
3102 # used for the update-keymaps target, so include rules even if !have_tools
3103 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3104 dependencies: [qemuutil, xkbcommon], install: have_tools)
3108 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3109 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3110 qemu_io = executable('qemu-io', files('qemu-io.c'),
3111 dependencies: [block, qemuutil], install: true)
3112 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3113 dependencies: [blockdev, qemuutil, gnutls, selinux],
3116 subdir('storage-daemon')
3117 subdir('contrib/rdmacm-mux')
3118 subdir('contrib/elf2dmp')
3120 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3121 dependencies: qemuutil,
3124 if 'CONFIG_VHOST_USER' in config_host
3125 subdir('contrib/vhost-user-blk')
3126 subdir('contrib/vhost-user-gpu')
3127 subdir('contrib/vhost-user-input')
3128 subdir('contrib/vhost-user-scsi')
3131 if targetos == 'linux'
3132 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3133 dependencies: [qemuutil, libcap_ng],
3135 install_dir: get_option('libexecdir'))
3137 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3138 dependencies: [authz, crypto, io, qom, qemuutil,
3139 libcap_ng, mpathpersist],
3144 subdir('contrib/ivshmem-client')
3145 subdir('contrib/ivshmem-server')
3158 if host_machine.system() == 'windows'
3160 find_program('scripts/nsis.py'),
3162 get_option('prefix'),
3163 meson.current_source_dir(),
3166 '-DDISPLAYVERSION=' + meson.project_version(),
3169 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3172 nsis_cmd += '-DCONFIG_GTK=y'
3175 nsis = custom_target('nsis',
3176 output: 'qemu-setup-' + meson.project_version() + '.exe',
3177 input: files('qemu.nsi'),
3178 build_always_stale: true,
3179 command: nsis_cmd + ['@INPUT@'])
3180 alias_target('installer', nsis)
3183 #########################
3184 # Configuration summary #
3185 #########################
3189 summary_info += {'Install prefix': get_option('prefix')}
3190 summary_info += {'BIOS directory': qemu_datadir}
3191 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
3192 summary_info += {'binary directory': get_option('bindir')}
3193 summary_info += {'library directory': get_option('libdir')}
3194 summary_info += {'module directory': qemu_moddir}
3195 summary_info += {'libexec directory': get_option('libexecdir')}
3196 summary_info += {'include directory': get_option('includedir')}
3197 summary_info += {'config directory': get_option('sysconfdir')}
3198 if targetos != 'windows'
3199 summary_info += {'local state directory': get_option('localstatedir')}
3200 summary_info += {'Manual directory': get_option('mandir')}
3202 summary_info += {'local state directory': 'queried at runtime'}
3204 summary_info += {'Doc directory': get_option('docdir')}
3205 summary_info += {'Build directory': meson.current_build_dir()}
3206 summary_info += {'Source path': meson.current_source_dir()}
3207 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3208 summary(summary_info, bool_yn: true, section: 'Directories')
3212 summary_info += {'git': config_host['GIT']}
3213 summary_info += {'make': config_host['MAKE']}
3214 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3215 summary_info += {'sphinx-build': sphinx_build}
3216 if config_host.has_key('HAVE_GDB_BIN')
3217 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3219 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3220 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
3221 summary_info += {'wixl': wixl}
3223 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
3224 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
3226 summary(summary_info, bool_yn: true, section: 'Host binaries')
3228 # Configurable features
3230 summary_info += {'Documentation': build_docs}
3231 summary_info += {'system-mode emulation': have_system}
3232 summary_info += {'user-mode emulation': have_user}
3233 summary_info += {'block layer': have_block}
3234 summary_info += {'Install blobs': get_option('install_blobs')}
3235 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3236 if config_host.has_key('CONFIG_MODULES')
3237 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
3239 summary_info += {'fuzzing support': get_option('fuzzing')}
3241 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3243 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3244 if 'simple' in get_option('trace_backends')
3245 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3247 summary_info += {'D-Bus display': dbus_display}
3248 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
3249 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
3250 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
3251 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
3252 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
3253 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
3254 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
3255 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3256 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
3257 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
3258 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
3259 summary(summary_info, bool_yn: true, section: 'Configurable features')
3261 # Compilation information
3263 summary_info += {'host CPU': cpu}
3264 summary_info += {'host endianness': build_machine.endian()}
3265 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3266 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3267 if link_language == 'cpp'
3268 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3270 summary_info += {'C++ compiler': false}
3272 if targetos == 'darwin'
3273 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3275 if targetos == 'windows'
3276 if 'WIN_SDK' in config_host
3277 summary_info += {'Windows SDK': config_host['WIN_SDK']}
3280 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3281 + ['-O' + get_option('optimization')]
3282 + (get_option('debug') ? ['-g'] : []))}
3283 if link_language == 'cpp'
3284 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3285 + ['-O' + get_option('optimization')]
3286 + (get_option('debug') ? ['-g'] : []))}
3288 link_args = get_option(link_language + '_link_args')
3289 if link_args.length() > 0
3290 summary_info += {'LDFLAGS': ' '.join(link_args)}
3292 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
3293 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
3294 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
3295 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3296 summary_info += {'PIE': get_option('b_pie')}
3297 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3298 summary_info += {'malloc trim support': has_malloc_trim}
3299 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
3300 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
3301 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
3302 summary_info += {'memory allocator': get_option('malloc')}
3303 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
3304 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
3305 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
3306 summary_info += {'gcov': get_option('b_coverage')}
3307 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3308 summary_info += {'CFI support': get_option('cfi')}
3309 if get_option('cfi')
3310 summary_info += {'CFI debug support': get_option('cfi_debug')}
3312 summary_info += {'strip binaries': get_option('strip')}
3313 summary_info += {'sparse': sparse}
3314 summary_info += {'mingw32 support': targetos == 'windows'}
3316 # snarf the cross-compilation information for tests
3317 foreach target: target_dirs
3318 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3319 if fs.exists(tcg_mak)
3320 config_cross_tcg = keyval.load(tcg_mak)
3321 target = config_cross_tcg['TARGET_NAME']
3323 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3324 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3325 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3326 elif 'CROSS_CC_GUEST' in config_cross_tcg
3327 summary_info += {target + ' tests'
3328 : config_cross_tcg['CROSS_CC_GUEST'] }
3333 summary(summary_info, bool_yn: true, section: 'Compilation')
3335 # Targets and accelerators
3338 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3339 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3340 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3341 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3342 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3343 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
3344 if config_host.has_key('CONFIG_XEN_BACKEND')
3345 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
3348 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3349 if config_all.has_key('CONFIG_TCG')
3350 if get_option('tcg_interpreter')
3351 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
3353 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3355 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3356 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3358 summary_info += {'target list': ' '.join(target_dirs)}
3360 summary_info += {'default devices': get_option('default_devices')}
3361 summary_info += {'out of process emulation': multiprocess_allowed}
3363 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3367 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3368 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
3370 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3371 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3372 summary_info += {'Use block whitelist in tools': config_host.has_key('CONFIG_BDRV_WHITELIST_TOOLS')}
3373 summary_info += {'VirtFS support': have_virtfs}
3374 summary_info += {'build virtiofs daemon': have_virtiofsd}
3375 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
3376 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
3377 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
3378 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
3379 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
3380 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
3381 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
3382 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
3383 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
3384 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
3385 summary_info += {'FUSE exports': fuse}
3387 summary(summary_info, bool_yn: true, section: 'Block layer support')
3391 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
3392 summary_info += {'GNUTLS support': gnutls}
3394 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3396 summary_info += {'libgcrypt': gcrypt}
3397 summary_info += {'nettle': nettle}
3399 summary_info += {' XTS': xts != 'private'}
3401 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
3402 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
3403 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
3404 summary(summary_info, bool_yn: true, section: 'Crypto')
3408 if targetos == 'darwin'
3409 summary_info += {'Cocoa support': cocoa}
3411 summary_info += {'SDL support': sdl}
3412 summary_info += {'SDL image support': sdl_image}
3413 summary_info += {'GTK support': gtk}
3414 summary_info += {'pixman': pixman}
3415 summary_info += {'VTE support': vte}
3416 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3417 summary_info += {'libtasn1': tasn1}
3418 summary_info += {'PAM': pam}
3419 summary_info += {'iconv support': iconv}
3420 summary_info += {'curses support': curses}
3421 summary_info += {'virgl support': virgl}
3422 summary_info += {'curl support': curl}
3423 summary_info += {'Multipath support': mpathpersist}
3424 summary_info += {'VNC support': vnc}
3426 summary_info += {'VNC SASL support': sasl}
3427 summary_info += {'VNC JPEG support': jpeg}
3428 summary_info += {'VNC PNG support': png}
3430 if targetos not in ['darwin', 'haiku', 'windows']
3431 summary_info += {'OSS support': oss}
3432 elif targetos == 'darwin'
3433 summary_info += {'CoreAudio support': coreaudio}
3434 elif targetos == 'windows'
3435 summary_info += {'DirectSound support': dsound}
3437 if targetos == 'linux'
3438 summary_info += {'ALSA support': alsa}
3439 summary_info += {'PulseAudio support': pulse}
3441 summary_info += {'JACK support': jack}
3442 summary_info += {'brlapi support': brlapi}
3443 summary_info += {'vde support': vde}
3444 summary_info += {'netmap support': have_netmap}
3445 summary_info += {'l2tpv3 support': have_l2tpv3}
3446 summary_info += {'Linux AIO support': libaio}
3447 summary_info += {'Linux io_uring support': linux_io_uring}
3448 summary_info += {'ATTR/XATTR support': libattr}
3449 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
3450 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
3451 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3452 summary_info += {'libcap-ng support': libcap_ng}
3453 summary_info += {'bpf support': libbpf}
3454 summary_info += {'spice protocol support': spice_protocol}
3455 if spice_protocol.found()
3456 summary_info += {' spice server support': spice}
3458 summary_info += {'rbd support': rbd}
3459 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
3460 summary_info += {'smartcard support': cacard}
3461 summary_info += {'U2F support': u2f}
3462 summary_info += {'libusb': libusb}
3463 summary_info += {'usb net redir': usbredir}
3464 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
3465 summary_info += {'GBM': gbm}
3466 summary_info += {'libiscsi support': libiscsi}
3467 summary_info += {'libnfs support': libnfs}
3468 if targetos == 'windows'
3469 if config_host.has_key('CONFIG_GUEST_AGENT')
3470 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
3471 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
3474 summary_info += {'seccomp support': seccomp}
3475 summary_info += {'GlusterFS support': glusterfs}
3476 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
3477 summary_info += {'libssh support': libssh}
3478 summary_info += {'lzo support': lzo}
3479 summary_info += {'snappy support': snappy}
3480 summary_info += {'bzip2 support': libbzip2}
3481 summary_info += {'lzfse support': liblzfse}
3482 summary_info += {'zstd support': zstd}
3483 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
3484 summary_info += {'libxml2': libxml2}
3485 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3486 summary_info += {'libpmem support': libpmem}
3487 summary_info += {'libdaxctl support': libdaxctl}
3488 summary_info += {'libudev': libudev}
3489 # Dummy dependency, keep .found()
3490 summary_info += {'FUSE lseek': fuse_lseek.found()}
3491 summary_info += {'selinux': selinux}
3492 summary(summary_info, bool_yn: true, section: 'Dependencies')
3494 if not supported_cpus.contains(cpu)
3496 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3498 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3499 message('The QEMU project intends to remove support for this host CPU in')
3500 message('a future release if nobody volunteers to maintain it and to')
3501 message('provide a build host for our continuous integration setup.')
3502 message('configure has succeeded and you can continue to build, but')
3503 message('if you care about QEMU on this platform you should contact')
3504 message('us upstream at qemu-devel@nongnu.org.')
3507 if not supported_oses.contains(targetos)
3509 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3511 message('Host OS ' + targetos + 'support is not currently maintained.')
3512 message('The QEMU project intends to remove support for this host OS in')
3513 message('a future release if nobody volunteers to maintain it and to')
3514 message('provide a build host for our continuous integration setup.')
3515 message('configure has succeeded and you can continue to build, but')
3516 message('if you care about QEMU on this platform you should contact')
3517 message('us upstream at qemu-devel@nongnu.org.')