1 project('qemu', ['c'], meson_version: '>=0.59.3',
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', 'thorough'], is_default: true)
7 add_test_setup('slow', exclude_suites: ['thorough'], env: ['G_TEST_SLOW=1', 'SPEED=slow'])
8 add_test_setup('thorough', env: ['G_TEST_SLOW=1', 'SPEED=thorough'])
10 not_found = dependency('', required: false)
11 keyval = import('keyval')
12 ss = import('sourceset')
15 sh = find_program('sh')
16 cc = meson.get_compiler('c')
17 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
18 enable_modules = 'CONFIG_MODULES' in config_host
19 enable_static = 'CONFIG_STATIC' in config_host
21 # Allow both shared and static libraries unless --enable-static
22 static_kwargs = enable_static ? {'static': true} : {}
24 # Temporary directory used for files created while
25 # configure runs. Since it is in the build directory
26 # we can safely blow away any previous version of it
27 # (and we need not jump through hoops to try to delete
28 # it when configure exits.)
29 tmpdir = meson.current_build_dir() / 'meson-private/temp'
31 if get_option('qemu_suffix').startswith('/')
32 error('qemu_suffix cannot start with a /')
35 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
36 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
37 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
38 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
40 qemu_desktopdir = get_option('datadir') / 'applications'
41 qemu_icondir = get_option('datadir') / 'icons'
43 config_host_data = configuration_data()
45 qapi_trace_events = []
47 bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
48 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
49 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
50 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc', 'sparc64']
52 cpu = host_machine.cpu_family()
54 # Unify riscv* to a single family.
55 if cpu in ['riscv32', 'riscv64']
59 targetos = host_machine.system()
61 target_dirs = config_host['TARGET_DIRS'].split()
62 have_linux_user = false
65 foreach target : target_dirs
66 have_linux_user = have_linux_user or target.endswith('linux-user')
67 have_bsd_user = have_bsd_user or target.endswith('bsd-user')
68 have_system = have_system or target.endswith('-softmmu')
70 have_user = have_linux_user or have_bsd_user
71 have_tools = get_option('tools') \
72 .disable_auto_if(not have_system) \
74 have_ga = get_option('guest_agent') \
75 .disable_auto_if(not have_system and not have_tools) \
76 .require(targetos in ['sunos', 'linux', 'windows'],
77 error_message: 'unsupported OS for QEMU guest agent') \
79 have_block = have_system or have_tools
81 python = import('python').find_installation()
83 if cpu not in supported_cpus
93 if cpu in ['x86', 'x86_64']
94 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
96 kvm_targets = ['aarch64-softmmu']
98 kvm_targets = ['s390x-softmmu']
99 elif cpu in ['ppc', 'ppc64']
100 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
101 elif cpu in ['mips', 'mips64']
102 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
103 elif cpu in ['riscv']
104 kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
110 if get_option('kvm').allowed() and targetos == 'linux'
111 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
113 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
115 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
117 if cpu in ['aarch64']
118 accelerator_targets += {
119 'CONFIG_HVF': ['aarch64-softmmu']
123 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
124 # i386 emulator provides xenpv machine type for multiple architectures
125 accelerator_targets += {
126 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
129 if cpu in ['x86', 'x86_64']
130 accelerator_targets += {
131 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
132 'CONFIG_HVF': ['x86_64-softmmu'],
133 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
134 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
139 # Darwin does not support references to thread-local variables in modules
140 if targetos != 'darwin'
141 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
144 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
145 unpack_edk2_blobs = false
146 foreach target : edk2_targets
147 if target in target_dirs
148 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
149 unpack_edk2_blobs = bzip2.found()
156 if 'dtrace' in get_option('trace_backends')
157 dtrace = find_program('dtrace', required: true)
158 stap = find_program('stap', required: false)
160 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
161 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
162 # instead. QEMU --enable-modules depends on this because the SystemTap
163 # semaphores are linked into the main binary and not the module's shared
165 add_global_arguments('-DSTAP_SDT_V2',
166 native: false, language: ['c', 'cpp', 'objc'])
174 qemu_cflags = config_host['QEMU_CFLAGS'].split()
175 qemu_cxxflags = config_host['QEMU_CXXFLAGS'].split()
176 qemu_objcflags = config_host['QEMU_OBJCFLAGS'].split()
177 qemu_ldflags = config_host['QEMU_LDFLAGS'].split()
179 if get_option('gprof')
180 qemu_cflags += ['-p']
181 qemu_cxxflags += ['-p']
182 qemu_objcflags += ['-p']
183 qemu_ldflags += ['-p']
186 # Specify linker-script with add_project_link_arguments so that it is not placed
187 # within a linker --start-group/--end-group pair
188 if get_option('fuzzing')
189 add_project_link_arguments(['-Wl,-T,',
190 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
191 native: false, language: ['c', 'cpp', 'objc'])
193 # Specify a filter to only instrument code that is directly related to
195 configure_file(output: 'instrumentation-filter',
196 input: 'scripts/oss-fuzz/instrumentation-filter-template',
198 add_global_arguments(
199 cc.get_supported_arguments('-fsanitize-coverage-allowlist=instrumentation-filter'),
200 native: false, language: ['c', 'cpp', 'objc'])
202 if get_option('fuzzing_engine') == ''
203 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
204 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
205 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
206 # unable to bind the fuzzer-related callbacks added by instrumentation.
207 add_global_arguments('-fsanitize=fuzzer-no-link',
208 native: false, language: ['c', 'cpp', 'objc'])
209 add_global_link_arguments('-fsanitize=fuzzer-no-link',
210 native: false, language: ['c', 'cpp', 'objc'])
211 # For the actual fuzzer binaries, we need to link against the libfuzzer
212 # library. They need to be configurable, to support OSS-Fuzz
213 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
215 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
216 # the needed CFLAGS have already been provided
217 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
221 add_global_arguments(qemu_cflags, native: false, language: ['c'])
222 add_global_arguments(qemu_cxxflags, native: false, language: ['cpp'])
223 add_global_arguments(qemu_objcflags, native: false, language: ['objc'])
224 add_global_link_arguments(qemu_ldflags, native: false, language: ['c', 'cpp', 'objc'])
226 if targetos == 'linux'
227 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
228 '-isystem', 'linux-headers',
229 language: ['c', 'cpp'])
232 add_project_arguments('-iquote', '.',
233 '-iquote', meson.current_source_dir(),
234 '-iquote', meson.current_source_dir() / 'include',
235 '-iquote', meson.current_source_dir() / 'disas/libvixl',
236 language: ['c', 'cpp', 'objc'])
238 link_language = meson.get_external_property('link_language', 'cpp')
239 if link_language == 'cpp'
240 add_languages('cpp', required: true, native: false)
241 cxx = meson.get_compiler('cpp')
246 if host_machine.system() == 'darwin'
247 add_languages('objc', required: false, native: false)
250 sparse = find_program('cgcc', required: get_option('sparse'))
253 command: [find_program('scripts/check_sparse.py'),
254 'compile_commands.json', sparse.full_path(), '-Wbitwise',
255 '-Wno-transparent-union', '-Wno-old-initializer',
256 '-Wno-non-pointer-null'])
259 ###########################################
260 # Target-specific checks and dependencies #
261 ###########################################
264 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
267 #include <sys/types.h>
268 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
269 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
271 args: ['-Werror', '-fsanitize=fuzzer'])
272 error('Your compiler does not support -fsanitize=fuzzer')
276 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
277 error('ftrace is supported only on Linux')
279 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
282 openlog("qemu", LOG_PID, LOG_DAEMON);
283 syslog(LOG_INFO, "configure");
286 error('syslog is not supported on this system')
289 # Miscellaneous Linux-only features
290 get_option('mpath') \
291 .require(targetos == 'linux', error_message: 'Multipath is supported only on Linux')
293 multiprocess_allowed = get_option('multiprocess') \
294 .require(targetos == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
297 have_tpm = get_option('tpm') \
298 .require(targetos != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
301 # Target-specific libraries and flags
302 libm = cc.find_library('m', required: false)
303 threads = dependency('threads')
304 util = cc.find_library('util', required: false)
310 emulator_link_args = []
316 if targetos == 'windows'
317 midl = find_program('midl', required: false)
318 widl = find_program('widl', required: false)
319 socket = cc.find_library('ws2_32')
320 winmm = cc.find_library('winmm')
322 win = import('windows')
323 version_res = win.compile_resources('version.rc',
324 depend_files: files('pc-bios/qemu-nsis.ico'),
325 include_directories: include_directories('.'))
327 elif targetos == 'darwin'
328 coref = dependency('appleframeworks', modules: 'CoreFoundation')
329 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
330 host_dsosuf = '.dylib'
331 elif targetos == 'sunos'
332 socket = [cc.find_library('socket'),
333 cc.find_library('nsl'),
334 cc.find_library('resolv')]
335 elif targetos == 'haiku'
336 socket = [cc.find_library('posix_error_mapper'),
337 cc.find_library('network'),
338 cc.find_library('bsd')]
339 elif targetos == 'openbsd'
340 if get_option('tcg').allowed() and target_dirs.length() > 0
341 # Disable OpenBSD W^X if available
342 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
346 # Target-specific configuration of accelerators
348 if get_option('kvm').allowed() and targetos == 'linux'
349 accelerators += 'CONFIG_KVM'
351 if get_option('xen').allowed() and 'CONFIG_XEN_BACKEND' in config_host
352 accelerators += 'CONFIG_XEN'
353 have_xen_pci_passthrough = get_option('xen_pci_passthrough').allowed() and targetos == 'linux'
355 have_xen_pci_passthrough = false
357 if get_option('whpx').allowed() and targetos == 'windows'
358 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
359 error('WHPX requires 64-bit host')
360 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
361 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
362 accelerators += 'CONFIG_WHPX'
365 if get_option('hvf').allowed()
366 hvf = dependency('appleframeworks', modules: 'Hypervisor',
367 required: get_option('hvf'))
369 accelerators += 'CONFIG_HVF'
372 if get_option('hax').allowed()
373 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
374 accelerators += 'CONFIG_HAX'
377 if targetos == 'netbsd'
378 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
380 accelerators += 'CONFIG_NVMM'
385 if get_option('tcg').allowed()
386 if host_arch == 'unknown'
387 if get_option('tcg_interpreter')
388 warning('Unsupported CPU @0@, will use TCG with TCI (slow)'.format(cpu))
390 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
392 elif get_option('tcg_interpreter')
393 warning('Use of the TCG interpreter is not recommended on this host')
394 warning('architecture. There is a native TCG execution backend available')
395 warning('which provides substantially better performance and reliability.')
396 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
397 warning('configuration option on this architecture to use the native')
400 if get_option('tcg_interpreter')
402 elif host_arch == 'sparc64'
404 elif host_arch == 'x86_64'
406 elif host_arch == 'ppc64'
409 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
410 language: ['c', 'cpp', 'objc'])
412 accelerators += 'CONFIG_TCG'
413 config_host += { 'CONFIG_TCG': 'y' }
416 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
417 error('KVM not available on this platform')
419 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
420 error('HVF not available on this platform')
422 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
423 error('NVMM not available on this platform')
425 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
426 error('WHPX not available on this platform')
428 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
429 if 'CONFIG_XEN' in accelerators
430 error('Xen PCI passthrough not available on this platform')
432 error('Xen PCI passthrough requested but Xen not enabled')
440 # The path to glib.h is added to all compilation commands. This was
441 # grandfathered in from the QEMU Makefiles.
442 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
443 native: false, language: ['c', 'cpp', 'objc'])
444 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
445 link_args: config_host['GLIB_LIBS'].split(),
446 version: config_host['GLIB_VERSION'])
447 # override glib dep with the configure results (for subprojects)
448 meson.override_dependency('glib-2.0', glib)
451 if 'CONFIG_GIO' in config_host
452 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
453 link_args: config_host['GIO_LIBS'].split(),
454 version: config_host['GLIB_VERSION'])
457 if 'ust' in get_option('trace_backends')
458 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
459 method: 'pkg-config', kwargs: static_kwargs)
462 if have_system or have_tools
463 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
464 method: 'pkg-config', kwargs: static_kwargs)
466 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
469 if not get_option('linux_aio').auto() or have_block
470 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
471 required: get_option('linux_aio'),
472 kwargs: static_kwargs)
474 linux_io_uring = not_found
475 if not get_option('linux_io_uring').auto() or have_block
476 linux_io_uring = dependency('liburing', version: '>=0.3',
477 required: get_option('linux_io_uring'),
478 method: 'pkg-config', kwargs: static_kwargs)
481 if not get_option('libnfs').auto() or have_block
482 libnfs = dependency('libnfs', version: '>=1.9.3',
483 required: get_option('libnfs'),
484 method: 'pkg-config', kwargs: static_kwargs)
489 #include <sys/types.h>
490 #ifdef CONFIG_LIBATTR
491 #include <attr/xattr.h>
493 #include <sys/xattr.h>
495 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
498 have_old_libattr = false
499 if get_option('attr').allowed()
500 if cc.links(libattr_test)
501 libattr = declare_dependency()
503 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
504 required: get_option('attr'),
505 kwargs: static_kwargs)
506 if libattr.found() and not \
507 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
509 if get_option('attr').enabled()
510 error('could not link libattr')
512 warning('could not link libattr, disabling')
515 have_old_libattr = libattr.found()
520 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
521 if cocoa.found() and get_option('sdl').enabled()
522 error('Cocoa and SDL cannot be enabled at the same time')
524 if cocoa.found() and get_option('gtk').enabled()
525 error('Cocoa and GTK+ cannot be enabled at the same time')
529 if not get_option('seccomp').auto() or have_system or have_tools
530 seccomp = dependency('libseccomp', version: '>=2.3.0',
531 required: get_option('seccomp'),
532 method: 'pkg-config', kwargs: static_kwargs)
535 libcap_ng = not_found
536 if not get_option('cap_ng').auto() or have_system or have_tools
537 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
538 required: get_option('cap_ng'),
539 kwargs: static_kwargs)
541 if libcap_ng.found() and not cc.links('''
545 capng_capability_to_name(CAPNG_EFFECTIVE);
547 }''', dependencies: libcap_ng)
548 libcap_ng = not_found
549 if get_option('cap_ng').enabled()
550 error('could not link libcap-ng')
552 warning('could not link libcap-ng, disabling')
556 if get_option('xkbcommon').auto() and not have_system and not have_tools
557 xkbcommon = not_found
559 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
560 method: 'pkg-config', kwargs: static_kwargs)
564 if not get_option('vde').auto() or have_system or have_tools
565 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
566 required: get_option('vde'),
567 kwargs: static_kwargs)
569 if vde.found() and not cc.links('''
570 #include <libvdeplug.h>
573 struct vde_open_args a = {0, 0, 0};
577 }''', dependencies: vde)
579 if get_option('cap_ng').enabled()
580 error('could not link libvdeplug')
582 warning('could not link libvdeplug, disabling')
587 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
588 pulse = dependency('libpulse', required: get_option('pa'),
589 method: 'pkg-config', kwargs: static_kwargs)
592 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
593 alsa = dependency('alsa', required: get_option('alsa'),
594 method: 'pkg-config', kwargs: static_kwargs)
597 if not get_option('jack').auto() or have_system
598 jack = dependency('jack', required: get_option('jack'),
599 method: 'pkg-config', kwargs: static_kwargs)
602 spice_protocol = not_found
603 if not get_option('spice_protocol').auto() or have_system
604 spice_protocol = dependency('spice-protocol', version: '>=0.12.3',
605 required: get_option('spice_protocol'),
606 method: 'pkg-config', kwargs: static_kwargs)
609 if not get_option('spice').auto() or have_system
610 spice = dependency('spice-server', version: '>=0.12.5',
611 required: get_option('spice'),
612 method: 'pkg-config', kwargs: static_kwargs)
614 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
616 rt = cc.find_library('rt', required: false)
619 if not get_option('libiscsi').auto() or have_block
620 libiscsi = dependency('libiscsi', version: '>=1.9.0',
621 required: get_option('libiscsi'),
622 method: 'pkg-config', kwargs: static_kwargs)
625 if not get_option('zstd').auto() or have_block
626 zstd = dependency('libzstd', version: '>=1.4.0',
627 required: get_option('zstd'),
628 method: 'pkg-config', kwargs: static_kwargs)
632 have_vhost_user_gpu = have_tools and targetos == 'linux' and pixman.found()
633 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
634 virgl = dependency('virglrenderer',
635 method: 'pkg-config',
636 required: get_option('virglrenderer'),
637 kwargs: static_kwargs)
640 if not get_option('curl').auto() or have_block
641 curl = dependency('libcurl', version: '>=7.29.0',
642 method: 'pkg-config',
643 required: get_option('curl'),
644 kwargs: static_kwargs)
647 if targetos == 'linux' and (have_system or have_tools)
648 libudev = dependency('libudev',
649 method: 'pkg-config',
650 required: get_option('libudev'),
651 kwargs: static_kwargs)
654 mpathlibs = [libudev]
655 mpathpersist = not_found
656 mpathpersist_new_api = false
657 if targetos == 'linux' and have_tools and get_option('mpath').allowed()
658 mpath_test_source_new = '''
660 #include <mpath_persist.h>
661 unsigned mpath_mx_alloc_len = 1024;
663 static struct config *multipath_conf;
664 extern struct udev *udev;
665 extern struct config *get_multipath_config(void);
666 extern void put_multipath_config(struct config *conf);
668 struct config *get_multipath_config(void) { return multipath_conf; }
669 void put_multipath_config(struct config *conf) { }
672 multipath_conf = mpath_lib_init();
675 mpath_test_source_old = '''
677 #include <mpath_persist.h>
678 unsigned mpath_mx_alloc_len = 1024;
681 struct udev *udev = udev_new();
682 mpath_lib_init(udev);
685 libmpathpersist = cc.find_library('mpathpersist',
686 required: get_option('mpath'),
687 kwargs: static_kwargs)
688 if libmpathpersist.found()
689 mpathlibs += libmpathpersist
691 mpathlibs += cc.find_library('devmapper',
692 required: get_option('mpath'),
693 kwargs: static_kwargs)
695 mpathlibs += cc.find_library('multipath',
696 required: get_option('mpath'),
697 kwargs: static_kwargs)
698 foreach lib: mpathlibs
704 if mpathlibs.length() == 0
705 msg = 'Dependencies missing for libmpathpersist'
706 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
707 mpathpersist = declare_dependency(dependencies: mpathlibs)
708 mpathpersist_new_api = true
709 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
710 mpathpersist = declare_dependency(dependencies: mpathlibs)
712 msg = 'Cannot detect libmpathpersist API'
714 if not mpathpersist.found()
715 if get_option('mpath').enabled()
718 warning(msg + ', disabling')
726 if have_system and get_option('curses').allowed()
728 #if defined(__APPLE__) || defined(__OpenBSD__)
729 #define _XOPEN_SOURCE_EXTENDED 1
736 setlocale(LC_ALL, "");
738 addwstr(L"wide chars\n");
740 add_wch(WACS_DEGREE);
744 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
745 foreach curses_dep : curses_dep_list
746 if not curses.found()
747 curses = dependency(curses_dep,
749 method: 'pkg-config',
750 kwargs: static_kwargs)
753 msg = get_option('curses').enabled() ? 'curses library not found' : ''
754 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
756 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
757 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
759 msg = 'curses package not usable'
763 if not curses.found()
764 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
765 if targetos != 'windows' and not has_curses_h
766 message('Trying with /usr/include/ncursesw')
767 curses_compile_args += ['-I/usr/include/ncursesw']
768 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
771 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
772 foreach curses_libname : curses_libname_list
773 libcurses = cc.find_library(curses_libname,
775 kwargs: static_kwargs)
777 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
778 curses = declare_dependency(compile_args: curses_compile_args,
779 dependencies: [libcurses])
782 msg = 'curses library not usable'
788 if get_option('iconv').allowed()
789 foreach link_args : [ ['-liconv'], [] ]
790 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
791 # We need to use libiconv if available because mixing libiconv's headers with
792 # the system libc does not work.
793 # However, without adding glib to the dependencies -L/usr/local/lib will not be
794 # included in the command line and libiconv will not be found.
798 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
799 return conv != (iconv_t) -1;
800 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
801 iconv = declare_dependency(link_args: link_args, dependencies: glib)
806 if curses.found() and not iconv.found()
807 if get_option('iconv').enabled()
808 error('iconv not available')
810 msg = 'iconv required for curses UI but not available'
813 if not curses.found() and msg != ''
814 if get_option('curses').enabled()
817 warning(msg + ', disabling')
823 if not get_option('brlapi').auto() or have_system
824 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
825 required: get_option('brlapi'),
826 kwargs: static_kwargs)
827 if brlapi.found() and not cc.links('''
830 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
832 if get_option('brlapi').enabled()
833 error('could not link brlapi')
835 warning('could not link brlapi, disabling')
841 if not get_option('sdl').auto() or (have_system and not cocoa.found())
842 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
843 sdl_image = not_found
846 # work around 2.0.8 bug
847 sdl = declare_dependency(compile_args: '-Wno-undef',
849 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
850 method: 'pkg-config', kwargs: static_kwargs)
852 if get_option('sdl_image').enabled()
853 error('sdl-image required, but SDL was @0@'.format(
854 get_option('sdl').disabled() ? 'disabled' : 'not found'))
856 sdl_image = not_found
860 if not get_option('rbd').auto() or have_block
861 librados = cc.find_library('rados', required: get_option('rbd'),
862 kwargs: static_kwargs)
863 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
864 required: get_option('rbd'),
865 kwargs: static_kwargs)
866 if librados.found() and librbd.found()
869 #include <rbd/librbd.h>
872 rados_create(&cluster, NULL);
873 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
877 }''', dependencies: [librbd, librados])
878 rbd = declare_dependency(dependencies: [librbd, librados])
879 elif get_option('rbd').enabled()
880 error('librbd >= 1.12.0 required')
882 warning('librbd >= 1.12.0 not found, disabling')
887 glusterfs = not_found
888 glusterfs_ftruncate_has_stat = false
889 glusterfs_iocb_has_stat = false
890 if not get_option('glusterfs').auto() or have_block
891 glusterfs = dependency('glusterfs-api', version: '>=3',
892 required: get_option('glusterfs'),
893 method: 'pkg-config', kwargs: static_kwargs)
895 glusterfs_ftruncate_has_stat = cc.links('''
896 #include <glusterfs/api/glfs.h>
901 /* new glfs_ftruncate() passes two additional args */
902 return glfs_ftruncate(NULL, 0, NULL, NULL);
904 ''', dependencies: glusterfs)
905 glusterfs_iocb_has_stat = cc.links('''
906 #include <glusterfs/api/glfs.h>
908 /* new glfs_io_cbk() passes two additional glfs_stat structs */
910 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
916 glfs_io_cbk iocb = &glusterfs_iocb;
917 iocb(NULL, 0 , NULL, NULL, NULL);
920 ''', dependencies: glusterfs)
925 if not get_option('libssh').auto() or have_block
926 libssh = dependency('libssh', version: '>=0.8.7',
927 method: 'pkg-config',
928 required: get_option('libssh'),
929 kwargs: static_kwargs)
933 if not get_option('bzip2').auto() or have_block
934 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
935 required: get_option('bzip2'),
936 kwargs: static_kwargs)
937 if libbzip2.found() and not cc.links('''
939 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
941 if get_option('bzip2').enabled()
942 error('could not link libbzip2')
944 warning('could not link libbzip2, disabling')
950 if not get_option('lzfse').auto() or have_block
951 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
952 required: get_option('lzfse'),
953 kwargs: static_kwargs)
955 if liblzfse.found() and not cc.links('''
957 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
959 if get_option('lzfse').enabled()
960 error('could not link liblzfse')
962 warning('could not link liblzfse, disabling')
967 if get_option('oss').allowed() and have_system
968 if not cc.has_header('sys/soundcard.h')
970 elif targetos == 'netbsd'
971 oss = cc.find_library('ossaudio', required: get_option('oss'),
972 kwargs: static_kwargs)
974 oss = declare_dependency()
978 if get_option('oss').enabled()
979 error('OSS not found')
984 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
985 if cc.has_header('dsound.h')
986 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
989 if not dsound.found()
990 if get_option('dsound').enabled()
991 error('DirectSound not found')
996 coreaudio = not_found
997 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
998 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
999 required: get_option('coreaudio'))
1003 if 'CONFIG_OPENGL' in config_host
1004 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
1005 link_args: config_host['OPENGL_LIBS'].split())
1008 if (have_system or have_tools) and (virgl.found() or opengl.found())
1009 gbm = dependency('gbm', method: 'pkg-config', required: false,
1010 kwargs: static_kwargs)
1012 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and gbm.found()
1015 gnutls_crypto = not_found
1016 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1017 # For general TLS support our min gnutls matches
1018 # that implied by our platform support matrix
1020 # For the crypto backends, we look for a newer
1023 # Version 3.6.8 is needed to get XTS
1024 # Version 3.6.13 is needed to get PBKDF
1025 # Version 3.6.14 is needed to get HW accelerated XTS
1027 # If newer enough gnutls isn't available, we can
1028 # still use a different crypto backend to satisfy
1029 # the platform support requirements
1030 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1031 method: 'pkg-config',
1033 kwargs: static_kwargs)
1034 if gnutls_crypto.found()
1035 gnutls = gnutls_crypto
1037 # Our min version if all we need is TLS
1038 gnutls = dependency('gnutls', version: '>=3.5.18',
1039 method: 'pkg-config',
1040 required: get_option('gnutls'),
1041 kwargs: static_kwargs)
1045 # We prefer use of gnutls for crypto, unless the options
1046 # explicitly asked for nettle or gcrypt.
1048 # If gnutls isn't available for crypto, then we'll prefer
1049 # gcrypt over nettle for performance reasons.
1054 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1055 error('Only one of gcrypt & nettle can be enabled')
1058 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1059 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1060 gnutls_crypto = not_found
1063 if not gnutls_crypto.found()
1064 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1065 gcrypt = dependency('libgcrypt', version: '>=1.8',
1066 method: 'config-tool',
1067 required: get_option('gcrypt'),
1068 kwargs: static_kwargs)
1069 # Debian has removed -lgpg-error from libgcrypt-config
1070 # as it "spreads unnecessary dependencies" which in
1071 # turn breaks static builds...
1072 if gcrypt.found() and enable_static
1073 gcrypt = declare_dependency(dependencies: [
1075 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
1078 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1079 nettle = dependency('nettle', version: '>=3.4',
1080 method: 'pkg-config',
1081 required: get_option('nettle'),
1082 kwargs: static_kwargs)
1083 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1092 if not get_option('gtk').auto() or (have_system and not cocoa.found())
1093 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1094 method: 'pkg-config',
1095 required: get_option('gtk'),
1096 kwargs: static_kwargs)
1098 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1099 method: 'pkg-config',
1101 kwargs: static_kwargs)
1102 gtk = declare_dependency(dependencies: [gtk, gtkx11])
1104 if not get_option('vte').auto() or have_system
1105 vte = dependency('vte-2.91',
1106 method: 'pkg-config',
1107 required: get_option('vte'),
1108 kwargs: static_kwargs)
1115 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
1116 kwargs: static_kwargs)
1119 if get_option('png').allowed() and have_system
1120 png = dependency('libpng', required: get_option('png'),
1121 method: 'pkg-config', kwargs: static_kwargs)
1126 if get_option('vnc').allowed() and have_system
1127 vnc = declare_dependency() # dummy dependency
1128 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1129 method: 'pkg-config', kwargs: static_kwargs)
1130 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1131 required: get_option('vnc_sasl'),
1132 kwargs: static_kwargs)
1134 sasl = declare_dependency(dependencies: sasl,
1135 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1140 if not get_option('auth_pam').auto() or have_system
1141 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1142 required: get_option('auth_pam'),
1143 kwargs: static_kwargs)
1145 if pam.found() and not cc.links('''
1147 #include <security/pam_appl.h>
1149 const char *service_name = "qemu";
1150 const char *user = "frank";
1151 const struct pam_conv pam_conv = { 0 };
1152 pam_handle_t *pamh = NULL;
1153 pam_start(service_name, user, &pam_conv, &pamh);
1155 }''', dependencies: pam)
1157 if get_option('auth_pam').enabled()
1158 error('could not link libpam')
1160 warning('could not link libpam, disabling')
1165 if not get_option('snappy').auto() or have_system
1166 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1167 required: get_option('snappy'),
1168 kwargs: static_kwargs)
1170 if snappy.found() and not linker.links('''
1171 #include <snappy-c.h>
1172 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1174 if get_option('snappy').enabled()
1175 error('could not link libsnappy')
1177 warning('could not link libsnappy, disabling')
1182 if not get_option('lzo').auto() or have_system
1183 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1184 required: get_option('lzo'),
1185 kwargs: static_kwargs)
1187 if lzo.found() and not cc.links('''
1188 #include <lzo/lzo1x.h>
1189 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1191 if get_option('lzo').enabled()
1192 error('could not link liblzo2')
1194 warning('could not link liblzo2, disabling')
1199 if not get_option('numa').auto() or have_system or have_tools
1200 numa = cc.find_library('numa', has_headers: ['numa.h'],
1201 required: get_option('numa'),
1202 kwargs: static_kwargs)
1204 if numa.found() and not cc.links('''
1206 int main(void) { return numa_available(); }
1207 ''', dependencies: numa)
1209 if get_option('numa').enabled()
1210 error('could not link numa')
1212 warning('could not link numa, disabling')
1217 if 'CONFIG_RDMA' in config_host
1218 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
1221 if 'CONFIG_XEN_BACKEND' in config_host
1222 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
1223 link_args: config_host['XEN_LIBS'].split())
1226 if not get_option('smartcard').auto() or have_system
1227 cacard = dependency('libcacard', required: get_option('smartcard'),
1228 version: '>=2.5.1', method: 'pkg-config',
1229 kwargs: static_kwargs)
1233 u2f = dependency('u2f-emu', required: get_option('u2f'),
1234 method: 'pkg-config',
1235 kwargs: static_kwargs)
1237 usbredir = not_found
1238 if not get_option('usb_redir').auto() or have_system
1239 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1240 version: '>=0.6', method: 'pkg-config',
1241 kwargs: static_kwargs)
1244 if not get_option('libusb').auto() or have_system
1245 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1246 version: '>=1.0.13', method: 'pkg-config',
1247 kwargs: static_kwargs)
1251 if not get_option('libpmem').auto() or have_system
1252 libpmem = dependency('libpmem', required: get_option('libpmem'),
1253 method: 'pkg-config', kwargs: static_kwargs)
1255 libdaxctl = not_found
1256 if not get_option('libdaxctl').auto() or have_system
1257 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1258 version: '>=57', method: 'pkg-config',
1259 kwargs: static_kwargs)
1263 tasn1 = dependency('libtasn1',
1264 method: 'pkg-config',
1265 kwargs: static_kwargs)
1267 keyutils = dependency('libkeyutils', required: false,
1268 method: 'pkg-config', kwargs: static_kwargs)
1270 has_gettid = cc.has_function('gettid')
1273 selinux = dependency('libselinux',
1274 required: get_option('selinux'),
1275 method: 'pkg-config', kwargs: static_kwargs)
1280 if get_option('malloc') == 'system'
1282 get_option('malloc_trim').allowed() and \
1283 cc.links('''#include <malloc.h>
1284 int main(void) { malloc_trim(0); return 0; }''')
1286 has_malloc_trim = false
1287 malloc = cc.find_library(get_option('malloc'), required: true)
1289 if not has_malloc_trim and get_option('malloc_trim').enabled()
1290 if get_option('malloc') == 'system'
1291 error('malloc_trim not available on this platform.')
1293 error('malloc_trim not available with non-libc memory allocator')
1297 # Check whether the glibc provides statx()
1299 gnu_source_prefix = '''
1304 statx_test = gnu_source_prefix + '''
1305 #include <sys/stat.h>
1307 struct statx statxbuf;
1308 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1312 has_statx = cc.links(statx_test)
1314 # Check whether statx() provides mount ID information
1316 statx_mnt_id_test = gnu_source_prefix + '''
1317 #include <sys/stat.h>
1319 struct statx statxbuf;
1320 statx(0, "", 0, STATX_BASIC_STATS | STATX_MNT_ID, &statxbuf);
1321 return statxbuf.stx_mnt_id;
1324 has_statx_mnt_id = cc.links(statx_mnt_id_test)
1326 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
1327 .require(targetos == 'linux',
1328 error_message: 'vhost_user_blk_server requires linux') \
1329 .require('CONFIG_VHOST_USER' in config_host,
1330 error_message: 'vhost_user_blk_server requires vhost-user support') \
1331 .disable_auto_if(not have_system) \
1334 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1335 error('Cannot enable fuse-lseek while fuse is disabled')
1338 fuse = dependency('fuse3', required: get_option('fuse'),
1339 version: '>=3.1', method: 'pkg-config',
1340 kwargs: static_kwargs)
1342 fuse_lseek = not_found
1343 if get_option('fuse_lseek').allowed()
1344 if fuse.version().version_compare('>=3.8')
1346 fuse_lseek = declare_dependency()
1347 elif get_option('fuse_lseek').enabled()
1349 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1351 error('fuse-lseek requires libfuse, which was not found')
1357 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1358 if libbpf.found() and not cc.links('''
1359 #include <bpf/libbpf.h>
1362 bpf_object__destroy_skeleton(NULL);
1364 }''', dependencies: libbpf)
1366 if get_option('bpf').enabled()
1367 error('libbpf skeleton test failed')
1369 warning('libbpf skeleton test failed, disabling')
1377 audio_drivers_selected = []
1379 audio_drivers_available = {
1380 'alsa': alsa.found(),
1381 'coreaudio': coreaudio.found(),
1382 'dsound': dsound.found(),
1383 'jack': jack.found(),
1385 'pa': pulse.found(),
1388 foreach k, v: audio_drivers_available
1389 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1392 # Default to native drivers first, OSS second, SDL third
1393 audio_drivers_priority = \
1394 [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
1395 (targetos == 'linux' ? [] : [ 'sdl' ])
1396 audio_drivers_default = []
1397 foreach k: audio_drivers_priority
1398 if audio_drivers_available[k]
1399 audio_drivers_default += k
1403 foreach k: get_option('audio_drv_list')
1405 audio_drivers_selected += audio_drivers_default
1406 elif not audio_drivers_available[k]
1407 error('Audio driver "@0@" not available.'.format(k))
1409 audio_drivers_selected += k
1413 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1414 '"' + '", "'.join(audio_drivers_selected) + '", ')
1416 if get_option('cfi')
1418 # Check for dependency on LTO
1419 if not get_option('b_lto')
1420 error('Selected Control-Flow Integrity but LTO is disabled')
1422 if config_host.has_key('CONFIG_MODULES')
1423 error('Selected Control-Flow Integrity is not compatible with modules')
1425 # Check for cfi flags. CFI requires LTO so we can't use
1426 # get_supported_arguments, but need a more complex "compiles" which allows
1428 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1429 args: ['-flto', '-fsanitize=cfi-icall'] )
1430 cfi_flags += '-fsanitize=cfi-icall'
1432 error('-fsanitize=cfi-icall is not supported by the compiler')
1434 if cc.compiles('int main () { return 0; }',
1435 name: '-fsanitize-cfi-icall-generalize-pointers',
1436 args: ['-flto', '-fsanitize=cfi-icall',
1437 '-fsanitize-cfi-icall-generalize-pointers'] )
1438 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1440 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1442 if get_option('cfi_debug')
1443 if cc.compiles('int main () { return 0; }',
1444 name: '-fno-sanitize-trap=cfi-icall',
1445 args: ['-flto', '-fsanitize=cfi-icall',
1446 '-fno-sanitize-trap=cfi-icall'] )
1447 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1449 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1452 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1453 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1456 have_host_block_device = (targetos != 'darwin' or
1457 cc.has_header('IOKit/storage/IOMedia.h'))
1459 # FIXME enable_modules shouldn't be necessary, but: https://github.com/mesonbuild/meson/issues/8333
1460 dbus_display = get_option('dbus_display') \
1461 .require(gio.version().version_compare('>=2.64'),
1462 error_message: '-display dbus requires glib>=2.64') \
1463 .require(enable_modules,
1464 error_message: '-display dbus requires --enable-modules') \
1465 .require(config_host.has_key('GDBUS_CODEGEN'),
1466 error_message: '-display dbus requires gdbus-codegen') \
1469 have_virtfs = get_option('virtfs') \
1470 .require(targetos == 'linux' or targetos == 'darwin',
1471 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
1472 .require(targetos == 'linux' or cc.has_function('pthread_fchdir_np'),
1473 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
1474 .require(targetos == 'darwin' or (libattr.found() and libcap_ng.found()),
1475 error_message: 'virtio-9p (virtfs) on Linux requires libcap-ng-devel and libattr-devel') \
1476 .disable_auto_if(not have_tools and not have_system) \
1479 have_virtfs_proxy_helper = targetos != 'darwin' and have_virtfs and have_tools
1481 foreach k : get_option('trace_backends')
1482 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1484 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1485 if get_option('iasl') != ''
1486 config_host_data.set_quoted('CONFIG_IASL', get_option('iasl'))
1488 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1489 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1490 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1491 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1492 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1493 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1494 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1495 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1496 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1497 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1498 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1499 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1501 have_slirp_smbd = get_option('slirp_smbd') \
1502 .require(targetos != 'windows', error_message: 'Host smbd not supported on this platform.') \
1505 smbd_path = get_option('smbd')
1507 smbd_path = (targetos == 'solaris' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
1509 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
1512 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
1514 config_host_data.set('CONFIG_ATTR', libattr.found())
1515 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
1516 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1517 config_host_data.set('CONFIG_COCOA', cocoa.found())
1518 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1519 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1520 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1521 config_host_data.set('CONFIG_LZO', lzo.found())
1522 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1523 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1524 config_host_data.set('CONFIG_CURL', curl.found())
1525 config_host_data.set('CONFIG_CURSES', curses.found())
1526 config_host_data.set('CONFIG_GBM', gbm.found())
1527 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1528 if glusterfs.found()
1529 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1530 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1531 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1532 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1533 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1534 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1536 config_host_data.set('CONFIG_GTK', gtk.found())
1537 config_host_data.set('CONFIG_VTE', vte.found())
1538 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1539 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1540 config_host_data.set('CONFIG_EBPF', libbpf.found())
1541 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1542 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1543 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1544 config_host_data.set('CONFIG_LIBSSH', libssh.found())
1545 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1546 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1547 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1548 config_host_data.set('CONFIG_NUMA', numa.found())
1549 config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
1550 config_host_data.set('CONFIG_RBD', rbd.found())
1551 config_host_data.set('CONFIG_SDL', sdl.found())
1552 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1553 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1554 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1555 config_host_data.set('CONFIG_TPM', have_tpm)
1556 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1557 config_host_data.set('CONFIG_VDE', vde.found())
1558 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1559 config_host_data.set('CONFIG_PNG', png.found())
1560 config_host_data.set('CONFIG_VNC', vnc.found())
1561 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1562 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1563 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1564 config_host_data.set('CONFIG_VTE', vte.found())
1565 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1566 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1567 config_host_data.set('CONFIG_GETTID', has_gettid)
1568 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1569 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1570 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1571 config_host_data.set('CONFIG_NETTLE', nettle.found())
1572 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1573 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1574 config_host_data.set('CONFIG_STATX', has_statx)
1575 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
1576 config_host_data.set('CONFIG_ZSTD', zstd.found())
1577 config_host_data.set('CONFIG_FUSE', fuse.found())
1578 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1579 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1580 if spice_protocol.found()
1581 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
1582 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
1583 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
1585 config_host_data.set('CONFIG_SPICE', spice.found())
1586 config_host_data.set('CONFIG_X11', x11.found())
1587 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
1588 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1589 config_host_data.set('CONFIG_SELINUX', selinux.found())
1590 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1591 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1592 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1593 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1595 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1596 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1598 have_coroutine_pool = get_option('coroutine_pool')
1599 if get_option('debug_stack_usage') and have_coroutine_pool
1600 message('Disabling coroutine pool to measure stack usage')
1601 have_coroutine_pool = false
1603 config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool)
1604 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
1605 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
1606 config_host_data.set('CONFIG_GPROF', get_option('gprof'))
1607 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
1608 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
1609 config_host_data.set('CONFIG_REPLICATION', get_option('live_block_migration').allowed())
1612 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1613 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1614 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1615 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1616 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1617 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1618 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1619 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1620 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1623 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1624 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1625 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1626 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1627 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1628 # Note that we need to specify prefix: here to avoid incorrectly
1629 # thinking that Windows has posix_memalign()
1630 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
1631 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
1632 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
1633 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
1634 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1635 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1636 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
1637 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1638 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1639 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1640 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1641 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1642 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1643 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1644 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1645 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1647 config_host_data.set('HAVE_IBV_ADVISE_MR',
1648 cc.has_function('ibv_advise_mr',
1649 args: config_host['RDMA_LIBS'].split(),
1650 prefix: '#include <infiniband/verbs.h>'))
1654 config_host_data.set('CONFIG_BYTESWAP_H',
1655 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1656 config_host_data.set('CONFIG_EPOLL_CREATE1',
1657 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1658 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1659 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1660 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1661 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1662 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1663 config_host_data.set('CONFIG_FIEMAP',
1664 cc.has_header('linux/fiemap.h') and
1665 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1666 config_host_data.set('CONFIG_GETRANDOM',
1667 cc.has_function('getrandom') and
1668 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1669 config_host_data.set('CONFIG_INOTIFY',
1670 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1671 config_host_data.set('CONFIG_INOTIFY1',
1672 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1673 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1674 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1675 prefix: '''#include <sys/endian.h>
1676 #include <sys/types.h>'''))
1677 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1678 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1679 config_host_data.set('CONFIG_RTNETLINK',
1680 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1681 config_host_data.set('CONFIG_SYSMACROS',
1682 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1683 config_host_data.set('HAVE_OPTRESET',
1684 cc.has_header_symbol('getopt.h', 'optreset'))
1685 config_host_data.set('HAVE_IPPROTO_MPTCP',
1686 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1689 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1690 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1691 prefix: '#include <signal.h>'))
1692 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1693 cc.has_member('struct stat', 'st_atim',
1694 prefix: '#include <sys/stat.h>'))
1697 config_host_data.set('CONFIG_IOVEC',
1698 cc.has_type('struct iovec',
1699 prefix: '#include <sys/uio.h>'))
1700 config_host_data.set('HAVE_UTMPX',
1701 cc.has_type('struct utmpx',
1702 prefix: '#include <utmpx.h>'))
1704 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1705 #include <sys/eventfd.h>
1706 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1707 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1710 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1711 return fdatasync(0);
1713 #error Not supported
1717 has_madvise = cc.links(gnu_source_prefix + '''
1718 #include <sys/types.h>
1719 #include <sys/mman.h>
1721 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
1722 missing_madvise_proto = false
1724 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
1725 # but forget to prototype it. In this case, has_madvise will be true (the
1726 # test program links despite a compile warning). To detect the
1727 # missing-prototype case, we try again with a definitely-bogus prototype.
1728 # This will only compile if the system headers don't provide the prototype;
1729 # otherwise the conflicting prototypes will cause a compiler error.
1730 missing_madvise_proto = cc.links(gnu_source_prefix + '''
1731 #include <sys/types.h>
1732 #include <sys/mman.h>
1734 extern int madvise(int);
1735 int main(void) { return madvise(0); }''')
1737 config_host_data.set('CONFIG_MADVISE', has_madvise)
1738 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
1740 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1741 #include <sys/mman.h>
1742 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1743 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1745 #if !defined(AT_EMPTY_PATH)
1746 # error missing definition
1748 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1750 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1757 return pipe2(pipefd, O_CLOEXEC);
1759 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1760 #include <sys/mman.h>
1762 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1764 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
1765 #include <pthread.h>
1767 static void *f(void *p) { return NULL; }
1771 pthread_create(&thread, 0, f, 0);
1772 pthread_setname_np(thread, "QEMU");
1774 }''', dependencies: threads))
1775 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
1776 #include <pthread.h>
1778 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
1782 pthread_create(&thread, 0, f, 0);
1784 }''', dependencies: threads))
1785 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
1786 #include <pthread.h>
1791 pthread_condattr_t attr
1792 pthread_condattr_init(&attr);
1793 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
1795 }''', dependencies: threads))
1797 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1798 #include <sys/signalfd.h>
1800 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1801 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1809 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1810 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1814 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
1815 #include <sys/mman.h>
1816 int main(int argc, char *argv[]) {
1817 return mlockall(MCL_FUTURE);
1821 if get_option('l2tpv3').allowed() and have_system
1822 have_l2tpv3 = cc.has_type('struct mmsghdr',
1823 prefix: gnu_source_prefix + '''
1824 #include <sys/socket.h>
1825 #include <linux/ip.h>''')
1827 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
1830 if get_option('netmap').allowed() and have_system
1831 have_netmap = cc.compiles('''
1832 #include <inttypes.h>
1834 #include <net/netmap.h>
1835 #include <net/netmap_user.h>
1836 #if (NETMAP_API < 11) || (NETMAP_API > 15)
1839 int main(void) { return 0; }''')
1840 if not have_netmap and get_option('netmap').enabled()
1841 error('Netmap headers not available')
1844 config_host_data.set('CONFIG_NETMAP', have_netmap)
1846 # Work around a system header bug with some kernel/XFS header
1847 # versions where they both try to define 'struct fsxattr':
1848 # xfs headers will not try to redefine structs from linux headers
1849 # if this macro is set.
1850 config_host_data.set('HAVE_FSXATTR', cc.links('''
1851 #include <linux/fs.h>
1857 # Some versions of Mac OS X incorrectly define SIZE_MAX
1858 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1861 int main(int argc, char *argv[]) {
1862 return printf("%zu", SIZE_MAX);
1863 }''', args: ['-Werror']))
1870 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
1871 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
1872 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
1873 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
1874 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
1878 # See if 64-bit atomic operations are supported.
1879 # Note that without __atomic builtins, we can only
1880 # assume atomic loads/stores max at pointer size.
1881 config_host_data.set('CONFIG_ATOMIC64', cc.links(atomic_test.format('uint64_t')))
1883 has_int128 = cc.links('''
1893 config_host_data.set('CONFIG_INT128', has_int128)
1896 # "do we have 128-bit atomics which are handled inline and specifically not
1897 # via libatomic". The reason we can't use libatomic is documented in the
1898 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
1899 has_atomic128 = cc.links(atomic_test.format('unsigned __int128'))
1901 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
1903 if not has_atomic128
1904 has_cmpxchg128 = cc.links('''
1907 unsigned __int128 x = 0, y = 0;
1908 __sync_val_compare_and_swap_16(&x, y, x);
1913 config_host_data.set('CONFIG_CMPXCHG128', has_cmpxchg128)
1917 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
1918 #include <sys/auxv.h>
1920 return getauxval(AT_HWCAP) == 0;
1923 have_cpuid_h = cc.links('''
1926 unsigned a, b, c, d;
1927 unsigned max = __get_cpuid_max(0, 0);
1930 __cpuid(1, a, b, c, d);
1934 __cpuid_count(7, 0, a, b, c, d);
1939 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
1941 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
1942 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
1943 .require(cc.links('''
1944 #pragma GCC push_options
1945 #pragma GCC target("avx2")
1947 #include <immintrin.h>
1948 static int bar(void *a) {
1949 __m256i x = *(__m256i *)a;
1950 return _mm256_testz_si256(x, x);
1952 int main(int argc, char *argv[]) { return bar(argv[0]); }
1953 '''), error_message: 'AVX2 not available').allowed())
1955 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
1956 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
1957 .require(cc.links('''
1958 #pragma GCC push_options
1959 #pragma GCC target("avx512f")
1961 #include <immintrin.h>
1962 static int bar(void *a) {
1963 __m512i x = *(__m512i *)a;
1964 return _mm512_test_epi64_mask(x, x);
1966 int main(int argc, char *argv[]) { return bar(argv[0]); }
1967 '''), error_message: 'AVX512F not available').allowed())
1969 if get_option('membarrier').disabled()
1970 have_membarrier = false
1971 elif targetos == 'windows'
1972 have_membarrier = true
1973 elif targetos == 'linux'
1974 have_membarrier = cc.compiles('''
1975 #include <linux/membarrier.h>
1976 #include <sys/syscall.h>
1980 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
1981 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
1985 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
1986 .require(have_membarrier, error_message: 'membarrier system call not available') \
1989 have_afalg = get_option('crypto_afalg') \
1990 .require(cc.compiles(gnu_source_prefix + '''
1992 #include <sys/types.h>
1993 #include <sys/socket.h>
1994 #include <linux/if_alg.h>
1997 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2000 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2001 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2003 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2004 'linux/vm_sockets.h', 'AF_VSOCK',
2005 prefix: '#include <sys/socket.h>',
2009 have_vss_sdk = false # old xp/2003 SDK
2010 if targetos == 'windows' and link_language == 'cpp'
2011 have_vss = cxx.compiles('''
2012 #define __MIDL_user_allocate_free_DEFINED__
2014 int main(void) { return VSS_CTX_BACKUP; }''')
2015 have_vss_sdk = cxx.has_header('vscoordint.h')
2017 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2019 ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target
2021 arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
2022 foreach k, v: config_host
2023 if ignored.contains(k)
2025 elif arrays.contains(k)
2027 v = '"' + '", "'.join(v.split()) + '", '
2029 config_host_data.set(k, v)
2030 elif k.startswith('CONFIG_')
2031 config_host_data.set(k, v == 'y' ? 1 : v)
2035 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2036 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2037 if targetos == 'windows'
2038 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2044 }''', name: '_lock_file and _unlock_file'))
2047 ########################
2048 # Target configuration #
2049 ########################
2051 minikconf = find_program('scripts/minikconf.py')
2053 config_all_devices = {}
2054 config_all_disas = {}
2055 config_devices_mak_list = []
2056 config_devices_h = {}
2057 config_target_h = {}
2058 config_target_mak = {}
2061 'alpha' : ['CONFIG_ALPHA_DIS'],
2062 'arm' : ['CONFIG_ARM_DIS'],
2063 'avr' : ['CONFIG_AVR_DIS'],
2064 'cris' : ['CONFIG_CRIS_DIS'],
2065 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2066 'hppa' : ['CONFIG_HPPA_DIS'],
2067 'i386' : ['CONFIG_I386_DIS'],
2068 'x86_64' : ['CONFIG_I386_DIS'],
2069 'm68k' : ['CONFIG_M68K_DIS'],
2070 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2071 'mips' : ['CONFIG_MIPS_DIS'],
2072 'nios2' : ['CONFIG_NIOS2_DIS'],
2073 'or1k' : ['CONFIG_OPENRISC_DIS'],
2074 'ppc' : ['CONFIG_PPC_DIS'],
2075 'riscv' : ['CONFIG_RISCV_DIS'],
2076 'rx' : ['CONFIG_RX_DIS'],
2077 's390' : ['CONFIG_S390_DIS'],
2078 'sh4' : ['CONFIG_SH4_DIS'],
2079 'sparc' : ['CONFIG_SPARC_DIS'],
2080 'xtensa' : ['CONFIG_XTENSA_DIS'],
2082 if link_language == 'cpp'
2084 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
2085 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
2086 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
2090 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2092 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2093 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2094 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2095 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2096 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
2097 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2098 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
2099 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2100 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2101 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2102 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
2103 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
2104 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
2106 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2108 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2109 actual_target_dirs = []
2111 foreach target : target_dirs
2112 config_target = { 'TARGET_NAME': target.split('-')[0] }
2113 if target.endswith('linux-user')
2114 if targetos != 'linux'
2118 error('Target @0@ is only available on a Linux host'.format(target))
2120 config_target += { 'CONFIG_LINUX_USER': 'y' }
2121 elif target.endswith('bsd-user')
2122 if 'CONFIG_BSD' not in config_host
2126 error('Target @0@ is only available on a BSD host'.format(target))
2128 config_target += { 'CONFIG_BSD_USER': 'y' }
2129 elif target.endswith('softmmu')
2130 config_target += { 'CONFIG_SOFTMMU': 'y' }
2132 if target.endswith('-user')
2134 'CONFIG_USER_ONLY': 'y',
2135 'CONFIG_QEMU_INTERP_PREFIX':
2136 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
2141 foreach sym: accelerators
2142 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2143 config_target += { sym: 'y' }
2144 config_all += { sym: 'y' }
2145 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
2146 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
2147 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
2148 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
2150 if target in modular_tcg
2151 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2153 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2155 accel_kconfig += [ sym + '=y' ]
2158 if accel_kconfig.length() == 0
2162 error('No accelerator available for target @0@'.format(target))
2165 actual_target_dirs += target
2166 config_target += keyval.load('configs/targets' / target + '.mak')
2167 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
2169 if 'TARGET_NEED_FDT' in config_target
2170 fdt_required += target
2174 if 'TARGET_BASE_ARCH' not in config_target
2175 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2177 if 'TARGET_ABI_DIR' not in config_target
2178 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2180 if 'TARGET_BIG_ENDIAN' not in config_target
2181 config_target += {'TARGET_BIG_ENDIAN': 'n'}
2184 foreach k, v: disassemblers
2185 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
2187 config_target += { sym: 'y' }
2188 config_all_disas += { sym: 'y' }
2193 config_target_data = configuration_data()
2194 foreach k, v: config_target
2195 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2197 elif ignored.contains(k)
2199 elif k == 'TARGET_BASE_ARCH'
2200 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2201 # not used to select files from sourcesets.
2202 config_target_data.set('TARGET_' + v.to_upper(), 1)
2203 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
2204 config_target_data.set_quoted(k, v)
2206 config_target_data.set(k, 1)
2208 config_target_data.set(k, 0)
2210 config_target_data.set(k, v)
2213 config_target_data.set('QEMU_ARCH',
2214 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
2215 config_target_h += {target: configure_file(output: target + '-config-target.h',
2216 configuration: config_target_data)}
2218 if target.endswith('-softmmu')
2219 config_input = meson.get_external_property(target, 'default')
2220 config_devices_mak = target + '-config-devices.mak'
2221 config_devices_mak = configure_file(
2222 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2223 output: config_devices_mak,
2224 depfile: config_devices_mak + '.d',
2226 command: [minikconf,
2227 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2228 config_devices_mak, '@DEPFILE@', '@INPUT@',
2229 host_kconfig, accel_kconfig,
2230 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
2232 config_devices_data = configuration_data()
2233 config_devices = keyval.load(config_devices_mak)
2234 foreach k, v: config_devices
2235 config_devices_data.set(k, 1)
2237 config_devices_mak_list += config_devices_mak
2238 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2239 configuration: config_devices_data)}
2240 config_target += config_devices
2241 config_all_devices += config_devices
2243 config_target_mak += {target: config_target}
2245 target_dirs = actual_target_dirs
2247 # This configuration is used to build files that are shared by
2248 # multiple binaries, and then extracted out of the "common"
2249 # static_library target.
2251 # We do not use all_sources()/all_dependencies(), because it would
2252 # build literally all source files, including devices only used by
2253 # targets that are not built for this compilation. The CONFIG_ALL
2254 # pseudo symbol replaces it.
2256 config_all += config_all_devices
2257 config_all += config_host
2258 config_all += config_all_disas
2260 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
2261 'CONFIG_SOFTMMU': have_system,
2262 'CONFIG_USER_ONLY': have_user,
2266 target_configs_h = []
2267 foreach target: target_dirs
2268 target_configs_h += config_target_h[target]
2269 target_configs_h += config_devices_h.get(target, [])
2271 genh += custom_target('config-poison.h',
2272 input: [target_configs_h],
2273 output: 'config-poison.h',
2275 command: [find_program('scripts/make-config-poison.sh'),
2282 capstone = not_found
2283 capstone_opt = get_option('capstone')
2284 if capstone_opt in ['enabled', 'auto', 'system']
2285 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
2286 capstone = dependency('capstone', version: '>=4.0',
2287 kwargs: static_kwargs, method: 'pkg-config',
2288 required: capstone_opt == 'system' or
2289 capstone_opt == 'enabled' and not have_internal)
2291 # Some versions of capstone have broken pkg-config file
2292 # that reports a wrong -I path, causing the #include to
2293 # fail later. If the system has such a broken version
2295 if capstone.found() and not cc.compiles('#include <capstone.h>',
2296 dependencies: [capstone])
2297 capstone = not_found
2298 if capstone_opt == 'system'
2299 error('system capstone requested, it does not appear to work')
2304 capstone_opt = 'system'
2306 capstone_opt = 'internal'
2308 capstone_opt = 'disabled'
2311 if capstone_opt == 'internal'
2312 capstone_data = configuration_data()
2313 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
2315 capstone_files = files(
2317 'capstone/MCInst.c',
2318 'capstone/MCInstrDesc.c',
2319 'capstone/MCRegisterInfo.c',
2320 'capstone/SStream.c',
2324 if 'CONFIG_ARM_DIS' in config_all_disas
2325 capstone_data.set('CAPSTONE_HAS_ARM', '1')
2326 capstone_files += files(
2327 'capstone/arch/ARM/ARMDisassembler.c',
2328 'capstone/arch/ARM/ARMInstPrinter.c',
2329 'capstone/arch/ARM/ARMMapping.c',
2330 'capstone/arch/ARM/ARMModule.c'
2334 # FIXME: This config entry currently depends on a c++ compiler.
2335 # Which is needed for building libvixl, but not for capstone.
2336 if 'CONFIG_ARM_A64_DIS' in config_all_disas
2337 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
2338 capstone_files += files(
2339 'capstone/arch/AArch64/AArch64BaseInfo.c',
2340 'capstone/arch/AArch64/AArch64Disassembler.c',
2341 'capstone/arch/AArch64/AArch64InstPrinter.c',
2342 'capstone/arch/AArch64/AArch64Mapping.c',
2343 'capstone/arch/AArch64/AArch64Module.c'
2347 if 'CONFIG_PPC_DIS' in config_all_disas
2348 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
2349 capstone_files += files(
2350 'capstone/arch/PowerPC/PPCDisassembler.c',
2351 'capstone/arch/PowerPC/PPCInstPrinter.c',
2352 'capstone/arch/PowerPC/PPCMapping.c',
2353 'capstone/arch/PowerPC/PPCModule.c'
2357 if 'CONFIG_S390_DIS' in config_all_disas
2358 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
2359 capstone_files += files(
2360 'capstone/arch/SystemZ/SystemZDisassembler.c',
2361 'capstone/arch/SystemZ/SystemZInstPrinter.c',
2362 'capstone/arch/SystemZ/SystemZMapping.c',
2363 'capstone/arch/SystemZ/SystemZModule.c',
2364 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
2368 if 'CONFIG_I386_DIS' in config_all_disas
2369 capstone_data.set('CAPSTONE_HAS_X86', 1)
2370 capstone_files += files(
2371 'capstone/arch/X86/X86Disassembler.c',
2372 'capstone/arch/X86/X86DisassemblerDecoder.c',
2373 'capstone/arch/X86/X86ATTInstPrinter.c',
2374 'capstone/arch/X86/X86IntelInstPrinter.c',
2375 'capstone/arch/X86/X86InstPrinterCommon.c',
2376 'capstone/arch/X86/X86Mapping.c',
2377 'capstone/arch/X86/X86Module.c'
2381 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
2384 # FIXME: There does not seem to be a way to completely replace the c_args
2385 # that come from add_project_arguments() -- we can only add to them.
2386 # So: disable all warnings with a big hammer.
2389 # Include all configuration defines via a header file, which will wind up
2390 # as a dependency on the object file, and thus changes here will result
2392 '-include', 'capstone-defs.h'
2395 libcapstone = static_library('capstone',
2396 build_by_default: false,
2397 sources: capstone_files,
2398 c_args: capstone_cargs,
2399 include_directories: 'capstone/include')
2400 capstone = declare_dependency(link_with: libcapstone,
2401 include_directories: 'capstone/include/capstone')
2405 slirp_opt = 'disabled'
2407 slirp_opt = get_option('slirp')
2408 if slirp_opt in ['enabled', 'auto', 'system']
2409 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2410 slirp = dependency('slirp', kwargs: static_kwargs,
2411 method: 'pkg-config',
2412 required: slirp_opt == 'system' or
2413 slirp_opt == 'enabled' and not have_internal)
2415 slirp_opt = 'system'
2417 slirp_opt = 'internal'
2419 slirp_opt = 'disabled'
2422 if slirp_opt == 'internal'
2424 if targetos == 'windows'
2425 slirp_deps = cc.find_library('iphlpapi')
2426 elif targetos == 'darwin'
2427 slirp_deps = cc.find_library('resolv')
2429 slirp_conf = configuration_data()
2430 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2431 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2432 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2433 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2434 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2436 'slirp/src/arp_table.c',
2437 'slirp/src/bootp.c',
2438 'slirp/src/cksum.c',
2439 'slirp/src/dhcpv6.c',
2440 'slirp/src/dnssearch.c',
2442 'slirp/src/ip6_icmp.c',
2443 'slirp/src/ip6_input.c',
2444 'slirp/src/ip6_output.c',
2445 'slirp/src/ip_icmp.c',
2446 'slirp/src/ip_input.c',
2447 'slirp/src/ip_output.c',
2451 'slirp/src/ndp_table.c',
2453 'slirp/src/slirp.c',
2454 'slirp/src/socket.c',
2455 'slirp/src/state.c',
2456 'slirp/src/stream.c',
2457 'slirp/src/tcp_input.c',
2458 'slirp/src/tcp_output.c',
2459 'slirp/src/tcp_subr.c',
2460 'slirp/src/tcp_timer.c',
2465 'slirp/src/version.c',
2466 'slirp/src/vmstate.c',
2470 input : 'slirp/src/libslirp-version.h.in',
2471 output : 'libslirp-version.h',
2472 configuration: slirp_conf)
2474 slirp_inc = include_directories('slirp', 'slirp/src')
2475 libslirp = static_library('slirp',
2476 build_by_default: false,
2477 sources: slirp_files,
2478 c_args: slirp_cargs,
2479 include_directories: slirp_inc)
2480 slirp = declare_dependency(link_with: libslirp,
2481 dependencies: slirp_deps,
2482 include_directories: slirp_inc)
2486 # For CFI, we need to compile slirp as a static library together with qemu.
2487 # This is because we register slirp functions as callbacks for QEMU Timers.
2488 # When using a system-wide shared libslirp, the type information for the
2489 # callback is missing and the timer call produces a false positive with CFI.
2491 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2492 # with control-flow integrity.
2493 if get_option('cfi') and slirp_opt == 'system'
2494 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2495 + ' Please configure with --enable-slirp=git')
2500 fdt_opt = get_option('fdt')
2501 if fdt_opt in ['enabled', 'auto', 'system']
2502 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2503 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2504 required: fdt_opt == 'system' or
2505 fdt_opt == 'enabled' and not have_internal)
2506 if fdt.found() and cc.links('''
2508 #include <libfdt_env.h>
2509 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2512 elif fdt_opt == 'system'
2513 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2515 fdt_opt = 'internal'
2517 fdt_opt = 'disabled'
2521 if fdt_opt == 'internal'
2524 'dtc/libfdt/fdt_ro.c',
2525 'dtc/libfdt/fdt_wip.c',
2526 'dtc/libfdt/fdt_sw.c',
2527 'dtc/libfdt/fdt_rw.c',
2528 'dtc/libfdt/fdt_strerror.c',
2529 'dtc/libfdt/fdt_empty_tree.c',
2530 'dtc/libfdt/fdt_addresses.c',
2531 'dtc/libfdt/fdt_overlay.c',
2532 'dtc/libfdt/fdt_check.c',
2535 fdt_inc = include_directories('dtc/libfdt')
2536 libfdt = static_library('fdt',
2537 build_by_default: false,
2539 include_directories: fdt_inc)
2540 fdt = declare_dependency(link_with: libfdt,
2541 include_directories: fdt_inc)
2544 fdt_opt = 'disabled'
2546 if not fdt.found() and fdt_required.length() > 0
2547 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2550 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2551 config_host_data.set('CONFIG_FDT', fdt.found())
2552 config_host_data.set('CONFIG_SLIRP', slirp.found())
2554 #####################
2555 # Generated sources #
2556 #####################
2558 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2560 hxtool = find_program('scripts/hxtool')
2561 shaderinclude = find_program('scripts/shaderinclude.pl')
2562 qapi_gen = find_program('scripts/qapi-gen.py')
2563 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2564 meson.current_source_dir() / 'scripts/qapi/commands.py',
2565 meson.current_source_dir() / 'scripts/qapi/common.py',
2566 meson.current_source_dir() / 'scripts/qapi/error.py',
2567 meson.current_source_dir() / 'scripts/qapi/events.py',
2568 meson.current_source_dir() / 'scripts/qapi/expr.py',
2569 meson.current_source_dir() / 'scripts/qapi/gen.py',
2570 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2571 meson.current_source_dir() / 'scripts/qapi/parser.py',
2572 meson.current_source_dir() / 'scripts/qapi/schema.py',
2573 meson.current_source_dir() / 'scripts/qapi/source.py',
2574 meson.current_source_dir() / 'scripts/qapi/types.py',
2575 meson.current_source_dir() / 'scripts/qapi/visit.py',
2576 meson.current_source_dir() / 'scripts/qapi/common.py',
2577 meson.current_source_dir() / 'scripts/qapi-gen.py'
2581 python, files('scripts/tracetool.py'),
2582 '--backend=' + ','.join(get_option('trace_backends'))
2584 tracetool_depends = files(
2585 'scripts/tracetool/backend/log.py',
2586 'scripts/tracetool/backend/__init__.py',
2587 'scripts/tracetool/backend/dtrace.py',
2588 'scripts/tracetool/backend/ftrace.py',
2589 'scripts/tracetool/backend/simple.py',
2590 'scripts/tracetool/backend/syslog.py',
2591 'scripts/tracetool/backend/ust.py',
2592 'scripts/tracetool/format/ust_events_c.py',
2593 'scripts/tracetool/format/ust_events_h.py',
2594 'scripts/tracetool/format/__init__.py',
2595 'scripts/tracetool/format/d.py',
2596 'scripts/tracetool/format/simpletrace_stap.py',
2597 'scripts/tracetool/format/c.py',
2598 'scripts/tracetool/format/h.py',
2599 'scripts/tracetool/format/log_stap.py',
2600 'scripts/tracetool/format/stap.py',
2601 'scripts/tracetool/__init__.py',
2602 'scripts/tracetool/transform.py',
2603 'scripts/tracetool/vcpu.py'
2606 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2607 meson.current_source_dir(),
2608 config_host['PKGVERSION'], meson.project_version()]
2609 qemu_version = custom_target('qemu-version.h',
2610 output: 'qemu-version.h',
2611 command: qemu_version_cmd,
2613 build_by_default: true,
2614 build_always_stale: true)
2615 genh += qemu_version
2619 ['qemu-options.hx', 'qemu-options.def'],
2620 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2624 ['hmp-commands.hx', 'hmp-commands.h'],
2625 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2628 foreach d : hx_headers
2629 hxdep += custom_target(d[1],
2633 build_by_default: true, # to be removed when added to a target
2634 command: [hxtool, '-h', '@INPUT0@'])
2642 authz_ss = ss.source_set()
2643 blockdev_ss = ss.source_set()
2644 block_ss = ss.source_set()
2645 chardev_ss = ss.source_set()
2646 common_ss = ss.source_set()
2647 crypto_ss = ss.source_set()
2648 hwcore_ss = ss.source_set()
2649 io_ss = ss.source_set()
2650 qmp_ss = ss.source_set()
2651 qom_ss = ss.source_set()
2652 softmmu_ss = ss.source_set()
2653 specific_fuzz_ss = ss.source_set()
2654 specific_ss = ss.source_set()
2655 stub_ss = ss.source_set()
2656 trace_ss = ss.source_set()
2657 user_ss = ss.source_set()
2658 util_ss = ss.source_set()
2661 qtest_module_ss = ss.source_set()
2662 tcg_module_ss = ss.source_set()
2668 target_softmmu_arch = {}
2669 target_user_arch = {}
2675 # TODO: add each directory to the subdirs from its own meson.build, once
2677 trace_events_subdirs = [
2685 trace_events_subdirs += [ 'linux-user' ]
2688 trace_events_subdirs += [ 'bsd-user' ]
2691 trace_events_subdirs += [
2700 trace_events_subdirs += [
2714 'hw/block/dataplane',
2764 if have_system or have_user
2765 trace_events_subdirs += [
2783 vhost_user = not_found
2784 if targetos == 'linux' and 'CONFIG_VHOST_USER' in config_host
2785 libvhost_user = subproject('libvhost-user')
2786 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2789 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
2790 # that is filled in by qapi/.
2803 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2804 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2807 stub_ss = stub_ss.apply(config_all, strict: false)
2809 util_ss.add_all(trace_ss)
2810 util_ss = util_ss.apply(config_all, strict: false)
2811 libqemuutil = static_library('qemuutil',
2812 sources: util_ss.sources() + stub_ss.sources() + genh,
2813 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2814 qemuutil = declare_dependency(link_with: libqemuutil,
2815 sources: genh + version_res)
2817 if have_system or have_user
2818 decodetree = generator(find_program('scripts/decodetree.py'),
2819 output: 'decode-@BASENAME@.c.inc',
2820 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2821 subdir('libdecnumber')
2838 if config_host_data.get('CONFIG_REPLICATION')
2839 block_ss.add(files('replication.c'))
2846 blockdev_ss.add(files(
2853 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2854 # os-win32.c does not
2855 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2856 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2859 common_ss.add(files('cpus-common.c'))
2863 common_ss.add(capstone)
2864 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2866 # Work around a gcc bug/misfeature wherein constant propagation looks
2868 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2869 # to guess that a const variable is always zero. Without lto, this is
2870 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2871 # without lto, not even the alias is required -- we simply use different
2872 # declarations in different compilation units.
2873 pagevary = files('page-vary-common.c')
2874 if get_option('b_lto')
2875 pagevary_flags = ['-fno-lto']
2876 if get_option('cfi')
2877 pagevary_flags += '-fno-sanitize=cfi-icall'
2879 pagevary = static_library('page-vary-common', sources: pagevary + genh,
2880 c_args: pagevary_flags)
2881 pagevary = declare_dependency(link_with: pagevary)
2883 common_ss.add(pagevary)
2884 specific_ss.add(files('page-vary.c'))
2892 subdir('semihosting')
2900 common_user_inc = []
2902 subdir('common-user')
2904 subdir('linux-user')
2906 # needed for fuzzing binaries
2907 subdir('tests/qtest/libqos')
2908 subdir('tests/qtest/fuzz')
2911 tcg_real_module_ss = ss.source_set()
2912 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
2913 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
2914 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
2915 'tcg': tcg_real_module_ss }}
2917 ########################
2918 # Library dependencies #
2919 ########################
2921 modinfo_collect = find_program('scripts/modinfo-collect.py')
2922 modinfo_generate = find_program('scripts/modinfo-generate.py')
2927 foreach d, list : modules
2928 foreach m, module_ss : list
2929 if enable_modules and targetos != 'windows'
2930 module_ss = module_ss.apply(config_all, strict: false)
2931 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2932 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2938 if module_ss.sources() != []
2939 # FIXME: Should use sl.extract_all_objects(recursive: true) as
2940 # input. Sources can be used multiple times but objects are
2941 # unique when it comes to lookup in compile_commands.json.
2942 # Depnds on a mesion version with
2943 # https://github.com/mesonbuild/meson/pull/8900
2944 modinfo_files += custom_target(d + '-' + m + '.modinfo',
2945 output: d + '-' + m + '.modinfo',
2946 input: module_ss.sources() + genh,
2948 command: [modinfo_collect, module_ss.sources()])
2952 block_ss.add_all(module_ss)
2954 softmmu_ss.add_all(module_ss)
2960 foreach d, list : target_modules
2961 foreach m, module_ss : list
2962 if enable_modules and targetos != 'windows'
2963 foreach target : target_dirs
2964 if target.endswith('-softmmu')
2965 config_target = config_target_mak[target]
2966 config_target += config_host
2967 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2968 c_args = ['-DNEED_CPU_H',
2969 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2970 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2971 target_module_ss = module_ss.apply(config_target, strict: false)
2972 if target_module_ss.sources() != []
2973 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
2974 sl = static_library(module_name,
2975 [genh, target_module_ss.sources()],
2976 dependencies: [modulecommon, target_module_ss.dependencies()],
2977 include_directories: target_inc,
2981 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
2982 modinfo_files += custom_target(module_name + '.modinfo',
2983 output: module_name + '.modinfo',
2984 input: target_module_ss.sources() + genh,
2986 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
2991 specific_ss.add_all(module_ss)
2997 modinfo_src = custom_target('modinfo.c',
2998 output: 'modinfo.c',
2999 input: modinfo_files,
3000 command: [modinfo_generate, '@INPUT@'],
3002 modinfo_lib = static_library('modinfo', modinfo_src)
3003 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
3004 softmmu_ss.add(modinfo_dep)
3007 nm = find_program('nm')
3008 undefsym = find_program('scripts/undefsym.py')
3009 block_syms = custom_target('block.syms', output: 'block.syms',
3010 input: [libqemuutil, block_mods],
3012 command: [undefsym, nm, '@INPUT@'])
3013 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3014 input: [libqemuutil, softmmu_mods],
3016 command: [undefsym, nm, '@INPUT@'])
3018 qom_ss = qom_ss.apply(config_host, strict: false)
3019 libqom = static_library('qom', qom_ss.sources() + genh,
3020 dependencies: [qom_ss.dependencies()],
3023 qom = declare_dependency(link_whole: libqom)
3025 authz_ss = authz_ss.apply(config_host, strict: false)
3026 libauthz = static_library('authz', authz_ss.sources() + genh,
3027 dependencies: [authz_ss.dependencies()],
3029 build_by_default: false)
3031 authz = declare_dependency(link_whole: libauthz,
3034 crypto_ss = crypto_ss.apply(config_host, strict: false)
3035 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3036 dependencies: [crypto_ss.dependencies()],
3038 build_by_default: false)
3040 crypto = declare_dependency(link_whole: libcrypto,
3041 dependencies: [authz, qom])
3043 io_ss = io_ss.apply(config_host, strict: false)
3044 libio = static_library('io', io_ss.sources() + genh,
3045 dependencies: [io_ss.dependencies()],
3046 link_with: libqemuutil,
3048 build_by_default: false)
3050 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3052 libmigration = static_library('migration', sources: migration_files + genh,
3054 build_by_default: false)
3055 migration = declare_dependency(link_with: libmigration,
3056 dependencies: [zlib, qom, io])
3057 softmmu_ss.add(migration)
3059 block_ss = block_ss.apply(config_host, strict: false)
3060 libblock = static_library('block', block_ss.sources() + genh,
3061 dependencies: block_ss.dependencies(),
3062 link_depends: block_syms,
3064 build_by_default: false)
3066 block = declare_dependency(link_whole: [libblock],
3067 link_args: '@block.syms',
3068 dependencies: [crypto, io])
3070 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
3071 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3072 dependencies: blockdev_ss.dependencies(),
3074 build_by_default: false)
3076 blockdev = declare_dependency(link_whole: [libblockdev],
3077 dependencies: [block])
3079 qmp_ss = qmp_ss.apply(config_host, strict: false)
3080 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3081 dependencies: qmp_ss.dependencies(),
3083 build_by_default: false)
3085 qmp = declare_dependency(link_whole: [libqmp])
3087 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3089 dependencies: chardev_ss.dependencies(),
3090 build_by_default: false)
3092 chardev = declare_dependency(link_whole: libchardev)
3094 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
3095 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3097 build_by_default: false)
3098 hwcore = declare_dependency(link_whole: libhwcore)
3099 common_ss.add(hwcore)
3105 emulator_modules = []
3106 foreach m : block_mods + softmmu_mods
3107 emulator_modules += shared_module(m.name(),
3108 build_by_default: true,
3112 install_dir: qemu_moddir)
3115 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3116 common_ss.add(qom, qemuutil)
3118 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
3119 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3121 common_all = common_ss.apply(config_all, strict: false)
3122 common_all = static_library('common',
3123 build_by_default: false,
3124 sources: common_all.sources() + genh,
3125 include_directories: common_user_inc,
3126 implicit_include_directories: false,
3127 dependencies: common_all.dependencies(),
3130 feature_to_c = find_program('scripts/feature_to_c.sh')
3132 if targetos == 'darwin'
3133 entitlement = find_program('scripts/entitlement.sh')
3137 foreach target : target_dirs
3138 config_target = config_target_mak[target]
3139 target_name = config_target['TARGET_NAME']
3140 target_base_arch = config_target['TARGET_BASE_ARCH']
3141 arch_srcs = [config_target_h[target]]
3143 c_args = ['-DNEED_CPU_H',
3144 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3145 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3146 link_args = emulator_link_args
3148 config_target += config_host
3149 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3150 if targetos == 'linux'
3151 target_inc += include_directories('linux-headers', is_system: true)
3153 if target.endswith('-softmmu')
3154 qemu_target_name = 'qemu-system-' + target_name
3155 target_type='system'
3156 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3157 arch_srcs += t.sources()
3158 arch_deps += t.dependencies()
3160 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3161 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3162 arch_srcs += hw.sources()
3163 arch_deps += hw.dependencies()
3165 arch_srcs += config_devices_h[target]
3166 link_args += ['@block.syms', '@qemu.syms']
3168 abi = config_target['TARGET_ABI_DIR']
3170 target_inc += common_user_inc
3171 qemu_target_name = 'qemu-' + target_name
3172 if target_base_arch in target_user_arch
3173 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3174 arch_srcs += t.sources()
3175 arch_deps += t.dependencies()
3177 if 'CONFIG_LINUX_USER' in config_target
3178 base_dir = 'linux-user'
3180 if 'CONFIG_BSD_USER' in config_target
3181 base_dir = 'bsd-user'
3182 target_inc += include_directories('bsd-user/' / targetos)
3183 target_inc += include_directories('bsd-user/host/' / host_arch)
3184 dir = base_dir / abi
3185 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3187 target_inc += include_directories(
3191 if 'CONFIG_LINUX_USER' in config_target
3192 dir = base_dir / abi
3193 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3194 if config_target.has_key('TARGET_SYSTBL_ABI')
3196 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3197 extra_args : config_target['TARGET_SYSTBL_ABI'])
3202 if 'TARGET_XML_FILES' in config_target
3203 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3204 output: target + '-gdbstub-xml.c',
3205 input: files(config_target['TARGET_XML_FILES'].split()),
3206 command: [feature_to_c, '@INPUT@'],
3208 arch_srcs += gdbstub_xml
3211 t = target_arch[target_base_arch].apply(config_target, strict: false)
3212 arch_srcs += t.sources()
3213 arch_deps += t.dependencies()
3215 target_common = common_ss.apply(config_target, strict: false)
3216 objects = common_all.extract_objects(target_common.sources())
3217 deps = target_common.dependencies()
3219 target_specific = specific_ss.apply(config_target, strict: false)
3220 arch_srcs += target_specific.sources()
3221 arch_deps += target_specific.dependencies()
3223 lib = static_library('qemu-' + target,
3224 sources: arch_srcs + genh,
3225 dependencies: arch_deps,
3227 include_directories: target_inc,
3229 build_by_default: false,
3232 if target.endswith('-softmmu')
3234 'name': 'qemu-system-' + target_name,
3235 'win_subsystem': 'console',
3236 'sources': files('softmmu/main.c'),
3239 if targetos == 'windows' and (sdl.found() or gtk.found())
3241 'name': 'qemu-system-' + target_name + 'w',
3242 'win_subsystem': 'windows',
3243 'sources': files('softmmu/main.c'),
3247 if get_option('fuzzing')
3248 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3250 'name': 'qemu-fuzz-' + target_name,
3251 'win_subsystem': 'console',
3252 'sources': specific_fuzz.sources(),
3253 'dependencies': specific_fuzz.dependencies(),
3258 'name': 'qemu-' + target_name,
3259 'win_subsystem': 'console',
3265 exe_name = exe['name']
3266 if targetos == 'darwin'
3267 exe_name += '-unsigned'
3270 emulator = executable(exe_name, exe['sources'],
3273 dependencies: arch_deps + deps + exe['dependencies'],
3274 objects: lib.extract_all_objects(recursive: true),
3275 link_language: link_language,
3276 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3277 link_args: link_args,
3278 win_subsystem: exe['win_subsystem'])
3280 if targetos == 'darwin'
3281 icon = 'pc-bios/qemu.rsrc'
3282 build_input = [emulator, files(icon)]
3284 get_option('bindir') / exe_name,
3285 meson.current_source_dir() / icon
3287 if 'CONFIG_HVF' in config_target
3288 entitlements = 'accel/hvf/entitlements.plist'
3289 build_input += files(entitlements)
3290 install_input += meson.current_source_dir() / entitlements
3293 emulators += {exe['name'] : custom_target(exe['name'],
3295 output: exe['name'],
3296 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3299 meson.add_install_script(entitlement, '--install',
3300 get_option('bindir') / exe['name'],
3303 emulators += {exe['name']: emulator}
3308 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3309 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3310 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3311 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3313 custom_target(exe['name'] + stp['ext'],
3314 input: trace_events_all,
3315 output: exe['name'] + stp['ext'],
3316 install: stp['install'],
3317 install_dir: get_option('datadir') / 'systemtap/tapset',
3319 tracetool, '--group=all', '--format=' + stp['fmt'],
3320 '--binary=' + stp['bin'],
3321 '--target-name=' + target_name,
3322 '--target-type=' + target_type,
3323 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3324 '@INPUT@', '@OUTPUT@'
3326 depend_files: tracetool_depends)
3332 # Other build targets
3334 if 'CONFIG_PLUGIN' in config_host
3335 install_headers('include/qemu/qemu-plugin.h')
3340 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3341 # when we don't build tools or system
3342 if xkbcommon.found()
3343 # used for the update-keymaps target, so include rules even if !have_tools
3344 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3345 dependencies: [qemuutil, xkbcommon], install: have_tools)
3349 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3350 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3351 qemu_io = executable('qemu-io', files('qemu-io.c'),
3352 dependencies: [block, qemuutil], install: true)
3353 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3354 dependencies: [blockdev, qemuutil, gnutls, selinux],
3357 subdir('storage-daemon')
3358 subdir('contrib/rdmacm-mux')
3359 subdir('contrib/elf2dmp')
3361 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3362 dependencies: qemuutil,
3365 if 'CONFIG_VHOST_USER' in config_host
3366 subdir('contrib/vhost-user-blk')
3367 subdir('contrib/vhost-user-gpu')
3368 subdir('contrib/vhost-user-input')
3369 subdir('contrib/vhost-user-scsi')
3372 if targetos == 'linux'
3373 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3374 dependencies: [qemuutil, libcap_ng],
3376 install_dir: get_option('libexecdir'))
3378 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3379 dependencies: [authz, crypto, io, qom, qemuutil,
3380 libcap_ng, mpathpersist],
3385 subdir('contrib/ivshmem-client')
3386 subdir('contrib/ivshmem-server')
3399 if host_machine.system() == 'windows'
3401 find_program('scripts/nsis.py'),
3403 get_option('prefix'),
3404 meson.current_source_dir(),
3407 '-DDISPLAYVERSION=' + meson.project_version(),
3410 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3413 nsis_cmd += '-DCONFIG_GTK=y'
3416 nsis = custom_target('nsis',
3417 output: 'qemu-setup-' + meson.project_version() + '.exe',
3418 input: files('qemu.nsi'),
3419 build_always_stale: true,
3420 command: nsis_cmd + ['@INPUT@'])
3421 alias_target('installer', nsis)
3424 #########################
3425 # Configuration summary #
3426 #########################
3430 summary_info += {'Install prefix': get_option('prefix')}
3431 summary_info += {'BIOS directory': qemu_datadir}
3432 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
3433 summary_info += {'binary directory': get_option('bindir')}
3434 summary_info += {'library directory': get_option('libdir')}
3435 summary_info += {'module directory': qemu_moddir}
3436 summary_info += {'libexec directory': get_option('libexecdir')}
3437 summary_info += {'include directory': get_option('includedir')}
3438 summary_info += {'config directory': get_option('sysconfdir')}
3439 if targetos != 'windows'
3440 summary_info += {'local state directory': get_option('localstatedir')}
3441 summary_info += {'Manual directory': get_option('mandir')}
3443 summary_info += {'local state directory': 'queried at runtime'}
3445 summary_info += {'Doc directory': get_option('docdir')}
3446 summary_info += {'Build directory': meson.current_build_dir()}
3447 summary_info += {'Source path': meson.current_source_dir()}
3448 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3449 summary(summary_info, bool_yn: true, section: 'Directories')
3453 summary_info += {'git': config_host['GIT']}
3454 summary_info += {'make': config_host['MAKE']}
3455 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3456 summary_info += {'sphinx-build': sphinx_build}
3457 if config_host.has_key('HAVE_GDB_BIN')
3458 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3460 if get_option('iasl') != ''
3461 summary_info += {'iasl': get_option('iasl')}
3463 summary_info += {'iasl': false}
3465 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3466 if targetos == 'windows' and have_ga
3467 summary_info += {'wixl': wixl}
3469 if slirp_opt != 'disabled' and have_system
3470 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
3472 summary(summary_info, bool_yn: true, section: 'Host binaries')
3474 # Configurable features
3476 summary_info += {'Documentation': build_docs}
3477 summary_info += {'system-mode emulation': have_system}
3478 summary_info += {'user-mode emulation': have_user}
3479 summary_info += {'block layer': have_block}
3480 summary_info += {'Install blobs': get_option('install_blobs')}
3481 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3482 if config_host.has_key('CONFIG_MODULES')
3483 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
3485 summary_info += {'fuzzing support': get_option('fuzzing')}
3487 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3489 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3490 if 'simple' in get_option('trace_backends')
3491 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3493 summary_info += {'D-Bus display': dbus_display}
3494 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
3495 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
3496 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
3497 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
3498 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
3499 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
3500 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
3501 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3502 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
3503 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
3504 summary_info += {'build guest agent': have_ga}
3505 summary(summary_info, bool_yn: true, section: 'Configurable features')
3507 # Compilation information
3509 summary_info += {'host CPU': cpu}
3510 summary_info += {'host endianness': build_machine.endian()}
3511 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3512 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3513 if link_language == 'cpp'
3514 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3516 summary_info += {'C++ compiler': false}
3518 if targetos == 'darwin'
3519 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3521 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3522 + ['-O' + get_option('optimization')]
3523 + (get_option('debug') ? ['-g'] : []))}
3524 if link_language == 'cpp'
3525 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3526 + ['-O' + get_option('optimization')]
3527 + (get_option('debug') ? ['-g'] : []))}
3529 if targetos == 'darwin'
3530 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args')
3531 + ['-O' + get_option('optimization')]
3532 + (get_option('debug') ? ['-g'] : []))}
3534 link_args = get_option(link_language + '_link_args')
3535 if link_args.length() > 0
3536 summary_info += {'LDFLAGS': ' '.join(link_args)}
3538 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
3539 summary_info += {'QEMU_CXXFLAGS': config_host['QEMU_CXXFLAGS']}
3540 summary_info += {'QEMU_OBJCFLAGS': config_host['QEMU_OBJCFLAGS']}
3541 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
3542 summary_info += {'profiler': get_option('profiler')}
3543 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3544 summary_info += {'PIE': get_option('b_pie')}
3545 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3546 summary_info += {'malloc trim support': has_malloc_trim}
3547 summary_info += {'membarrier': have_membarrier}
3548 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
3549 summary_info += {'mutex debugging': get_option('debug_mutex')}
3550 summary_info += {'memory allocator': get_option('malloc')}
3551 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
3552 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
3553 summary_info += {'gprof enabled': get_option('gprof')}
3554 summary_info += {'gcov': get_option('b_coverage')}
3555 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3556 summary_info += {'CFI support': get_option('cfi')}
3557 if get_option('cfi')
3558 summary_info += {'CFI debug support': get_option('cfi_debug')}
3560 summary_info += {'strip binaries': get_option('strip')}
3561 summary_info += {'sparse': sparse}
3562 summary_info += {'mingw32 support': targetos == 'windows'}
3564 # snarf the cross-compilation information for tests
3565 foreach target: target_dirs
3566 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3567 if fs.exists(tcg_mak)
3568 config_cross_tcg = keyval.load(tcg_mak)
3569 target = config_cross_tcg['TARGET_NAME']
3571 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3572 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3573 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3574 elif 'CROSS_CC_GUEST' in config_cross_tcg
3575 summary_info += {target + ' tests'
3576 : config_cross_tcg['CROSS_CC_GUEST'] }
3581 summary(summary_info, bool_yn: true, section: 'Compilation')
3583 # Targets and accelerators
3586 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3587 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3588 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3589 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3590 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3591 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
3592 if config_host.has_key('CONFIG_XEN_BACKEND')
3593 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
3596 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3597 if config_all.has_key('CONFIG_TCG')
3598 if get_option('tcg_interpreter')
3599 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
3601 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3603 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3604 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3606 summary_info += {'target list': ' '.join(target_dirs)}
3608 summary_info += {'default devices': get_option('default_devices')}
3609 summary_info += {'out of process emulation': multiprocess_allowed}
3611 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3615 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3616 summary_info += {'coroutine pool': have_coroutine_pool}
3618 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3619 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3620 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
3621 summary_info += {'VirtFS support': have_virtfs}
3622 summary_info += {'build virtiofs daemon': have_virtiofsd}
3623 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
3624 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
3625 summary_info += {'bochs support': get_option('bochs').allowed()}
3626 summary_info += {'cloop support': get_option('cloop').allowed()}
3627 summary_info += {'dmg support': get_option('dmg').allowed()}
3628 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
3629 summary_info += {'vdi support': get_option('vdi').allowed()}
3630 summary_info += {'vvfat support': get_option('vvfat').allowed()}
3631 summary_info += {'qed support': get_option('qed').allowed()}
3632 summary_info += {'parallels support': get_option('parallels').allowed()}
3633 summary_info += {'FUSE exports': fuse}
3635 summary(summary_info, bool_yn: true, section: 'Block layer support')
3639 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
3640 summary_info += {'GNUTLS support': gnutls}
3642 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3644 summary_info += {'libgcrypt': gcrypt}
3645 summary_info += {'nettle': nettle}
3647 summary_info += {' XTS': xts != 'private'}
3649 summary_info += {'AF_ALG support': have_afalg}
3650 summary_info += {'rng-none': get_option('rng_none')}
3651 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
3652 summary(summary_info, bool_yn: true, section: 'Crypto')
3656 if targetos == 'darwin'
3657 summary_info += {'Cocoa support': cocoa}
3659 summary_info += {'SDL support': sdl}
3660 summary_info += {'SDL image support': sdl_image}
3661 summary_info += {'GTK support': gtk}
3662 summary_info += {'pixman': pixman}
3663 summary_info += {'VTE support': vte}
3664 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3665 summary_info += {'libtasn1': tasn1}
3666 summary_info += {'PAM': pam}
3667 summary_info += {'iconv support': iconv}
3668 summary_info += {'curses support': curses}
3669 summary_info += {'virgl support': virgl}
3670 summary_info += {'curl support': curl}
3671 summary_info += {'Multipath support': mpathpersist}
3672 summary_info += {'PNG support': png}
3673 summary_info += {'VNC support': vnc}
3675 summary_info += {'VNC SASL support': sasl}
3676 summary_info += {'VNC JPEG support': jpeg}
3678 if targetos not in ['darwin', 'haiku', 'windows']
3679 summary_info += {'OSS support': oss}
3680 elif targetos == 'darwin'
3681 summary_info += {'CoreAudio support': coreaudio}
3682 elif targetos == 'windows'
3683 summary_info += {'DirectSound support': dsound}
3685 if targetos == 'linux'
3686 summary_info += {'ALSA support': alsa}
3687 summary_info += {'PulseAudio support': pulse}
3689 summary_info += {'JACK support': jack}
3690 summary_info += {'brlapi support': brlapi}
3691 summary_info += {'vde support': vde}
3692 summary_info += {'netmap support': have_netmap}
3693 summary_info += {'l2tpv3 support': have_l2tpv3}
3694 summary_info += {'Linux AIO support': libaio}
3695 summary_info += {'Linux io_uring support': linux_io_uring}
3696 summary_info += {'ATTR/XATTR support': libattr}
3697 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
3698 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
3699 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3700 summary_info += {'libcap-ng support': libcap_ng}
3701 summary_info += {'bpf support': libbpf}
3702 summary_info += {'spice protocol support': spice_protocol}
3703 if spice_protocol.found()
3704 summary_info += {' spice server support': spice}
3706 summary_info += {'rbd support': rbd}
3707 summary_info += {'smartcard support': cacard}
3708 summary_info += {'U2F support': u2f}
3709 summary_info += {'libusb': libusb}
3710 summary_info += {'usb net redir': usbredir}
3711 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
3712 summary_info += {'GBM': gbm}
3713 summary_info += {'libiscsi support': libiscsi}
3714 summary_info += {'libnfs support': libnfs}
3715 if targetos == 'windows'
3717 summary_info += {'QGA VSS support': have_qga_vss}
3720 summary_info += {'seccomp support': seccomp}
3721 summary_info += {'GlusterFS support': glusterfs}
3722 summary_info += {'TPM support': have_tpm}
3723 summary_info += {'libssh support': libssh}
3724 summary_info += {'lzo support': lzo}
3725 summary_info += {'snappy support': snappy}
3726 summary_info += {'bzip2 support': libbzip2}
3727 summary_info += {'lzfse support': liblzfse}
3728 summary_info += {'zstd support': zstd}
3729 summary_info += {'NUMA host support': numa}
3730 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3731 summary_info += {'libpmem support': libpmem}
3732 summary_info += {'libdaxctl support': libdaxctl}
3733 summary_info += {'libudev': libudev}
3734 # Dummy dependency, keep .found()
3735 summary_info += {'FUSE lseek': fuse_lseek.found()}
3736 summary_info += {'selinux': selinux}
3737 summary(summary_info, bool_yn: true, section: 'Dependencies')
3739 if not supported_cpus.contains(cpu)
3741 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3743 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3744 message('The QEMU project intends to remove support for this host CPU in')
3745 message('a future release if nobody volunteers to maintain it and to')
3746 message('provide a build host for our continuous integration setup.')
3747 message('configure has succeeded and you can continue to build, but')
3748 message('if you care about QEMU on this platform you should contact')
3749 message('us upstream at qemu-devel@nongnu.org.')
3752 if not supported_oses.contains(targetos)
3754 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3756 message('Host OS ' + targetos + 'support is not currently maintained.')
3757 message('The QEMU project intends to remove support for this host OS in')
3758 message('a future release if nobody volunteers to maintain it and to')
3759 message('provide a build host for our continuous integration setup.')
3760 message('configure has succeeded and you can continue to build, but')
3761 message('if you care about QEMU on this platform you should contact')
3762 message('us upstream at qemu-devel@nongnu.org.')