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 gdbus_codegen = not_found
452 if not get_option('gio').auto() or have_system
453 gio = dependency('gio-2.0', required: get_option('gio'),
454 method: 'pkg-config', kwargs: static_kwargs)
455 if gio.found() and not cc.links('''
459 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
461 }''', dependencies: [glib, gio])
462 if get_option('gio').enabled()
463 error('The installed libgio is broken for static linking')
468 gdbus_codegen = find_program(gio.get_variable('gdbus_codegen'),
469 required: get_option('gio'))
470 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
471 method: 'pkg-config', kwargs: static_kwargs)
472 gio = declare_dependency(dependencies: [gio, gio_unix],
473 version: gio.version())
478 if 'ust' in get_option('trace_backends')
479 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
480 method: 'pkg-config', kwargs: static_kwargs)
483 if have_system or have_tools
484 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
485 method: 'pkg-config', kwargs: static_kwargs)
487 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
490 if not get_option('linux_aio').auto() or have_block
491 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
492 required: get_option('linux_aio'),
493 kwargs: static_kwargs)
495 linux_io_uring = not_found
496 if not get_option('linux_io_uring').auto() or have_block
497 linux_io_uring = dependency('liburing', version: '>=0.3',
498 required: get_option('linux_io_uring'),
499 method: 'pkg-config', kwargs: static_kwargs)
502 if not get_option('libnfs').auto() or have_block
503 libnfs = dependency('libnfs', version: '>=1.9.3',
504 required: get_option('libnfs'),
505 method: 'pkg-config', kwargs: static_kwargs)
510 #include <sys/types.h>
511 #ifdef CONFIG_LIBATTR
512 #include <attr/xattr.h>
514 #include <sys/xattr.h>
516 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
519 have_old_libattr = false
520 if get_option('attr').allowed()
521 if cc.links(libattr_test)
522 libattr = declare_dependency()
524 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
525 required: get_option('attr'),
526 kwargs: static_kwargs)
527 if libattr.found() and not \
528 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
530 if get_option('attr').enabled()
531 error('could not link libattr')
533 warning('could not link libattr, disabling')
536 have_old_libattr = libattr.found()
541 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
542 if cocoa.found() and get_option('sdl').enabled()
543 error('Cocoa and SDL cannot be enabled at the same time')
545 if cocoa.found() and get_option('gtk').enabled()
546 error('Cocoa and GTK+ cannot be enabled at the same time')
550 if not get_option('seccomp').auto() or have_system or have_tools
551 seccomp = dependency('libseccomp', version: '>=2.3.0',
552 required: get_option('seccomp'),
553 method: 'pkg-config', kwargs: static_kwargs)
556 libcap_ng = not_found
557 if not get_option('cap_ng').auto() or have_system or have_tools
558 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
559 required: get_option('cap_ng'),
560 kwargs: static_kwargs)
562 if libcap_ng.found() and not cc.links('''
566 capng_capability_to_name(CAPNG_EFFECTIVE);
568 }''', dependencies: libcap_ng)
569 libcap_ng = not_found
570 if get_option('cap_ng').enabled()
571 error('could not link libcap-ng')
573 warning('could not link libcap-ng, disabling')
577 if get_option('xkbcommon').auto() and not have_system and not have_tools
578 xkbcommon = not_found
580 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
581 method: 'pkg-config', kwargs: static_kwargs)
585 if not get_option('vde').auto() or have_system or have_tools
586 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
587 required: get_option('vde'),
588 kwargs: static_kwargs)
590 if vde.found() and not cc.links('''
591 #include <libvdeplug.h>
594 struct vde_open_args a = {0, 0, 0};
598 }''', dependencies: vde)
600 if get_option('cap_ng').enabled()
601 error('could not link libvdeplug')
603 warning('could not link libvdeplug, disabling')
608 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
609 pulse = dependency('libpulse', required: get_option('pa'),
610 method: 'pkg-config', kwargs: static_kwargs)
613 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
614 alsa = dependency('alsa', required: get_option('alsa'),
615 method: 'pkg-config', kwargs: static_kwargs)
618 if not get_option('jack').auto() or have_system
619 jack = dependency('jack', required: get_option('jack'),
620 method: 'pkg-config', kwargs: static_kwargs)
623 spice_protocol = not_found
624 if not get_option('spice_protocol').auto() or have_system
625 spice_protocol = dependency('spice-protocol', version: '>=0.12.3',
626 required: get_option('spice_protocol'),
627 method: 'pkg-config', kwargs: static_kwargs)
630 if not get_option('spice').auto() or have_system
631 spice = dependency('spice-server', version: '>=0.12.5',
632 required: get_option('spice'),
633 method: 'pkg-config', kwargs: static_kwargs)
635 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
637 rt = cc.find_library('rt', required: false)
640 if not get_option('libiscsi').auto() or have_block
641 libiscsi = dependency('libiscsi', version: '>=1.9.0',
642 required: get_option('libiscsi'),
643 method: 'pkg-config', kwargs: static_kwargs)
646 if not get_option('zstd').auto() or have_block
647 zstd = dependency('libzstd', version: '>=1.4.0',
648 required: get_option('zstd'),
649 method: 'pkg-config', kwargs: static_kwargs)
653 have_vhost_user_gpu = have_tools and targetos == 'linux' and pixman.found()
654 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
655 virgl = dependency('virglrenderer',
656 method: 'pkg-config',
657 required: get_option('virglrenderer'),
658 kwargs: static_kwargs)
661 if not get_option('curl').auto() or have_block
662 curl = dependency('libcurl', version: '>=7.29.0',
663 method: 'pkg-config',
664 required: get_option('curl'),
665 kwargs: static_kwargs)
668 if targetos == 'linux' and (have_system or have_tools)
669 libudev = dependency('libudev',
670 method: 'pkg-config',
671 required: get_option('libudev'),
672 kwargs: static_kwargs)
675 mpathlibs = [libudev]
676 mpathpersist = not_found
677 mpathpersist_new_api = false
678 if targetos == 'linux' and have_tools and get_option('mpath').allowed()
679 mpath_test_source_new = '''
681 #include <mpath_persist.h>
682 unsigned mpath_mx_alloc_len = 1024;
684 static struct config *multipath_conf;
685 extern struct udev *udev;
686 extern struct config *get_multipath_config(void);
687 extern void put_multipath_config(struct config *conf);
689 struct config *get_multipath_config(void) { return multipath_conf; }
690 void put_multipath_config(struct config *conf) { }
693 multipath_conf = mpath_lib_init();
696 mpath_test_source_old = '''
698 #include <mpath_persist.h>
699 unsigned mpath_mx_alloc_len = 1024;
702 struct udev *udev = udev_new();
703 mpath_lib_init(udev);
706 libmpathpersist = cc.find_library('mpathpersist',
707 required: get_option('mpath'),
708 kwargs: static_kwargs)
709 if libmpathpersist.found()
710 mpathlibs += libmpathpersist
712 mpathlibs += cc.find_library('devmapper',
713 required: get_option('mpath'),
714 kwargs: static_kwargs)
716 mpathlibs += cc.find_library('multipath',
717 required: get_option('mpath'),
718 kwargs: static_kwargs)
719 foreach lib: mpathlibs
725 if mpathlibs.length() == 0
726 msg = 'Dependencies missing for libmpathpersist'
727 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
728 mpathpersist = declare_dependency(dependencies: mpathlibs)
729 mpathpersist_new_api = true
730 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
731 mpathpersist = declare_dependency(dependencies: mpathlibs)
733 msg = 'Cannot detect libmpathpersist API'
735 if not mpathpersist.found()
736 if get_option('mpath').enabled()
739 warning(msg + ', disabling')
747 if have_system and get_option('curses').allowed()
749 #if defined(__APPLE__) || defined(__OpenBSD__)
750 #define _XOPEN_SOURCE_EXTENDED 1
757 setlocale(LC_ALL, "");
759 addwstr(L"wide chars\n");
761 add_wch(WACS_DEGREE);
765 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
766 foreach curses_dep : curses_dep_list
767 if not curses.found()
768 curses = dependency(curses_dep,
770 method: 'pkg-config',
771 kwargs: static_kwargs)
774 msg = get_option('curses').enabled() ? 'curses library not found' : ''
775 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
777 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
778 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
780 msg = 'curses package not usable'
784 if not curses.found()
785 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
786 if targetos != 'windows' and not has_curses_h
787 message('Trying with /usr/include/ncursesw')
788 curses_compile_args += ['-I/usr/include/ncursesw']
789 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
792 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
793 foreach curses_libname : curses_libname_list
794 libcurses = cc.find_library(curses_libname,
796 kwargs: static_kwargs)
798 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
799 curses = declare_dependency(compile_args: curses_compile_args,
800 dependencies: [libcurses])
803 msg = 'curses library not usable'
809 if get_option('iconv').allowed()
810 foreach link_args : [ ['-liconv'], [] ]
811 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
812 # We need to use libiconv if available because mixing libiconv's headers with
813 # the system libc does not work.
814 # However, without adding glib to the dependencies -L/usr/local/lib will not be
815 # included in the command line and libiconv will not be found.
819 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
820 return conv != (iconv_t) -1;
821 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
822 iconv = declare_dependency(link_args: link_args, dependencies: glib)
827 if curses.found() and not iconv.found()
828 if get_option('iconv').enabled()
829 error('iconv not available')
831 msg = 'iconv required for curses UI but not available'
834 if not curses.found() and msg != ''
835 if get_option('curses').enabled()
838 warning(msg + ', disabling')
844 if not get_option('brlapi').auto() or have_system
845 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
846 required: get_option('brlapi'),
847 kwargs: static_kwargs)
848 if brlapi.found() and not cc.links('''
851 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
853 if get_option('brlapi').enabled()
854 error('could not link brlapi')
856 warning('could not link brlapi, disabling')
862 if not get_option('sdl').auto() or (have_system and not cocoa.found())
863 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
864 sdl_image = not_found
867 # work around 2.0.8 bug
868 sdl = declare_dependency(compile_args: '-Wno-undef',
870 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
871 method: 'pkg-config', kwargs: static_kwargs)
873 if get_option('sdl_image').enabled()
874 error('sdl-image required, but SDL was @0@'.format(
875 get_option('sdl').disabled() ? 'disabled' : 'not found'))
877 sdl_image = not_found
881 if not get_option('rbd').auto() or have_block
882 librados = cc.find_library('rados', required: get_option('rbd'),
883 kwargs: static_kwargs)
884 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
885 required: get_option('rbd'),
886 kwargs: static_kwargs)
887 if librados.found() and librbd.found()
890 #include <rbd/librbd.h>
893 rados_create(&cluster, NULL);
894 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
898 }''', dependencies: [librbd, librados])
899 rbd = declare_dependency(dependencies: [librbd, librados])
900 elif get_option('rbd').enabled()
901 error('librbd >= 1.12.0 required')
903 warning('librbd >= 1.12.0 not found, disabling')
908 glusterfs = not_found
909 glusterfs_ftruncate_has_stat = false
910 glusterfs_iocb_has_stat = false
911 if not get_option('glusterfs').auto() or have_block
912 glusterfs = dependency('glusterfs-api', version: '>=3',
913 required: get_option('glusterfs'),
914 method: 'pkg-config', kwargs: static_kwargs)
916 glusterfs_ftruncate_has_stat = cc.links('''
917 #include <glusterfs/api/glfs.h>
922 /* new glfs_ftruncate() passes two additional args */
923 return glfs_ftruncate(NULL, 0, NULL, NULL);
925 ''', dependencies: glusterfs)
926 glusterfs_iocb_has_stat = cc.links('''
927 #include <glusterfs/api/glfs.h>
929 /* new glfs_io_cbk() passes two additional glfs_stat structs */
931 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
937 glfs_io_cbk iocb = &glusterfs_iocb;
938 iocb(NULL, 0 , NULL, NULL, NULL);
941 ''', dependencies: glusterfs)
946 if not get_option('libssh').auto() or have_block
947 libssh = dependency('libssh', version: '>=0.8.7',
948 method: 'pkg-config',
949 required: get_option('libssh'),
950 kwargs: static_kwargs)
954 if not get_option('bzip2').auto() or have_block
955 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
956 required: get_option('bzip2'),
957 kwargs: static_kwargs)
958 if libbzip2.found() and not cc.links('''
960 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
962 if get_option('bzip2').enabled()
963 error('could not link libbzip2')
965 warning('could not link libbzip2, disabling')
971 if not get_option('lzfse').auto() or have_block
972 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
973 required: get_option('lzfse'),
974 kwargs: static_kwargs)
976 if liblzfse.found() and not cc.links('''
978 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
980 if get_option('lzfse').enabled()
981 error('could not link liblzfse')
983 warning('could not link liblzfse, disabling')
988 if get_option('oss').allowed() and have_system
989 if not cc.has_header('sys/soundcard.h')
991 elif targetos == 'netbsd'
992 oss = cc.find_library('ossaudio', required: get_option('oss'),
993 kwargs: static_kwargs)
995 oss = declare_dependency()
999 if get_option('oss').enabled()
1000 error('OSS not found')
1005 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
1006 if cc.has_header('dsound.h')
1007 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
1010 if not dsound.found()
1011 if get_option('dsound').enabled()
1012 error('DirectSound not found')
1017 coreaudio = not_found
1018 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
1019 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
1020 required: get_option('coreaudio'))
1024 if not get_option('opengl').auto() or have_system or have_vhost_user_gpu
1025 epoxy = dependency('epoxy', method: 'pkg-config',
1026 required: get_option('opengl'), kwargs: static_kwargs)
1027 if cc.has_header('epoxy/egl.h', dependencies: epoxy)
1029 elif get_option('opengl').enabled()
1030 error('epoxy/egl.h not found')
1034 if (have_system or have_tools) and (virgl.found() or opengl.found())
1035 gbm = dependency('gbm', method: 'pkg-config', required: false,
1036 kwargs: static_kwargs)
1038 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and gbm.found()
1041 gnutls_crypto = not_found
1042 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1043 # For general TLS support our min gnutls matches
1044 # that implied by our platform support matrix
1046 # For the crypto backends, we look for a newer
1049 # Version 3.6.8 is needed to get XTS
1050 # Version 3.6.13 is needed to get PBKDF
1051 # Version 3.6.14 is needed to get HW accelerated XTS
1053 # If newer enough gnutls isn't available, we can
1054 # still use a different crypto backend to satisfy
1055 # the platform support requirements
1056 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1057 method: 'pkg-config',
1059 kwargs: static_kwargs)
1060 if gnutls_crypto.found()
1061 gnutls = gnutls_crypto
1063 # Our min version if all we need is TLS
1064 gnutls = dependency('gnutls', version: '>=3.5.18',
1065 method: 'pkg-config',
1066 required: get_option('gnutls'),
1067 kwargs: static_kwargs)
1071 # We prefer use of gnutls for crypto, unless the options
1072 # explicitly asked for nettle or gcrypt.
1074 # If gnutls isn't available for crypto, then we'll prefer
1075 # gcrypt over nettle for performance reasons.
1080 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1081 error('Only one of gcrypt & nettle can be enabled')
1084 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1085 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1086 gnutls_crypto = not_found
1089 if not gnutls_crypto.found()
1090 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1091 gcrypt = dependency('libgcrypt', version: '>=1.8',
1092 method: 'config-tool',
1093 required: get_option('gcrypt'),
1094 kwargs: static_kwargs)
1095 # Debian has removed -lgpg-error from libgcrypt-config
1096 # as it "spreads unnecessary dependencies" which in
1097 # turn breaks static builds...
1098 if gcrypt.found() and enable_static
1099 gcrypt = declare_dependency(dependencies: [
1101 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
1104 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1105 nettle = dependency('nettle', version: '>=3.4',
1106 method: 'pkg-config',
1107 required: get_option('nettle'),
1108 kwargs: static_kwargs)
1109 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1118 if not get_option('gtk').auto() or (have_system and not cocoa.found())
1119 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1120 method: 'pkg-config',
1121 required: get_option('gtk'),
1122 kwargs: static_kwargs)
1124 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1125 method: 'pkg-config',
1127 kwargs: static_kwargs)
1128 gtk = declare_dependency(dependencies: [gtk, gtkx11])
1130 if not get_option('vte').auto() or have_system
1131 vte = dependency('vte-2.91',
1132 method: 'pkg-config',
1133 required: get_option('vte'),
1134 kwargs: static_kwargs)
1141 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
1142 kwargs: static_kwargs)
1145 if get_option('png').allowed() and have_system
1146 png = dependency('libpng', required: get_option('png'),
1147 method: 'pkg-config', kwargs: static_kwargs)
1152 if get_option('vnc').allowed() and have_system
1153 vnc = declare_dependency() # dummy dependency
1154 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1155 method: 'pkg-config', kwargs: static_kwargs)
1156 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1157 required: get_option('vnc_sasl'),
1158 kwargs: static_kwargs)
1160 sasl = declare_dependency(dependencies: sasl,
1161 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1166 if not get_option('auth_pam').auto() or have_system
1167 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1168 required: get_option('auth_pam'),
1169 kwargs: static_kwargs)
1171 if pam.found() and not cc.links('''
1173 #include <security/pam_appl.h>
1175 const char *service_name = "qemu";
1176 const char *user = "frank";
1177 const struct pam_conv pam_conv = { 0 };
1178 pam_handle_t *pamh = NULL;
1179 pam_start(service_name, user, &pam_conv, &pamh);
1181 }''', dependencies: pam)
1183 if get_option('auth_pam').enabled()
1184 error('could not link libpam')
1186 warning('could not link libpam, disabling')
1191 if not get_option('snappy').auto() or have_system
1192 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1193 required: get_option('snappy'),
1194 kwargs: static_kwargs)
1196 if snappy.found() and not linker.links('''
1197 #include <snappy-c.h>
1198 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1200 if get_option('snappy').enabled()
1201 error('could not link libsnappy')
1203 warning('could not link libsnappy, disabling')
1208 if not get_option('lzo').auto() or have_system
1209 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1210 required: get_option('lzo'),
1211 kwargs: static_kwargs)
1213 if lzo.found() and not cc.links('''
1214 #include <lzo/lzo1x.h>
1215 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1217 if get_option('lzo').enabled()
1218 error('could not link liblzo2')
1220 warning('could not link liblzo2, disabling')
1225 if not get_option('numa').auto() or have_system or have_tools
1226 numa = cc.find_library('numa', has_headers: ['numa.h'],
1227 required: get_option('numa'),
1228 kwargs: static_kwargs)
1230 if numa.found() and not cc.links('''
1232 int main(void) { return numa_available(); }
1233 ''', dependencies: numa)
1235 if get_option('numa').enabled()
1236 error('could not link numa')
1238 warning('could not link numa, disabling')
1243 if not get_option('rdma').auto() or have_system
1244 libumad = cc.find_library('ibumad', required: get_option('rdma'))
1245 rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'],
1246 required: get_option('rdma'),
1247 kwargs: static_kwargs),
1248 cc.find_library('ibverbs', required: get_option('rdma'),
1249 kwargs: static_kwargs),
1251 rdma = declare_dependency(dependencies: rdma_libs)
1252 foreach lib: rdma_libs
1260 if 'CONFIG_XEN_BACKEND' in config_host
1261 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
1262 link_args: config_host['XEN_LIBS'].split())
1265 if not get_option('smartcard').auto() or have_system
1266 cacard = dependency('libcacard', required: get_option('smartcard'),
1267 version: '>=2.5.1', method: 'pkg-config',
1268 kwargs: static_kwargs)
1272 u2f = dependency('u2f-emu', required: get_option('u2f'),
1273 method: 'pkg-config',
1274 kwargs: static_kwargs)
1276 usbredir = not_found
1277 if not get_option('usb_redir').auto() or have_system
1278 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1279 version: '>=0.6', method: 'pkg-config',
1280 kwargs: static_kwargs)
1283 if not get_option('libusb').auto() or have_system
1284 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1285 version: '>=1.0.13', method: 'pkg-config',
1286 kwargs: static_kwargs)
1290 if not get_option('libpmem').auto() or have_system
1291 libpmem = dependency('libpmem', required: get_option('libpmem'),
1292 method: 'pkg-config', kwargs: static_kwargs)
1294 libdaxctl = not_found
1295 if not get_option('libdaxctl').auto() or have_system
1296 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1297 version: '>=57', method: 'pkg-config',
1298 kwargs: static_kwargs)
1302 tasn1 = dependency('libtasn1',
1303 method: 'pkg-config',
1304 kwargs: static_kwargs)
1306 keyutils = dependency('libkeyutils', required: false,
1307 method: 'pkg-config', kwargs: static_kwargs)
1309 has_gettid = cc.has_function('gettid')
1312 selinux = dependency('libselinux',
1313 required: get_option('selinux'),
1314 method: 'pkg-config', kwargs: static_kwargs)
1319 if get_option('malloc') == 'system'
1321 get_option('malloc_trim').allowed() and \
1322 cc.links('''#include <malloc.h>
1323 int main(void) { malloc_trim(0); return 0; }''')
1325 has_malloc_trim = false
1326 malloc = cc.find_library(get_option('malloc'), required: true)
1328 if not has_malloc_trim and get_option('malloc_trim').enabled()
1329 if get_option('malloc') == 'system'
1330 error('malloc_trim not available on this platform.')
1332 error('malloc_trim not available with non-libc memory allocator')
1336 # Check whether the glibc provides statx()
1338 gnu_source_prefix = '''
1343 statx_test = gnu_source_prefix + '''
1344 #include <sys/stat.h>
1346 struct statx statxbuf;
1347 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1351 has_statx = cc.links(statx_test)
1353 # Check whether statx() provides mount ID information
1355 statx_mnt_id_test = gnu_source_prefix + '''
1356 #include <sys/stat.h>
1358 struct statx statxbuf;
1359 statx(0, "", 0, STATX_BASIC_STATS | STATX_MNT_ID, &statxbuf);
1360 return statxbuf.stx_mnt_id;
1363 has_statx_mnt_id = cc.links(statx_mnt_id_test)
1365 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
1366 .require(targetos == 'linux',
1367 error_message: 'vhost_user_blk_server requires linux') \
1368 .require('CONFIG_VHOST_USER' in config_host,
1369 error_message: 'vhost_user_blk_server requires vhost-user support') \
1370 .disable_auto_if(not have_system) \
1373 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1374 error('Cannot enable fuse-lseek while fuse is disabled')
1377 fuse = dependency('fuse3', required: get_option('fuse'),
1378 version: '>=3.1', method: 'pkg-config',
1379 kwargs: static_kwargs)
1381 fuse_lseek = not_found
1382 if get_option('fuse_lseek').allowed()
1383 if fuse.version().version_compare('>=3.8')
1385 fuse_lseek = declare_dependency()
1386 elif get_option('fuse_lseek').enabled()
1388 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1390 error('fuse-lseek requires libfuse, which was not found')
1396 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1397 if libbpf.found() and not cc.links('''
1398 #include <bpf/libbpf.h>
1401 bpf_object__destroy_skeleton(NULL);
1403 }''', dependencies: libbpf)
1405 if get_option('bpf').enabled()
1406 error('libbpf skeleton test failed')
1408 warning('libbpf skeleton test failed, disabling')
1416 audio_drivers_selected = []
1418 audio_drivers_available = {
1419 'alsa': alsa.found(),
1420 'coreaudio': coreaudio.found(),
1421 'dsound': dsound.found(),
1422 'jack': jack.found(),
1424 'pa': pulse.found(),
1427 foreach k, v: audio_drivers_available
1428 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1431 # Default to native drivers first, OSS second, SDL third
1432 audio_drivers_priority = \
1433 [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
1434 (targetos == 'linux' ? [] : [ 'sdl' ])
1435 audio_drivers_default = []
1436 foreach k: audio_drivers_priority
1437 if audio_drivers_available[k]
1438 audio_drivers_default += k
1442 foreach k: get_option('audio_drv_list')
1444 audio_drivers_selected += audio_drivers_default
1445 elif not audio_drivers_available[k]
1446 error('Audio driver "@0@" not available.'.format(k))
1448 audio_drivers_selected += k
1452 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1453 '"' + '", "'.join(audio_drivers_selected) + '", ')
1455 if get_option('cfi')
1457 # Check for dependency on LTO
1458 if not get_option('b_lto')
1459 error('Selected Control-Flow Integrity but LTO is disabled')
1461 if config_host.has_key('CONFIG_MODULES')
1462 error('Selected Control-Flow Integrity is not compatible with modules')
1464 # Check for cfi flags. CFI requires LTO so we can't use
1465 # get_supported_arguments, but need a more complex "compiles" which allows
1467 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1468 args: ['-flto', '-fsanitize=cfi-icall'] )
1469 cfi_flags += '-fsanitize=cfi-icall'
1471 error('-fsanitize=cfi-icall is not supported by the compiler')
1473 if cc.compiles('int main () { return 0; }',
1474 name: '-fsanitize-cfi-icall-generalize-pointers',
1475 args: ['-flto', '-fsanitize=cfi-icall',
1476 '-fsanitize-cfi-icall-generalize-pointers'] )
1477 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1479 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1481 if get_option('cfi_debug')
1482 if cc.compiles('int main () { return 0; }',
1483 name: '-fno-sanitize-trap=cfi-icall',
1484 args: ['-flto', '-fsanitize=cfi-icall',
1485 '-fno-sanitize-trap=cfi-icall'] )
1486 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1488 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1491 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1492 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1495 have_host_block_device = (targetos != 'darwin' or
1496 cc.has_header('IOKit/storage/IOMedia.h'))
1498 # FIXME enable_modules shouldn't be necessary, but: https://github.com/mesonbuild/meson/issues/8333
1499 dbus_display = get_option('dbus_display') \
1500 .require(gio.version().version_compare('>=2.64'),
1501 error_message: '-display dbus requires glib>=2.64') \
1502 .require(enable_modules,
1503 error_message: '-display dbus requires --enable-modules') \
1504 .require(gdbus_codegen.found(),
1505 error_message: '-display dbus requires gdbus-codegen') \
1508 have_virtfs = get_option('virtfs') \
1509 .require(targetos == 'linux' or targetos == 'darwin',
1510 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
1511 .require(targetos == 'linux' or cc.has_function('pthread_fchdir_np'),
1512 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
1513 .require(targetos == 'darwin' or (libattr.found() and libcap_ng.found()),
1514 error_message: 'virtio-9p (virtfs) on Linux requires libcap-ng-devel and libattr-devel') \
1515 .disable_auto_if(not have_tools and not have_system) \
1518 have_virtfs_proxy_helper = targetos != 'darwin' and have_virtfs and have_tools
1520 foreach k : get_option('trace_backends')
1521 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1523 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1524 if get_option('iasl') != ''
1525 config_host_data.set_quoted('CONFIG_IASL', get_option('iasl'))
1527 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1528 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1529 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1530 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1531 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1532 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1533 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1534 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1535 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1536 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1537 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1538 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1540 have_slirp_smbd = get_option('slirp_smbd') \
1541 .require(targetos != 'windows', error_message: 'Host smbd not supported on this platform.') \
1544 smbd_path = get_option('smbd')
1546 smbd_path = (targetos == 'solaris' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
1548 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
1551 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
1553 if get_option('module_upgrades') and not enable_modules
1554 error('Cannot enable module-upgrades as modules are not enabled')
1556 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
1558 config_host_data.set('CONFIG_ATTR', libattr.found())
1559 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
1560 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1561 config_host_data.set('CONFIG_COCOA', cocoa.found())
1562 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1563 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1564 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1565 config_host_data.set('CONFIG_LZO', lzo.found())
1566 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1567 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1568 config_host_data.set('CONFIG_CURL', curl.found())
1569 config_host_data.set('CONFIG_CURSES', curses.found())
1570 config_host_data.set('CONFIG_GBM', gbm.found())
1571 config_host_data.set('CONFIG_GIO', gio.found())
1572 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1573 if glusterfs.found()
1574 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1575 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1576 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1577 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1578 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1579 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1581 config_host_data.set('CONFIG_GTK', gtk.found())
1582 config_host_data.set('CONFIG_VTE', vte.found())
1583 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1584 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1585 config_host_data.set('CONFIG_EBPF', libbpf.found())
1586 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1587 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1588 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1589 config_host_data.set('CONFIG_LIBSSH', libssh.found())
1590 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1591 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1592 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1593 config_host_data.set('CONFIG_NUMA', numa.found())
1594 config_host_data.set('CONFIG_OPENGL', opengl.found())
1595 config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
1596 config_host_data.set('CONFIG_RBD', rbd.found())
1597 config_host_data.set('CONFIG_RDMA', rdma.found())
1598 config_host_data.set('CONFIG_SDL', sdl.found())
1599 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1600 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1601 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1602 config_host_data.set('CONFIG_TPM', have_tpm)
1603 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1604 config_host_data.set('CONFIG_VDE', vde.found())
1605 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1606 config_host_data.set('CONFIG_PNG', png.found())
1607 config_host_data.set('CONFIG_VNC', vnc.found())
1608 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1609 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1610 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1611 config_host_data.set('CONFIG_VTE', vte.found())
1612 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1613 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1614 config_host_data.set('CONFIG_GETTID', has_gettid)
1615 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1616 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1617 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1618 config_host_data.set('CONFIG_NETTLE', nettle.found())
1619 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1620 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1621 config_host_data.set('CONFIG_STATX', has_statx)
1622 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
1623 config_host_data.set('CONFIG_ZSTD', zstd.found())
1624 config_host_data.set('CONFIG_FUSE', fuse.found())
1625 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1626 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1627 if spice_protocol.found()
1628 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
1629 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
1630 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
1632 config_host_data.set('CONFIG_SPICE', spice.found())
1633 config_host_data.set('CONFIG_X11', x11.found())
1634 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
1635 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1636 config_host_data.set('CONFIG_SELINUX', selinux.found())
1637 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1638 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1639 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1640 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1642 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1643 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1645 have_coroutine_pool = get_option('coroutine_pool')
1646 if get_option('debug_stack_usage') and have_coroutine_pool
1647 message('Disabling coroutine pool to measure stack usage')
1648 have_coroutine_pool = false
1650 config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool)
1651 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
1652 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
1653 config_host_data.set('CONFIG_GPROF', get_option('gprof'))
1654 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
1655 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
1656 config_host_data.set('CONFIG_REPLICATION', get_option('live_block_migration').allowed())
1659 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1660 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1661 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1662 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1663 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1664 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1665 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1666 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1667 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1670 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1671 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1672 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1673 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1674 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1675 # Note that we need to specify prefix: here to avoid incorrectly
1676 # thinking that Windows has posix_memalign()
1677 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
1678 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
1679 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
1680 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
1681 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1682 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1683 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
1684 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1685 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1686 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1687 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1688 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1689 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1690 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1691 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1692 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1694 config_host_data.set('HAVE_IBV_ADVISE_MR',
1695 cc.has_function('ibv_advise_mr',
1697 prefix: '#include <infiniband/verbs.h>'))
1701 config_host_data.set('CONFIG_BYTESWAP_H',
1702 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1703 config_host_data.set('CONFIG_EPOLL_CREATE1',
1704 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1705 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1706 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1707 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1708 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1709 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1710 config_host_data.set('CONFIG_FIEMAP',
1711 cc.has_header('linux/fiemap.h') and
1712 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1713 config_host_data.set('CONFIG_GETRANDOM',
1714 cc.has_function('getrandom') and
1715 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1716 config_host_data.set('CONFIG_INOTIFY',
1717 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1718 config_host_data.set('CONFIG_INOTIFY1',
1719 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1720 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1721 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1722 prefix: '''#include <sys/endian.h>
1723 #include <sys/types.h>'''))
1724 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1725 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1726 config_host_data.set('CONFIG_RTNETLINK',
1727 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1728 config_host_data.set('CONFIG_SYSMACROS',
1729 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1730 config_host_data.set('HAVE_OPTRESET',
1731 cc.has_header_symbol('getopt.h', 'optreset'))
1732 config_host_data.set('HAVE_IPPROTO_MPTCP',
1733 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1736 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1737 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1738 prefix: '#include <signal.h>'))
1739 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1740 cc.has_member('struct stat', 'st_atim',
1741 prefix: '#include <sys/stat.h>'))
1744 config_host_data.set('CONFIG_IOVEC',
1745 cc.has_type('struct iovec',
1746 prefix: '#include <sys/uio.h>'))
1747 config_host_data.set('HAVE_UTMPX',
1748 cc.has_type('struct utmpx',
1749 prefix: '#include <utmpx.h>'))
1751 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1752 #include <sys/eventfd.h>
1753 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1754 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1757 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1758 return fdatasync(0);
1760 #error Not supported
1764 has_madvise = cc.links(gnu_source_prefix + '''
1765 #include <sys/types.h>
1766 #include <sys/mman.h>
1768 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
1769 missing_madvise_proto = false
1771 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
1772 # but forget to prototype it. In this case, has_madvise will be true (the
1773 # test program links despite a compile warning). To detect the
1774 # missing-prototype case, we try again with a definitely-bogus prototype.
1775 # This will only compile if the system headers don't provide the prototype;
1776 # otherwise the conflicting prototypes will cause a compiler error.
1777 missing_madvise_proto = cc.links(gnu_source_prefix + '''
1778 #include <sys/types.h>
1779 #include <sys/mman.h>
1781 extern int madvise(int);
1782 int main(void) { return madvise(0); }''')
1784 config_host_data.set('CONFIG_MADVISE', has_madvise)
1785 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
1787 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1788 #include <sys/mman.h>
1789 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1790 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1792 #if !defined(AT_EMPTY_PATH)
1793 # error missing definition
1795 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1797 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1804 return pipe2(pipefd, O_CLOEXEC);
1806 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1807 #include <sys/mman.h>
1809 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1811 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
1812 #include <pthread.h>
1814 static void *f(void *p) { return NULL; }
1818 pthread_create(&thread, 0, f, 0);
1819 pthread_setname_np(thread, "QEMU");
1821 }''', dependencies: threads))
1822 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
1823 #include <pthread.h>
1825 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
1829 pthread_create(&thread, 0, f, 0);
1831 }''', dependencies: threads))
1832 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
1833 #include <pthread.h>
1838 pthread_condattr_t attr
1839 pthread_condattr_init(&attr);
1840 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
1842 }''', dependencies: threads))
1844 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1845 #include <sys/signalfd.h>
1847 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1848 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1856 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1857 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1861 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
1862 #include <sys/mman.h>
1863 int main(int argc, char *argv[]) {
1864 return mlockall(MCL_FUTURE);
1868 if get_option('l2tpv3').allowed() and have_system
1869 have_l2tpv3 = cc.has_type('struct mmsghdr',
1870 prefix: gnu_source_prefix + '''
1871 #include <sys/socket.h>
1872 #include <linux/ip.h>''')
1874 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
1877 if get_option('netmap').allowed() and have_system
1878 have_netmap = cc.compiles('''
1879 #include <inttypes.h>
1881 #include <net/netmap.h>
1882 #include <net/netmap_user.h>
1883 #if (NETMAP_API < 11) || (NETMAP_API > 15)
1886 int main(void) { return 0; }''')
1887 if not have_netmap and get_option('netmap').enabled()
1888 error('Netmap headers not available')
1891 config_host_data.set('CONFIG_NETMAP', have_netmap)
1893 # Work around a system header bug with some kernel/XFS header
1894 # versions where they both try to define 'struct fsxattr':
1895 # xfs headers will not try to redefine structs from linux headers
1896 # if this macro is set.
1897 config_host_data.set('HAVE_FSXATTR', cc.links('''
1898 #include <linux/fs.h>
1904 # Some versions of Mac OS X incorrectly define SIZE_MAX
1905 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1908 int main(int argc, char *argv[]) {
1909 return printf("%zu", SIZE_MAX);
1910 }''', args: ['-Werror']))
1917 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
1918 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
1919 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
1920 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
1921 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
1925 # See if 64-bit atomic operations are supported.
1926 # Note that without __atomic builtins, we can only
1927 # assume atomic loads/stores max at pointer size.
1928 config_host_data.set('CONFIG_ATOMIC64', cc.links(atomic_test.format('uint64_t')))
1930 has_int128 = cc.links('''
1940 config_host_data.set('CONFIG_INT128', has_int128)
1943 # "do we have 128-bit atomics which are handled inline and specifically not
1944 # via libatomic". The reason we can't use libatomic is documented in the
1945 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
1946 has_atomic128 = cc.links(atomic_test.format('unsigned __int128'))
1948 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
1950 if not has_atomic128
1951 has_cmpxchg128 = cc.links('''
1954 unsigned __int128 x = 0, y = 0;
1955 __sync_val_compare_and_swap_16(&x, y, x);
1960 config_host_data.set('CONFIG_CMPXCHG128', has_cmpxchg128)
1964 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
1965 #include <sys/auxv.h>
1967 return getauxval(AT_HWCAP) == 0;
1970 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
1971 #include <linux/usbdevice_fs.h>
1973 #ifndef USBDEVFS_GET_CAPABILITIES
1974 #error "USBDEVFS_GET_CAPABILITIES undefined"
1977 #ifndef USBDEVFS_DISCONNECT_CLAIM
1978 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
1981 int main(void) { return 0; }'''))
1983 have_keyring = get_option('keyring') \
1984 .require(targetos == 'linux', error_message: 'keyring is only available on Linux') \
1985 .require(cc.compiles('''
1987 #include <asm/unistd.h>
1988 #include <linux/keyctl.h>
1989 #include <sys/syscall.h>
1992 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
1993 }'''), error_message: 'keyctl syscall not available on this system').allowed()
1994 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
1996 have_cpuid_h = cc.links('''
1999 unsigned a, b, c, d;
2000 unsigned max = __get_cpuid_max(0, 0);
2003 __cpuid(1, a, b, c, d);
2007 __cpuid_count(7, 0, a, b, c, d);
2012 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2014 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2015 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2016 .require(cc.links('''
2017 #pragma GCC push_options
2018 #pragma GCC target("avx2")
2020 #include <immintrin.h>
2021 static int bar(void *a) {
2022 __m256i x = *(__m256i *)a;
2023 return _mm256_testz_si256(x, x);
2025 int main(int argc, char *argv[]) { return bar(argv[0]); }
2026 '''), error_message: 'AVX2 not available').allowed())
2028 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2029 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2030 .require(cc.links('''
2031 #pragma GCC push_options
2032 #pragma GCC target("avx512f")
2034 #include <immintrin.h>
2035 static int bar(void *a) {
2036 __m512i x = *(__m512i *)a;
2037 return _mm512_test_epi64_mask(x, x);
2039 int main(int argc, char *argv[]) { return bar(argv[0]); }
2040 '''), error_message: 'AVX512F not available').allowed())
2042 have_pvrdma = get_option('pvrdma') \
2043 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
2044 .require(cc.compiles('''
2049 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2052 }'''), error_message: 'PVRDMA requires mremap').allowed()
2055 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.compiles('''
2056 #include <infiniband/verbs.h>
2060 struct ibv_pd *pd = NULL;
2066 mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2072 if get_option('membarrier').disabled()
2073 have_membarrier = false
2074 elif targetos == 'windows'
2075 have_membarrier = true
2076 elif targetos == 'linux'
2077 have_membarrier = cc.compiles('''
2078 #include <linux/membarrier.h>
2079 #include <sys/syscall.h>
2083 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2084 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2088 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2089 .require(have_membarrier, error_message: 'membarrier system call not available') \
2092 have_afalg = get_option('crypto_afalg') \
2093 .require(cc.compiles(gnu_source_prefix + '''
2095 #include <sys/types.h>
2096 #include <sys/socket.h>
2097 #include <linux/if_alg.h>
2100 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2103 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2104 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2106 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2107 'linux/vm_sockets.h', 'AF_VSOCK',
2108 prefix: '#include <sys/socket.h>',
2112 have_vss_sdk = false # old xp/2003 SDK
2113 if targetos == 'windows' and link_language == 'cpp'
2114 have_vss = cxx.compiles('''
2115 #define __MIDL_user_allocate_free_DEFINED__
2117 int main(void) { return VSS_CTX_BACKUP; }''')
2118 have_vss_sdk = cxx.has_header('vscoordint.h')
2120 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2122 ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target
2124 arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
2125 foreach k, v: config_host
2126 if ignored.contains(k)
2128 elif arrays.contains(k)
2130 v = '"' + '", "'.join(v.split()) + '", '
2132 config_host_data.set(k, v)
2133 elif k.startswith('CONFIG_')
2134 config_host_data.set(k, v == 'y' ? 1 : v)
2138 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2139 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2140 if targetos == 'windows'
2141 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2147 }''', name: '_lock_file and _unlock_file'))
2150 ########################
2151 # Target configuration #
2152 ########################
2154 minikconf = find_program('scripts/minikconf.py')
2156 config_all_devices = {}
2157 config_all_disas = {}
2158 config_devices_mak_list = []
2159 config_devices_h = {}
2160 config_target_h = {}
2161 config_target_mak = {}
2164 'alpha' : ['CONFIG_ALPHA_DIS'],
2165 'arm' : ['CONFIG_ARM_DIS'],
2166 'avr' : ['CONFIG_AVR_DIS'],
2167 'cris' : ['CONFIG_CRIS_DIS'],
2168 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2169 'hppa' : ['CONFIG_HPPA_DIS'],
2170 'i386' : ['CONFIG_I386_DIS'],
2171 'x86_64' : ['CONFIG_I386_DIS'],
2172 'm68k' : ['CONFIG_M68K_DIS'],
2173 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2174 'mips' : ['CONFIG_MIPS_DIS'],
2175 'nios2' : ['CONFIG_NIOS2_DIS'],
2176 'or1k' : ['CONFIG_OPENRISC_DIS'],
2177 'ppc' : ['CONFIG_PPC_DIS'],
2178 'riscv' : ['CONFIG_RISCV_DIS'],
2179 'rx' : ['CONFIG_RX_DIS'],
2180 's390' : ['CONFIG_S390_DIS'],
2181 'sh4' : ['CONFIG_SH4_DIS'],
2182 'sparc' : ['CONFIG_SPARC_DIS'],
2183 'xtensa' : ['CONFIG_XTENSA_DIS'],
2185 if link_language == 'cpp'
2187 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
2188 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
2189 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
2193 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2195 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2196 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2197 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2198 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2199 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2200 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2201 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
2202 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2203 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2204 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2205 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
2206 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
2207 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
2209 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2211 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2212 actual_target_dirs = []
2214 foreach target : target_dirs
2215 config_target = { 'TARGET_NAME': target.split('-')[0] }
2216 if target.endswith('linux-user')
2217 if targetos != 'linux'
2221 error('Target @0@ is only available on a Linux host'.format(target))
2223 config_target += { 'CONFIG_LINUX_USER': 'y' }
2224 elif target.endswith('bsd-user')
2225 if 'CONFIG_BSD' not in config_host
2229 error('Target @0@ is only available on a BSD host'.format(target))
2231 config_target += { 'CONFIG_BSD_USER': 'y' }
2232 elif target.endswith('softmmu')
2233 config_target += { 'CONFIG_SOFTMMU': 'y' }
2235 if target.endswith('-user')
2237 'CONFIG_USER_ONLY': 'y',
2238 'CONFIG_QEMU_INTERP_PREFIX':
2239 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
2244 foreach sym: accelerators
2245 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2246 config_target += { sym: 'y' }
2247 config_all += { sym: 'y' }
2248 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
2249 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
2251 if target in modular_tcg
2252 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2254 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2256 accel_kconfig += [ sym + '=y' ]
2259 if accel_kconfig.length() == 0
2263 error('No accelerator available for target @0@'.format(target))
2266 actual_target_dirs += target
2267 config_target += keyval.load('configs/targets' / target + '.mak')
2268 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
2270 if 'TARGET_NEED_FDT' in config_target
2271 fdt_required += target
2275 if 'TARGET_BASE_ARCH' not in config_target
2276 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2278 if 'TARGET_ABI_DIR' not in config_target
2279 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2281 if 'TARGET_BIG_ENDIAN' not in config_target
2282 config_target += {'TARGET_BIG_ENDIAN': 'n'}
2285 foreach k, v: disassemblers
2286 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
2288 config_target += { sym: 'y' }
2289 config_all_disas += { sym: 'y' }
2294 config_target_data = configuration_data()
2295 foreach k, v: config_target
2296 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2298 elif ignored.contains(k)
2300 elif k == 'TARGET_BASE_ARCH'
2301 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2302 # not used to select files from sourcesets.
2303 config_target_data.set('TARGET_' + v.to_upper(), 1)
2304 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
2305 config_target_data.set_quoted(k, v)
2307 config_target_data.set(k, 1)
2309 config_target_data.set(k, 0)
2311 config_target_data.set(k, v)
2314 config_target_data.set('QEMU_ARCH',
2315 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
2316 config_target_h += {target: configure_file(output: target + '-config-target.h',
2317 configuration: config_target_data)}
2319 if target.endswith('-softmmu')
2320 config_input = meson.get_external_property(target, 'default')
2321 config_devices_mak = target + '-config-devices.mak'
2322 config_devices_mak = configure_file(
2323 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2324 output: config_devices_mak,
2325 depfile: config_devices_mak + '.d',
2327 command: [minikconf,
2328 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2329 config_devices_mak, '@DEPFILE@', '@INPUT@',
2330 host_kconfig, accel_kconfig,
2331 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
2333 config_devices_data = configuration_data()
2334 config_devices = keyval.load(config_devices_mak)
2335 foreach k, v: config_devices
2336 config_devices_data.set(k, 1)
2338 config_devices_mak_list += config_devices_mak
2339 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2340 configuration: config_devices_data)}
2341 config_target += config_devices
2342 config_all_devices += config_devices
2344 config_target_mak += {target: config_target}
2346 target_dirs = actual_target_dirs
2348 # This configuration is used to build files that are shared by
2349 # multiple binaries, and then extracted out of the "common"
2350 # static_library target.
2352 # We do not use all_sources()/all_dependencies(), because it would
2353 # build literally all source files, including devices only used by
2354 # targets that are not built for this compilation. The CONFIG_ALL
2355 # pseudo symbol replaces it.
2357 config_all += config_all_devices
2358 config_all += config_host
2359 config_all += config_all_disas
2361 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
2362 'CONFIG_SOFTMMU': have_system,
2363 'CONFIG_USER_ONLY': have_user,
2367 target_configs_h = []
2368 foreach target: target_dirs
2369 target_configs_h += config_target_h[target]
2370 target_configs_h += config_devices_h.get(target, [])
2372 genh += custom_target('config-poison.h',
2373 input: [target_configs_h],
2374 output: 'config-poison.h',
2376 command: [find_program('scripts/make-config-poison.sh'),
2383 capstone = not_found
2384 capstone_opt = get_option('capstone')
2385 if capstone_opt in ['enabled', 'auto', 'system']
2386 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
2387 capstone = dependency('capstone', version: '>=4.0',
2388 kwargs: static_kwargs, method: 'pkg-config',
2389 required: capstone_opt == 'system' or
2390 capstone_opt == 'enabled' and not have_internal)
2392 # Some versions of capstone have broken pkg-config file
2393 # that reports a wrong -I path, causing the #include to
2394 # fail later. If the system has such a broken version
2396 if capstone.found() and not cc.compiles('#include <capstone.h>',
2397 dependencies: [capstone])
2398 capstone = not_found
2399 if capstone_opt == 'system'
2400 error('system capstone requested, it does not appear to work')
2405 capstone_opt = 'system'
2407 capstone_opt = 'internal'
2409 capstone_opt = 'disabled'
2412 if capstone_opt == 'internal'
2413 capstone_data = configuration_data()
2414 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
2416 capstone_files = files(
2418 'capstone/MCInst.c',
2419 'capstone/MCInstrDesc.c',
2420 'capstone/MCRegisterInfo.c',
2421 'capstone/SStream.c',
2425 if 'CONFIG_ARM_DIS' in config_all_disas
2426 capstone_data.set('CAPSTONE_HAS_ARM', '1')
2427 capstone_files += files(
2428 'capstone/arch/ARM/ARMDisassembler.c',
2429 'capstone/arch/ARM/ARMInstPrinter.c',
2430 'capstone/arch/ARM/ARMMapping.c',
2431 'capstone/arch/ARM/ARMModule.c'
2435 # FIXME: This config entry currently depends on a c++ compiler.
2436 # Which is needed for building libvixl, but not for capstone.
2437 if 'CONFIG_ARM_A64_DIS' in config_all_disas
2438 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
2439 capstone_files += files(
2440 'capstone/arch/AArch64/AArch64BaseInfo.c',
2441 'capstone/arch/AArch64/AArch64Disassembler.c',
2442 'capstone/arch/AArch64/AArch64InstPrinter.c',
2443 'capstone/arch/AArch64/AArch64Mapping.c',
2444 'capstone/arch/AArch64/AArch64Module.c'
2448 if 'CONFIG_PPC_DIS' in config_all_disas
2449 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
2450 capstone_files += files(
2451 'capstone/arch/PowerPC/PPCDisassembler.c',
2452 'capstone/arch/PowerPC/PPCInstPrinter.c',
2453 'capstone/arch/PowerPC/PPCMapping.c',
2454 'capstone/arch/PowerPC/PPCModule.c'
2458 if 'CONFIG_S390_DIS' in config_all_disas
2459 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
2460 capstone_files += files(
2461 'capstone/arch/SystemZ/SystemZDisassembler.c',
2462 'capstone/arch/SystemZ/SystemZInstPrinter.c',
2463 'capstone/arch/SystemZ/SystemZMapping.c',
2464 'capstone/arch/SystemZ/SystemZModule.c',
2465 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
2469 if 'CONFIG_I386_DIS' in config_all_disas
2470 capstone_data.set('CAPSTONE_HAS_X86', 1)
2471 capstone_files += files(
2472 'capstone/arch/X86/X86Disassembler.c',
2473 'capstone/arch/X86/X86DisassemblerDecoder.c',
2474 'capstone/arch/X86/X86ATTInstPrinter.c',
2475 'capstone/arch/X86/X86IntelInstPrinter.c',
2476 'capstone/arch/X86/X86InstPrinterCommon.c',
2477 'capstone/arch/X86/X86Mapping.c',
2478 'capstone/arch/X86/X86Module.c'
2482 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
2485 # FIXME: There does not seem to be a way to completely replace the c_args
2486 # that come from add_project_arguments() -- we can only add to them.
2487 # So: disable all warnings with a big hammer.
2490 # Include all configuration defines via a header file, which will wind up
2491 # as a dependency on the object file, and thus changes here will result
2493 '-include', 'capstone-defs.h'
2496 libcapstone = static_library('capstone',
2497 build_by_default: false,
2498 sources: capstone_files,
2499 c_args: capstone_cargs,
2500 include_directories: 'capstone/include')
2501 capstone = declare_dependency(link_with: libcapstone,
2502 include_directories: 'capstone/include/capstone')
2506 slirp_opt = 'disabled'
2508 slirp_opt = get_option('slirp')
2509 if slirp_opt in ['enabled', 'auto', 'system']
2510 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2511 slirp = dependency('slirp', kwargs: static_kwargs,
2512 method: 'pkg-config',
2513 required: slirp_opt == 'system' or
2514 slirp_opt == 'enabled' and not have_internal)
2516 slirp_opt = 'system'
2518 slirp_opt = 'internal'
2520 slirp_opt = 'disabled'
2523 if slirp_opt == 'internal'
2525 if targetos == 'windows'
2526 slirp_deps = cc.find_library('iphlpapi')
2527 elif targetos == 'darwin'
2528 slirp_deps = cc.find_library('resolv')
2530 slirp_conf = configuration_data()
2531 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2532 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2533 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2534 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2535 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2537 'slirp/src/arp_table.c',
2538 'slirp/src/bootp.c',
2539 'slirp/src/cksum.c',
2540 'slirp/src/dhcpv6.c',
2541 'slirp/src/dnssearch.c',
2543 'slirp/src/ip6_icmp.c',
2544 'slirp/src/ip6_input.c',
2545 'slirp/src/ip6_output.c',
2546 'slirp/src/ip_icmp.c',
2547 'slirp/src/ip_input.c',
2548 'slirp/src/ip_output.c',
2552 'slirp/src/ndp_table.c',
2554 'slirp/src/slirp.c',
2555 'slirp/src/socket.c',
2556 'slirp/src/state.c',
2557 'slirp/src/stream.c',
2558 'slirp/src/tcp_input.c',
2559 'slirp/src/tcp_output.c',
2560 'slirp/src/tcp_subr.c',
2561 'slirp/src/tcp_timer.c',
2566 'slirp/src/version.c',
2567 'slirp/src/vmstate.c',
2571 input : 'slirp/src/libslirp-version.h.in',
2572 output : 'libslirp-version.h',
2573 configuration: slirp_conf)
2575 slirp_inc = include_directories('slirp', 'slirp/src')
2576 libslirp = static_library('slirp',
2577 build_by_default: false,
2578 sources: slirp_files,
2579 c_args: slirp_cargs,
2580 include_directories: slirp_inc)
2581 slirp = declare_dependency(link_with: libslirp,
2582 dependencies: slirp_deps,
2583 include_directories: slirp_inc)
2587 # For CFI, we need to compile slirp as a static library together with qemu.
2588 # This is because we register slirp functions as callbacks for QEMU Timers.
2589 # When using a system-wide shared libslirp, the type information for the
2590 # callback is missing and the timer call produces a false positive with CFI.
2592 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2593 # with control-flow integrity.
2594 if get_option('cfi') and slirp_opt == 'system'
2595 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2596 + ' Please configure with --enable-slirp=git')
2601 fdt_opt = get_option('fdt')
2602 if fdt_opt in ['enabled', 'auto', 'system']
2603 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2604 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2605 required: fdt_opt == 'system' or
2606 fdt_opt == 'enabled' and not have_internal)
2607 if fdt.found() and cc.links('''
2609 #include <libfdt_env.h>
2610 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2613 elif fdt_opt == 'system'
2614 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2616 fdt_opt = 'internal'
2618 fdt_opt = 'disabled'
2622 if fdt_opt == 'internal'
2625 'dtc/libfdt/fdt_ro.c',
2626 'dtc/libfdt/fdt_wip.c',
2627 'dtc/libfdt/fdt_sw.c',
2628 'dtc/libfdt/fdt_rw.c',
2629 'dtc/libfdt/fdt_strerror.c',
2630 'dtc/libfdt/fdt_empty_tree.c',
2631 'dtc/libfdt/fdt_addresses.c',
2632 'dtc/libfdt/fdt_overlay.c',
2633 'dtc/libfdt/fdt_check.c',
2636 fdt_inc = include_directories('dtc/libfdt')
2637 libfdt = static_library('fdt',
2638 build_by_default: false,
2640 include_directories: fdt_inc)
2641 fdt = declare_dependency(link_with: libfdt,
2642 include_directories: fdt_inc)
2645 fdt_opt = 'disabled'
2647 if not fdt.found() and fdt_required.length() > 0
2648 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2651 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2652 config_host_data.set('CONFIG_FDT', fdt.found())
2653 config_host_data.set('CONFIG_SLIRP', slirp.found())
2655 #####################
2656 # Generated sources #
2657 #####################
2659 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2661 hxtool = find_program('scripts/hxtool')
2662 shaderinclude = find_program('scripts/shaderinclude.pl')
2663 qapi_gen = find_program('scripts/qapi-gen.py')
2664 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2665 meson.current_source_dir() / 'scripts/qapi/commands.py',
2666 meson.current_source_dir() / 'scripts/qapi/common.py',
2667 meson.current_source_dir() / 'scripts/qapi/error.py',
2668 meson.current_source_dir() / 'scripts/qapi/events.py',
2669 meson.current_source_dir() / 'scripts/qapi/expr.py',
2670 meson.current_source_dir() / 'scripts/qapi/gen.py',
2671 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2672 meson.current_source_dir() / 'scripts/qapi/parser.py',
2673 meson.current_source_dir() / 'scripts/qapi/schema.py',
2674 meson.current_source_dir() / 'scripts/qapi/source.py',
2675 meson.current_source_dir() / 'scripts/qapi/types.py',
2676 meson.current_source_dir() / 'scripts/qapi/visit.py',
2677 meson.current_source_dir() / 'scripts/qapi/common.py',
2678 meson.current_source_dir() / 'scripts/qapi-gen.py'
2682 python, files('scripts/tracetool.py'),
2683 '--backend=' + ','.join(get_option('trace_backends'))
2685 tracetool_depends = files(
2686 'scripts/tracetool/backend/log.py',
2687 'scripts/tracetool/backend/__init__.py',
2688 'scripts/tracetool/backend/dtrace.py',
2689 'scripts/tracetool/backend/ftrace.py',
2690 'scripts/tracetool/backend/simple.py',
2691 'scripts/tracetool/backend/syslog.py',
2692 'scripts/tracetool/backend/ust.py',
2693 'scripts/tracetool/format/ust_events_c.py',
2694 'scripts/tracetool/format/ust_events_h.py',
2695 'scripts/tracetool/format/__init__.py',
2696 'scripts/tracetool/format/d.py',
2697 'scripts/tracetool/format/simpletrace_stap.py',
2698 'scripts/tracetool/format/c.py',
2699 'scripts/tracetool/format/h.py',
2700 'scripts/tracetool/format/log_stap.py',
2701 'scripts/tracetool/format/stap.py',
2702 'scripts/tracetool/__init__.py',
2703 'scripts/tracetool/transform.py',
2704 'scripts/tracetool/vcpu.py'
2707 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2708 meson.current_source_dir(),
2709 config_host['PKGVERSION'], meson.project_version()]
2710 qemu_version = custom_target('qemu-version.h',
2711 output: 'qemu-version.h',
2712 command: qemu_version_cmd,
2714 build_by_default: true,
2715 build_always_stale: true)
2716 genh += qemu_version
2720 ['qemu-options.hx', 'qemu-options.def'],
2721 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2725 ['hmp-commands.hx', 'hmp-commands.h'],
2726 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2729 foreach d : hx_headers
2730 hxdep += custom_target(d[1],
2734 build_by_default: true, # to be removed when added to a target
2735 command: [hxtool, '-h', '@INPUT0@'])
2743 authz_ss = ss.source_set()
2744 blockdev_ss = ss.source_set()
2745 block_ss = ss.source_set()
2746 chardev_ss = ss.source_set()
2747 common_ss = ss.source_set()
2748 crypto_ss = ss.source_set()
2749 hwcore_ss = ss.source_set()
2750 io_ss = ss.source_set()
2751 qmp_ss = ss.source_set()
2752 qom_ss = ss.source_set()
2753 softmmu_ss = ss.source_set()
2754 specific_fuzz_ss = ss.source_set()
2755 specific_ss = ss.source_set()
2756 stub_ss = ss.source_set()
2757 trace_ss = ss.source_set()
2758 user_ss = ss.source_set()
2759 util_ss = ss.source_set()
2762 qtest_module_ss = ss.source_set()
2763 tcg_module_ss = ss.source_set()
2769 target_softmmu_arch = {}
2770 target_user_arch = {}
2776 # TODO: add each directory to the subdirs from its own meson.build, once
2778 trace_events_subdirs = [
2786 trace_events_subdirs += [ 'linux-user' ]
2789 trace_events_subdirs += [ 'bsd-user' ]
2792 trace_events_subdirs += [
2801 trace_events_subdirs += [
2815 'hw/block/dataplane',
2865 if have_system or have_user
2866 trace_events_subdirs += [
2884 vhost_user = not_found
2885 if targetos == 'linux' and 'CONFIG_VHOST_USER' in config_host
2886 libvhost_user = subproject('libvhost-user')
2887 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2890 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
2891 # that is filled in by qapi/.
2904 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2905 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2908 stub_ss = stub_ss.apply(config_all, strict: false)
2910 util_ss.add_all(trace_ss)
2911 util_ss = util_ss.apply(config_all, strict: false)
2912 libqemuutil = static_library('qemuutil',
2913 sources: util_ss.sources() + stub_ss.sources() + genh,
2914 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2915 qemuutil = declare_dependency(link_with: libqemuutil,
2916 sources: genh + version_res)
2918 if have_system or have_user
2919 decodetree = generator(find_program('scripts/decodetree.py'),
2920 output: 'decode-@BASENAME@.c.inc',
2921 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2922 subdir('libdecnumber')
2939 if config_host_data.get('CONFIG_REPLICATION')
2940 block_ss.add(files('replication.c'))
2947 blockdev_ss.add(files(
2954 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2955 # os-win32.c does not
2956 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2957 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2960 common_ss.add(files('cpus-common.c'))
2964 common_ss.add(capstone)
2965 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2967 # Work around a gcc bug/misfeature wherein constant propagation looks
2969 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2970 # to guess that a const variable is always zero. Without lto, this is
2971 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2972 # without lto, not even the alias is required -- we simply use different
2973 # declarations in different compilation units.
2974 pagevary = files('page-vary-common.c')
2975 if get_option('b_lto')
2976 pagevary_flags = ['-fno-lto']
2977 if get_option('cfi')
2978 pagevary_flags += '-fno-sanitize=cfi-icall'
2980 pagevary = static_library('page-vary-common', sources: pagevary + genh,
2981 c_args: pagevary_flags)
2982 pagevary = declare_dependency(link_with: pagevary)
2984 common_ss.add(pagevary)
2985 specific_ss.add(files('page-vary.c'))
2993 subdir('semihosting')
3001 common_user_inc = []
3003 subdir('common-user')
3005 subdir('linux-user')
3007 # needed for fuzzing binaries
3008 subdir('tests/qtest/libqos')
3009 subdir('tests/qtest/fuzz')
3012 tcg_real_module_ss = ss.source_set()
3013 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3014 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3015 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3016 'tcg': tcg_real_module_ss }}
3018 ########################
3019 # Library dependencies #
3020 ########################
3022 modinfo_collect = find_program('scripts/modinfo-collect.py')
3023 modinfo_generate = find_program('scripts/modinfo-generate.py')
3028 foreach d, list : modules
3029 foreach m, module_ss : list
3030 if enable_modules and targetos != 'windows'
3031 module_ss = module_ss.apply(config_all, strict: false)
3032 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3033 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3039 if module_ss.sources() != []
3040 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3041 # input. Sources can be used multiple times but objects are
3042 # unique when it comes to lookup in compile_commands.json.
3043 # Depnds on a mesion version with
3044 # https://github.com/mesonbuild/meson/pull/8900
3045 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3046 output: d + '-' + m + '.modinfo',
3047 input: module_ss.sources() + genh,
3049 command: [modinfo_collect, module_ss.sources()])
3053 block_ss.add_all(module_ss)
3055 softmmu_ss.add_all(module_ss)
3061 foreach d, list : target_modules
3062 foreach m, module_ss : list
3063 if enable_modules and targetos != 'windows'
3064 foreach target : target_dirs
3065 if target.endswith('-softmmu')
3066 config_target = config_target_mak[target]
3067 config_target += config_host
3068 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3069 c_args = ['-DNEED_CPU_H',
3070 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3071 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3072 target_module_ss = module_ss.apply(config_target, strict: false)
3073 if target_module_ss.sources() != []
3074 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3075 sl = static_library(module_name,
3076 [genh, target_module_ss.sources()],
3077 dependencies: [modulecommon, target_module_ss.dependencies()],
3078 include_directories: target_inc,
3082 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3083 modinfo_files += custom_target(module_name + '.modinfo',
3084 output: module_name + '.modinfo',
3085 input: target_module_ss.sources() + genh,
3087 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3092 specific_ss.add_all(module_ss)
3098 modinfo_src = custom_target('modinfo.c',
3099 output: 'modinfo.c',
3100 input: modinfo_files,
3101 command: [modinfo_generate, '@INPUT@'],
3103 modinfo_lib = static_library('modinfo', modinfo_src)
3104 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
3105 softmmu_ss.add(modinfo_dep)
3108 nm = find_program('nm')
3109 undefsym = find_program('scripts/undefsym.py')
3110 block_syms = custom_target('block.syms', output: 'block.syms',
3111 input: [libqemuutil, block_mods],
3113 command: [undefsym, nm, '@INPUT@'])
3114 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3115 input: [libqemuutil, softmmu_mods],
3117 command: [undefsym, nm, '@INPUT@'])
3119 qom_ss = qom_ss.apply(config_host, strict: false)
3120 libqom = static_library('qom', qom_ss.sources() + genh,
3121 dependencies: [qom_ss.dependencies()],
3124 qom = declare_dependency(link_whole: libqom)
3126 authz_ss = authz_ss.apply(config_host, strict: false)
3127 libauthz = static_library('authz', authz_ss.sources() + genh,
3128 dependencies: [authz_ss.dependencies()],
3130 build_by_default: false)
3132 authz = declare_dependency(link_whole: libauthz,
3135 crypto_ss = crypto_ss.apply(config_host, strict: false)
3136 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3137 dependencies: [crypto_ss.dependencies()],
3139 build_by_default: false)
3141 crypto = declare_dependency(link_whole: libcrypto,
3142 dependencies: [authz, qom])
3144 io_ss = io_ss.apply(config_host, strict: false)
3145 libio = static_library('io', io_ss.sources() + genh,
3146 dependencies: [io_ss.dependencies()],
3147 link_with: libqemuutil,
3149 build_by_default: false)
3151 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3153 libmigration = static_library('migration', sources: migration_files + genh,
3155 build_by_default: false)
3156 migration = declare_dependency(link_with: libmigration,
3157 dependencies: [zlib, qom, io])
3158 softmmu_ss.add(migration)
3160 block_ss = block_ss.apply(config_host, strict: false)
3161 libblock = static_library('block', block_ss.sources() + genh,
3162 dependencies: block_ss.dependencies(),
3163 link_depends: block_syms,
3165 build_by_default: false)
3167 block = declare_dependency(link_whole: [libblock],
3168 link_args: '@block.syms',
3169 dependencies: [crypto, io])
3171 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
3172 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3173 dependencies: blockdev_ss.dependencies(),
3175 build_by_default: false)
3177 blockdev = declare_dependency(link_whole: [libblockdev],
3178 dependencies: [block])
3180 qmp_ss = qmp_ss.apply(config_host, strict: false)
3181 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3182 dependencies: qmp_ss.dependencies(),
3184 build_by_default: false)
3186 qmp = declare_dependency(link_whole: [libqmp])
3188 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3190 dependencies: chardev_ss.dependencies(),
3191 build_by_default: false)
3193 chardev = declare_dependency(link_whole: libchardev)
3195 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
3196 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3198 build_by_default: false)
3199 hwcore = declare_dependency(link_whole: libhwcore)
3200 common_ss.add(hwcore)
3206 emulator_modules = []
3207 foreach m : block_mods + softmmu_mods
3208 emulator_modules += shared_module(m.name(),
3209 build_by_default: true,
3213 install_dir: qemu_moddir)
3216 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3217 common_ss.add(qom, qemuutil)
3219 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
3220 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3222 common_all = common_ss.apply(config_all, strict: false)
3223 common_all = static_library('common',
3224 build_by_default: false,
3225 sources: common_all.sources() + genh,
3226 include_directories: common_user_inc,
3227 implicit_include_directories: false,
3228 dependencies: common_all.dependencies(),
3231 feature_to_c = find_program('scripts/feature_to_c.sh')
3233 if targetos == 'darwin'
3234 entitlement = find_program('scripts/entitlement.sh')
3238 foreach target : target_dirs
3239 config_target = config_target_mak[target]
3240 target_name = config_target['TARGET_NAME']
3241 target_base_arch = config_target['TARGET_BASE_ARCH']
3242 arch_srcs = [config_target_h[target]]
3244 c_args = ['-DNEED_CPU_H',
3245 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3246 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3247 link_args = emulator_link_args
3249 config_target += config_host
3250 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3251 if targetos == 'linux'
3252 target_inc += include_directories('linux-headers', is_system: true)
3254 if target.endswith('-softmmu')
3255 qemu_target_name = 'qemu-system-' + target_name
3256 target_type='system'
3257 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3258 arch_srcs += t.sources()
3259 arch_deps += t.dependencies()
3261 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3262 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3263 arch_srcs += hw.sources()
3264 arch_deps += hw.dependencies()
3266 arch_srcs += config_devices_h[target]
3267 link_args += ['@block.syms', '@qemu.syms']
3269 abi = config_target['TARGET_ABI_DIR']
3271 target_inc += common_user_inc
3272 qemu_target_name = 'qemu-' + target_name
3273 if target_base_arch in target_user_arch
3274 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3275 arch_srcs += t.sources()
3276 arch_deps += t.dependencies()
3278 if 'CONFIG_LINUX_USER' in config_target
3279 base_dir = 'linux-user'
3281 if 'CONFIG_BSD_USER' in config_target
3282 base_dir = 'bsd-user'
3283 target_inc += include_directories('bsd-user/' / targetos)
3284 target_inc += include_directories('bsd-user/host/' / host_arch)
3285 dir = base_dir / abi
3286 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3288 target_inc += include_directories(
3292 if 'CONFIG_LINUX_USER' in config_target
3293 dir = base_dir / abi
3294 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3295 if config_target.has_key('TARGET_SYSTBL_ABI')
3297 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3298 extra_args : config_target['TARGET_SYSTBL_ABI'])
3303 if 'TARGET_XML_FILES' in config_target
3304 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3305 output: target + '-gdbstub-xml.c',
3306 input: files(config_target['TARGET_XML_FILES'].split()),
3307 command: [feature_to_c, '@INPUT@'],
3309 arch_srcs += gdbstub_xml
3312 t = target_arch[target_base_arch].apply(config_target, strict: false)
3313 arch_srcs += t.sources()
3314 arch_deps += t.dependencies()
3316 target_common = common_ss.apply(config_target, strict: false)
3317 objects = common_all.extract_objects(target_common.sources())
3318 deps = target_common.dependencies()
3320 target_specific = specific_ss.apply(config_target, strict: false)
3321 arch_srcs += target_specific.sources()
3322 arch_deps += target_specific.dependencies()
3324 lib = static_library('qemu-' + target,
3325 sources: arch_srcs + genh,
3326 dependencies: arch_deps,
3328 include_directories: target_inc,
3330 build_by_default: false,
3333 if target.endswith('-softmmu')
3335 'name': 'qemu-system-' + target_name,
3336 'win_subsystem': 'console',
3337 'sources': files('softmmu/main.c'),
3340 if targetos == 'windows' and (sdl.found() or gtk.found())
3342 'name': 'qemu-system-' + target_name + 'w',
3343 'win_subsystem': 'windows',
3344 'sources': files('softmmu/main.c'),
3348 if get_option('fuzzing')
3349 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3351 'name': 'qemu-fuzz-' + target_name,
3352 'win_subsystem': 'console',
3353 'sources': specific_fuzz.sources(),
3354 'dependencies': specific_fuzz.dependencies(),
3359 'name': 'qemu-' + target_name,
3360 'win_subsystem': 'console',
3366 exe_name = exe['name']
3367 if targetos == 'darwin'
3368 exe_name += '-unsigned'
3371 emulator = executable(exe_name, exe['sources'],
3374 dependencies: arch_deps + deps + exe['dependencies'],
3375 objects: lib.extract_all_objects(recursive: true),
3376 link_language: link_language,
3377 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3378 link_args: link_args,
3379 win_subsystem: exe['win_subsystem'])
3381 if targetos == 'darwin'
3382 icon = 'pc-bios/qemu.rsrc'
3383 build_input = [emulator, files(icon)]
3385 get_option('bindir') / exe_name,
3386 meson.current_source_dir() / icon
3388 if 'CONFIG_HVF' in config_target
3389 entitlements = 'accel/hvf/entitlements.plist'
3390 build_input += files(entitlements)
3391 install_input += meson.current_source_dir() / entitlements
3394 emulators += {exe['name'] : custom_target(exe['name'],
3396 output: exe['name'],
3397 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3400 meson.add_install_script(entitlement, '--install',
3401 get_option('bindir') / exe['name'],
3404 emulators += {exe['name']: emulator}
3409 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3410 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3411 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3412 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3414 custom_target(exe['name'] + stp['ext'],
3415 input: trace_events_all,
3416 output: exe['name'] + stp['ext'],
3417 install: stp['install'],
3418 install_dir: get_option('datadir') / 'systemtap/tapset',
3420 tracetool, '--group=all', '--format=' + stp['fmt'],
3421 '--binary=' + stp['bin'],
3422 '--target-name=' + target_name,
3423 '--target-type=' + target_type,
3424 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3425 '@INPUT@', '@OUTPUT@'
3427 depend_files: tracetool_depends)
3433 # Other build targets
3435 if 'CONFIG_PLUGIN' in config_host
3436 install_headers('include/qemu/qemu-plugin.h')
3441 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3442 # when we don't build tools or system
3443 if xkbcommon.found()
3444 # used for the update-keymaps target, so include rules even if !have_tools
3445 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3446 dependencies: [qemuutil, xkbcommon], install: have_tools)
3450 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3451 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3452 qemu_io = executable('qemu-io', files('qemu-io.c'),
3453 dependencies: [block, qemuutil], install: true)
3454 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3455 dependencies: [blockdev, qemuutil, gnutls, selinux],
3458 subdir('storage-daemon')
3459 subdir('contrib/rdmacm-mux')
3460 subdir('contrib/elf2dmp')
3462 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3463 dependencies: qemuutil,
3466 if 'CONFIG_VHOST_USER' in config_host
3467 subdir('contrib/vhost-user-blk')
3468 subdir('contrib/vhost-user-gpu')
3469 subdir('contrib/vhost-user-input')
3470 subdir('contrib/vhost-user-scsi')
3473 if targetos == 'linux'
3474 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3475 dependencies: [qemuutil, libcap_ng],
3477 install_dir: get_option('libexecdir'))
3479 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3480 dependencies: [authz, crypto, io, qom, qemuutil,
3481 libcap_ng, mpathpersist],
3486 subdir('contrib/ivshmem-client')
3487 subdir('contrib/ivshmem-server')
3500 if host_machine.system() == 'windows'
3502 find_program('scripts/nsis.py'),
3504 get_option('prefix'),
3505 meson.current_source_dir(),
3508 '-DDISPLAYVERSION=' + meson.project_version(),
3511 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3514 nsis_cmd += '-DCONFIG_GTK=y'
3517 nsis = custom_target('nsis',
3518 output: 'qemu-setup-' + meson.project_version() + '.exe',
3519 input: files('qemu.nsi'),
3520 build_always_stale: true,
3521 command: nsis_cmd + ['@INPUT@'])
3522 alias_target('installer', nsis)
3525 #########################
3526 # Configuration summary #
3527 #########################
3531 summary_info += {'Install prefix': get_option('prefix')}
3532 summary_info += {'BIOS directory': qemu_datadir}
3533 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
3534 summary_info += {'binary directory': get_option('bindir')}
3535 summary_info += {'library directory': get_option('libdir')}
3536 summary_info += {'module directory': qemu_moddir}
3537 summary_info += {'libexec directory': get_option('libexecdir')}
3538 summary_info += {'include directory': get_option('includedir')}
3539 summary_info += {'config directory': get_option('sysconfdir')}
3540 if targetos != 'windows'
3541 summary_info += {'local state directory': get_option('localstatedir')}
3542 summary_info += {'Manual directory': get_option('mandir')}
3544 summary_info += {'local state directory': 'queried at runtime'}
3546 summary_info += {'Doc directory': get_option('docdir')}
3547 summary_info += {'Build directory': meson.current_build_dir()}
3548 summary_info += {'Source path': meson.current_source_dir()}
3549 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3550 summary(summary_info, bool_yn: true, section: 'Directories')
3554 summary_info += {'git': config_host['GIT']}
3555 summary_info += {'make': config_host['MAKE']}
3556 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3557 summary_info += {'sphinx-build': sphinx_build}
3558 if config_host.has_key('HAVE_GDB_BIN')
3559 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3561 if get_option('iasl') != ''
3562 summary_info += {'iasl': get_option('iasl')}
3564 summary_info += {'iasl': false}
3566 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3567 if targetos == 'windows' and have_ga
3568 summary_info += {'wixl': wixl}
3570 if slirp_opt != 'disabled' and have_system
3571 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
3573 summary(summary_info, bool_yn: true, section: 'Host binaries')
3575 # Configurable features
3577 summary_info += {'Documentation': build_docs}
3578 summary_info += {'system-mode emulation': have_system}
3579 summary_info += {'user-mode emulation': have_user}
3580 summary_info += {'block layer': have_block}
3581 summary_info += {'Install blobs': get_option('install_blobs')}
3582 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3583 if config_host.has_key('CONFIG_MODULES')
3584 summary_info += {'alternative module path': get_option('module_upgrades')}
3586 summary_info += {'fuzzing support': get_option('fuzzing')}
3588 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3590 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3591 if 'simple' in get_option('trace_backends')
3592 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3594 summary_info += {'D-Bus display': dbus_display}
3595 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
3596 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
3597 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
3598 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
3599 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
3600 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
3601 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
3602 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3603 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
3604 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
3605 summary_info += {'build guest agent': have_ga}
3606 summary(summary_info, bool_yn: true, section: 'Configurable features')
3608 # Compilation information
3610 summary_info += {'host CPU': cpu}
3611 summary_info += {'host endianness': build_machine.endian()}
3612 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3613 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3614 if link_language == 'cpp'
3615 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3617 summary_info += {'C++ compiler': false}
3619 if targetos == 'darwin'
3620 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3622 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3623 + ['-O' + get_option('optimization')]
3624 + (get_option('debug') ? ['-g'] : []))}
3625 if link_language == 'cpp'
3626 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3627 + ['-O' + get_option('optimization')]
3628 + (get_option('debug') ? ['-g'] : []))}
3630 if targetos == 'darwin'
3631 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args')
3632 + ['-O' + get_option('optimization')]
3633 + (get_option('debug') ? ['-g'] : []))}
3635 link_args = get_option(link_language + '_link_args')
3636 if link_args.length() > 0
3637 summary_info += {'LDFLAGS': ' '.join(link_args)}
3639 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_cflags)}
3640 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_cxxflags)}
3641 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_objcflags)}
3642 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
3643 summary_info += {'profiler': get_option('profiler')}
3644 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3645 summary_info += {'PIE': get_option('b_pie')}
3646 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3647 summary_info += {'malloc trim support': has_malloc_trim}
3648 summary_info += {'membarrier': have_membarrier}
3649 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
3650 summary_info += {'mutex debugging': get_option('debug_mutex')}
3651 summary_info += {'memory allocator': get_option('malloc')}
3652 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
3653 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
3654 summary_info += {'gprof enabled': get_option('gprof')}
3655 summary_info += {'gcov': get_option('b_coverage')}
3656 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3657 summary_info += {'CFI support': get_option('cfi')}
3658 if get_option('cfi')
3659 summary_info += {'CFI debug support': get_option('cfi_debug')}
3661 summary_info += {'strip binaries': get_option('strip')}
3662 summary_info += {'sparse': sparse}
3663 summary_info += {'mingw32 support': targetos == 'windows'}
3665 # snarf the cross-compilation information for tests
3666 foreach target: target_dirs
3667 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3668 if fs.exists(tcg_mak)
3669 config_cross_tcg = keyval.load(tcg_mak)
3670 target = config_cross_tcg['TARGET_NAME']
3672 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3673 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3674 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3675 elif 'CROSS_CC_GUEST' in config_cross_tcg
3676 summary_info += {target + ' tests'
3677 : config_cross_tcg['CROSS_CC_GUEST'] }
3682 summary(summary_info, bool_yn: true, section: 'Compilation')
3684 # Targets and accelerators
3687 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3688 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3689 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3690 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3691 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3692 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
3693 if config_host.has_key('CONFIG_XEN_BACKEND')
3694 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
3697 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3698 if config_all.has_key('CONFIG_TCG')
3699 if get_option('tcg_interpreter')
3700 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
3702 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3704 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3705 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3707 summary_info += {'target list': ' '.join(target_dirs)}
3709 summary_info += {'default devices': get_option('default_devices')}
3710 summary_info += {'out of process emulation': multiprocess_allowed}
3712 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3716 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3717 summary_info += {'coroutine pool': have_coroutine_pool}
3719 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3720 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3721 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
3722 summary_info += {'VirtFS support': have_virtfs}
3723 summary_info += {'build virtiofs daemon': have_virtiofsd}
3724 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
3725 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
3726 summary_info += {'bochs support': get_option('bochs').allowed()}
3727 summary_info += {'cloop support': get_option('cloop').allowed()}
3728 summary_info += {'dmg support': get_option('dmg').allowed()}
3729 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
3730 summary_info += {'vdi support': get_option('vdi').allowed()}
3731 summary_info += {'vvfat support': get_option('vvfat').allowed()}
3732 summary_info += {'qed support': get_option('qed').allowed()}
3733 summary_info += {'parallels support': get_option('parallels').allowed()}
3734 summary_info += {'FUSE exports': fuse}
3736 summary(summary_info, bool_yn: true, section: 'Block layer support')
3740 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
3741 summary_info += {'GNUTLS support': gnutls}
3743 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3745 summary_info += {'libgcrypt': gcrypt}
3746 summary_info += {'nettle': nettle}
3748 summary_info += {' XTS': xts != 'private'}
3750 summary_info += {'AF_ALG support': have_afalg}
3751 summary_info += {'rng-none': get_option('rng_none')}
3752 summary_info += {'Linux keyring': have_keyring}
3753 summary(summary_info, bool_yn: true, section: 'Crypto')
3757 if targetos == 'darwin'
3758 summary_info += {'Cocoa support': cocoa}
3760 summary_info += {'SDL support': sdl}
3761 summary_info += {'SDL image support': sdl_image}
3762 summary_info += {'GTK support': gtk}
3763 summary_info += {'pixman': pixman}
3764 summary_info += {'VTE support': vte}
3765 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3766 summary_info += {'libtasn1': tasn1}
3767 summary_info += {'PAM': pam}
3768 summary_info += {'iconv support': iconv}
3769 summary_info += {'curses support': curses}
3770 summary_info += {'virgl support': virgl}
3771 summary_info += {'curl support': curl}
3772 summary_info += {'Multipath support': mpathpersist}
3773 summary_info += {'PNG support': png}
3774 summary_info += {'VNC support': vnc}
3776 summary_info += {'VNC SASL support': sasl}
3777 summary_info += {'VNC JPEG support': jpeg}
3779 if targetos not in ['darwin', 'haiku', 'windows']
3780 summary_info += {'OSS support': oss}
3781 elif targetos == 'darwin'
3782 summary_info += {'CoreAudio support': coreaudio}
3783 elif targetos == 'windows'
3784 summary_info += {'DirectSound support': dsound}
3786 if targetos == 'linux'
3787 summary_info += {'ALSA support': alsa}
3788 summary_info += {'PulseAudio support': pulse}
3790 summary_info += {'JACK support': jack}
3791 summary_info += {'brlapi support': brlapi}
3792 summary_info += {'vde support': vde}
3793 summary_info += {'netmap support': have_netmap}
3794 summary_info += {'l2tpv3 support': have_l2tpv3}
3795 summary_info += {'Linux AIO support': libaio}
3796 summary_info += {'Linux io_uring support': linux_io_uring}
3797 summary_info += {'ATTR/XATTR support': libattr}
3798 summary_info += {'RDMA support': rdma}
3799 summary_info += {'PVRDMA support': have_pvrdma}
3800 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3801 summary_info += {'libcap-ng support': libcap_ng}
3802 summary_info += {'bpf support': libbpf}
3803 summary_info += {'spice protocol support': spice_protocol}
3804 if spice_protocol.found()
3805 summary_info += {' spice server support': spice}
3807 summary_info += {'rbd support': rbd}
3808 summary_info += {'smartcard support': cacard}
3809 summary_info += {'U2F support': u2f}
3810 summary_info += {'libusb': libusb}
3811 summary_info += {'usb net redir': usbredir}
3812 summary_info += {'OpenGL support (epoxy)': opengl}
3813 summary_info += {'GBM': gbm}
3814 summary_info += {'libiscsi support': libiscsi}
3815 summary_info += {'libnfs support': libnfs}
3816 if targetos == 'windows'
3818 summary_info += {'QGA VSS support': have_qga_vss}
3821 summary_info += {'seccomp support': seccomp}
3822 summary_info += {'GlusterFS support': glusterfs}
3823 summary_info += {'TPM support': have_tpm}
3824 summary_info += {'libssh support': libssh}
3825 summary_info += {'lzo support': lzo}
3826 summary_info += {'snappy support': snappy}
3827 summary_info += {'bzip2 support': libbzip2}
3828 summary_info += {'lzfse support': liblzfse}
3829 summary_info += {'zstd support': zstd}
3830 summary_info += {'NUMA host support': numa}
3831 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3832 summary_info += {'libpmem support': libpmem}
3833 summary_info += {'libdaxctl support': libdaxctl}
3834 summary_info += {'libudev': libudev}
3835 # Dummy dependency, keep .found()
3836 summary_info += {'FUSE lseek': fuse_lseek.found()}
3837 summary_info += {'selinux': selinux}
3838 summary(summary_info, bool_yn: true, section: 'Dependencies')
3840 if not supported_cpus.contains(cpu)
3842 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3844 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3845 message('The QEMU project intends to remove support for this host CPU in')
3846 message('a future release if nobody volunteers to maintain it and to')
3847 message('provide a build host for our continuous integration setup.')
3848 message('configure has succeeded and you can continue to build, but')
3849 message('if you care about QEMU on this platform you should contact')
3850 message('us upstream at qemu-devel@nongnu.org.')
3853 if not supported_oses.contains(targetos)
3855 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3857 message('Host OS ' + targetos + 'support is not currently maintained.')
3858 message('The QEMU project intends to remove support for this host OS in')
3859 message('a future release if nobody volunteers to maintain it and to')
3860 message('provide a build host for our continuous integration setup.')
3861 message('configure has succeeded and you can continue to build, but')
3862 message('if you care about QEMU on this platform you should contact')
3863 message('us upstream at qemu-devel@nongnu.org.')