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_GETIFADDRS', cc.has_function('getifaddrs'))
1691 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1692 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1693 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1695 config_host_data.set('HAVE_IBV_ADVISE_MR',
1696 cc.has_function('ibv_advise_mr',
1698 prefix: '#include <infiniband/verbs.h>'))
1702 config_host_data.set('CONFIG_BYTESWAP_H',
1703 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1704 config_host_data.set('CONFIG_EPOLL_CREATE1',
1705 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1706 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1707 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1708 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1709 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1710 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1711 config_host_data.set('CONFIG_FIEMAP',
1712 cc.has_header('linux/fiemap.h') and
1713 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1714 config_host_data.set('CONFIG_GETRANDOM',
1715 cc.has_function('getrandom') and
1716 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1717 config_host_data.set('CONFIG_INOTIFY',
1718 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1719 config_host_data.set('CONFIG_INOTIFY1',
1720 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1721 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1722 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1723 prefix: '''#include <sys/endian.h>
1724 #include <sys/types.h>'''))
1725 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1726 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1727 config_host_data.set('CONFIG_RTNETLINK',
1728 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1729 config_host_data.set('CONFIG_SYSMACROS',
1730 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1731 config_host_data.set('HAVE_OPTRESET',
1732 cc.has_header_symbol('getopt.h', 'optreset'))
1733 config_host_data.set('HAVE_IPPROTO_MPTCP',
1734 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1737 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1738 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1739 prefix: '#include <signal.h>'))
1740 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1741 cc.has_member('struct stat', 'st_atim',
1742 prefix: '#include <sys/stat.h>'))
1745 config_host_data.set('CONFIG_IOVEC',
1746 cc.has_type('struct iovec',
1747 prefix: '#include <sys/uio.h>'))
1748 config_host_data.set('HAVE_UTMPX',
1749 cc.has_type('struct utmpx',
1750 prefix: '#include <utmpx.h>'))
1752 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1753 #include <sys/eventfd.h>
1754 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1755 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1758 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1759 return fdatasync(0);
1761 #error Not supported
1765 has_madvise = cc.links(gnu_source_prefix + '''
1766 #include <sys/types.h>
1767 #include <sys/mman.h>
1769 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
1770 missing_madvise_proto = false
1772 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
1773 # but forget to prototype it. In this case, has_madvise will be true (the
1774 # test program links despite a compile warning). To detect the
1775 # missing-prototype case, we try again with a definitely-bogus prototype.
1776 # This will only compile if the system headers don't provide the prototype;
1777 # otherwise the conflicting prototypes will cause a compiler error.
1778 missing_madvise_proto = cc.links(gnu_source_prefix + '''
1779 #include <sys/types.h>
1780 #include <sys/mman.h>
1782 extern int madvise(int);
1783 int main(void) { return madvise(0); }''')
1785 config_host_data.set('CONFIG_MADVISE', has_madvise)
1786 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
1788 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1789 #include <sys/mman.h>
1790 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1791 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1793 #if !defined(AT_EMPTY_PATH)
1794 # error missing definition
1796 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1798 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1805 return pipe2(pipefd, O_CLOEXEC);
1807 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1808 #include <sys/mman.h>
1810 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1812 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
1813 #include <pthread.h>
1815 static void *f(void *p) { return NULL; }
1819 pthread_create(&thread, 0, f, 0);
1820 pthread_setname_np(thread, "QEMU");
1822 }''', dependencies: threads))
1823 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
1824 #include <pthread.h>
1826 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
1830 pthread_create(&thread, 0, f, 0);
1832 }''', dependencies: threads))
1833 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
1834 #include <pthread.h>
1839 pthread_condattr_t attr
1840 pthread_condattr_init(&attr);
1841 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
1843 }''', dependencies: threads))
1845 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1846 #include <sys/signalfd.h>
1848 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1849 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1857 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1858 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1862 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
1863 #include <sys/mman.h>
1864 int main(int argc, char *argv[]) {
1865 return mlockall(MCL_FUTURE);
1869 if get_option('l2tpv3').allowed() and have_system
1870 have_l2tpv3 = cc.has_type('struct mmsghdr',
1871 prefix: gnu_source_prefix + '''
1872 #include <sys/socket.h>
1873 #include <linux/ip.h>''')
1875 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
1878 if get_option('netmap').allowed() and have_system
1879 have_netmap = cc.compiles('''
1880 #include <inttypes.h>
1882 #include <net/netmap.h>
1883 #include <net/netmap_user.h>
1884 #if (NETMAP_API < 11) || (NETMAP_API > 15)
1887 int main(void) { return 0; }''')
1888 if not have_netmap and get_option('netmap').enabled()
1889 error('Netmap headers not available')
1892 config_host_data.set('CONFIG_NETMAP', have_netmap)
1894 # Work around a system header bug with some kernel/XFS header
1895 # versions where they both try to define 'struct fsxattr':
1896 # xfs headers will not try to redefine structs from linux headers
1897 # if this macro is set.
1898 config_host_data.set('HAVE_FSXATTR', cc.links('''
1899 #include <linux/fs.h>
1905 # Some versions of Mac OS X incorrectly define SIZE_MAX
1906 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1909 int main(int argc, char *argv[]) {
1910 return printf("%zu", SIZE_MAX);
1911 }''', args: ['-Werror']))
1918 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
1919 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
1920 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
1921 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
1922 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
1926 # See if 64-bit atomic operations are supported.
1927 # Note that without __atomic builtins, we can only
1928 # assume atomic loads/stores max at pointer size.
1929 config_host_data.set('CONFIG_ATOMIC64', cc.links(atomic_test.format('uint64_t')))
1931 has_int128 = cc.links('''
1941 config_host_data.set('CONFIG_INT128', has_int128)
1944 # "do we have 128-bit atomics which are handled inline and specifically not
1945 # via libatomic". The reason we can't use libatomic is documented in the
1946 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
1947 has_atomic128 = cc.links(atomic_test.format('unsigned __int128'))
1949 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
1951 if not has_atomic128
1952 has_cmpxchg128 = cc.links('''
1955 unsigned __int128 x = 0, y = 0;
1956 __sync_val_compare_and_swap_16(&x, y, x);
1961 config_host_data.set('CONFIG_CMPXCHG128', has_cmpxchg128)
1965 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
1966 #include <sys/auxv.h>
1968 return getauxval(AT_HWCAP) == 0;
1971 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
1972 #include <linux/usbdevice_fs.h>
1974 #ifndef USBDEVFS_GET_CAPABILITIES
1975 #error "USBDEVFS_GET_CAPABILITIES undefined"
1978 #ifndef USBDEVFS_DISCONNECT_CLAIM
1979 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
1982 int main(void) { return 0; }'''))
1984 have_keyring = get_option('keyring') \
1985 .require(targetos == 'linux', error_message: 'keyring is only available on Linux') \
1986 .require(cc.compiles('''
1988 #include <asm/unistd.h>
1989 #include <linux/keyctl.h>
1990 #include <sys/syscall.h>
1993 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
1994 }'''), error_message: 'keyctl syscall not available on this system').allowed()
1995 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
1997 have_cpuid_h = cc.links('''
2000 unsigned a, b, c, d;
2001 unsigned max = __get_cpuid_max(0, 0);
2004 __cpuid(1, a, b, c, d);
2008 __cpuid_count(7, 0, a, b, c, d);
2013 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2015 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2016 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2017 .require(cc.links('''
2018 #pragma GCC push_options
2019 #pragma GCC target("avx2")
2021 #include <immintrin.h>
2022 static int bar(void *a) {
2023 __m256i x = *(__m256i *)a;
2024 return _mm256_testz_si256(x, x);
2026 int main(int argc, char *argv[]) { return bar(argv[0]); }
2027 '''), error_message: 'AVX2 not available').allowed())
2029 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2030 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2031 .require(cc.links('''
2032 #pragma GCC push_options
2033 #pragma GCC target("avx512f")
2035 #include <immintrin.h>
2036 static int bar(void *a) {
2037 __m512i x = *(__m512i *)a;
2038 return _mm512_test_epi64_mask(x, x);
2040 int main(int argc, char *argv[]) { return bar(argv[0]); }
2041 '''), error_message: 'AVX512F not available').allowed())
2043 have_pvrdma = get_option('pvrdma') \
2044 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
2045 .require(cc.compiles('''
2050 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2053 }'''), error_message: 'PVRDMA requires mremap').allowed()
2056 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.compiles('''
2057 #include <infiniband/verbs.h>
2061 struct ibv_pd *pd = NULL;
2067 mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2073 if get_option('membarrier').disabled()
2074 have_membarrier = false
2075 elif targetos == 'windows'
2076 have_membarrier = true
2077 elif targetos == 'linux'
2078 have_membarrier = cc.compiles('''
2079 #include <linux/membarrier.h>
2080 #include <sys/syscall.h>
2084 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2085 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2089 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2090 .require(have_membarrier, error_message: 'membarrier system call not available') \
2093 have_afalg = get_option('crypto_afalg') \
2094 .require(cc.compiles(gnu_source_prefix + '''
2096 #include <sys/types.h>
2097 #include <sys/socket.h>
2098 #include <linux/if_alg.h>
2101 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2104 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2105 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2107 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2108 'linux/vm_sockets.h', 'AF_VSOCK',
2109 prefix: '#include <sys/socket.h>',
2113 have_vss_sdk = false # old xp/2003 SDK
2114 if targetos == 'windows' and link_language == 'cpp'
2115 have_vss = cxx.compiles('''
2116 #define __MIDL_user_allocate_free_DEFINED__
2118 int main(void) { return VSS_CTX_BACKUP; }''')
2119 have_vss_sdk = cxx.has_header('vscoordint.h')
2121 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2123 ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target
2125 arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
2126 foreach k, v: config_host
2127 if ignored.contains(k)
2129 elif arrays.contains(k)
2131 v = '"' + '", "'.join(v.split()) + '", '
2133 config_host_data.set(k, v)
2134 elif k.startswith('CONFIG_')
2135 config_host_data.set(k, v == 'y' ? 1 : v)
2139 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2140 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2141 if targetos == 'windows'
2142 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2148 }''', name: '_lock_file and _unlock_file'))
2151 ########################
2152 # Target configuration #
2153 ########################
2155 minikconf = find_program('scripts/minikconf.py')
2157 config_all_devices = {}
2158 config_all_disas = {}
2159 config_devices_mak_list = []
2160 config_devices_h = {}
2161 config_target_h = {}
2162 config_target_mak = {}
2165 'alpha' : ['CONFIG_ALPHA_DIS'],
2166 'arm' : ['CONFIG_ARM_DIS'],
2167 'avr' : ['CONFIG_AVR_DIS'],
2168 'cris' : ['CONFIG_CRIS_DIS'],
2169 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2170 'hppa' : ['CONFIG_HPPA_DIS'],
2171 'i386' : ['CONFIG_I386_DIS'],
2172 'x86_64' : ['CONFIG_I386_DIS'],
2173 'm68k' : ['CONFIG_M68K_DIS'],
2174 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2175 'mips' : ['CONFIG_MIPS_DIS'],
2176 'nios2' : ['CONFIG_NIOS2_DIS'],
2177 'or1k' : ['CONFIG_OPENRISC_DIS'],
2178 'ppc' : ['CONFIG_PPC_DIS'],
2179 'riscv' : ['CONFIG_RISCV_DIS'],
2180 'rx' : ['CONFIG_RX_DIS'],
2181 's390' : ['CONFIG_S390_DIS'],
2182 'sh4' : ['CONFIG_SH4_DIS'],
2183 'sparc' : ['CONFIG_SPARC_DIS'],
2184 'xtensa' : ['CONFIG_XTENSA_DIS'],
2186 if link_language == 'cpp'
2188 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
2189 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
2190 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
2194 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2196 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2197 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2198 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2199 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2200 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2201 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2202 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
2203 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2204 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2205 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2206 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
2207 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
2208 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
2210 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2212 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2213 actual_target_dirs = []
2215 foreach target : target_dirs
2216 config_target = { 'TARGET_NAME': target.split('-')[0] }
2217 if target.endswith('linux-user')
2218 if targetos != 'linux'
2222 error('Target @0@ is only available on a Linux host'.format(target))
2224 config_target += { 'CONFIG_LINUX_USER': 'y' }
2225 elif target.endswith('bsd-user')
2226 if 'CONFIG_BSD' not in config_host
2230 error('Target @0@ is only available on a BSD host'.format(target))
2232 config_target += { 'CONFIG_BSD_USER': 'y' }
2233 elif target.endswith('softmmu')
2234 config_target += { 'CONFIG_SOFTMMU': 'y' }
2236 if target.endswith('-user')
2238 'CONFIG_USER_ONLY': 'y',
2239 'CONFIG_QEMU_INTERP_PREFIX':
2240 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
2245 foreach sym: accelerators
2246 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2247 config_target += { sym: 'y' }
2248 config_all += { sym: 'y' }
2249 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
2250 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
2252 if target in modular_tcg
2253 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2255 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2257 accel_kconfig += [ sym + '=y' ]
2260 if accel_kconfig.length() == 0
2264 error('No accelerator available for target @0@'.format(target))
2267 actual_target_dirs += target
2268 config_target += keyval.load('configs/targets' / target + '.mak')
2269 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
2271 if 'TARGET_NEED_FDT' in config_target
2272 fdt_required += target
2276 if 'TARGET_BASE_ARCH' not in config_target
2277 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2279 if 'TARGET_ABI_DIR' not in config_target
2280 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2282 if 'TARGET_BIG_ENDIAN' not in config_target
2283 config_target += {'TARGET_BIG_ENDIAN': 'n'}
2286 foreach k, v: disassemblers
2287 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
2289 config_target += { sym: 'y' }
2290 config_all_disas += { sym: 'y' }
2295 config_target_data = configuration_data()
2296 foreach k, v: config_target
2297 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2299 elif ignored.contains(k)
2301 elif k == 'TARGET_BASE_ARCH'
2302 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2303 # not used to select files from sourcesets.
2304 config_target_data.set('TARGET_' + v.to_upper(), 1)
2305 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
2306 config_target_data.set_quoted(k, v)
2308 config_target_data.set(k, 1)
2310 config_target_data.set(k, 0)
2312 config_target_data.set(k, v)
2315 config_target_data.set('QEMU_ARCH',
2316 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
2317 config_target_h += {target: configure_file(output: target + '-config-target.h',
2318 configuration: config_target_data)}
2320 if target.endswith('-softmmu')
2321 config_input = meson.get_external_property(target, 'default')
2322 config_devices_mak = target + '-config-devices.mak'
2323 config_devices_mak = configure_file(
2324 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2325 output: config_devices_mak,
2326 depfile: config_devices_mak + '.d',
2328 command: [minikconf,
2329 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2330 config_devices_mak, '@DEPFILE@', '@INPUT@',
2331 host_kconfig, accel_kconfig,
2332 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
2334 config_devices_data = configuration_data()
2335 config_devices = keyval.load(config_devices_mak)
2336 foreach k, v: config_devices
2337 config_devices_data.set(k, 1)
2339 config_devices_mak_list += config_devices_mak
2340 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2341 configuration: config_devices_data)}
2342 config_target += config_devices
2343 config_all_devices += config_devices
2345 config_target_mak += {target: config_target}
2347 target_dirs = actual_target_dirs
2349 # This configuration is used to build files that are shared by
2350 # multiple binaries, and then extracted out of the "common"
2351 # static_library target.
2353 # We do not use all_sources()/all_dependencies(), because it would
2354 # build literally all source files, including devices only used by
2355 # targets that are not built for this compilation. The CONFIG_ALL
2356 # pseudo symbol replaces it.
2358 config_all += config_all_devices
2359 config_all += config_host
2360 config_all += config_all_disas
2362 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
2363 'CONFIG_SOFTMMU': have_system,
2364 'CONFIG_USER_ONLY': have_user,
2368 target_configs_h = []
2369 foreach target: target_dirs
2370 target_configs_h += config_target_h[target]
2371 target_configs_h += config_devices_h.get(target, [])
2373 genh += custom_target('config-poison.h',
2374 input: [target_configs_h],
2375 output: 'config-poison.h',
2377 command: [find_program('scripts/make-config-poison.sh'),
2384 capstone = not_found
2385 capstone_opt = get_option('capstone')
2386 if capstone_opt in ['enabled', 'auto', 'system']
2387 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
2388 capstone = dependency('capstone', version: '>=4.0',
2389 kwargs: static_kwargs, method: 'pkg-config',
2390 required: capstone_opt == 'system' or
2391 capstone_opt == 'enabled' and not have_internal)
2393 # Some versions of capstone have broken pkg-config file
2394 # that reports a wrong -I path, causing the #include to
2395 # fail later. If the system has such a broken version
2397 if capstone.found() and not cc.compiles('#include <capstone.h>',
2398 dependencies: [capstone])
2399 capstone = not_found
2400 if capstone_opt == 'system'
2401 error('system capstone requested, it does not appear to work')
2406 capstone_opt = 'system'
2408 capstone_opt = 'internal'
2410 capstone_opt = 'disabled'
2413 if capstone_opt == 'internal'
2414 capstone_data = configuration_data()
2415 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
2417 capstone_files = files(
2419 'capstone/MCInst.c',
2420 'capstone/MCInstrDesc.c',
2421 'capstone/MCRegisterInfo.c',
2422 'capstone/SStream.c',
2426 if 'CONFIG_ARM_DIS' in config_all_disas
2427 capstone_data.set('CAPSTONE_HAS_ARM', '1')
2428 capstone_files += files(
2429 'capstone/arch/ARM/ARMDisassembler.c',
2430 'capstone/arch/ARM/ARMInstPrinter.c',
2431 'capstone/arch/ARM/ARMMapping.c',
2432 'capstone/arch/ARM/ARMModule.c'
2436 # FIXME: This config entry currently depends on a c++ compiler.
2437 # Which is needed for building libvixl, but not for capstone.
2438 if 'CONFIG_ARM_A64_DIS' in config_all_disas
2439 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
2440 capstone_files += files(
2441 'capstone/arch/AArch64/AArch64BaseInfo.c',
2442 'capstone/arch/AArch64/AArch64Disassembler.c',
2443 'capstone/arch/AArch64/AArch64InstPrinter.c',
2444 'capstone/arch/AArch64/AArch64Mapping.c',
2445 'capstone/arch/AArch64/AArch64Module.c'
2449 if 'CONFIG_PPC_DIS' in config_all_disas
2450 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
2451 capstone_files += files(
2452 'capstone/arch/PowerPC/PPCDisassembler.c',
2453 'capstone/arch/PowerPC/PPCInstPrinter.c',
2454 'capstone/arch/PowerPC/PPCMapping.c',
2455 'capstone/arch/PowerPC/PPCModule.c'
2459 if 'CONFIG_S390_DIS' in config_all_disas
2460 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
2461 capstone_files += files(
2462 'capstone/arch/SystemZ/SystemZDisassembler.c',
2463 'capstone/arch/SystemZ/SystemZInstPrinter.c',
2464 'capstone/arch/SystemZ/SystemZMapping.c',
2465 'capstone/arch/SystemZ/SystemZModule.c',
2466 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
2470 if 'CONFIG_I386_DIS' in config_all_disas
2471 capstone_data.set('CAPSTONE_HAS_X86', 1)
2472 capstone_files += files(
2473 'capstone/arch/X86/X86Disassembler.c',
2474 'capstone/arch/X86/X86DisassemblerDecoder.c',
2475 'capstone/arch/X86/X86ATTInstPrinter.c',
2476 'capstone/arch/X86/X86IntelInstPrinter.c',
2477 'capstone/arch/X86/X86InstPrinterCommon.c',
2478 'capstone/arch/X86/X86Mapping.c',
2479 'capstone/arch/X86/X86Module.c'
2483 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
2486 # FIXME: There does not seem to be a way to completely replace the c_args
2487 # that come from add_project_arguments() -- we can only add to them.
2488 # So: disable all warnings with a big hammer.
2491 # Include all configuration defines via a header file, which will wind up
2492 # as a dependency on the object file, and thus changes here will result
2494 '-include', 'capstone-defs.h'
2497 libcapstone = static_library('capstone',
2498 build_by_default: false,
2499 sources: capstone_files,
2500 c_args: capstone_cargs,
2501 include_directories: 'capstone/include')
2502 capstone = declare_dependency(link_with: libcapstone,
2503 include_directories: 'capstone/include/capstone')
2507 slirp_opt = 'disabled'
2509 slirp_opt = get_option('slirp')
2510 if slirp_opt in ['enabled', 'auto', 'system']
2511 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2512 slirp = dependency('slirp', kwargs: static_kwargs,
2513 method: 'pkg-config',
2514 required: slirp_opt == 'system' or
2515 slirp_opt == 'enabled' and not have_internal)
2517 slirp_opt = 'system'
2519 slirp_opt = 'internal'
2521 slirp_opt = 'disabled'
2524 if slirp_opt == 'internal'
2526 if targetos == 'windows'
2527 slirp_deps = cc.find_library('iphlpapi')
2528 elif targetos == 'darwin'
2529 slirp_deps = cc.find_library('resolv')
2531 slirp_conf = configuration_data()
2532 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2533 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2534 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2535 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2536 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2538 'slirp/src/arp_table.c',
2539 'slirp/src/bootp.c',
2540 'slirp/src/cksum.c',
2541 'slirp/src/dhcpv6.c',
2542 'slirp/src/dnssearch.c',
2544 'slirp/src/ip6_icmp.c',
2545 'slirp/src/ip6_input.c',
2546 'slirp/src/ip6_output.c',
2547 'slirp/src/ip_icmp.c',
2548 'slirp/src/ip_input.c',
2549 'slirp/src/ip_output.c',
2553 'slirp/src/ndp_table.c',
2555 'slirp/src/slirp.c',
2556 'slirp/src/socket.c',
2557 'slirp/src/state.c',
2558 'slirp/src/stream.c',
2559 'slirp/src/tcp_input.c',
2560 'slirp/src/tcp_output.c',
2561 'slirp/src/tcp_subr.c',
2562 'slirp/src/tcp_timer.c',
2567 'slirp/src/version.c',
2568 'slirp/src/vmstate.c',
2572 input : 'slirp/src/libslirp-version.h.in',
2573 output : 'libslirp-version.h',
2574 configuration: slirp_conf)
2576 slirp_inc = include_directories('slirp', 'slirp/src')
2577 libslirp = static_library('slirp',
2578 build_by_default: false,
2579 sources: slirp_files,
2580 c_args: slirp_cargs,
2581 include_directories: slirp_inc)
2582 slirp = declare_dependency(link_with: libslirp,
2583 dependencies: slirp_deps,
2584 include_directories: slirp_inc)
2588 # For CFI, we need to compile slirp as a static library together with qemu.
2589 # This is because we register slirp functions as callbacks for QEMU Timers.
2590 # When using a system-wide shared libslirp, the type information for the
2591 # callback is missing and the timer call produces a false positive with CFI.
2593 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2594 # with control-flow integrity.
2595 if get_option('cfi') and slirp_opt == 'system'
2596 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2597 + ' Please configure with --enable-slirp=git')
2602 fdt_opt = get_option('fdt')
2603 if fdt_opt in ['enabled', 'auto', 'system']
2604 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2605 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2606 required: fdt_opt == 'system' or
2607 fdt_opt == 'enabled' and not have_internal)
2608 if fdt.found() and cc.links('''
2610 #include <libfdt_env.h>
2611 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2614 elif fdt_opt == 'system'
2615 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2617 fdt_opt = 'internal'
2619 fdt_opt = 'disabled'
2623 if fdt_opt == 'internal'
2626 'dtc/libfdt/fdt_ro.c',
2627 'dtc/libfdt/fdt_wip.c',
2628 'dtc/libfdt/fdt_sw.c',
2629 'dtc/libfdt/fdt_rw.c',
2630 'dtc/libfdt/fdt_strerror.c',
2631 'dtc/libfdt/fdt_empty_tree.c',
2632 'dtc/libfdt/fdt_addresses.c',
2633 'dtc/libfdt/fdt_overlay.c',
2634 'dtc/libfdt/fdt_check.c',
2637 fdt_inc = include_directories('dtc/libfdt')
2638 libfdt = static_library('fdt',
2639 build_by_default: false,
2641 include_directories: fdt_inc)
2642 fdt = declare_dependency(link_with: libfdt,
2643 include_directories: fdt_inc)
2646 fdt_opt = 'disabled'
2648 if not fdt.found() and fdt_required.length() > 0
2649 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2652 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2653 config_host_data.set('CONFIG_FDT', fdt.found())
2654 config_host_data.set('CONFIG_SLIRP', slirp.found())
2656 #####################
2657 # Generated sources #
2658 #####################
2660 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2662 hxtool = find_program('scripts/hxtool')
2663 shaderinclude = find_program('scripts/shaderinclude.pl')
2664 qapi_gen = find_program('scripts/qapi-gen.py')
2665 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2666 meson.current_source_dir() / 'scripts/qapi/commands.py',
2667 meson.current_source_dir() / 'scripts/qapi/common.py',
2668 meson.current_source_dir() / 'scripts/qapi/error.py',
2669 meson.current_source_dir() / 'scripts/qapi/events.py',
2670 meson.current_source_dir() / 'scripts/qapi/expr.py',
2671 meson.current_source_dir() / 'scripts/qapi/gen.py',
2672 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2673 meson.current_source_dir() / 'scripts/qapi/parser.py',
2674 meson.current_source_dir() / 'scripts/qapi/schema.py',
2675 meson.current_source_dir() / 'scripts/qapi/source.py',
2676 meson.current_source_dir() / 'scripts/qapi/types.py',
2677 meson.current_source_dir() / 'scripts/qapi/visit.py',
2678 meson.current_source_dir() / 'scripts/qapi/common.py',
2679 meson.current_source_dir() / 'scripts/qapi-gen.py'
2683 python, files('scripts/tracetool.py'),
2684 '--backend=' + ','.join(get_option('trace_backends'))
2686 tracetool_depends = files(
2687 'scripts/tracetool/backend/log.py',
2688 'scripts/tracetool/backend/__init__.py',
2689 'scripts/tracetool/backend/dtrace.py',
2690 'scripts/tracetool/backend/ftrace.py',
2691 'scripts/tracetool/backend/simple.py',
2692 'scripts/tracetool/backend/syslog.py',
2693 'scripts/tracetool/backend/ust.py',
2694 'scripts/tracetool/format/ust_events_c.py',
2695 'scripts/tracetool/format/ust_events_h.py',
2696 'scripts/tracetool/format/__init__.py',
2697 'scripts/tracetool/format/d.py',
2698 'scripts/tracetool/format/simpletrace_stap.py',
2699 'scripts/tracetool/format/c.py',
2700 'scripts/tracetool/format/h.py',
2701 'scripts/tracetool/format/log_stap.py',
2702 'scripts/tracetool/format/stap.py',
2703 'scripts/tracetool/__init__.py',
2704 'scripts/tracetool/transform.py',
2705 'scripts/tracetool/vcpu.py'
2708 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2709 meson.current_source_dir(),
2710 config_host['PKGVERSION'], meson.project_version()]
2711 qemu_version = custom_target('qemu-version.h',
2712 output: 'qemu-version.h',
2713 command: qemu_version_cmd,
2715 build_by_default: true,
2716 build_always_stale: true)
2717 genh += qemu_version
2721 ['qemu-options.hx', 'qemu-options.def'],
2722 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2726 ['hmp-commands.hx', 'hmp-commands.h'],
2727 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2730 foreach d : hx_headers
2731 hxdep += custom_target(d[1],
2735 build_by_default: true, # to be removed when added to a target
2736 command: [hxtool, '-h', '@INPUT0@'])
2744 authz_ss = ss.source_set()
2745 blockdev_ss = ss.source_set()
2746 block_ss = ss.source_set()
2747 chardev_ss = ss.source_set()
2748 common_ss = ss.source_set()
2749 crypto_ss = ss.source_set()
2750 hwcore_ss = ss.source_set()
2751 io_ss = ss.source_set()
2752 qmp_ss = ss.source_set()
2753 qom_ss = ss.source_set()
2754 softmmu_ss = ss.source_set()
2755 specific_fuzz_ss = ss.source_set()
2756 specific_ss = ss.source_set()
2757 stub_ss = ss.source_set()
2758 trace_ss = ss.source_set()
2759 user_ss = ss.source_set()
2760 util_ss = ss.source_set()
2763 qtest_module_ss = ss.source_set()
2764 tcg_module_ss = ss.source_set()
2770 target_softmmu_arch = {}
2771 target_user_arch = {}
2777 # TODO: add each directory to the subdirs from its own meson.build, once
2779 trace_events_subdirs = [
2787 trace_events_subdirs += [ 'linux-user' ]
2790 trace_events_subdirs += [ 'bsd-user' ]
2793 trace_events_subdirs += [
2802 trace_events_subdirs += [
2816 'hw/block/dataplane',
2866 if have_system or have_user
2867 trace_events_subdirs += [
2885 vhost_user = not_found
2886 if targetos == 'linux' and 'CONFIG_VHOST_USER' in config_host
2887 libvhost_user = subproject('libvhost-user')
2888 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2891 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
2892 # that is filled in by qapi/.
2905 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2906 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2909 stub_ss = stub_ss.apply(config_all, strict: false)
2911 util_ss.add_all(trace_ss)
2912 util_ss = util_ss.apply(config_all, strict: false)
2913 libqemuutil = static_library('qemuutil',
2914 sources: util_ss.sources() + stub_ss.sources() + genh,
2915 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2916 qemuutil = declare_dependency(link_with: libqemuutil,
2917 sources: genh + version_res)
2919 if have_system or have_user
2920 decodetree = generator(find_program('scripts/decodetree.py'),
2921 output: 'decode-@BASENAME@.c.inc',
2922 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2923 subdir('libdecnumber')
2940 if config_host_data.get('CONFIG_REPLICATION')
2941 block_ss.add(files('replication.c'))
2948 blockdev_ss.add(files(
2955 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2956 # os-win32.c does not
2957 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2958 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2961 common_ss.add(files('cpus-common.c'))
2965 common_ss.add(capstone)
2966 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2968 # Work around a gcc bug/misfeature wherein constant propagation looks
2970 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2971 # to guess that a const variable is always zero. Without lto, this is
2972 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2973 # without lto, not even the alias is required -- we simply use different
2974 # declarations in different compilation units.
2975 pagevary = files('page-vary-common.c')
2976 if get_option('b_lto')
2977 pagevary_flags = ['-fno-lto']
2978 if get_option('cfi')
2979 pagevary_flags += '-fno-sanitize=cfi-icall'
2981 pagevary = static_library('page-vary-common', sources: pagevary + genh,
2982 c_args: pagevary_flags)
2983 pagevary = declare_dependency(link_with: pagevary)
2985 common_ss.add(pagevary)
2986 specific_ss.add(files('page-vary.c'))
2994 subdir('semihosting')
3002 common_user_inc = []
3004 subdir('common-user')
3006 subdir('linux-user')
3008 # needed for fuzzing binaries
3009 subdir('tests/qtest/libqos')
3010 subdir('tests/qtest/fuzz')
3013 tcg_real_module_ss = ss.source_set()
3014 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3015 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3016 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3017 'tcg': tcg_real_module_ss }}
3019 ########################
3020 # Library dependencies #
3021 ########################
3023 modinfo_collect = find_program('scripts/modinfo-collect.py')
3024 modinfo_generate = find_program('scripts/modinfo-generate.py')
3029 foreach d, list : modules
3030 foreach m, module_ss : list
3031 if enable_modules and targetos != 'windows'
3032 module_ss = module_ss.apply(config_all, strict: false)
3033 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3034 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3040 if module_ss.sources() != []
3041 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3042 # input. Sources can be used multiple times but objects are
3043 # unique when it comes to lookup in compile_commands.json.
3044 # Depnds on a mesion version with
3045 # https://github.com/mesonbuild/meson/pull/8900
3046 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3047 output: d + '-' + m + '.modinfo',
3048 input: module_ss.sources() + genh,
3050 command: [modinfo_collect, module_ss.sources()])
3054 block_ss.add_all(module_ss)
3056 softmmu_ss.add_all(module_ss)
3062 foreach d, list : target_modules
3063 foreach m, module_ss : list
3064 if enable_modules and targetos != 'windows'
3065 foreach target : target_dirs
3066 if target.endswith('-softmmu')
3067 config_target = config_target_mak[target]
3068 config_target += config_host
3069 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3070 c_args = ['-DNEED_CPU_H',
3071 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3072 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3073 target_module_ss = module_ss.apply(config_target, strict: false)
3074 if target_module_ss.sources() != []
3075 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3076 sl = static_library(module_name,
3077 [genh, target_module_ss.sources()],
3078 dependencies: [modulecommon, target_module_ss.dependencies()],
3079 include_directories: target_inc,
3083 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3084 modinfo_files += custom_target(module_name + '.modinfo',
3085 output: module_name + '.modinfo',
3086 input: target_module_ss.sources() + genh,
3088 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3093 specific_ss.add_all(module_ss)
3099 modinfo_src = custom_target('modinfo.c',
3100 output: 'modinfo.c',
3101 input: modinfo_files,
3102 command: [modinfo_generate, '@INPUT@'],
3104 modinfo_lib = static_library('modinfo', modinfo_src)
3105 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
3106 softmmu_ss.add(modinfo_dep)
3109 nm = find_program('nm')
3110 undefsym = find_program('scripts/undefsym.py')
3111 block_syms = custom_target('block.syms', output: 'block.syms',
3112 input: [libqemuutil, block_mods],
3114 command: [undefsym, nm, '@INPUT@'])
3115 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3116 input: [libqemuutil, softmmu_mods],
3118 command: [undefsym, nm, '@INPUT@'])
3120 qom_ss = qom_ss.apply(config_host, strict: false)
3121 libqom = static_library('qom', qom_ss.sources() + genh,
3122 dependencies: [qom_ss.dependencies()],
3125 qom = declare_dependency(link_whole: libqom)
3127 authz_ss = authz_ss.apply(config_host, strict: false)
3128 libauthz = static_library('authz', authz_ss.sources() + genh,
3129 dependencies: [authz_ss.dependencies()],
3131 build_by_default: false)
3133 authz = declare_dependency(link_whole: libauthz,
3136 crypto_ss = crypto_ss.apply(config_host, strict: false)
3137 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3138 dependencies: [crypto_ss.dependencies()],
3140 build_by_default: false)
3142 crypto = declare_dependency(link_whole: libcrypto,
3143 dependencies: [authz, qom])
3145 io_ss = io_ss.apply(config_host, strict: false)
3146 libio = static_library('io', io_ss.sources() + genh,
3147 dependencies: [io_ss.dependencies()],
3148 link_with: libqemuutil,
3150 build_by_default: false)
3152 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3154 libmigration = static_library('migration', sources: migration_files + genh,
3156 build_by_default: false)
3157 migration = declare_dependency(link_with: libmigration,
3158 dependencies: [zlib, qom, io])
3159 softmmu_ss.add(migration)
3161 block_ss = block_ss.apply(config_host, strict: false)
3162 libblock = static_library('block', block_ss.sources() + genh,
3163 dependencies: block_ss.dependencies(),
3164 link_depends: block_syms,
3166 build_by_default: false)
3168 block = declare_dependency(link_whole: [libblock],
3169 link_args: '@block.syms',
3170 dependencies: [crypto, io])
3172 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
3173 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3174 dependencies: blockdev_ss.dependencies(),
3176 build_by_default: false)
3178 blockdev = declare_dependency(link_whole: [libblockdev],
3179 dependencies: [block])
3181 qmp_ss = qmp_ss.apply(config_host, strict: false)
3182 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3183 dependencies: qmp_ss.dependencies(),
3185 build_by_default: false)
3187 qmp = declare_dependency(link_whole: [libqmp])
3189 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3191 dependencies: chardev_ss.dependencies(),
3192 build_by_default: false)
3194 chardev = declare_dependency(link_whole: libchardev)
3196 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
3197 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3199 build_by_default: false)
3200 hwcore = declare_dependency(link_whole: libhwcore)
3201 common_ss.add(hwcore)
3207 emulator_modules = []
3208 foreach m : block_mods + softmmu_mods
3209 emulator_modules += shared_module(m.name(),
3210 build_by_default: true,
3214 install_dir: qemu_moddir)
3217 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3218 common_ss.add(qom, qemuutil)
3220 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
3221 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3223 common_all = common_ss.apply(config_all, strict: false)
3224 common_all = static_library('common',
3225 build_by_default: false,
3226 sources: common_all.sources() + genh,
3227 include_directories: common_user_inc,
3228 implicit_include_directories: false,
3229 dependencies: common_all.dependencies(),
3232 feature_to_c = find_program('scripts/feature_to_c.sh')
3234 if targetos == 'darwin'
3235 entitlement = find_program('scripts/entitlement.sh')
3239 foreach target : target_dirs
3240 config_target = config_target_mak[target]
3241 target_name = config_target['TARGET_NAME']
3242 target_base_arch = config_target['TARGET_BASE_ARCH']
3243 arch_srcs = [config_target_h[target]]
3245 c_args = ['-DNEED_CPU_H',
3246 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3247 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3248 link_args = emulator_link_args
3250 config_target += config_host
3251 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3252 if targetos == 'linux'
3253 target_inc += include_directories('linux-headers', is_system: true)
3255 if target.endswith('-softmmu')
3256 qemu_target_name = 'qemu-system-' + target_name
3257 target_type='system'
3258 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3259 arch_srcs += t.sources()
3260 arch_deps += t.dependencies()
3262 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3263 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3264 arch_srcs += hw.sources()
3265 arch_deps += hw.dependencies()
3267 arch_srcs += config_devices_h[target]
3268 link_args += ['@block.syms', '@qemu.syms']
3270 abi = config_target['TARGET_ABI_DIR']
3272 target_inc += common_user_inc
3273 qemu_target_name = 'qemu-' + target_name
3274 if target_base_arch in target_user_arch
3275 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3276 arch_srcs += t.sources()
3277 arch_deps += t.dependencies()
3279 if 'CONFIG_LINUX_USER' in config_target
3280 base_dir = 'linux-user'
3282 if 'CONFIG_BSD_USER' in config_target
3283 base_dir = 'bsd-user'
3284 target_inc += include_directories('bsd-user/' / targetos)
3285 target_inc += include_directories('bsd-user/host/' / host_arch)
3286 dir = base_dir / abi
3287 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3289 target_inc += include_directories(
3293 if 'CONFIG_LINUX_USER' in config_target
3294 dir = base_dir / abi
3295 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3296 if config_target.has_key('TARGET_SYSTBL_ABI')
3298 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3299 extra_args : config_target['TARGET_SYSTBL_ABI'])
3304 if 'TARGET_XML_FILES' in config_target
3305 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3306 output: target + '-gdbstub-xml.c',
3307 input: files(config_target['TARGET_XML_FILES'].split()),
3308 command: [feature_to_c, '@INPUT@'],
3310 arch_srcs += gdbstub_xml
3313 t = target_arch[target_base_arch].apply(config_target, strict: false)
3314 arch_srcs += t.sources()
3315 arch_deps += t.dependencies()
3317 target_common = common_ss.apply(config_target, strict: false)
3318 objects = common_all.extract_objects(target_common.sources())
3319 deps = target_common.dependencies()
3321 target_specific = specific_ss.apply(config_target, strict: false)
3322 arch_srcs += target_specific.sources()
3323 arch_deps += target_specific.dependencies()
3325 lib = static_library('qemu-' + target,
3326 sources: arch_srcs + genh,
3327 dependencies: arch_deps,
3329 include_directories: target_inc,
3331 build_by_default: false,
3334 if target.endswith('-softmmu')
3336 'name': 'qemu-system-' + target_name,
3337 'win_subsystem': 'console',
3338 'sources': files('softmmu/main.c'),
3341 if targetos == 'windows' and (sdl.found() or gtk.found())
3343 'name': 'qemu-system-' + target_name + 'w',
3344 'win_subsystem': 'windows',
3345 'sources': files('softmmu/main.c'),
3349 if get_option('fuzzing')
3350 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3352 'name': 'qemu-fuzz-' + target_name,
3353 'win_subsystem': 'console',
3354 'sources': specific_fuzz.sources(),
3355 'dependencies': specific_fuzz.dependencies(),
3360 'name': 'qemu-' + target_name,
3361 'win_subsystem': 'console',
3367 exe_name = exe['name']
3368 if targetos == 'darwin'
3369 exe_name += '-unsigned'
3372 emulator = executable(exe_name, exe['sources'],
3375 dependencies: arch_deps + deps + exe['dependencies'],
3376 objects: lib.extract_all_objects(recursive: true),
3377 link_language: link_language,
3378 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3379 link_args: link_args,
3380 win_subsystem: exe['win_subsystem'])
3382 if targetos == 'darwin'
3383 icon = 'pc-bios/qemu.rsrc'
3384 build_input = [emulator, files(icon)]
3386 get_option('bindir') / exe_name,
3387 meson.current_source_dir() / icon
3389 if 'CONFIG_HVF' in config_target
3390 entitlements = 'accel/hvf/entitlements.plist'
3391 build_input += files(entitlements)
3392 install_input += meson.current_source_dir() / entitlements
3395 emulators += {exe['name'] : custom_target(exe['name'],
3397 output: exe['name'],
3398 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3401 meson.add_install_script(entitlement, '--install',
3402 get_option('bindir') / exe['name'],
3405 emulators += {exe['name']: emulator}
3410 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3411 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3412 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3413 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3415 custom_target(exe['name'] + stp['ext'],
3416 input: trace_events_all,
3417 output: exe['name'] + stp['ext'],
3418 install: stp['install'],
3419 install_dir: get_option('datadir') / 'systemtap/tapset',
3421 tracetool, '--group=all', '--format=' + stp['fmt'],
3422 '--binary=' + stp['bin'],
3423 '--target-name=' + target_name,
3424 '--target-type=' + target_type,
3425 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3426 '@INPUT@', '@OUTPUT@'
3428 depend_files: tracetool_depends)
3434 # Other build targets
3436 if 'CONFIG_PLUGIN' in config_host
3437 install_headers('include/qemu/qemu-plugin.h')
3442 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3443 # when we don't build tools or system
3444 if xkbcommon.found()
3445 # used for the update-keymaps target, so include rules even if !have_tools
3446 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3447 dependencies: [qemuutil, xkbcommon], install: have_tools)
3451 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3452 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3453 qemu_io = executable('qemu-io', files('qemu-io.c'),
3454 dependencies: [block, qemuutil], install: true)
3455 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3456 dependencies: [blockdev, qemuutil, gnutls, selinux],
3459 subdir('storage-daemon')
3460 subdir('contrib/rdmacm-mux')
3461 subdir('contrib/elf2dmp')
3463 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3464 dependencies: qemuutil,
3467 if 'CONFIG_VHOST_USER' in config_host
3468 subdir('contrib/vhost-user-blk')
3469 subdir('contrib/vhost-user-gpu')
3470 subdir('contrib/vhost-user-input')
3471 subdir('contrib/vhost-user-scsi')
3474 if targetos == 'linux'
3475 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3476 dependencies: [qemuutil, libcap_ng],
3478 install_dir: get_option('libexecdir'))
3480 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3481 dependencies: [authz, crypto, io, qom, qemuutil,
3482 libcap_ng, mpathpersist],
3487 subdir('contrib/ivshmem-client')
3488 subdir('contrib/ivshmem-server')
3501 if host_machine.system() == 'windows'
3503 find_program('scripts/nsis.py'),
3505 get_option('prefix'),
3506 meson.current_source_dir(),
3509 '-DDISPLAYVERSION=' + meson.project_version(),
3512 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3515 nsis_cmd += '-DCONFIG_GTK=y'
3518 nsis = custom_target('nsis',
3519 output: 'qemu-setup-' + meson.project_version() + '.exe',
3520 input: files('qemu.nsi'),
3521 build_always_stale: true,
3522 command: nsis_cmd + ['@INPUT@'])
3523 alias_target('installer', nsis)
3526 #########################
3527 # Configuration summary #
3528 #########################
3532 summary_info += {'Install prefix': get_option('prefix')}
3533 summary_info += {'BIOS directory': qemu_datadir}
3534 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
3535 summary_info += {'binary directory': get_option('bindir')}
3536 summary_info += {'library directory': get_option('libdir')}
3537 summary_info += {'module directory': qemu_moddir}
3538 summary_info += {'libexec directory': get_option('libexecdir')}
3539 summary_info += {'include directory': get_option('includedir')}
3540 summary_info += {'config directory': get_option('sysconfdir')}
3541 if targetos != 'windows'
3542 summary_info += {'local state directory': get_option('localstatedir')}
3543 summary_info += {'Manual directory': get_option('mandir')}
3545 summary_info += {'local state directory': 'queried at runtime'}
3547 summary_info += {'Doc directory': get_option('docdir')}
3548 summary_info += {'Build directory': meson.current_build_dir()}
3549 summary_info += {'Source path': meson.current_source_dir()}
3550 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3551 summary(summary_info, bool_yn: true, section: 'Directories')
3555 summary_info += {'git': config_host['GIT']}
3556 summary_info += {'make': config_host['MAKE']}
3557 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3558 summary_info += {'sphinx-build': sphinx_build}
3559 if config_host.has_key('HAVE_GDB_BIN')
3560 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3562 if get_option('iasl') != ''
3563 summary_info += {'iasl': get_option('iasl')}
3565 summary_info += {'iasl': false}
3567 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3568 if targetos == 'windows' and have_ga
3569 summary_info += {'wixl': wixl}
3571 if slirp_opt != 'disabled' and have_system
3572 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
3574 summary(summary_info, bool_yn: true, section: 'Host binaries')
3576 # Configurable features
3578 summary_info += {'Documentation': build_docs}
3579 summary_info += {'system-mode emulation': have_system}
3580 summary_info += {'user-mode emulation': have_user}
3581 summary_info += {'block layer': have_block}
3582 summary_info += {'Install blobs': get_option('install_blobs')}
3583 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3584 if config_host.has_key('CONFIG_MODULES')
3585 summary_info += {'alternative module path': get_option('module_upgrades')}
3587 summary_info += {'fuzzing support': get_option('fuzzing')}
3589 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3591 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3592 if 'simple' in get_option('trace_backends')
3593 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3595 summary_info += {'D-Bus display': dbus_display}
3596 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
3597 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
3598 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
3599 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
3600 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
3601 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
3602 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
3603 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3604 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
3605 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
3606 summary_info += {'build guest agent': have_ga}
3607 summary(summary_info, bool_yn: true, section: 'Configurable features')
3609 # Compilation information
3611 summary_info += {'host CPU': cpu}
3612 summary_info += {'host endianness': build_machine.endian()}
3613 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3614 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3615 if link_language == 'cpp'
3616 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3618 summary_info += {'C++ compiler': false}
3620 if targetos == 'darwin'
3621 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3623 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3624 + ['-O' + get_option('optimization')]
3625 + (get_option('debug') ? ['-g'] : []))}
3626 if link_language == 'cpp'
3627 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3628 + ['-O' + get_option('optimization')]
3629 + (get_option('debug') ? ['-g'] : []))}
3631 if targetos == 'darwin'
3632 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args')
3633 + ['-O' + get_option('optimization')]
3634 + (get_option('debug') ? ['-g'] : []))}
3636 link_args = get_option(link_language + '_link_args')
3637 if link_args.length() > 0
3638 summary_info += {'LDFLAGS': ' '.join(link_args)}
3640 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_cflags)}
3641 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_cxxflags)}
3642 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_objcflags)}
3643 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
3644 summary_info += {'profiler': get_option('profiler')}
3645 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3646 summary_info += {'PIE': get_option('b_pie')}
3647 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3648 summary_info += {'malloc trim support': has_malloc_trim}
3649 summary_info += {'membarrier': have_membarrier}
3650 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
3651 summary_info += {'mutex debugging': get_option('debug_mutex')}
3652 summary_info += {'memory allocator': get_option('malloc')}
3653 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
3654 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
3655 summary_info += {'gprof enabled': get_option('gprof')}
3656 summary_info += {'gcov': get_option('b_coverage')}
3657 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3658 summary_info += {'CFI support': get_option('cfi')}
3659 if get_option('cfi')
3660 summary_info += {'CFI debug support': get_option('cfi_debug')}
3662 summary_info += {'strip binaries': get_option('strip')}
3663 summary_info += {'sparse': sparse}
3664 summary_info += {'mingw32 support': targetos == 'windows'}
3666 # snarf the cross-compilation information for tests
3667 foreach target: target_dirs
3668 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3669 if fs.exists(tcg_mak)
3670 config_cross_tcg = keyval.load(tcg_mak)
3671 target = config_cross_tcg['TARGET_NAME']
3673 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3674 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3675 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3676 elif 'CROSS_CC_GUEST' in config_cross_tcg
3677 summary_info += {target + ' tests'
3678 : config_cross_tcg['CROSS_CC_GUEST'] }
3683 summary(summary_info, bool_yn: true, section: 'Compilation')
3685 # Targets and accelerators
3688 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3689 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3690 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3691 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3692 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3693 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
3694 if config_host.has_key('CONFIG_XEN_BACKEND')
3695 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
3698 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3699 if config_all.has_key('CONFIG_TCG')
3700 if get_option('tcg_interpreter')
3701 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
3703 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3705 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3706 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3708 summary_info += {'target list': ' '.join(target_dirs)}
3710 summary_info += {'default devices': get_option('default_devices')}
3711 summary_info += {'out of process emulation': multiprocess_allowed}
3713 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3717 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3718 summary_info += {'coroutine pool': have_coroutine_pool}
3720 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3721 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3722 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
3723 summary_info += {'VirtFS support': have_virtfs}
3724 summary_info += {'build virtiofs daemon': have_virtiofsd}
3725 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
3726 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
3727 summary_info += {'bochs support': get_option('bochs').allowed()}
3728 summary_info += {'cloop support': get_option('cloop').allowed()}
3729 summary_info += {'dmg support': get_option('dmg').allowed()}
3730 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
3731 summary_info += {'vdi support': get_option('vdi').allowed()}
3732 summary_info += {'vvfat support': get_option('vvfat').allowed()}
3733 summary_info += {'qed support': get_option('qed').allowed()}
3734 summary_info += {'parallels support': get_option('parallels').allowed()}
3735 summary_info += {'FUSE exports': fuse}
3737 summary(summary_info, bool_yn: true, section: 'Block layer support')
3741 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
3742 summary_info += {'GNUTLS support': gnutls}
3744 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3746 summary_info += {'libgcrypt': gcrypt}
3747 summary_info += {'nettle': nettle}
3749 summary_info += {' XTS': xts != 'private'}
3751 summary_info += {'AF_ALG support': have_afalg}
3752 summary_info += {'rng-none': get_option('rng_none')}
3753 summary_info += {'Linux keyring': have_keyring}
3754 summary(summary_info, bool_yn: true, section: 'Crypto')
3758 if targetos == 'darwin'
3759 summary_info += {'Cocoa support': cocoa}
3761 summary_info += {'SDL support': sdl}
3762 summary_info += {'SDL image support': sdl_image}
3763 summary_info += {'GTK support': gtk}
3764 summary_info += {'pixman': pixman}
3765 summary_info += {'VTE support': vte}
3766 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3767 summary_info += {'libtasn1': tasn1}
3768 summary_info += {'PAM': pam}
3769 summary_info += {'iconv support': iconv}
3770 summary_info += {'curses support': curses}
3771 summary_info += {'virgl support': virgl}
3772 summary_info += {'curl support': curl}
3773 summary_info += {'Multipath support': mpathpersist}
3774 summary_info += {'PNG support': png}
3775 summary_info += {'VNC support': vnc}
3777 summary_info += {'VNC SASL support': sasl}
3778 summary_info += {'VNC JPEG support': jpeg}
3780 if targetos not in ['darwin', 'haiku', 'windows']
3781 summary_info += {'OSS support': oss}
3782 elif targetos == 'darwin'
3783 summary_info += {'CoreAudio support': coreaudio}
3784 elif targetos == 'windows'
3785 summary_info += {'DirectSound support': dsound}
3787 if targetos == 'linux'
3788 summary_info += {'ALSA support': alsa}
3789 summary_info += {'PulseAudio support': pulse}
3791 summary_info += {'JACK support': jack}
3792 summary_info += {'brlapi support': brlapi}
3793 summary_info += {'vde support': vde}
3794 summary_info += {'netmap support': have_netmap}
3795 summary_info += {'l2tpv3 support': have_l2tpv3}
3796 summary_info += {'Linux AIO support': libaio}
3797 summary_info += {'Linux io_uring support': linux_io_uring}
3798 summary_info += {'ATTR/XATTR support': libattr}
3799 summary_info += {'RDMA support': rdma}
3800 summary_info += {'PVRDMA support': have_pvrdma}
3801 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3802 summary_info += {'libcap-ng support': libcap_ng}
3803 summary_info += {'bpf support': libbpf}
3804 summary_info += {'spice protocol support': spice_protocol}
3805 if spice_protocol.found()
3806 summary_info += {' spice server support': spice}
3808 summary_info += {'rbd support': rbd}
3809 summary_info += {'smartcard support': cacard}
3810 summary_info += {'U2F support': u2f}
3811 summary_info += {'libusb': libusb}
3812 summary_info += {'usb net redir': usbredir}
3813 summary_info += {'OpenGL support (epoxy)': opengl}
3814 summary_info += {'GBM': gbm}
3815 summary_info += {'libiscsi support': libiscsi}
3816 summary_info += {'libnfs support': libnfs}
3817 if targetos == 'windows'
3819 summary_info += {'QGA VSS support': have_qga_vss}
3822 summary_info += {'seccomp support': seccomp}
3823 summary_info += {'GlusterFS support': glusterfs}
3824 summary_info += {'TPM support': have_tpm}
3825 summary_info += {'libssh support': libssh}
3826 summary_info += {'lzo support': lzo}
3827 summary_info += {'snappy support': snappy}
3828 summary_info += {'bzip2 support': libbzip2}
3829 summary_info += {'lzfse support': liblzfse}
3830 summary_info += {'zstd support': zstd}
3831 summary_info += {'NUMA host support': numa}
3832 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3833 summary_info += {'libpmem support': libpmem}
3834 summary_info += {'libdaxctl support': libdaxctl}
3835 summary_info += {'libudev': libudev}
3836 # Dummy dependency, keep .found()
3837 summary_info += {'FUSE lseek': fuse_lseek.found()}
3838 summary_info += {'selinux': selinux}
3839 summary(summary_info, bool_yn: true, section: 'Dependencies')
3841 if not supported_cpus.contains(cpu)
3843 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3845 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3846 message('The QEMU project intends to remove support for this host CPU in')
3847 message('a future release if nobody volunteers to maintain it and to')
3848 message('provide a build host for our continuous integration setup.')
3849 message('configure has succeeded and you can continue to build, but')
3850 message('if you care about QEMU on this platform you should contact')
3851 message('us upstream at qemu-devel@nongnu.org.')
3854 if not supported_oses.contains(targetos)
3856 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3858 message('Host OS ' + targetos + 'support is not currently maintained.')
3859 message('The QEMU project intends to remove support for this host OS in')
3860 message('a future release if nobody volunteers to maintain it and to')
3861 message('provide a build host for our continuous integration setup.')
3862 message('configure has succeeded and you can continue to build, but')
3863 message('if you care about QEMU on this platform you should contact')
3864 message('us upstream at qemu-devel@nongnu.org.')