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
81 if cpu in ['x86', 'x86_64']
82 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
84 kvm_targets = ['aarch64-softmmu']
86 kvm_targets = ['s390x-softmmu']
87 elif cpu in ['ppc', 'ppc64']
88 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
89 elif cpu in ['mips', 'mips64']
90 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
96 if not get_option('kvm').disabled() and targetos == 'linux'
97 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
99 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
101 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
103 if cpu in ['aarch64']
104 accelerator_targets += {
105 'CONFIG_HVF': ['aarch64-softmmu']
109 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
110 # i386 emulator provides xenpv machine type for multiple architectures
111 accelerator_targets += {
112 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
115 if cpu in ['x86', 'x86_64']
116 accelerator_targets += {
117 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
118 'CONFIG_HVF': ['x86_64-softmmu'],
119 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
120 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
125 # Darwin does not support references to thread-local variables in modules
126 if targetos != 'darwin'
127 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
130 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
131 unpack_edk2_blobs = false
132 foreach target : edk2_targets
133 if target in target_dirs
134 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
135 unpack_edk2_blobs = bzip2.found()
142 if 'dtrace' in get_option('trace_backends')
143 dtrace = find_program('dtrace', required: true)
144 stap = find_program('stap', required: false)
146 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
147 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
148 # instead. QEMU --enable-modules depends on this because the SystemTap
149 # semaphores are linked into the main binary and not the module's shared
151 add_global_arguments('-DSTAP_SDT_V2',
152 native: false, language: ['c', 'cpp', 'objc'])
160 # Specify linker-script with add_project_link_arguments so that it is not placed
161 # within a linker --start-group/--end-group pair
162 if get_option('fuzzing')
163 add_project_link_arguments(['-Wl,-T,',
164 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
165 native: false, language: ['c', 'cpp', 'objc'])
167 # Specify a filter to only instrument code that is directly related to
169 configure_file(output: 'instrumentation-filter',
170 input: 'scripts/oss-fuzz/instrumentation-filter-template',
172 add_global_arguments(
173 cc.get_supported_arguments('-fsanitize-coverage-allowlist=instrumentation-filter'),
174 native: false, language: ['c', 'cpp', 'objc'])
176 if get_option('fuzzing_engine') == ''
177 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
178 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
179 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
180 # unable to bind the fuzzer-related callbacks added by instrumentation.
181 add_global_arguments('-fsanitize=fuzzer-no-link',
182 native: false, language: ['c', 'cpp', 'objc'])
183 add_global_link_arguments('-fsanitize=fuzzer-no-link',
184 native: false, language: ['c', 'cpp', 'objc'])
185 # For the actual fuzzer binaries, we need to link against the libfuzzer
186 # library. They need to be configurable, to support OSS-Fuzz
187 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
189 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
190 # the needed CFLAGS have already been provided
191 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
195 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
196 native: false, language: ['c', 'objc'])
197 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
198 native: false, language: 'cpp')
199 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
200 native: false, language: ['c', 'cpp', 'objc'])
202 if targetos == 'linux'
203 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
204 '-isystem', 'linux-headers',
205 language: ['c', 'cpp'])
208 add_project_arguments('-iquote', '.',
209 '-iquote', meson.current_source_dir(),
210 '-iquote', meson.current_source_dir() / 'include',
211 '-iquote', meson.current_source_dir() / 'disas/libvixl',
212 language: ['c', 'cpp', 'objc'])
214 link_language = meson.get_external_property('link_language', 'cpp')
215 if link_language == 'cpp'
216 add_languages('cpp', required: true, native: false)
217 cxx = meson.get_compiler('cpp')
222 if host_machine.system() == 'darwin'
223 add_languages('objc', required: false, native: false)
226 sparse = find_program('cgcc', required: get_option('sparse'))
229 command: [find_program('scripts/check_sparse.py'),
230 'compile_commands.json', sparse.full_path(), '-Wbitwise',
231 '-Wno-transparent-union', '-Wno-old-initializer',
232 '-Wno-non-pointer-null'])
235 ###########################################
236 # Target-specific checks and dependencies #
237 ###########################################
239 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
242 #include <sys/types.h>
243 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
244 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
246 args: ['-Werror', '-fsanitize=fuzzer'])
247 error('Your compiler does not support -fsanitize=fuzzer')
250 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
251 error('ftrace is supported only on Linux')
253 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
256 openlog("qemu", LOG_PID, LOG_DAEMON);
257 syslog(LOG_INFO, "configure");
260 error('syslog is not supported on this system')
263 if targetos != 'linux' and get_option('mpath').enabled()
264 error('Multipath is supported only on Linux')
267 if targetos != 'linux' and get_option('multiprocess').enabled()
268 error('Multiprocess QEMU is supported only on Linux')
270 multiprocess_allowed = targetos == 'linux' and not get_option('multiprocess').disabled()
272 libm = cc.find_library('m', required: false)
273 threads = dependency('threads')
274 util = cc.find_library('util', required: false)
280 emulator_link_args = []
284 if targetos == 'windows'
285 socket = cc.find_library('ws2_32')
286 winmm = cc.find_library('winmm')
288 win = import('windows')
289 version_res = win.compile_resources('version.rc',
290 depend_files: files('pc-bios/qemu-nsis.ico'),
291 include_directories: include_directories('.'))
293 elif targetos == 'darwin'
294 coref = dependency('appleframeworks', modules: 'CoreFoundation')
295 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
296 host_dsosuf = '.dylib'
297 elif targetos == 'sunos'
298 socket = [cc.find_library('socket'),
299 cc.find_library('nsl'),
300 cc.find_library('resolv')]
301 elif targetos == 'haiku'
302 socket = [cc.find_library('posix_error_mapper'),
303 cc.find_library('network'),
304 cc.find_library('bsd')]
305 elif targetos == 'openbsd'
306 if not get_option('tcg').disabled() and target_dirs.length() > 0
307 # Disable OpenBSD W^X if available
308 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
313 if not get_option('kvm').disabled() and targetos == 'linux'
314 accelerators += 'CONFIG_KVM'
316 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
317 accelerators += 'CONFIG_XEN'
318 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
320 have_xen_pci_passthrough = false
322 if not get_option('whpx').disabled() and targetos == 'windows'
323 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
324 error('WHPX requires 64-bit host')
325 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
326 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
327 accelerators += 'CONFIG_WHPX'
330 if not get_option('hvf').disabled()
331 hvf = dependency('appleframeworks', modules: 'Hypervisor',
332 required: get_option('hvf'))
334 accelerators += 'CONFIG_HVF'
337 if not get_option('hax').disabled()
338 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
339 accelerators += 'CONFIG_HAX'
342 if targetos == 'netbsd'
343 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
345 accelerators += 'CONFIG_NVMM'
350 if not get_option('tcg').disabled()
351 if host_arch == 'unknown'
352 if get_option('tcg_interpreter')
353 warning('Unsupported CPU @0@, will use TCG with TCI (slow)'.format(cpu))
355 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
357 elif get_option('tcg_interpreter')
358 warning('Use of the TCG interpreter is not recommended on this host')
359 warning('architecture. There is a native TCG execution backend available')
360 warning('which provides substantially better performance and reliability.')
361 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
362 warning('configuration option on this architecture to use the native')
365 if get_option('tcg_interpreter')
367 elif host_arch == 'sparc64'
369 elif host_arch == 'x86_64'
371 elif host_arch == 'ppc64'
374 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
375 language: ['c', 'cpp', 'objc'])
377 accelerators += 'CONFIG_TCG'
378 config_host += { 'CONFIG_TCG': 'y' }
381 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
382 error('KVM not available on this platform')
384 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
385 error('HVF not available on this platform')
387 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
388 error('NVMM not available on this platform')
390 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
391 error('WHPX not available on this platform')
393 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
394 if 'CONFIG_XEN' in accelerators
395 error('Xen PCI passthrough not available on this platform')
397 error('Xen PCI passthrough requested but Xen not enabled')
405 # The path to glib.h is added to all compilation commands. This was
406 # grandfathered in from the QEMU Makefiles.
407 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
408 native: false, language: ['c', 'cpp', 'objc'])
409 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
410 link_args: config_host['GLIB_LIBS'].split(),
411 version: config_host['GLIB_VERSION'])
412 # override glib dep with the configure results (for subprojects)
413 meson.override_dependency('glib-2.0', glib)
416 if 'CONFIG_GIO' in config_host
417 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
418 link_args: config_host['GIO_LIBS'].split(),
419 version: config_host['GLIB_VERSION'])
422 if 'ust' in get_option('trace_backends')
423 lttng = dependency('lttng-ust', required: true, method: 'pkg-config',
424 kwargs: static_kwargs)
427 if have_system or have_tools
428 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
429 method: 'pkg-config', kwargs: static_kwargs)
431 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
434 if not get_option('linux_aio').auto() or have_block
435 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
436 required: get_option('linux_aio'),
437 kwargs: static_kwargs)
439 linux_io_uring = not_found
440 if not get_option('linux_io_uring').auto() or have_block
441 linux_io_uring = dependency('liburing', required: get_option('linux_io_uring'),
442 method: 'pkg-config', kwargs: static_kwargs)
445 if not get_option('libxml2').auto() or have_block
446 libxml2 = dependency('libxml-2.0', required: get_option('libxml2'),
447 method: 'pkg-config', kwargs: static_kwargs)
450 if not get_option('libnfs').auto() or have_block
451 libnfs = dependency('libnfs', version: '>=1.9.3',
452 required: get_option('libnfs'),
453 method: 'pkg-config', kwargs: static_kwargs)
458 #include <sys/types.h>
459 #ifdef CONFIG_LIBATTR
460 #include <attr/xattr.h>
462 #include <sys/xattr.h>
464 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
467 have_old_libattr = false
468 if not get_option('attr').disabled()
469 if cc.links(libattr_test)
470 libattr = declare_dependency()
472 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
473 required: get_option('attr'),
474 kwargs: static_kwargs)
475 if libattr.found() and not \
476 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
478 if get_option('attr').enabled()
479 error('could not link libattr')
481 warning('could not link libattr, disabling')
484 have_old_libattr = libattr.found()
489 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
490 if cocoa.found() and get_option('sdl').enabled()
491 error('Cocoa and SDL cannot be enabled at the same time')
493 if cocoa.found() and get_option('gtk').enabled()
494 error('Cocoa and GTK+ cannot be enabled at the same time')
498 if not get_option('seccomp').auto() or have_system or have_tools
499 seccomp = dependency('libseccomp', version: '>=2.3.0',
500 required: get_option('seccomp'),
501 method: 'pkg-config', kwargs: static_kwargs)
504 libcap_ng = not_found
505 if not get_option('cap_ng').auto() or have_system or have_tools
506 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
507 required: get_option('cap_ng'),
508 kwargs: static_kwargs)
510 if libcap_ng.found() and not cc.links('''
514 capng_capability_to_name(CAPNG_EFFECTIVE);
516 }''', dependencies: libcap_ng)
517 libcap_ng = not_found
518 if get_option('cap_ng').enabled()
519 error('could not link libcap-ng')
521 warning('could not link libcap-ng, disabling')
525 if get_option('xkbcommon').auto() and not have_system and not have_tools
526 xkbcommon = not_found
528 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
529 method: 'pkg-config', kwargs: static_kwargs)
533 if not get_option('vde').auto() or have_system or have_tools
534 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
535 required: get_option('vde'),
536 kwargs: static_kwargs)
538 if vde.found() and not cc.links('''
539 #include <libvdeplug.h>
542 struct vde_open_args a = {0, 0, 0};
546 }''', dependencies: vde)
548 if get_option('cap_ng').enabled()
549 error('could not link libvdeplug')
551 warning('could not link libvdeplug, disabling')
556 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
557 pulse = dependency('libpulse', required: get_option('pa'),
558 method: 'pkg-config', kwargs: static_kwargs)
561 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
562 alsa = dependency('alsa', required: get_option('alsa'),
563 method: 'pkg-config', kwargs: static_kwargs)
566 if not get_option('jack').auto() or have_system
567 jack = dependency('jack', required: get_option('jack'),
568 method: 'pkg-config', kwargs: static_kwargs)
571 spice_protocol = not_found
572 if not get_option('spice_protocol').auto() or have_system
573 spice_protocol = dependency('spice-protocol', version: '>=0.12.3',
574 required: get_option('spice_protocol'),
575 method: 'pkg-config', kwargs: static_kwargs)
578 if not get_option('spice').auto() or have_system
579 spice = dependency('spice-server', version: '>=0.12.5',
580 required: get_option('spice'),
581 method: 'pkg-config', kwargs: static_kwargs)
583 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
585 rt = cc.find_library('rt', required: false)
588 if not get_option('libiscsi').auto() or have_block
589 libiscsi = dependency('libiscsi', version: '>=1.9.0',
590 required: get_option('libiscsi'),
591 method: 'pkg-config', kwargs: static_kwargs)
594 if not get_option('zstd').auto() or have_block
595 zstd = dependency('libzstd', version: '>=1.4.0',
596 required: get_option('zstd'),
597 method: 'pkg-config', kwargs: static_kwargs)
600 if not get_option('virglrenderer').auto() or have_system
601 virgl = dependency('virglrenderer',
602 method: 'pkg-config',
603 required: get_option('virglrenderer'),
604 kwargs: static_kwargs)
607 if not get_option('curl').auto() or have_block
608 curl = dependency('libcurl', version: '>=7.29.0',
609 method: 'pkg-config',
610 required: get_option('curl'),
611 kwargs: static_kwargs)
614 if targetos == 'linux' and (have_system or have_tools)
615 libudev = dependency('libudev',
616 method: 'pkg-config',
617 required: get_option('libudev'),
618 kwargs: static_kwargs)
621 mpathlibs = [libudev]
622 mpathpersist = not_found
623 mpathpersist_new_api = false
624 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
625 mpath_test_source_new = '''
627 #include <mpath_persist.h>
628 unsigned mpath_mx_alloc_len = 1024;
630 static struct config *multipath_conf;
631 extern struct udev *udev;
632 extern struct config *get_multipath_config(void);
633 extern void put_multipath_config(struct config *conf);
635 struct config *get_multipath_config(void) { return multipath_conf; }
636 void put_multipath_config(struct config *conf) { }
639 multipath_conf = mpath_lib_init();
642 mpath_test_source_old = '''
644 #include <mpath_persist.h>
645 unsigned mpath_mx_alloc_len = 1024;
648 struct udev *udev = udev_new();
649 mpath_lib_init(udev);
652 libmpathpersist = cc.find_library('mpathpersist',
653 required: get_option('mpath'),
654 kwargs: static_kwargs)
655 if libmpathpersist.found()
656 mpathlibs += libmpathpersist
658 mpathlibs += cc.find_library('devmapper',
659 required: get_option('mpath'),
660 kwargs: static_kwargs)
662 mpathlibs += cc.find_library('multipath',
663 required: get_option('mpath'),
664 kwargs: static_kwargs)
665 foreach lib: mpathlibs
671 if mpathlibs.length() == 0
672 msg = 'Dependencies missing for libmpathpersist'
673 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
674 mpathpersist = declare_dependency(dependencies: mpathlibs)
675 mpathpersist_new_api = true
676 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
677 mpathpersist = declare_dependency(dependencies: mpathlibs)
679 msg = 'Cannot detect libmpathpersist API'
681 if not mpathpersist.found()
682 if get_option('mpath').enabled()
685 warning(msg + ', disabling')
693 if have_system and not get_option('curses').disabled()
695 #if defined(__APPLE__) || defined(__OpenBSD__)
696 #define _XOPEN_SOURCE_EXTENDED 1
703 setlocale(LC_ALL, "");
705 addwstr(L"wide chars\n");
707 add_wch(WACS_DEGREE);
711 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
712 foreach curses_dep : curses_dep_list
713 if not curses.found()
714 curses = dependency(curses_dep,
716 method: 'pkg-config',
717 kwargs: static_kwargs)
720 msg = get_option('curses').enabled() ? 'curses library not found' : ''
721 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
723 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
724 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
726 msg = 'curses package not usable'
730 if not curses.found()
731 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
732 if targetos != 'windows' and not has_curses_h
733 message('Trying with /usr/include/ncursesw')
734 curses_compile_args += ['-I/usr/include/ncursesw']
735 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
738 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
739 foreach curses_libname : curses_libname_list
740 libcurses = cc.find_library(curses_libname,
742 kwargs: static_kwargs)
744 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
745 curses = declare_dependency(compile_args: curses_compile_args,
746 dependencies: [libcurses])
749 msg = 'curses library not usable'
755 if not get_option('iconv').disabled()
756 foreach link_args : [ ['-liconv'], [] ]
757 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
758 # We need to use libiconv if available because mixing libiconv's headers with
759 # the system libc does not work.
760 # However, without adding glib to the dependencies -L/usr/local/lib will not be
761 # included in the command line and libiconv will not be found.
765 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
766 return conv != (iconv_t) -1;
767 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
768 iconv = declare_dependency(link_args: link_args, dependencies: glib)
773 if curses.found() and not iconv.found()
774 if get_option('iconv').enabled()
775 error('iconv not available')
777 msg = 'iconv required for curses UI but not available'
780 if not curses.found() and msg != ''
781 if get_option('curses').enabled()
784 warning(msg + ', disabling')
790 if not get_option('brlapi').auto() or have_system
791 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
792 required: get_option('brlapi'),
793 kwargs: static_kwargs)
794 if brlapi.found() and not cc.links('''
797 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
799 if get_option('brlapi').enabled()
800 error('could not link brlapi')
802 warning('could not link brlapi, disabling')
808 if not get_option('sdl').auto() or (have_system and not cocoa.found())
809 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
810 sdl_image = not_found
813 # work around 2.0.8 bug
814 sdl = declare_dependency(compile_args: '-Wno-undef',
816 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
817 method: 'pkg-config', kwargs: static_kwargs)
819 if get_option('sdl_image').enabled()
820 error('sdl-image required, but SDL was @0@'.format(
821 get_option('sdl').disabled() ? 'disabled' : 'not found'))
823 sdl_image = not_found
827 if not get_option('rbd').auto() or have_block
828 librados = cc.find_library('rados', required: get_option('rbd'),
829 kwargs: static_kwargs)
830 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
831 required: get_option('rbd'),
832 kwargs: static_kwargs)
833 if librados.found() and librbd.found()
836 #include <rbd/librbd.h>
839 rados_create(&cluster, NULL);
840 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
844 }''', dependencies: [librbd, librados])
845 rbd = declare_dependency(dependencies: [librbd, librados])
846 elif get_option('rbd').enabled()
847 error('librbd >= 1.12.0 required')
849 warning('librbd >= 1.12.0 not found, disabling')
854 glusterfs = not_found
855 glusterfs_ftruncate_has_stat = false
856 glusterfs_iocb_has_stat = false
857 if not get_option('glusterfs').auto() or have_block
858 glusterfs = dependency('glusterfs-api', version: '>=3',
859 required: get_option('glusterfs'),
860 method: 'pkg-config', kwargs: static_kwargs)
862 glusterfs_ftruncate_has_stat = cc.links('''
863 #include <glusterfs/api/glfs.h>
868 /* new glfs_ftruncate() passes two additional args */
869 return glfs_ftruncate(NULL, 0, NULL, NULL);
871 ''', dependencies: glusterfs)
872 glusterfs_iocb_has_stat = cc.links('''
873 #include <glusterfs/api/glfs.h>
875 /* new glfs_io_cbk() passes two additional glfs_stat structs */
877 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
883 glfs_io_cbk iocb = &glusterfs_iocb;
884 iocb(NULL, 0 , NULL, NULL, NULL);
887 ''', dependencies: glusterfs)
892 if not get_option('libssh').auto() or have_block
893 libssh = dependency('libssh', version: '>=0.8.7',
894 method: 'pkg-config',
895 required: get_option('libssh'),
896 kwargs: static_kwargs)
900 if not get_option('bzip2').auto() or have_block
901 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
902 required: get_option('bzip2'),
903 kwargs: static_kwargs)
904 if libbzip2.found() and not cc.links('''
906 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
908 if get_option('bzip2').enabled()
909 error('could not link libbzip2')
911 warning('could not link libbzip2, disabling')
917 if not get_option('lzfse').auto() or have_block
918 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
919 required: get_option('lzfse'),
920 kwargs: static_kwargs)
922 if liblzfse.found() and not cc.links('''
924 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
926 if get_option('lzfse').enabled()
927 error('could not link liblzfse')
929 warning('could not link liblzfse, disabling')
934 if have_system and not get_option('oss').disabled()
935 if not cc.has_header('sys/soundcard.h')
937 elif targetos == 'netbsd'
938 oss = cc.find_library('ossaudio', required: get_option('oss'),
939 kwargs: static_kwargs)
941 oss = declare_dependency()
945 if get_option('oss').enabled()
946 error('OSS not found')
951 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
952 if cc.has_header('dsound.h')
953 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
956 if not dsound.found()
957 if get_option('dsound').enabled()
958 error('DirectSound not found')
963 coreaudio = not_found
964 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
965 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
966 required: get_option('coreaudio'))
970 if 'CONFIG_OPENGL' in config_host
971 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
972 link_args: config_host['OPENGL_LIBS'].split())
975 if (have_system or have_tools) and (virgl.found() or opengl.found())
976 gbm = dependency('gbm', method: 'pkg-config', required: false,
977 kwargs: static_kwargs)
981 gnutls_crypto = not_found
982 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
983 # For general TLS support our min gnutls matches
984 # that implied by our platform support matrix
986 # For the crypto backends, we look for a newer
989 # Version 3.6.8 is needed to get XTS
990 # Version 3.6.13 is needed to get PBKDF
991 # Version 3.6.14 is needed to get HW accelerated XTS
993 # If newer enough gnutls isn't available, we can
994 # still use a different crypto backend to satisfy
995 # the platform support requirements
996 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
997 method: 'pkg-config',
999 kwargs: static_kwargs)
1000 if gnutls_crypto.found()
1001 gnutls = gnutls_crypto
1003 # Our min version if all we need is TLS
1004 gnutls = dependency('gnutls', version: '>=3.5.18',
1005 method: 'pkg-config',
1006 required: get_option('gnutls'),
1007 kwargs: static_kwargs)
1011 # We prefer use of gnutls for crypto, unless the options
1012 # explicitly asked for nettle or gcrypt.
1014 # If gnutls isn't available for crypto, then we'll prefer
1015 # gcrypt over nettle for performance reasons.
1020 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1021 error('Only one of gcrypt & nettle can be enabled')
1024 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1025 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1026 gnutls_crypto = not_found
1029 if not gnutls_crypto.found()
1030 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1031 gcrypt = dependency('libgcrypt', version: '>=1.8',
1032 method: 'config-tool',
1033 required: get_option('gcrypt'),
1034 kwargs: static_kwargs)
1035 # Debian has removed -lgpg-error from libgcrypt-config
1036 # as it "spreads unnecessary dependencies" which in
1037 # turn breaks static builds...
1038 if gcrypt.found() and enable_static
1039 gcrypt = declare_dependency(dependencies: [
1041 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
1044 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1045 nettle = dependency('nettle', version: '>=3.4',
1046 method: 'pkg-config',
1047 required: get_option('nettle'),
1048 kwargs: static_kwargs)
1049 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1058 if not get_option('gtk').auto() or (have_system and not cocoa.found())
1059 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1060 method: 'pkg-config',
1061 required: get_option('gtk'),
1062 kwargs: static_kwargs)
1064 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1065 method: 'pkg-config',
1067 kwargs: static_kwargs)
1068 gtk = declare_dependency(dependencies: [gtk, gtkx11])
1070 if not get_option('vte').auto() or have_system
1071 vte = dependency('vte-2.91',
1072 method: 'pkg-config',
1073 required: get_option('vte'),
1074 kwargs: static_kwargs)
1081 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
1082 kwargs: static_kwargs)
1088 if have_system and not get_option('vnc').disabled()
1089 vnc = declare_dependency() # dummy dependency
1090 png = dependency('libpng', required: get_option('vnc_png'),
1091 method: 'pkg-config', kwargs: static_kwargs)
1092 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1093 method: 'pkg-config', kwargs: static_kwargs)
1094 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1095 required: get_option('vnc_sasl'),
1096 kwargs: static_kwargs)
1098 sasl = declare_dependency(dependencies: sasl,
1099 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1104 if not get_option('auth_pam').auto() or have_system
1105 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1106 required: get_option('auth_pam'),
1107 kwargs: static_kwargs)
1109 if pam.found() and not cc.links('''
1111 #include <security/pam_appl.h>
1113 const char *service_name = "qemu";
1114 const char *user = "frank";
1115 const struct pam_conv pam_conv = { 0 };
1116 pam_handle_t *pamh = NULL;
1117 pam_start(service_name, user, &pam_conv, &pamh);
1119 }''', dependencies: pam)
1121 if get_option('auth_pam').enabled()
1122 error('could not link libpam')
1124 warning('could not link libpam, disabling')
1129 if not get_option('snappy').auto() or have_system
1130 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1131 required: get_option('snappy'),
1132 kwargs: static_kwargs)
1134 if snappy.found() and not linker.links('''
1135 #include <snappy-c.h>
1136 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1138 if get_option('snappy').enabled()
1139 error('could not link libsnappy')
1141 warning('could not link libsnappy, disabling')
1146 if not get_option('lzo').auto() or have_system
1147 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1148 required: get_option('lzo'),
1149 kwargs: static_kwargs)
1151 if lzo.found() and not cc.links('''
1152 #include <lzo/lzo1x.h>
1153 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1155 if get_option('lzo').enabled()
1156 error('could not link liblzo2')
1158 warning('could not link liblzo2, disabling')
1163 if 'CONFIG_RDMA' in config_host
1164 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
1167 if 'CONFIG_NUMA' in config_host
1168 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
1171 if 'CONFIG_XEN_BACKEND' in config_host
1172 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
1173 link_args: config_host['XEN_LIBS'].split())
1176 if not get_option('smartcard').auto() or have_system
1177 cacard = dependency('libcacard', required: get_option('smartcard'),
1178 version: '>=2.5.1', method: 'pkg-config',
1179 kwargs: static_kwargs)
1183 u2f = dependency('u2f-emu', required: get_option('u2f'),
1184 method: 'pkg-config',
1185 kwargs: static_kwargs)
1187 usbredir = not_found
1188 if not get_option('usb_redir').auto() or have_system
1189 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1190 version: '>=0.6', method: 'pkg-config',
1191 kwargs: static_kwargs)
1194 if not get_option('libusb').auto() or have_system
1195 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1196 version: '>=1.0.13', method: 'pkg-config',
1197 kwargs: static_kwargs)
1201 if not get_option('libpmem').auto() or have_system
1202 libpmem = dependency('libpmem', required: get_option('libpmem'),
1203 method: 'pkg-config', kwargs: static_kwargs)
1205 libdaxctl = not_found
1206 if not get_option('libdaxctl').auto() or have_system
1207 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1208 version: '>=57', method: 'pkg-config',
1209 kwargs: static_kwargs)
1213 tasn1 = dependency('libtasn1',
1214 method: 'pkg-config',
1215 kwargs: static_kwargs)
1217 keyutils = dependency('libkeyutils', required: false,
1218 method: 'pkg-config', kwargs: static_kwargs)
1220 has_gettid = cc.has_function('gettid')
1223 selinux = dependency('libselinux',
1224 required: get_option('selinux'),
1225 method: 'pkg-config', kwargs: static_kwargs)
1230 if get_option('malloc') == 'system'
1232 not get_option('malloc_trim').disabled() and \
1233 cc.links('''#include <malloc.h>
1234 int main(void) { malloc_trim(0); return 0; }''')
1236 has_malloc_trim = false
1237 malloc = cc.find_library(get_option('malloc'), required: true)
1239 if not has_malloc_trim and get_option('malloc_trim').enabled()
1240 if get_option('malloc') == 'system'
1241 error('malloc_trim not available on this platform.')
1243 error('malloc_trim not available with non-libc memory allocator')
1247 # Check whether the glibc provides statx()
1249 gnu_source_prefix = '''
1254 statx_test = gnu_source_prefix + '''
1255 #include <sys/stat.h>
1257 struct statx statxbuf;
1258 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1262 has_statx = cc.links(statx_test)
1264 have_vhost_user_blk_server = (targetos == 'linux' and
1265 'CONFIG_VHOST_USER' in config_host)
1267 if get_option('vhost_user_blk_server').enabled()
1268 if targetos != 'linux'
1269 error('vhost_user_blk_server requires linux')
1270 elif 'CONFIG_VHOST_USER' not in config_host
1271 error('vhost_user_blk_server requires vhost-user support')
1273 elif get_option('vhost_user_blk_server').disabled() or not have_system
1274 have_vhost_user_blk_server = false
1278 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1279 error('Cannot enable fuse-lseek while fuse is disabled')
1282 fuse = dependency('fuse3', required: get_option('fuse'),
1283 version: '>=3.1', method: 'pkg-config',
1284 kwargs: static_kwargs)
1286 fuse_lseek = not_found
1287 if not get_option('fuse_lseek').disabled()
1288 if fuse.version().version_compare('>=3.8')
1290 fuse_lseek = declare_dependency()
1291 elif get_option('fuse_lseek').enabled()
1293 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1295 error('fuse-lseek requires libfuse, which was not found')
1301 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1302 if libbpf.found() and not cc.links('''
1303 #include <bpf/libbpf.h>
1306 bpf_object__destroy_skeleton(NULL);
1308 }''', dependencies: libbpf)
1310 if get_option('bpf').enabled()
1311 error('libbpf skeleton test failed')
1313 warning('libbpf skeleton test failed, disabling')
1321 audio_drivers_selected = []
1323 audio_drivers_available = {
1324 'alsa': alsa.found(),
1325 'coreaudio': coreaudio.found(),
1326 'dsound': dsound.found(),
1327 'jack': jack.found(),
1329 'pa': pulse.found(),
1332 foreach k, v: audio_drivers_available
1333 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1336 # Default to native drivers first, OSS second, SDL third
1337 audio_drivers_priority = \
1338 [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
1339 (targetos == 'linux' ? [] : [ 'sdl' ])
1340 audio_drivers_default = []
1341 foreach k: audio_drivers_priority
1342 if audio_drivers_available[k]
1343 audio_drivers_default += k
1347 foreach k: get_option('audio_drv_list')
1349 audio_drivers_selected += audio_drivers_default
1350 elif not audio_drivers_available[k]
1351 error('Audio driver "@0@" not available.'.format(k))
1353 audio_drivers_selected += k
1357 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1358 '"' + '", "'.join(audio_drivers_selected) + '", ')
1360 if get_option('cfi')
1362 # Check for dependency on LTO
1363 if not get_option('b_lto')
1364 error('Selected Control-Flow Integrity but LTO is disabled')
1366 if config_host.has_key('CONFIG_MODULES')
1367 error('Selected Control-Flow Integrity is not compatible with modules')
1369 # Check for cfi flags. CFI requires LTO so we can't use
1370 # get_supported_arguments, but need a more complex "compiles" which allows
1372 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1373 args: ['-flto', '-fsanitize=cfi-icall'] )
1374 cfi_flags += '-fsanitize=cfi-icall'
1376 error('-fsanitize=cfi-icall is not supported by the compiler')
1378 if cc.compiles('int main () { return 0; }',
1379 name: '-fsanitize-cfi-icall-generalize-pointers',
1380 args: ['-flto', '-fsanitize=cfi-icall',
1381 '-fsanitize-cfi-icall-generalize-pointers'] )
1382 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1384 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1386 if get_option('cfi_debug')
1387 if cc.compiles('int main () { return 0; }',
1388 name: '-fno-sanitize-trap=cfi-icall',
1389 args: ['-flto', '-fsanitize=cfi-icall',
1390 '-fno-sanitize-trap=cfi-icall'] )
1391 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1393 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1396 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1397 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1400 have_host_block_device = (targetos != 'darwin' or
1401 cc.has_header('IOKit/storage/IOMedia.h'))
1403 dbus_display = false
1404 if not get_option('dbus_display').disabled()
1405 # FIXME enable_modules shouldn't be necessary, but: https://github.com/mesonbuild/meson/issues/8333
1406 dbus_display = gio.version().version_compare('>=2.64') and config_host.has_key('GDBUS_CODEGEN') and enable_modules
1407 if get_option('dbus_display').enabled() and not dbus_display
1408 error('Requirements missing to enable -display dbus (glib>=2.64 && --enable-modules)')
1412 have_virtfs = (targetos == 'linux' and
1417 have_virtfs_proxy_helper = have_virtfs and have_tools
1419 if get_option('virtfs').enabled()
1421 if targetos != 'linux'
1422 error('virtio-9p (virtfs) requires Linux')
1423 elif not libcap_ng.found() or not libattr.found()
1424 error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1425 elif not have_system
1426 error('virtio-9p (virtfs) needs system emulation support')
1429 elif get_option('virtfs').disabled()
1433 foreach k : get_option('trace_backends')
1434 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1436 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1438 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1439 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1440 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1441 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1442 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1443 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1444 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1445 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1446 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1447 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1448 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1449 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1451 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
1453 config_host_data.set('CONFIG_ATTR', libattr.found())
1454 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1455 config_host_data.set('CONFIG_COCOA', cocoa.found())
1456 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1457 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1458 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1459 config_host_data.set('CONFIG_LZO', lzo.found())
1460 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1461 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1462 config_host_data.set('CONFIG_CURL', curl.found())
1463 config_host_data.set('CONFIG_CURSES', curses.found())
1464 config_host_data.set('CONFIG_GBM', gbm.found())
1465 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1466 if glusterfs.found()
1467 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1468 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1469 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1470 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1471 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1472 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1474 config_host_data.set('CONFIG_GTK', gtk.found())
1475 config_host_data.set('CONFIG_VTE', vte.found())
1476 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1477 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1478 config_host_data.set('CONFIG_EBPF', libbpf.found())
1479 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1480 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1481 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1482 config_host_data.set('CONFIG_LIBSSH', libssh.found())
1483 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1484 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1485 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1486 config_host_data.set('CONFIG_RBD', rbd.found())
1487 config_host_data.set('CONFIG_SDL', sdl.found())
1488 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1489 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1490 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1491 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1492 config_host_data.set('CONFIG_VDE', vde.found())
1493 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1494 config_host_data.set('CONFIG_VNC', vnc.found())
1495 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1496 config_host_data.set('CONFIG_VNC_PNG', png.found())
1497 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1498 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1499 config_host_data.set('CONFIG_VTE', vte.found())
1500 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1501 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1502 config_host_data.set('CONFIG_GETTID', has_gettid)
1503 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1504 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1505 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1506 config_host_data.set('CONFIG_NETTLE', nettle.found())
1507 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1508 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1509 config_host_data.set('CONFIG_STATX', has_statx)
1510 config_host_data.set('CONFIG_ZSTD', zstd.found())
1511 config_host_data.set('CONFIG_FUSE', fuse.found())
1512 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1513 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1514 if spice_protocol.found()
1515 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
1516 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
1517 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
1519 config_host_data.set('CONFIG_SPICE', spice.found())
1520 config_host_data.set('CONFIG_X11', x11.found())
1521 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
1522 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1523 config_host_data.set('CONFIG_SELINUX', selinux.found())
1524 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1525 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1526 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1527 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1529 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1530 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1531 config_host_data.set('HOST_WORDS_BIGENDIAN', host_machine.endian() == 'big')
1534 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1535 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1536 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1537 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1538 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1539 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1540 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1541 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1542 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1545 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1546 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1547 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1548 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1549 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1550 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
1551 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1552 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1553 config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
1554 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1555 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1556 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1557 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1558 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1559 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1560 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1561 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1562 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1564 config_host_data.set('HAVE_IBV_ADVISE_MR',
1565 cc.has_function('ibv_advise_mr',
1566 args: config_host['RDMA_LIBS'].split(),
1567 prefix: '#include <infiniband/verbs.h>'))
1571 config_host_data.set('CONFIG_BYTESWAP_H',
1572 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1573 config_host_data.set('CONFIG_EPOLL_CREATE1',
1574 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1575 config_host_data.set('CONFIG_HAS_ENVIRON',
1576 cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix))
1577 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1578 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1579 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1580 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1581 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1582 config_host_data.set('CONFIG_FIEMAP',
1583 cc.has_header('linux/fiemap.h') and
1584 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1585 config_host_data.set('CONFIG_GETRANDOM',
1586 cc.has_function('getrandom') and
1587 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1588 config_host_data.set('CONFIG_INOTIFY',
1589 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1590 config_host_data.set('CONFIG_INOTIFY1',
1591 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1592 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1593 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1594 prefix: '''#include <sys/endian.h>
1595 #include <sys/types.h>'''))
1596 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1597 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1598 config_host_data.set('CONFIG_RTNETLINK',
1599 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1600 config_host_data.set('CONFIG_SYSMACROS',
1601 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1602 config_host_data.set('HAVE_OPTRESET',
1603 cc.has_header_symbol('getopt.h', 'optreset'))
1604 config_host_data.set('HAVE_IPPROTO_MPTCP',
1605 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1608 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1609 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1610 prefix: '#include <signal.h>'))
1611 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1612 cc.has_member('struct stat', 'st_atim',
1613 prefix: '#include <sys/stat.h>'))
1616 config_host_data.set('CONFIG_IOVEC',
1617 cc.has_type('struct iovec',
1618 prefix: '#include <sys/uio.h>'))
1619 config_host_data.set('HAVE_UTMPX',
1620 cc.has_type('struct utmpx',
1621 prefix: '#include <utmpx.h>'))
1623 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1624 #include <sys/eventfd.h>
1625 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1626 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1629 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1630 return fdatasync(0);
1632 #error Not supported
1635 config_host_data.set('CONFIG_MADVISE', cc.links(gnu_source_prefix + '''
1636 #include <sys/types.h>
1637 #include <sys/mman.h>
1639 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }'''))
1640 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1641 #include <sys/mman.h>
1642 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1643 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1645 #if !defined(AT_EMPTY_PATH)
1646 # error missing definition
1648 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1650 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1657 return pipe2(pipefd, O_CLOEXEC);
1659 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1660 #include <sys/mman.h>
1662 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1664 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
1665 #include <pthread.h>
1667 static void *f(void *p) { return NULL; }
1671 pthread_create(&thread, 0, f, 0);
1672 pthread_setname_np(thread, "QEMU");
1674 }''', dependencies: threads))
1675 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
1676 #include <pthread.h>
1678 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
1682 pthread_create(&thread, 0, f, 0);
1684 }''', dependencies: threads))
1686 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1687 #include <sys/signalfd.h>
1689 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1690 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1698 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1699 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1703 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
1704 #include <sys/mman.h>
1705 int main(int argc, char *argv[]) {
1706 return mlockall(MCL_FUTURE);
1710 if not get_option('l2tpv3').disabled() and have_system
1711 have_l2tpv3 = cc.has_type('struct mmsghdr',
1712 prefix: gnu_source_prefix + '''
1713 #include <sys/socket.h>
1714 #include <linux/ip.h>''')
1716 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
1719 if not get_option('netmap').disabled() and have_system
1720 have_netmap = cc.compiles('''
1721 #include <inttypes.h>
1723 #include <net/netmap.h>
1724 #include <net/netmap_user.h>
1725 #if (NETMAP_API < 11) || (NETMAP_API > 15)
1728 int main(void) { return 0; }''')
1729 if not have_netmap and get_option('netmap').enabled()
1730 error('Netmap headers not available')
1733 config_host_data.set('CONFIG_NETMAP', have_netmap)
1735 # Work around a system header bug with some kernel/XFS header
1736 # versions where they both try to define 'struct fsxattr':
1737 # xfs headers will not try to redefine structs from linux headers
1738 # if this macro is set.
1739 config_host_data.set('HAVE_FSXATTR', cc.links('''
1740 #include <linux/fs.h>
1746 # Some versions of Mac OS X incorrectly define SIZE_MAX
1747 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1750 int main(int argc, char *argv[]) {
1751 return printf("%zu", SIZE_MAX);
1752 }''', args: ['-Werror']))
1754 # See if 64-bit atomic operations are supported.
1755 # Note that without __atomic builtins, we can only
1756 # assume atomic loads/stores max at pointer size.
1757 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
1761 uint64_t x = 0, y = 0;
1762 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
1763 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
1764 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
1765 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
1766 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
1770 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
1771 #include <sys/auxv.h>
1773 return getauxval(AT_HWCAP) == 0;
1776 config_host_data.set('CONFIG_AF_VSOCK', cc.compiles(gnu_source_prefix + '''
1778 #include <sys/types.h>
1779 #include <sys/socket.h>
1780 #if !defined(AF_VSOCK)
1781 # error missing AF_VSOCK flag
1783 #include <linux/vm_sockets.h>
1786 struct sockaddr_vm svm;
1787 socklen_t len = sizeof(svm);
1788 sock = socket(AF_VSOCK, SOCK_STREAM, 0);
1789 ret = getpeername(sock, (struct sockaddr *)&svm, &len);
1790 if ((ret == -1) && (errno == ENOTCONN)) {
1796 ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target
1798 arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1799 strings = ['CONFIG_IASL']
1800 foreach k, v: config_host
1801 if ignored.contains(k)
1803 elif arrays.contains(k)
1805 v = '"' + '", "'.join(v.split()) + '", '
1807 config_host_data.set(k, v)
1808 elif strings.contains(k)
1809 config_host_data.set_quoted(k, v)
1810 elif k.startswith('CONFIG_')
1811 config_host_data.set(k, v == 'y' ? 1 : v)
1815 ########################
1816 # Target configuration #
1817 ########################
1819 minikconf = find_program('scripts/minikconf.py')
1821 config_all_devices = {}
1822 config_all_disas = {}
1823 config_devices_mak_list = []
1824 config_devices_h = {}
1825 config_target_h = {}
1826 config_target_mak = {}
1829 'alpha' : ['CONFIG_ALPHA_DIS'],
1830 'arm' : ['CONFIG_ARM_DIS'],
1831 'avr' : ['CONFIG_AVR_DIS'],
1832 'cris' : ['CONFIG_CRIS_DIS'],
1833 'hexagon' : ['CONFIG_HEXAGON_DIS'],
1834 'hppa' : ['CONFIG_HPPA_DIS'],
1835 'i386' : ['CONFIG_I386_DIS'],
1836 'x86_64' : ['CONFIG_I386_DIS'],
1837 'm68k' : ['CONFIG_M68K_DIS'],
1838 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1839 'mips' : ['CONFIG_MIPS_DIS'],
1840 'nios2' : ['CONFIG_NIOS2_DIS'],
1841 'or1k' : ['CONFIG_OPENRISC_DIS'],
1842 'ppc' : ['CONFIG_PPC_DIS'],
1843 'riscv' : ['CONFIG_RISCV_DIS'],
1844 'rx' : ['CONFIG_RX_DIS'],
1845 's390' : ['CONFIG_S390_DIS'],
1846 'sh4' : ['CONFIG_SH4_DIS'],
1847 'sparc' : ['CONFIG_SPARC_DIS'],
1848 'xtensa' : ['CONFIG_XTENSA_DIS'],
1850 if link_language == 'cpp'
1852 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1853 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1854 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1858 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
1860 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
1861 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1862 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
1863 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
1864 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1865 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1866 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1867 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1868 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1869 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1870 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1871 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1872 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1874 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1876 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1877 actual_target_dirs = []
1879 foreach target : target_dirs
1880 config_target = { 'TARGET_NAME': target.split('-')[0] }
1881 if target.endswith('linux-user')
1882 if targetos != 'linux'
1886 error('Target @0@ is only available on a Linux host'.format(target))
1888 config_target += { 'CONFIG_LINUX_USER': 'y' }
1889 elif target.endswith('bsd-user')
1890 if 'CONFIG_BSD' not in config_host
1894 error('Target @0@ is only available on a BSD host'.format(target))
1896 config_target += { 'CONFIG_BSD_USER': 'y' }
1897 elif target.endswith('softmmu')
1898 config_target += { 'CONFIG_SOFTMMU': 'y' }
1900 if target.endswith('-user')
1902 'CONFIG_USER_ONLY': 'y',
1903 'CONFIG_QEMU_INTERP_PREFIX':
1904 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1909 foreach sym: accelerators
1910 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1911 config_target += { sym: 'y' }
1912 config_all += { sym: 'y' }
1913 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1914 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1915 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1916 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1918 if target in modular_tcg
1919 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
1921 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
1923 accel_kconfig += [ sym + '=y' ]
1926 if accel_kconfig.length() == 0
1930 error('No accelerator available for target @0@'.format(target))
1933 actual_target_dirs += target
1934 config_target += keyval.load('configs/targets' / target + '.mak')
1935 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1937 if 'TARGET_NEED_FDT' in config_target
1938 fdt_required += target
1942 if 'TARGET_BASE_ARCH' not in config_target
1943 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1945 if 'TARGET_ABI_DIR' not in config_target
1946 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1949 foreach k, v: disassemblers
1950 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1952 config_target += { sym: 'y' }
1953 config_all_disas += { sym: 'y' }
1958 config_target_data = configuration_data()
1959 foreach k, v: config_target
1960 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1962 elif ignored.contains(k)
1964 elif k == 'TARGET_BASE_ARCH'
1965 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1966 # not used to select files from sourcesets.
1967 config_target_data.set('TARGET_' + v.to_upper(), 1)
1968 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1969 config_target_data.set_quoted(k, v)
1971 config_target_data.set(k, 1)
1973 config_target_data.set(k, v)
1976 config_target_data.set('QEMU_ARCH',
1977 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
1978 config_target_h += {target: configure_file(output: target + '-config-target.h',
1979 configuration: config_target_data)}
1981 if target.endswith('-softmmu')
1982 config_input = meson.get_external_property(target, 'default')
1983 config_devices_mak = target + '-config-devices.mak'
1984 config_devices_mak = configure_file(
1985 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
1986 output: config_devices_mak,
1987 depfile: config_devices_mak + '.d',
1989 command: [minikconf,
1990 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1991 config_devices_mak, '@DEPFILE@', '@INPUT@',
1992 host_kconfig, accel_kconfig,
1993 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
1995 config_devices_data = configuration_data()
1996 config_devices = keyval.load(config_devices_mak)
1997 foreach k, v: config_devices
1998 config_devices_data.set(k, 1)
2000 config_devices_mak_list += config_devices_mak
2001 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2002 configuration: config_devices_data)}
2003 config_target += config_devices
2004 config_all_devices += config_devices
2006 config_target_mak += {target: config_target}
2008 target_dirs = actual_target_dirs
2010 # This configuration is used to build files that are shared by
2011 # multiple binaries, and then extracted out of the "common"
2012 # static_library target.
2014 # We do not use all_sources()/all_dependencies(), because it would
2015 # build literally all source files, including devices only used by
2016 # targets that are not built for this compilation. The CONFIG_ALL
2017 # pseudo symbol replaces it.
2019 config_all += config_all_devices
2020 config_all += config_host
2021 config_all += config_all_disas
2023 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
2024 'CONFIG_SOFTMMU': have_system,
2025 'CONFIG_USER_ONLY': have_user,
2033 capstone = not_found
2034 capstone_opt = get_option('capstone')
2035 if capstone_opt in ['enabled', 'auto', 'system']
2036 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
2037 capstone = dependency('capstone', version: '>=4.0',
2038 kwargs: static_kwargs, method: 'pkg-config',
2039 required: capstone_opt == 'system' or
2040 capstone_opt == 'enabled' and not have_internal)
2042 # Some versions of capstone have broken pkg-config file
2043 # that reports a wrong -I path, causing the #include to
2044 # fail later. If the system has such a broken version
2046 if capstone.found() and not cc.compiles('#include <capstone.h>',
2047 dependencies: [capstone])
2048 capstone = not_found
2049 if capstone_opt == 'system'
2050 error('system capstone requested, it does not appear to work')
2055 capstone_opt = 'system'
2057 capstone_opt = 'internal'
2059 capstone_opt = 'disabled'
2062 if capstone_opt == 'internal'
2063 capstone_data = configuration_data()
2064 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
2066 capstone_files = files(
2068 'capstone/MCInst.c',
2069 'capstone/MCInstrDesc.c',
2070 'capstone/MCRegisterInfo.c',
2071 'capstone/SStream.c',
2075 if 'CONFIG_ARM_DIS' in config_all_disas
2076 capstone_data.set('CAPSTONE_HAS_ARM', '1')
2077 capstone_files += files(
2078 'capstone/arch/ARM/ARMDisassembler.c',
2079 'capstone/arch/ARM/ARMInstPrinter.c',
2080 'capstone/arch/ARM/ARMMapping.c',
2081 'capstone/arch/ARM/ARMModule.c'
2085 # FIXME: This config entry currently depends on a c++ compiler.
2086 # Which is needed for building libvixl, but not for capstone.
2087 if 'CONFIG_ARM_A64_DIS' in config_all_disas
2088 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
2089 capstone_files += files(
2090 'capstone/arch/AArch64/AArch64BaseInfo.c',
2091 'capstone/arch/AArch64/AArch64Disassembler.c',
2092 'capstone/arch/AArch64/AArch64InstPrinter.c',
2093 'capstone/arch/AArch64/AArch64Mapping.c',
2094 'capstone/arch/AArch64/AArch64Module.c'
2098 if 'CONFIG_PPC_DIS' in config_all_disas
2099 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
2100 capstone_files += files(
2101 'capstone/arch/PowerPC/PPCDisassembler.c',
2102 'capstone/arch/PowerPC/PPCInstPrinter.c',
2103 'capstone/arch/PowerPC/PPCMapping.c',
2104 'capstone/arch/PowerPC/PPCModule.c'
2108 if 'CONFIG_S390_DIS' in config_all_disas
2109 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
2110 capstone_files += files(
2111 'capstone/arch/SystemZ/SystemZDisassembler.c',
2112 'capstone/arch/SystemZ/SystemZInstPrinter.c',
2113 'capstone/arch/SystemZ/SystemZMapping.c',
2114 'capstone/arch/SystemZ/SystemZModule.c',
2115 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
2119 if 'CONFIG_I386_DIS' in config_all_disas
2120 capstone_data.set('CAPSTONE_HAS_X86', 1)
2121 capstone_files += files(
2122 'capstone/arch/X86/X86Disassembler.c',
2123 'capstone/arch/X86/X86DisassemblerDecoder.c',
2124 'capstone/arch/X86/X86ATTInstPrinter.c',
2125 'capstone/arch/X86/X86IntelInstPrinter.c',
2126 'capstone/arch/X86/X86InstPrinterCommon.c',
2127 'capstone/arch/X86/X86Mapping.c',
2128 'capstone/arch/X86/X86Module.c'
2132 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
2135 # FIXME: There does not seem to be a way to completely replace the c_args
2136 # that come from add_project_arguments() -- we can only add to them.
2137 # So: disable all warnings with a big hammer.
2140 # Include all configuration defines via a header file, which will wind up
2141 # as a dependency on the object file, and thus changes here will result
2143 '-include', 'capstone-defs.h'
2146 libcapstone = static_library('capstone',
2147 build_by_default: false,
2148 sources: capstone_files,
2149 c_args: capstone_cargs,
2150 include_directories: 'capstone/include')
2151 capstone = declare_dependency(link_with: libcapstone,
2152 include_directories: 'capstone/include/capstone')
2156 slirp_opt = 'disabled'
2158 slirp_opt = get_option('slirp')
2159 if slirp_opt in ['enabled', 'auto', 'system']
2160 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2161 slirp = dependency('slirp', kwargs: static_kwargs,
2162 method: 'pkg-config',
2163 required: slirp_opt == 'system' or
2164 slirp_opt == 'enabled' and not have_internal)
2166 slirp_opt = 'system'
2168 slirp_opt = 'internal'
2170 slirp_opt = 'disabled'
2173 if slirp_opt == 'internal'
2175 if targetos == 'windows'
2176 slirp_deps = cc.find_library('iphlpapi')
2177 elif targetos == 'darwin'
2178 slirp_deps = cc.find_library('resolv')
2180 slirp_conf = configuration_data()
2181 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2182 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2183 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2184 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2185 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2187 'slirp/src/arp_table.c',
2188 'slirp/src/bootp.c',
2189 'slirp/src/cksum.c',
2190 'slirp/src/dhcpv6.c',
2191 'slirp/src/dnssearch.c',
2193 'slirp/src/ip6_icmp.c',
2194 'slirp/src/ip6_input.c',
2195 'slirp/src/ip6_output.c',
2196 'slirp/src/ip_icmp.c',
2197 'slirp/src/ip_input.c',
2198 'slirp/src/ip_output.c',
2202 'slirp/src/ndp_table.c',
2204 'slirp/src/slirp.c',
2205 'slirp/src/socket.c',
2206 'slirp/src/state.c',
2207 'slirp/src/stream.c',
2208 'slirp/src/tcp_input.c',
2209 'slirp/src/tcp_output.c',
2210 'slirp/src/tcp_subr.c',
2211 'slirp/src/tcp_timer.c',
2216 'slirp/src/version.c',
2217 'slirp/src/vmstate.c',
2221 input : 'slirp/src/libslirp-version.h.in',
2222 output : 'libslirp-version.h',
2223 configuration: slirp_conf)
2225 slirp_inc = include_directories('slirp', 'slirp/src')
2226 libslirp = static_library('slirp',
2227 build_by_default: false,
2228 sources: slirp_files,
2229 c_args: slirp_cargs,
2230 include_directories: slirp_inc)
2231 slirp = declare_dependency(link_with: libslirp,
2232 dependencies: slirp_deps,
2233 include_directories: slirp_inc)
2237 # For CFI, we need to compile slirp as a static library together with qemu.
2238 # This is because we register slirp functions as callbacks for QEMU Timers.
2239 # When using a system-wide shared libslirp, the type information for the
2240 # callback is missing and the timer call produces a false positive with CFI.
2242 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2243 # with control-flow integrity.
2244 if get_option('cfi') and slirp_opt == 'system'
2245 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2246 + ' Please configure with --enable-slirp=git')
2250 fdt_opt = get_option('fdt')
2252 if fdt_opt in ['enabled', 'auto', 'system']
2253 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2254 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2255 required: fdt_opt == 'system' or
2256 fdt_opt == 'enabled' and not have_internal)
2257 if fdt.found() and cc.links('''
2259 #include <libfdt_env.h>
2260 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
2263 elif fdt_opt == 'system'
2264 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2266 fdt_opt = 'internal'
2268 fdt_opt = 'disabled'
2272 if fdt_opt == 'internal'
2275 'dtc/libfdt/fdt_ro.c',
2276 'dtc/libfdt/fdt_wip.c',
2277 'dtc/libfdt/fdt_sw.c',
2278 'dtc/libfdt/fdt_rw.c',
2279 'dtc/libfdt/fdt_strerror.c',
2280 'dtc/libfdt/fdt_empty_tree.c',
2281 'dtc/libfdt/fdt_addresses.c',
2282 'dtc/libfdt/fdt_overlay.c',
2283 'dtc/libfdt/fdt_check.c',
2286 fdt_inc = include_directories('dtc/libfdt')
2287 libfdt = static_library('fdt',
2288 build_by_default: false,
2290 include_directories: fdt_inc)
2291 fdt = declare_dependency(link_with: libfdt,
2292 include_directories: fdt_inc)
2295 if not fdt.found() and fdt_required.length() > 0
2296 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2299 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2300 config_host_data.set('CONFIG_FDT', fdt.found())
2301 config_host_data.set('CONFIG_SLIRP', slirp.found())
2303 #####################
2304 # Generated sources #
2305 #####################
2307 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2309 hxtool = find_program('scripts/hxtool')
2310 shaderinclude = find_program('scripts/shaderinclude.pl')
2311 qapi_gen = find_program('scripts/qapi-gen.py')
2312 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2313 meson.current_source_dir() / 'scripts/qapi/commands.py',
2314 meson.current_source_dir() / 'scripts/qapi/common.py',
2315 meson.current_source_dir() / 'scripts/qapi/error.py',
2316 meson.current_source_dir() / 'scripts/qapi/events.py',
2317 meson.current_source_dir() / 'scripts/qapi/expr.py',
2318 meson.current_source_dir() / 'scripts/qapi/gen.py',
2319 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2320 meson.current_source_dir() / 'scripts/qapi/parser.py',
2321 meson.current_source_dir() / 'scripts/qapi/schema.py',
2322 meson.current_source_dir() / 'scripts/qapi/source.py',
2323 meson.current_source_dir() / 'scripts/qapi/types.py',
2324 meson.current_source_dir() / 'scripts/qapi/visit.py',
2325 meson.current_source_dir() / 'scripts/qapi/common.py',
2326 meson.current_source_dir() / 'scripts/qapi-gen.py'
2330 python, files('scripts/tracetool.py'),
2331 '--backend=' + ','.join(get_option('trace_backends'))
2333 tracetool_depends = files(
2334 'scripts/tracetool/backend/log.py',
2335 'scripts/tracetool/backend/__init__.py',
2336 'scripts/tracetool/backend/dtrace.py',
2337 'scripts/tracetool/backend/ftrace.py',
2338 'scripts/tracetool/backend/simple.py',
2339 'scripts/tracetool/backend/syslog.py',
2340 'scripts/tracetool/backend/ust.py',
2341 'scripts/tracetool/format/tcg_h.py',
2342 'scripts/tracetool/format/ust_events_c.py',
2343 'scripts/tracetool/format/ust_events_h.py',
2344 'scripts/tracetool/format/__init__.py',
2345 'scripts/tracetool/format/d.py',
2346 'scripts/tracetool/format/tcg_helper_c.py',
2347 'scripts/tracetool/format/simpletrace_stap.py',
2348 'scripts/tracetool/format/c.py',
2349 'scripts/tracetool/format/h.py',
2350 'scripts/tracetool/format/tcg_helper_h.py',
2351 'scripts/tracetool/format/log_stap.py',
2352 'scripts/tracetool/format/stap.py',
2353 'scripts/tracetool/format/tcg_helper_wrapper_h.py',
2354 'scripts/tracetool/__init__.py',
2355 'scripts/tracetool/transform.py',
2356 'scripts/tracetool/vcpu.py'
2359 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2360 meson.current_source_dir(),
2361 config_host['PKGVERSION'], meson.project_version()]
2362 qemu_version = custom_target('qemu-version.h',
2363 output: 'qemu-version.h',
2364 command: qemu_version_cmd,
2366 build_by_default: true,
2367 build_always_stale: true)
2368 genh += qemu_version
2372 ['qemu-options.hx', 'qemu-options.def'],
2373 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2377 ['hmp-commands.hx', 'hmp-commands.h'],
2378 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2381 foreach d : hx_headers
2382 hxdep += custom_target(d[1],
2386 build_by_default: true, # to be removed when added to a target
2387 command: [hxtool, '-h', '@INPUT0@'])
2395 authz_ss = ss.source_set()
2396 blockdev_ss = ss.source_set()
2397 block_ss = ss.source_set()
2398 chardev_ss = ss.source_set()
2399 common_ss = ss.source_set()
2400 common_user_ss = ss.source_set()
2401 crypto_ss = ss.source_set()
2402 hwcore_ss = ss.source_set()
2403 io_ss = ss.source_set()
2404 qmp_ss = ss.source_set()
2405 qom_ss = ss.source_set()
2406 softmmu_ss = ss.source_set()
2407 specific_fuzz_ss = ss.source_set()
2408 specific_ss = ss.source_set()
2409 stub_ss = ss.source_set()
2410 trace_ss = ss.source_set()
2411 user_ss = ss.source_set()
2412 util_ss = ss.source_set()
2415 qtest_module_ss = ss.source_set()
2416 tcg_module_ss = ss.source_set()
2422 target_softmmu_arch = {}
2423 target_user_arch = {}
2429 # TODO: add each directory to the subdirs from its own meson.build, once
2431 trace_events_subdirs = [
2439 trace_events_subdirs += [ 'linux-user' ]
2442 trace_events_subdirs += [
2451 trace_events_subdirs += [
2465 'hw/block/dataplane',
2515 if have_system or have_user
2516 trace_events_subdirs += [
2533 vhost_user = not_found
2534 if 'CONFIG_VHOST_USER' in config_host
2535 libvhost_user = subproject('libvhost-user')
2536 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2551 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2552 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2555 stub_ss = stub_ss.apply(config_all, strict: false)
2557 util_ss.add_all(trace_ss)
2558 util_ss = util_ss.apply(config_all, strict: false)
2559 libqemuutil = static_library('qemuutil',
2560 sources: util_ss.sources() + stub_ss.sources() + genh,
2561 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2562 qemuutil = declare_dependency(link_with: libqemuutil,
2563 sources: genh + version_res)
2565 if have_system or have_user
2566 decodetree = generator(find_program('scripts/decodetree.py'),
2567 output: 'decode-@BASENAME@.c.inc',
2568 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2569 subdir('libdecnumber')
2586 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
2592 blockdev_ss.add(files(
2599 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2600 # os-win32.c does not
2601 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2602 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2605 common_ss.add(files('cpus-common.c'))
2609 common_ss.add(capstone)
2610 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2612 # Work around a gcc bug/misfeature wherein constant propagation looks
2614 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2615 # to guess that a const variable is always zero. Without lto, this is
2616 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2617 # without lto, not even the alias is required -- we simply use different
2618 # declarations in different compilation units.
2619 pagevary = files('page-vary-common.c')
2620 if get_option('b_lto')
2621 pagevary_flags = ['-fno-lto']
2622 if get_option('cfi')
2623 pagevary_flags += '-fno-sanitize=cfi-icall'
2625 pagevary = static_library('page-vary-common', sources: pagevary,
2626 c_args: pagevary_flags)
2627 pagevary = declare_dependency(link_with: pagevary)
2629 common_ss.add(pagevary)
2630 specific_ss.add(files('page-vary.c'))
2638 subdir('semihosting')
2646 common_user_inc = []
2648 subdir('common-user')
2650 subdir('linux-user')
2652 common_user_ss = common_user_ss.apply(config_all, strict: false)
2653 common_user = static_library('common-user',
2654 sources: common_user_ss.sources(),
2655 dependencies: common_user_ss.dependencies(),
2656 include_directories: common_user_inc,
2658 build_by_default: false)
2659 common_user = declare_dependency(link_with: common_user)
2661 user_ss.add(common_user)
2663 # needed for fuzzing binaries
2664 subdir('tests/qtest/libqos')
2665 subdir('tests/qtest/fuzz')
2668 tcg_real_module_ss = ss.source_set()
2669 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
2670 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
2671 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
2672 'tcg': tcg_real_module_ss }}
2674 ########################
2675 # Library dependencies #
2676 ########################
2678 modinfo_collect = find_program('scripts/modinfo-collect.py')
2679 modinfo_generate = find_program('scripts/modinfo-generate.py')
2684 foreach d, list : modules
2685 foreach m, module_ss : list
2686 if enable_modules and targetos != 'windows'
2687 module_ss = module_ss.apply(config_all, strict: false)
2688 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2689 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2695 if module_ss.sources() != []
2696 # FIXME: Should use sl.extract_all_objects(recursive: true) as
2697 # input. Sources can be used multiple times but objects are
2698 # unique when it comes to lookup in compile_commands.json.
2699 # Depnds on a mesion version with
2700 # https://github.com/mesonbuild/meson/pull/8900
2701 modinfo_files += custom_target(d + '-' + m + '.modinfo',
2702 output: d + '-' + m + '.modinfo',
2703 input: module_ss.sources() + genh,
2705 command: [modinfo_collect, module_ss.sources()])
2709 block_ss.add_all(module_ss)
2711 softmmu_ss.add_all(module_ss)
2717 foreach d, list : target_modules
2718 foreach m, module_ss : list
2719 if enable_modules and targetos != 'windows'
2720 foreach target : target_dirs
2721 if target.endswith('-softmmu')
2722 config_target = config_target_mak[target]
2723 config_target += config_host
2724 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2725 c_args = ['-DNEED_CPU_H',
2726 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2727 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2728 target_module_ss = module_ss.apply(config_target, strict: false)
2729 if target_module_ss.sources() != []
2730 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
2731 sl = static_library(module_name,
2732 [genh, target_module_ss.sources()],
2733 dependencies: [modulecommon, target_module_ss.dependencies()],
2734 include_directories: target_inc,
2738 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
2739 modinfo_files += custom_target(module_name + '.modinfo',
2740 output: module_name + '.modinfo',
2741 input: target_module_ss.sources() + genh,
2743 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
2748 specific_ss.add_all(module_ss)
2754 modinfo_src = custom_target('modinfo.c',
2755 output: 'modinfo.c',
2756 input: modinfo_files,
2757 command: [modinfo_generate, '@INPUT@'],
2759 modinfo_lib = static_library('modinfo', modinfo_src)
2760 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
2761 softmmu_ss.add(modinfo_dep)
2764 nm = find_program('nm')
2765 undefsym = find_program('scripts/undefsym.py')
2766 block_syms = custom_target('block.syms', output: 'block.syms',
2767 input: [libqemuutil, block_mods],
2769 command: [undefsym, nm, '@INPUT@'])
2770 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2771 input: [libqemuutil, softmmu_mods],
2773 command: [undefsym, nm, '@INPUT@'])
2775 qom_ss = qom_ss.apply(config_host, strict: false)
2776 libqom = static_library('qom', qom_ss.sources() + genh,
2777 dependencies: [qom_ss.dependencies()],
2780 qom = declare_dependency(link_whole: libqom)
2782 authz_ss = authz_ss.apply(config_host, strict: false)
2783 libauthz = static_library('authz', authz_ss.sources() + genh,
2784 dependencies: [authz_ss.dependencies()],
2786 build_by_default: false)
2788 authz = declare_dependency(link_whole: libauthz,
2791 crypto_ss = crypto_ss.apply(config_host, strict: false)
2792 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2793 dependencies: [crypto_ss.dependencies()],
2795 build_by_default: false)
2797 crypto = declare_dependency(link_whole: libcrypto,
2798 dependencies: [authz, qom])
2800 io_ss = io_ss.apply(config_host, strict: false)
2801 libio = static_library('io', io_ss.sources() + genh,
2802 dependencies: [io_ss.dependencies()],
2803 link_with: libqemuutil,
2805 build_by_default: false)
2807 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2809 libmigration = static_library('migration', sources: migration_files + genh,
2811 build_by_default: false)
2812 migration = declare_dependency(link_with: libmigration,
2813 dependencies: [zlib, qom, io])
2814 softmmu_ss.add(migration)
2816 block_ss = block_ss.apply(config_host, strict: false)
2817 libblock = static_library('block', block_ss.sources() + genh,
2818 dependencies: block_ss.dependencies(),
2819 link_depends: block_syms,
2821 build_by_default: false)
2823 block = declare_dependency(link_whole: [libblock],
2824 link_args: '@block.syms',
2825 dependencies: [crypto, io])
2827 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2828 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2829 dependencies: blockdev_ss.dependencies(),
2831 build_by_default: false)
2833 blockdev = declare_dependency(link_whole: [libblockdev],
2834 dependencies: [block])
2836 qmp_ss = qmp_ss.apply(config_host, strict: false)
2837 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2838 dependencies: qmp_ss.dependencies(),
2840 build_by_default: false)
2842 qmp = declare_dependency(link_whole: [libqmp])
2844 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2846 dependencies: [gnutls],
2847 build_by_default: false)
2849 chardev = declare_dependency(link_whole: libchardev)
2851 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
2852 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
2854 build_by_default: false)
2855 hwcore = declare_dependency(link_whole: libhwcore)
2856 common_ss.add(hwcore)
2862 foreach m : block_mods + softmmu_mods
2863 shared_module(m.name(),
2867 install_dir: qemu_moddir)
2870 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2871 common_ss.add(qom, qemuutil)
2873 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2874 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2876 common_all = common_ss.apply(config_all, strict: false)
2877 common_all = static_library('common',
2878 build_by_default: false,
2879 sources: common_all.sources() + genh,
2880 implicit_include_directories: false,
2881 dependencies: common_all.dependencies(),
2884 feature_to_c = find_program('scripts/feature_to_c.sh')
2887 foreach target : target_dirs
2888 config_target = config_target_mak[target]
2889 target_name = config_target['TARGET_NAME']
2890 target_base_arch = config_target['TARGET_BASE_ARCH']
2891 arch_srcs = [config_target_h[target]]
2893 c_args = ['-DNEED_CPU_H',
2894 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2895 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2896 link_args = emulator_link_args
2898 config_target += config_host
2899 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2900 if targetos == 'linux'
2901 target_inc += include_directories('linux-headers', is_system: true)
2903 if target.endswith('-softmmu')
2904 qemu_target_name = 'qemu-system-' + target_name
2905 target_type='system'
2906 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
2907 arch_srcs += t.sources()
2908 arch_deps += t.dependencies()
2910 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
2911 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2912 arch_srcs += hw.sources()
2913 arch_deps += hw.dependencies()
2915 arch_srcs += config_devices_h[target]
2916 link_args += ['@block.syms', '@qemu.syms']
2918 abi = config_target['TARGET_ABI_DIR']
2920 qemu_target_name = 'qemu-' + target_name
2921 if target_base_arch in target_user_arch
2922 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
2923 arch_srcs += t.sources()
2924 arch_deps += t.dependencies()
2926 if 'CONFIG_LINUX_USER' in config_target
2927 base_dir = 'linux-user'
2928 target_inc += include_directories('linux-user/host/' / host_arch)
2930 if 'CONFIG_BSD_USER' in config_target
2931 base_dir = 'bsd-user'
2932 target_inc += include_directories('bsd-user/' / targetos)
2933 dir = base_dir / abi
2934 arch_srcs += files(dir / 'target_arch_cpu.c')
2936 target_inc += include_directories(
2940 if 'CONFIG_LINUX_USER' in config_target
2941 dir = base_dir / abi
2942 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2943 if config_target.has_key('TARGET_SYSTBL_ABI')
2945 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2946 extra_args : config_target['TARGET_SYSTBL_ABI'])
2951 if 'TARGET_XML_FILES' in config_target
2952 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2953 output: target + '-gdbstub-xml.c',
2954 input: files(config_target['TARGET_XML_FILES'].split()),
2955 command: [feature_to_c, '@INPUT@'],
2957 arch_srcs += gdbstub_xml
2960 t = target_arch[target_base_arch].apply(config_target, strict: false)
2961 arch_srcs += t.sources()
2962 arch_deps += t.dependencies()
2964 target_common = common_ss.apply(config_target, strict: false)
2965 objects = common_all.extract_objects(target_common.sources())
2966 deps = target_common.dependencies()
2968 target_specific = specific_ss.apply(config_target, strict: false)
2969 arch_srcs += target_specific.sources()
2970 arch_deps += target_specific.dependencies()
2972 lib = static_library('qemu-' + target,
2973 sources: arch_srcs + genh,
2974 dependencies: arch_deps,
2976 include_directories: target_inc,
2978 build_by_default: false,
2981 if target.endswith('-softmmu')
2983 'name': 'qemu-system-' + target_name,
2984 'win_subsystem': 'console',
2985 'sources': files('softmmu/main.c'),
2988 if targetos == 'windows' and (sdl.found() or gtk.found())
2990 'name': 'qemu-system-' + target_name + 'w',
2991 'win_subsystem': 'windows',
2992 'sources': files('softmmu/main.c'),
2996 if get_option('fuzzing')
2997 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2999 'name': 'qemu-fuzz-' + target_name,
3000 'win_subsystem': 'console',
3001 'sources': specific_fuzz.sources(),
3002 'dependencies': specific_fuzz.dependencies(),
3007 'name': 'qemu-' + target_name,
3008 'win_subsystem': 'console',
3014 exe_name = exe['name']
3015 if targetos == 'darwin'
3016 exe_name += '-unsigned'
3019 emulator = executable(exe_name, exe['sources'],
3022 dependencies: arch_deps + deps + exe['dependencies'],
3023 objects: lib.extract_all_objects(recursive: true),
3024 link_language: link_language,
3025 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3026 link_args: link_args,
3027 win_subsystem: exe['win_subsystem'])
3029 if targetos == 'darwin'
3030 icon = 'pc-bios/qemu.rsrc'
3031 build_input = [emulator, files(icon)]
3033 get_option('bindir') / exe_name,
3034 meson.current_source_dir() / icon
3036 if 'CONFIG_HVF' in config_target
3037 entitlements = 'accel/hvf/entitlements.plist'
3038 build_input += files(entitlements)
3039 install_input += meson.current_source_dir() / entitlements
3042 emulators += {exe['name'] : custom_target(exe['name'],
3044 output: exe['name'],
3046 files('scripts/entitlement.sh'),
3052 meson.add_install_script('scripts/entitlement.sh', '--install',
3053 get_option('bindir') / exe['name'],
3056 emulators += {exe['name']: emulator}
3061 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3062 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3063 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3064 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3066 custom_target(exe['name'] + stp['ext'],
3067 input: trace_events_all,
3068 output: exe['name'] + stp['ext'],
3069 install: stp['install'],
3070 install_dir: get_option('datadir') / 'systemtap/tapset',
3072 tracetool, '--group=all', '--format=' + stp['fmt'],
3073 '--binary=' + stp['bin'],
3074 '--target-name=' + target_name,
3075 '--target-type=' + target_type,
3076 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3077 '@INPUT@', '@OUTPUT@'
3079 depend_files: tracetool_depends)
3085 # Other build targets
3087 if 'CONFIG_PLUGIN' in config_host
3088 install_headers('include/qemu/qemu-plugin.h')
3091 if 'CONFIG_GUEST_AGENT' in config_host
3093 elif get_option('guest_agent_msi').enabled()
3094 error('Guest agent MSI requested, but the guest agent is not being built')
3097 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3098 # when we don't build tools or system
3099 if xkbcommon.found()
3100 # used for the update-keymaps target, so include rules even if !have_tools
3101 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3102 dependencies: [qemuutil, xkbcommon], install: have_tools)
3106 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3107 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3108 qemu_io = executable('qemu-io', files('qemu-io.c'),
3109 dependencies: [block, qemuutil], install: true)
3110 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3111 dependencies: [blockdev, qemuutil, gnutls, selinux],
3114 subdir('storage-daemon')
3115 subdir('contrib/rdmacm-mux')
3116 subdir('contrib/elf2dmp')
3118 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3119 dependencies: qemuutil,
3122 if 'CONFIG_VHOST_USER' in config_host
3123 subdir('contrib/vhost-user-blk')
3124 subdir('contrib/vhost-user-gpu')
3125 subdir('contrib/vhost-user-input')
3126 subdir('contrib/vhost-user-scsi')
3129 if targetos == 'linux'
3130 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3131 dependencies: [qemuutil, libcap_ng],
3133 install_dir: get_option('libexecdir'))
3135 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3136 dependencies: [authz, crypto, io, qom, qemuutil,
3137 libcap_ng, mpathpersist],
3142 subdir('contrib/ivshmem-client')
3143 subdir('contrib/ivshmem-server')
3156 if host_machine.system() == 'windows'
3158 find_program('scripts/nsis.py'),
3160 get_option('prefix'),
3161 meson.current_source_dir(),
3164 '-DDISPLAYVERSION=' + meson.project_version(),
3167 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3170 nsis_cmd += '-DCONFIG_GTK=y'
3173 nsis = custom_target('nsis',
3174 output: 'qemu-setup-' + meson.project_version() + '.exe',
3175 input: files('qemu.nsi'),
3176 build_always_stale: true,
3177 command: nsis_cmd + ['@INPUT@'])
3178 alias_target('installer', nsis)
3181 #########################
3182 # Configuration summary #
3183 #########################
3187 summary_info += {'Install prefix': get_option('prefix')}
3188 summary_info += {'BIOS directory': qemu_datadir}
3189 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
3190 summary_info += {'binary directory': get_option('bindir')}
3191 summary_info += {'library directory': get_option('libdir')}
3192 summary_info += {'module directory': qemu_moddir}
3193 summary_info += {'libexec directory': get_option('libexecdir')}
3194 summary_info += {'include directory': get_option('includedir')}
3195 summary_info += {'config directory': get_option('sysconfdir')}
3196 if targetos != 'windows'
3197 summary_info += {'local state directory': get_option('localstatedir')}
3198 summary_info += {'Manual directory': get_option('mandir')}
3200 summary_info += {'local state directory': 'queried at runtime'}
3202 summary_info += {'Doc directory': get_option('docdir')}
3203 summary_info += {'Build directory': meson.current_build_dir()}
3204 summary_info += {'Source path': meson.current_source_dir()}
3205 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3206 summary(summary_info, bool_yn: true, section: 'Directories')
3210 summary_info += {'git': config_host['GIT']}
3211 summary_info += {'make': config_host['MAKE']}
3212 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3213 summary_info += {'sphinx-build': sphinx_build}
3214 if config_host.has_key('HAVE_GDB_BIN')
3215 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3217 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3218 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
3219 summary_info += {'wixl': wixl}
3221 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
3222 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
3224 summary(summary_info, bool_yn: true, section: 'Host binaries')
3226 # Configurable features
3228 summary_info += {'Documentation': build_docs}
3229 summary_info += {'system-mode emulation': have_system}
3230 summary_info += {'user-mode emulation': have_user}
3231 summary_info += {'block layer': have_block}
3232 summary_info += {'Install blobs': get_option('install_blobs')}
3233 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3234 if config_host.has_key('CONFIG_MODULES')
3235 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
3237 summary_info += {'fuzzing support': get_option('fuzzing')}
3239 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3241 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3242 if 'simple' in get_option('trace_backends')
3243 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3245 summary_info += {'D-Bus display': dbus_display}
3246 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
3247 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
3248 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
3249 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
3250 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
3251 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
3252 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
3253 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3254 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
3255 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
3256 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
3257 summary(summary_info, bool_yn: true, section: 'Configurable features')
3259 # Compilation information
3261 summary_info += {'host CPU': cpu}
3262 summary_info += {'host endianness': build_machine.endian()}
3263 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3264 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3265 if link_language == 'cpp'
3266 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3268 summary_info += {'C++ compiler': false}
3270 if targetos == 'darwin'
3271 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3273 if targetos == 'windows'
3274 if 'WIN_SDK' in config_host
3275 summary_info += {'Windows SDK': config_host['WIN_SDK']}
3278 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3279 + ['-O' + get_option('optimization')]
3280 + (get_option('debug') ? ['-g'] : []))}
3281 if link_language == 'cpp'
3282 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3283 + ['-O' + get_option('optimization')]
3284 + (get_option('debug') ? ['-g'] : []))}
3286 link_args = get_option(link_language + '_link_args')
3287 if link_args.length() > 0
3288 summary_info += {'LDFLAGS': ' '.join(link_args)}
3290 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
3291 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
3292 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
3293 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3294 summary_info += {'PIE': get_option('b_pie')}
3295 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3296 summary_info += {'malloc trim support': has_malloc_trim}
3297 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
3298 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
3299 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
3300 summary_info += {'memory allocator': get_option('malloc')}
3301 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
3302 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
3303 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
3304 summary_info += {'gcov': get_option('b_coverage')}
3305 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3306 summary_info += {'CFI support': get_option('cfi')}
3307 if get_option('cfi')
3308 summary_info += {'CFI debug support': get_option('cfi_debug')}
3310 summary_info += {'strip binaries': get_option('strip')}
3311 summary_info += {'sparse': sparse}
3312 summary_info += {'mingw32 support': targetos == 'windows'}
3314 # snarf the cross-compilation information for tests
3315 foreach target: target_dirs
3316 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3317 if fs.exists(tcg_mak)
3318 config_cross_tcg = keyval.load(tcg_mak)
3319 target = config_cross_tcg['TARGET_NAME']
3321 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3322 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3323 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3324 elif 'CROSS_CC_GUEST' in config_cross_tcg
3325 summary_info += {target + ' tests'
3326 : config_cross_tcg['CROSS_CC_GUEST'] }
3331 summary(summary_info, bool_yn: true, section: 'Compilation')
3333 # Targets and accelerators
3336 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3337 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3338 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3339 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3340 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3341 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
3342 if config_host.has_key('CONFIG_XEN_BACKEND')
3343 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
3346 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3347 if config_all.has_key('CONFIG_TCG')
3348 if get_option('tcg_interpreter')
3349 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
3351 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3353 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3354 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3356 summary_info += {'target list': ' '.join(target_dirs)}
3358 summary_info += {'default devices': get_option('default_devices')}
3359 summary_info += {'out of process emulation': multiprocess_allowed}
3361 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3365 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3366 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
3368 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3369 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3370 summary_info += {'Use block whitelist in tools': config_host.has_key('CONFIG_BDRV_WHITELIST_TOOLS')}
3371 summary_info += {'VirtFS support': have_virtfs}
3372 summary_info += {'build virtiofs daemon': have_virtiofsd}
3373 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
3374 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
3375 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
3376 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
3377 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
3378 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
3379 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
3380 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
3381 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
3382 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
3383 summary_info += {'FUSE exports': fuse}
3385 summary(summary_info, bool_yn: true, section: 'Block layer support')
3389 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
3390 summary_info += {'GNUTLS support': gnutls}
3392 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3394 summary_info += {'libgcrypt': gcrypt}
3395 summary_info += {'nettle': nettle}
3397 summary_info += {' XTS': xts != 'private'}
3399 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
3400 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
3401 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
3402 summary(summary_info, bool_yn: true, section: 'Crypto')
3406 if targetos == 'darwin'
3407 summary_info += {'Cocoa support': cocoa}
3409 summary_info += {'SDL support': sdl}
3410 summary_info += {'SDL image support': sdl_image}
3411 summary_info += {'GTK support': gtk}
3412 summary_info += {'pixman': pixman}
3413 summary_info += {'VTE support': vte}
3414 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3415 summary_info += {'libtasn1': tasn1}
3416 summary_info += {'PAM': pam}
3417 summary_info += {'iconv support': iconv}
3418 summary_info += {'curses support': curses}
3419 summary_info += {'virgl support': virgl}
3420 summary_info += {'curl support': curl}
3421 summary_info += {'Multipath support': mpathpersist}
3422 summary_info += {'VNC support': vnc}
3424 summary_info += {'VNC SASL support': sasl}
3425 summary_info += {'VNC JPEG support': jpeg}
3426 summary_info += {'VNC PNG support': png}
3428 if targetos not in ['darwin', 'haiku', 'windows']
3429 summary_info += {'OSS support': oss}
3430 elif targetos == 'darwin'
3431 summary_info += {'CoreAudio support': coreaudio}
3432 elif targetos == 'windows'
3433 summary_info += {'DirectSound support': dsound}
3435 if targetos == 'linux'
3436 summary_info += {'ALSA support': alsa}
3437 summary_info += {'PulseAudio support': pulse}
3439 summary_info += {'JACK support': jack}
3440 summary_info += {'brlapi support': brlapi}
3441 summary_info += {'vde support': vde}
3442 summary_info += {'netmap support': have_netmap}
3443 summary_info += {'l2tpv3 support': have_l2tpv3}
3444 summary_info += {'Linux AIO support': libaio}
3445 summary_info += {'Linux io_uring support': linux_io_uring}
3446 summary_info += {'ATTR/XATTR support': libattr}
3447 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
3448 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
3449 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3450 summary_info += {'libcap-ng support': libcap_ng}
3451 summary_info += {'bpf support': libbpf}
3452 summary_info += {'spice protocol support': spice_protocol}
3453 if spice_protocol.found()
3454 summary_info += {' spice server support': spice}
3456 summary_info += {'rbd support': rbd}
3457 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
3458 summary_info += {'smartcard support': cacard}
3459 summary_info += {'U2F support': u2f}
3460 summary_info += {'libusb': libusb}
3461 summary_info += {'usb net redir': usbredir}
3462 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
3463 summary_info += {'GBM': gbm}
3464 summary_info += {'libiscsi support': libiscsi}
3465 summary_info += {'libnfs support': libnfs}
3466 if targetos == 'windows'
3467 if config_host.has_key('CONFIG_GUEST_AGENT')
3468 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
3469 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
3472 summary_info += {'seccomp support': seccomp}
3473 summary_info += {'GlusterFS support': glusterfs}
3474 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
3475 summary_info += {'libssh support': libssh}
3476 summary_info += {'lzo support': lzo}
3477 summary_info += {'snappy support': snappy}
3478 summary_info += {'bzip2 support': libbzip2}
3479 summary_info += {'lzfse support': liblzfse}
3480 summary_info += {'zstd support': zstd}
3481 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
3482 summary_info += {'libxml2': libxml2}
3483 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3484 summary_info += {'libpmem support': libpmem}
3485 summary_info += {'libdaxctl support': libdaxctl}
3486 summary_info += {'libudev': libudev}
3487 # Dummy dependency, keep .found()
3488 summary_info += {'FUSE lseek': fuse_lseek.found()}
3489 summary_info += {'selinux': selinux}
3490 summary(summary_info, bool_yn: true, section: 'Dependencies')
3492 if not supported_cpus.contains(cpu)
3494 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3496 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3497 message('The QEMU project intends to remove support for this host CPU in')
3498 message('a future release if nobody volunteers to maintain it and to')
3499 message('provide a build host for our continuous integration setup.')
3500 message('configure has succeeded and you can continue to build, but')
3501 message('if you care about QEMU on this platform you should contact')
3502 message('us upstream at qemu-devel@nongnu.org.')
3505 if not supported_oses.contains(targetos)
3507 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3509 message('Host OS ' + targetos + 'support is not currently maintained.')
3510 message('The QEMU project intends to remove support for this host OS in')
3511 message('a future release if nobody volunteers to maintain it and to')
3512 message('provide a build host for our continuous integration setup.')
3513 message('configure has succeeded and you can continue to build, but')
3514 message('if you care about QEMU on this platform you should contact')
3515 message('us upstream at qemu-devel@nongnu.org.')