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'])
170 if get_option('iasl') == ''
171 iasl = find_program('iasl', required: false)
173 iasl = find_program(get_option('iasl'), required: true)
180 qemu_cflags = config_host['QEMU_CFLAGS'].split()
181 qemu_cxxflags = config_host['QEMU_CXXFLAGS'].split()
182 qemu_objcflags = config_host['QEMU_OBJCFLAGS'].split()
183 qemu_ldflags = config_host['QEMU_LDFLAGS'].split()
185 if targetos == 'windows'
186 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat')
187 # Disable ASLR for debug builds to allow debugging with gdb
188 if get_option('optimization') == '0'
189 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase')
193 if get_option('gprof')
194 qemu_cflags += ['-p']
195 qemu_cxxflags += ['-p']
196 qemu_objcflags += ['-p']
197 qemu_ldflags += ['-p']
200 # Specify linker-script with add_project_link_arguments so that it is not placed
201 # within a linker --start-group/--end-group pair
202 if get_option('fuzzing')
203 add_project_link_arguments(['-Wl,-T,',
204 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
205 native: false, language: ['c', 'cpp', 'objc'])
207 # Specify a filter to only instrument code that is directly related to
209 configure_file(output: 'instrumentation-filter',
210 input: 'scripts/oss-fuzz/instrumentation-filter-template',
212 add_global_arguments(
213 cc.get_supported_arguments('-fsanitize-coverage-allowlist=instrumentation-filter'),
214 native: false, language: ['c', 'cpp', 'objc'])
216 if get_option('fuzzing_engine') == ''
217 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
218 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
219 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
220 # unable to bind the fuzzer-related callbacks added by instrumentation.
221 add_global_arguments('-fsanitize=fuzzer-no-link',
222 native: false, language: ['c', 'cpp', 'objc'])
223 add_global_link_arguments('-fsanitize=fuzzer-no-link',
224 native: false, language: ['c', 'cpp', 'objc'])
225 # For the actual fuzzer binaries, we need to link against the libfuzzer
226 # library. They need to be configurable, to support OSS-Fuzz
227 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
229 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
230 # the needed CFLAGS have already been provided
231 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
235 add_global_arguments(qemu_cflags, native: false, language: ['c'])
236 add_global_arguments(qemu_cxxflags, native: false, language: ['cpp'])
237 add_global_arguments(qemu_objcflags, native: false, language: ['objc'])
238 add_global_link_arguments(qemu_ldflags, native: false, language: ['c', 'cpp', 'objc'])
240 if targetos == 'linux'
241 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
242 '-isystem', 'linux-headers',
243 language: ['c', 'cpp'])
246 add_project_arguments('-iquote', '.',
247 '-iquote', meson.current_source_dir(),
248 '-iquote', meson.current_source_dir() / 'include',
249 '-iquote', meson.current_source_dir() / 'disas/libvixl',
250 language: ['c', 'cpp', 'objc'])
252 link_language = meson.get_external_property('link_language', 'cpp')
253 if link_language == 'cpp'
254 add_languages('cpp', required: true, native: false)
255 cxx = meson.get_compiler('cpp')
260 if host_machine.system() == 'darwin'
261 add_languages('objc', required: false, native: false)
264 sparse = find_program('cgcc', required: get_option('sparse'))
267 command: [find_program('scripts/check_sparse.py'),
268 'compile_commands.json', sparse.full_path(), '-Wbitwise',
269 '-Wno-transparent-union', '-Wno-old-initializer',
270 '-Wno-non-pointer-null'])
273 ###########################################
274 # Target-specific checks and dependencies #
275 ###########################################
278 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
281 #include <sys/types.h>
282 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
283 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
285 args: ['-Werror', '-fsanitize=fuzzer'])
286 error('Your compiler does not support -fsanitize=fuzzer')
290 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
291 error('ftrace is supported only on Linux')
293 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
296 openlog("qemu", LOG_PID, LOG_DAEMON);
297 syslog(LOG_INFO, "configure");
300 error('syslog is not supported on this system')
303 # Miscellaneous Linux-only features
304 get_option('mpath') \
305 .require(targetos == 'linux', error_message: 'Multipath is supported only on Linux')
307 multiprocess_allowed = get_option('multiprocess') \
308 .require(targetos == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
311 have_tpm = get_option('tpm') \
312 .require(targetos != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
315 # Target-specific libraries and flags
316 libm = cc.find_library('m', required: false)
317 threads = dependency('threads')
318 util = cc.find_library('util', required: false)
324 emulator_link_args = []
330 if targetos == 'windows'
331 midl = find_program('midl', required: false)
332 widl = find_program('widl', required: false)
333 socket = cc.find_library('ws2_32')
334 winmm = cc.find_library('winmm')
336 win = import('windows')
337 version_res = win.compile_resources('version.rc',
338 depend_files: files('pc-bios/qemu-nsis.ico'),
339 include_directories: include_directories('.'))
341 elif targetos == 'darwin'
342 coref = dependency('appleframeworks', modules: 'CoreFoundation')
343 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
344 host_dsosuf = '.dylib'
345 elif targetos == 'sunos'
346 socket = [cc.find_library('socket'),
347 cc.find_library('nsl'),
348 cc.find_library('resolv')]
349 elif targetos == 'haiku'
350 socket = [cc.find_library('posix_error_mapper'),
351 cc.find_library('network'),
352 cc.find_library('bsd')]
353 elif targetos == 'openbsd'
354 if get_option('tcg').allowed() and target_dirs.length() > 0
355 # Disable OpenBSD W^X if available
356 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
360 # Target-specific configuration of accelerators
362 if get_option('kvm').allowed() and targetos == 'linux'
363 accelerators += 'CONFIG_KVM'
365 if get_option('whpx').allowed() and targetos == 'windows'
366 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
367 error('WHPX requires 64-bit host')
368 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
369 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
370 accelerators += 'CONFIG_WHPX'
373 if get_option('hvf').allowed()
374 hvf = dependency('appleframeworks', modules: 'Hypervisor',
375 required: get_option('hvf'))
377 accelerators += 'CONFIG_HVF'
380 if get_option('hax').allowed()
381 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
382 accelerators += 'CONFIG_HAX'
385 if targetos == 'netbsd'
386 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
388 accelerators += 'CONFIG_NVMM'
393 if get_option('tcg').allowed()
394 if host_arch == 'unknown'
395 if get_option('tcg_interpreter')
396 warning('Unsupported CPU @0@, will use TCG with TCI (slow)'.format(cpu))
398 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
400 elif get_option('tcg_interpreter')
401 warning('Use of the TCG interpreter is not recommended on this host')
402 warning('architecture. There is a native TCG execution backend available')
403 warning('which provides substantially better performance and reliability.')
404 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
405 warning('configuration option on this architecture to use the native')
408 if get_option('tcg_interpreter')
410 elif host_arch == 'sparc64'
412 elif host_arch == 'x86_64'
414 elif host_arch == 'ppc64'
417 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
418 language: ['c', 'cpp', 'objc'])
420 accelerators += 'CONFIG_TCG'
421 config_host += { 'CONFIG_TCG': 'y' }
424 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
425 error('KVM not available on this platform')
427 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
428 error('HVF not available on this platform')
430 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
431 error('NVMM not available on this platform')
433 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
434 error('WHPX not available on this platform')
441 # The path to glib.h is added to all compilation commands. This was
442 # grandfathered in from the QEMU Makefiles.
443 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
444 native: false, language: ['c', 'cpp', 'objc'])
445 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
446 link_args: config_host['GLIB_LIBS'].split(),
447 version: config_host['GLIB_VERSION'])
448 # override glib dep with the configure results (for subprojects)
449 meson.override_dependency('glib-2.0', glib)
452 gdbus_codegen = not_found
453 if not get_option('gio').auto() or have_system
454 gio = dependency('gio-2.0', required: get_option('gio'),
455 method: 'pkg-config', kwargs: static_kwargs)
456 if gio.found() and not cc.links('''
460 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
462 }''', dependencies: [glib, gio])
463 if get_option('gio').enabled()
464 error('The installed libgio is broken for static linking')
469 gdbus_codegen = find_program(gio.get_variable('gdbus_codegen'),
470 required: get_option('gio'))
471 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
472 method: 'pkg-config', kwargs: static_kwargs)
473 gio = declare_dependency(dependencies: [gio, gio_unix],
474 version: gio.version())
479 if 'ust' in get_option('trace_backends')
480 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
481 method: 'pkg-config', kwargs: static_kwargs)
484 if have_system or have_tools
485 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
486 method: 'pkg-config', kwargs: static_kwargs)
488 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
491 if not get_option('linux_aio').auto() or have_block
492 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
493 required: get_option('linux_aio'),
494 kwargs: static_kwargs)
496 linux_io_uring = not_found
497 if not get_option('linux_io_uring').auto() or have_block
498 linux_io_uring = dependency('liburing', version: '>=0.3',
499 required: get_option('linux_io_uring'),
500 method: 'pkg-config', kwargs: static_kwargs)
503 if not get_option('libnfs').auto() or have_block
504 libnfs = dependency('libnfs', version: '>=1.9.3',
505 required: get_option('libnfs'),
506 method: 'pkg-config', kwargs: static_kwargs)
511 #include <sys/types.h>
512 #ifdef CONFIG_LIBATTR
513 #include <attr/xattr.h>
515 #include <sys/xattr.h>
517 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
520 have_old_libattr = false
521 if get_option('attr').allowed()
522 if cc.links(libattr_test)
523 libattr = declare_dependency()
525 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
526 required: get_option('attr'),
527 kwargs: static_kwargs)
528 if libattr.found() and not \
529 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
531 if get_option('attr').enabled()
532 error('could not link libattr')
534 warning('could not link libattr, disabling')
537 have_old_libattr = libattr.found()
542 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
543 if cocoa.found() and get_option('sdl').enabled()
544 error('Cocoa and SDL cannot be enabled at the same time')
546 if cocoa.found() and get_option('gtk').enabled()
547 error('Cocoa and GTK+ cannot be enabled at the same time')
551 if not get_option('seccomp').auto() or have_system or have_tools
552 seccomp = dependency('libseccomp', version: '>=2.3.0',
553 required: get_option('seccomp'),
554 method: 'pkg-config', kwargs: static_kwargs)
557 libcap_ng = not_found
558 if not get_option('cap_ng').auto() or have_system or have_tools
559 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
560 required: get_option('cap_ng'),
561 kwargs: static_kwargs)
563 if libcap_ng.found() and not cc.links('''
567 capng_capability_to_name(CAPNG_EFFECTIVE);
569 }''', dependencies: libcap_ng)
570 libcap_ng = not_found
571 if get_option('cap_ng').enabled()
572 error('could not link libcap-ng')
574 warning('could not link libcap-ng, disabling')
578 if get_option('xkbcommon').auto() and not have_system and not have_tools
579 xkbcommon = not_found
581 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
582 method: 'pkg-config', kwargs: static_kwargs)
586 if not get_option('vde').auto() or have_system or have_tools
587 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
588 required: get_option('vde'),
589 kwargs: static_kwargs)
591 if vde.found() and not cc.links('''
592 #include <libvdeplug.h>
595 struct vde_open_args a = {0, 0, 0};
599 }''', dependencies: vde)
601 if get_option('cap_ng').enabled()
602 error('could not link libvdeplug')
604 warning('could not link libvdeplug, disabling')
609 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
610 pulse = dependency('libpulse', required: get_option('pa'),
611 method: 'pkg-config', kwargs: static_kwargs)
614 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
615 alsa = dependency('alsa', required: get_option('alsa'),
616 method: 'pkg-config', kwargs: static_kwargs)
619 if not get_option('jack').auto() or have_system
620 jack = dependency('jack', required: get_option('jack'),
621 method: 'pkg-config', kwargs: static_kwargs)
624 spice_protocol = not_found
625 if not get_option('spice_protocol').auto() or have_system
626 spice_protocol = dependency('spice-protocol', version: '>=0.12.3',
627 required: get_option('spice_protocol'),
628 method: 'pkg-config', kwargs: static_kwargs)
631 if not get_option('spice').auto() or have_system
632 spice = dependency('spice-server', version: '>=0.12.5',
633 required: get_option('spice'),
634 method: 'pkg-config', kwargs: static_kwargs)
636 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
638 rt = cc.find_library('rt', required: false)
641 if not get_option('libiscsi').auto() or have_block
642 libiscsi = dependency('libiscsi', version: '>=1.9.0',
643 required: get_option('libiscsi'),
644 method: 'pkg-config', kwargs: static_kwargs)
647 if not get_option('zstd').auto() or have_block
648 zstd = dependency('libzstd', version: '>=1.4.0',
649 required: get_option('zstd'),
650 method: 'pkg-config', kwargs: static_kwargs)
654 have_vhost_user_gpu = have_tools and targetos == 'linux' and pixman.found()
655 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
656 virgl = dependency('virglrenderer',
657 method: 'pkg-config',
658 required: get_option('virglrenderer'),
659 kwargs: static_kwargs)
662 if not get_option('curl').auto() or have_block
663 curl = dependency('libcurl', version: '>=7.29.0',
664 method: 'pkg-config',
665 required: get_option('curl'),
666 kwargs: static_kwargs)
669 if targetos == 'linux' and (have_system or have_tools)
670 libudev = dependency('libudev',
671 method: 'pkg-config',
672 required: get_option('libudev'),
673 kwargs: static_kwargs)
676 mpathlibs = [libudev]
677 mpathpersist = not_found
678 mpathpersist_new_api = false
679 if targetos == 'linux' and have_tools and get_option('mpath').allowed()
680 mpath_test_source_new = '''
682 #include <mpath_persist.h>
683 unsigned mpath_mx_alloc_len = 1024;
685 static struct config *multipath_conf;
686 extern struct udev *udev;
687 extern struct config *get_multipath_config(void);
688 extern void put_multipath_config(struct config *conf);
690 struct config *get_multipath_config(void) { return multipath_conf; }
691 void put_multipath_config(struct config *conf) { }
694 multipath_conf = mpath_lib_init();
697 mpath_test_source_old = '''
699 #include <mpath_persist.h>
700 unsigned mpath_mx_alloc_len = 1024;
703 struct udev *udev = udev_new();
704 mpath_lib_init(udev);
707 libmpathpersist = cc.find_library('mpathpersist',
708 required: get_option('mpath'),
709 kwargs: static_kwargs)
710 if libmpathpersist.found()
711 mpathlibs += libmpathpersist
713 mpathlibs += cc.find_library('devmapper',
714 required: get_option('mpath'),
715 kwargs: static_kwargs)
717 mpathlibs += cc.find_library('multipath',
718 required: get_option('mpath'),
719 kwargs: static_kwargs)
720 foreach lib: mpathlibs
726 if mpathlibs.length() == 0
727 msg = 'Dependencies missing for libmpathpersist'
728 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
729 mpathpersist = declare_dependency(dependencies: mpathlibs)
730 mpathpersist_new_api = true
731 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
732 mpathpersist = declare_dependency(dependencies: mpathlibs)
734 msg = 'Cannot detect libmpathpersist API'
736 if not mpathpersist.found()
737 if get_option('mpath').enabled()
740 warning(msg + ', disabling')
748 if have_system and get_option('curses').allowed()
750 #if defined(__APPLE__) || defined(__OpenBSD__)
751 #define _XOPEN_SOURCE_EXTENDED 1
758 setlocale(LC_ALL, "");
760 addwstr(L"wide chars\n");
762 add_wch(WACS_DEGREE);
766 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
767 foreach curses_dep : curses_dep_list
768 if not curses.found()
769 curses = dependency(curses_dep,
771 method: 'pkg-config',
772 kwargs: static_kwargs)
775 msg = get_option('curses').enabled() ? 'curses library not found' : ''
776 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
778 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
779 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
781 msg = 'curses package not usable'
785 if not curses.found()
786 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
787 if targetos != 'windows' and not has_curses_h
788 message('Trying with /usr/include/ncursesw')
789 curses_compile_args += ['-I/usr/include/ncursesw']
790 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
793 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
794 foreach curses_libname : curses_libname_list
795 libcurses = cc.find_library(curses_libname,
797 kwargs: static_kwargs)
799 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
800 curses = declare_dependency(compile_args: curses_compile_args,
801 dependencies: [libcurses])
804 msg = 'curses library not usable'
810 if get_option('iconv').allowed()
811 foreach link_args : [ ['-liconv'], [] ]
812 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
813 # We need to use libiconv if available because mixing libiconv's headers with
814 # the system libc does not work.
815 # However, without adding glib to the dependencies -L/usr/local/lib will not be
816 # included in the command line and libiconv will not be found.
820 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
821 return conv != (iconv_t) -1;
822 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
823 iconv = declare_dependency(link_args: link_args, dependencies: glib)
828 if curses.found() and not iconv.found()
829 if get_option('iconv').enabled()
830 error('iconv not available')
832 msg = 'iconv required for curses UI but not available'
835 if not curses.found() and msg != ''
836 if get_option('curses').enabled()
839 warning(msg + ', disabling')
845 if not get_option('brlapi').auto() or have_system
846 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
847 required: get_option('brlapi'),
848 kwargs: static_kwargs)
849 if brlapi.found() and not cc.links('''
852 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
854 if get_option('brlapi').enabled()
855 error('could not link brlapi')
857 warning('could not link brlapi, disabling')
863 if not get_option('sdl').auto() or (have_system and not cocoa.found())
864 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
865 sdl_image = not_found
868 # work around 2.0.8 bug
869 sdl = declare_dependency(compile_args: '-Wno-undef',
871 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
872 method: 'pkg-config', kwargs: static_kwargs)
874 if get_option('sdl_image').enabled()
875 error('sdl-image required, but SDL was @0@'.format(
876 get_option('sdl').disabled() ? 'disabled' : 'not found'))
878 sdl_image = not_found
882 if not get_option('rbd').auto() or have_block
883 librados = cc.find_library('rados', required: get_option('rbd'),
884 kwargs: static_kwargs)
885 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
886 required: get_option('rbd'),
887 kwargs: static_kwargs)
888 if librados.found() and librbd.found()
891 #include <rbd/librbd.h>
894 rados_create(&cluster, NULL);
895 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
899 }''', dependencies: [librbd, librados])
900 rbd = declare_dependency(dependencies: [librbd, librados])
901 elif get_option('rbd').enabled()
902 error('librbd >= 1.12.0 required')
904 warning('librbd >= 1.12.0 not found, disabling')
909 glusterfs = not_found
910 glusterfs_ftruncate_has_stat = false
911 glusterfs_iocb_has_stat = false
912 if not get_option('glusterfs').auto() or have_block
913 glusterfs = dependency('glusterfs-api', version: '>=3',
914 required: get_option('glusterfs'),
915 method: 'pkg-config', kwargs: static_kwargs)
917 glusterfs_ftruncate_has_stat = cc.links('''
918 #include <glusterfs/api/glfs.h>
923 /* new glfs_ftruncate() passes two additional args */
924 return glfs_ftruncate(NULL, 0, NULL, NULL);
926 ''', dependencies: glusterfs)
927 glusterfs_iocb_has_stat = cc.links('''
928 #include <glusterfs/api/glfs.h>
930 /* new glfs_io_cbk() passes two additional glfs_stat structs */
932 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
938 glfs_io_cbk iocb = &glusterfs_iocb;
939 iocb(NULL, 0 , NULL, NULL, NULL);
942 ''', dependencies: glusterfs)
947 if not get_option('libssh').auto() or have_block
948 libssh = dependency('libssh', version: '>=0.8.7',
949 method: 'pkg-config',
950 required: get_option('libssh'),
951 kwargs: static_kwargs)
955 if not get_option('bzip2').auto() or have_block
956 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
957 required: get_option('bzip2'),
958 kwargs: static_kwargs)
959 if libbzip2.found() and not cc.links('''
961 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
963 if get_option('bzip2').enabled()
964 error('could not link libbzip2')
966 warning('could not link libbzip2, disabling')
972 if not get_option('lzfse').auto() or have_block
973 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
974 required: get_option('lzfse'),
975 kwargs: static_kwargs)
977 if liblzfse.found() and not cc.links('''
979 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
981 if get_option('lzfse').enabled()
982 error('could not link liblzfse')
984 warning('could not link liblzfse, disabling')
989 if get_option('oss').allowed() and have_system
990 if not cc.has_header('sys/soundcard.h')
992 elif targetos == 'netbsd'
993 oss = cc.find_library('ossaudio', required: get_option('oss'),
994 kwargs: static_kwargs)
996 oss = declare_dependency()
1000 if get_option('oss').enabled()
1001 error('OSS not found')
1006 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
1007 if cc.has_header('dsound.h')
1008 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
1011 if not dsound.found()
1012 if get_option('dsound').enabled()
1013 error('DirectSound not found')
1018 coreaudio = not_found
1019 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
1020 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
1021 required: get_option('coreaudio'))
1025 if not get_option('opengl').auto() or have_system or have_vhost_user_gpu
1026 epoxy = dependency('epoxy', method: 'pkg-config',
1027 required: get_option('opengl'), kwargs: static_kwargs)
1028 if cc.has_header('epoxy/egl.h', dependencies: epoxy)
1030 elif get_option('opengl').enabled()
1031 error('epoxy/egl.h not found')
1035 if (have_system or have_tools) and (virgl.found() or opengl.found())
1036 gbm = dependency('gbm', method: 'pkg-config', required: false,
1037 kwargs: static_kwargs)
1039 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and gbm.found()
1042 gnutls_crypto = not_found
1043 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1044 # For general TLS support our min gnutls matches
1045 # that implied by our platform support matrix
1047 # For the crypto backends, we look for a newer
1050 # Version 3.6.8 is needed to get XTS
1051 # Version 3.6.13 is needed to get PBKDF
1052 # Version 3.6.14 is needed to get HW accelerated XTS
1054 # If newer enough gnutls isn't available, we can
1055 # still use a different crypto backend to satisfy
1056 # the platform support requirements
1057 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1058 method: 'pkg-config',
1060 kwargs: static_kwargs)
1061 if gnutls_crypto.found()
1062 gnutls = gnutls_crypto
1064 # Our min version if all we need is TLS
1065 gnutls = dependency('gnutls', version: '>=3.5.18',
1066 method: 'pkg-config',
1067 required: get_option('gnutls'),
1068 kwargs: static_kwargs)
1072 # We prefer use of gnutls for crypto, unless the options
1073 # explicitly asked for nettle or gcrypt.
1075 # If gnutls isn't available for crypto, then we'll prefer
1076 # gcrypt over nettle for performance reasons.
1081 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1082 error('Only one of gcrypt & nettle can be enabled')
1085 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1086 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1087 gnutls_crypto = not_found
1090 if not gnutls_crypto.found()
1091 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1092 gcrypt = dependency('libgcrypt', version: '>=1.8',
1093 method: 'config-tool',
1094 required: get_option('gcrypt'),
1095 kwargs: static_kwargs)
1096 # Debian has removed -lgpg-error from libgcrypt-config
1097 # as it "spreads unnecessary dependencies" which in
1098 # turn breaks static builds...
1099 if gcrypt.found() and enable_static
1100 gcrypt = declare_dependency(dependencies: [
1102 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
1105 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1106 nettle = dependency('nettle', version: '>=3.4',
1107 method: 'pkg-config',
1108 required: get_option('nettle'),
1109 kwargs: static_kwargs)
1110 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1119 if not get_option('gtk').auto() or (have_system and not cocoa.found())
1120 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1121 method: 'pkg-config',
1122 required: get_option('gtk'),
1123 kwargs: static_kwargs)
1125 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1126 method: 'pkg-config',
1128 kwargs: static_kwargs)
1129 gtk = declare_dependency(dependencies: [gtk, gtkx11])
1131 if not get_option('vte').auto() or have_system
1132 vte = dependency('vte-2.91',
1133 method: 'pkg-config',
1134 required: get_option('vte'),
1135 kwargs: static_kwargs)
1142 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
1143 kwargs: static_kwargs)
1146 if get_option('png').allowed() and have_system
1147 png = dependency('libpng', required: get_option('png'),
1148 method: 'pkg-config', kwargs: static_kwargs)
1153 if get_option('vnc').allowed() and have_system
1154 vnc = declare_dependency() # dummy dependency
1155 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1156 method: 'pkg-config', kwargs: static_kwargs)
1157 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1158 required: get_option('vnc_sasl'),
1159 kwargs: static_kwargs)
1161 sasl = declare_dependency(dependencies: sasl,
1162 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1167 if not get_option('auth_pam').auto() or have_system
1168 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1169 required: get_option('auth_pam'),
1170 kwargs: static_kwargs)
1172 if pam.found() and not cc.links('''
1174 #include <security/pam_appl.h>
1176 const char *service_name = "qemu";
1177 const char *user = "frank";
1178 const struct pam_conv pam_conv = { 0 };
1179 pam_handle_t *pamh = NULL;
1180 pam_start(service_name, user, &pam_conv, &pamh);
1182 }''', dependencies: pam)
1184 if get_option('auth_pam').enabled()
1185 error('could not link libpam')
1187 warning('could not link libpam, disabling')
1192 if not get_option('snappy').auto() or have_system
1193 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1194 required: get_option('snappy'),
1195 kwargs: static_kwargs)
1197 if snappy.found() and not linker.links('''
1198 #include <snappy-c.h>
1199 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1201 if get_option('snappy').enabled()
1202 error('could not link libsnappy')
1204 warning('could not link libsnappy, disabling')
1209 if not get_option('lzo').auto() or have_system
1210 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1211 required: get_option('lzo'),
1212 kwargs: static_kwargs)
1214 if lzo.found() and not cc.links('''
1215 #include <lzo/lzo1x.h>
1216 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1218 if get_option('lzo').enabled()
1219 error('could not link liblzo2')
1221 warning('could not link liblzo2, disabling')
1226 if not get_option('numa').auto() or have_system or have_tools
1227 numa = cc.find_library('numa', has_headers: ['numa.h'],
1228 required: get_option('numa'),
1229 kwargs: static_kwargs)
1231 if numa.found() and not cc.links('''
1233 int main(void) { return numa_available(); }
1234 ''', dependencies: numa)
1236 if get_option('numa').enabled()
1237 error('could not link numa')
1239 warning('could not link numa, disabling')
1244 if not get_option('rdma').auto() or have_system
1245 libumad = cc.find_library('ibumad', required: get_option('rdma'))
1246 rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'],
1247 required: get_option('rdma'),
1248 kwargs: static_kwargs),
1249 cc.find_library('ibverbs', required: get_option('rdma'),
1250 kwargs: static_kwargs),
1252 rdma = declare_dependency(dependencies: rdma_libs)
1253 foreach lib: rdma_libs
1261 if get_option('xen').enabled() or (get_option('xen').auto() and have_system)
1262 xencontrol = dependency('xencontrol', required: false,
1263 method: 'pkg-config', kwargs: static_kwargs)
1264 if xencontrol.found()
1265 xen_pc = declare_dependency(version: xencontrol.version(),
1268 # disabler: true makes xen_pc.found() return false if any is not found
1269 dependency('xenstore', required: false,
1270 method: 'pkg-config', kwargs: static_kwargs,
1272 dependency('xenforeignmemory', required: false,
1273 method: 'pkg-config', kwargs: static_kwargs,
1275 dependency('xengnttab', required: false,
1276 method: 'pkg-config', kwargs: static_kwargs,
1278 dependency('xenevtchn', required: false,
1279 method: 'pkg-config', kwargs: static_kwargs,
1281 dependency('xendevicemodel', required: false,
1282 method: 'pkg-config', kwargs: static_kwargs,
1284 # optional, no "disabler: true"
1285 dependency('xentoolcore', required: false,
1286 method: 'pkg-config', kwargs: static_kwargs)])
1292 xen_tests = [ '4.11.0', '4.10.0', '4.9.0', '4.8.0', '4.7.1', '4.6.0', '4.5.0', '4.2.0' ]
1294 '4.11.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
1295 '4.10.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
1296 '4.9.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1297 '4.8.0': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1298 '4.7.1': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1299 '4.6.0': [ 'xenstore', 'xenctrl' ],
1300 '4.5.0': [ 'xenstore', 'xenctrl' ],
1301 '4.2.0': [ 'xenstore', 'xenctrl' ],
1304 foreach ver: xen_tests
1305 # cache the various library tests to avoid polluting the logs
1307 foreach l: xen_libs[ver]
1308 if l not in xen_deps
1309 xen_deps += { l: cc.find_library(l, required: false) }
1311 xen_test_deps += xen_deps[l]
1314 # Use -D to pick just one of the test programs in scripts/xen-detect.c
1315 xen_version = ver.split('.')
1316 xen_ctrl_version = xen_version[0] + \
1317 ('0' + xen_version[1]).substring(-2) + \
1318 ('0' + xen_version[2]).substring(-2)
1319 if cc.links(files('scripts/xen-detect.c'),
1320 args: '-DCONFIG_XEN_CTRL_INTERFACE_VERSION=' + xen_ctrl_version,
1321 dependencies: xen_test_deps)
1322 xen = declare_dependency(version: ver, dependencies: xen_test_deps)
1328 accelerators += 'CONFIG_XEN'
1329 elif get_option('xen').enabled()
1330 error('could not compile and link Xen test program')
1333 have_xen_pci_passthrough = get_option('xen_pci_passthrough') \
1334 .require(xen.found(),
1335 error_message: 'Xen PCI passthrough requested but Xen not enabled') \
1336 .require(targetos == 'linux',
1337 error_message: 'Xen PCI passthrough not available on this platform') \
1342 if not get_option('smartcard').auto() or have_system
1343 cacard = dependency('libcacard', required: get_option('smartcard'),
1344 version: '>=2.5.1', method: 'pkg-config',
1345 kwargs: static_kwargs)
1349 u2f = dependency('u2f-emu', required: get_option('u2f'),
1350 method: 'pkg-config',
1351 kwargs: static_kwargs)
1353 usbredir = not_found
1354 if not get_option('usb_redir').auto() or have_system
1355 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1356 version: '>=0.6', method: 'pkg-config',
1357 kwargs: static_kwargs)
1360 if not get_option('libusb').auto() or have_system
1361 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1362 version: '>=1.0.13', method: 'pkg-config',
1363 kwargs: static_kwargs)
1367 if not get_option('libpmem').auto() or have_system
1368 libpmem = dependency('libpmem', required: get_option('libpmem'),
1369 method: 'pkg-config', kwargs: static_kwargs)
1371 libdaxctl = not_found
1372 if not get_option('libdaxctl').auto() or have_system
1373 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1374 version: '>=57', method: 'pkg-config',
1375 kwargs: static_kwargs)
1379 tasn1 = dependency('libtasn1',
1380 method: 'pkg-config',
1381 kwargs: static_kwargs)
1383 keyutils = dependency('libkeyutils', required: false,
1384 method: 'pkg-config', kwargs: static_kwargs)
1386 has_gettid = cc.has_function('gettid')
1389 selinux = dependency('libselinux',
1390 required: get_option('selinux'),
1391 method: 'pkg-config', kwargs: static_kwargs)
1396 if get_option('malloc') == 'system'
1398 get_option('malloc_trim').allowed() and \
1399 cc.links('''#include <malloc.h>
1400 int main(void) { malloc_trim(0); return 0; }''')
1402 has_malloc_trim = false
1403 malloc = cc.find_library(get_option('malloc'), required: true)
1405 if not has_malloc_trim and get_option('malloc_trim').enabled()
1406 if get_option('malloc') == 'system'
1407 error('malloc_trim not available on this platform.')
1409 error('malloc_trim not available with non-libc memory allocator')
1413 # Check whether the glibc provides statx()
1415 gnu_source_prefix = '''
1420 statx_test = gnu_source_prefix + '''
1421 #include <sys/stat.h>
1423 struct statx statxbuf;
1424 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1428 has_statx = cc.links(statx_test)
1430 # Check whether statx() provides mount ID information
1432 statx_mnt_id_test = gnu_source_prefix + '''
1433 #include <sys/stat.h>
1435 struct statx statxbuf;
1436 statx(0, "", 0, STATX_BASIC_STATS | STATX_MNT_ID, &statxbuf);
1437 return statxbuf.stx_mnt_id;
1440 has_statx_mnt_id = cc.links(statx_mnt_id_test)
1442 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
1443 .require(targetos == 'linux',
1444 error_message: 'vhost_user_blk_server requires linux') \
1445 .require('CONFIG_VHOST_USER' in config_host,
1446 error_message: 'vhost_user_blk_server requires vhost-user support') \
1447 .disable_auto_if(not have_system) \
1450 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1451 error('Cannot enable fuse-lseek while fuse is disabled')
1454 fuse = dependency('fuse3', required: get_option('fuse'),
1455 version: '>=3.1', method: 'pkg-config',
1456 kwargs: static_kwargs)
1458 fuse_lseek = not_found
1459 if get_option('fuse_lseek').allowed()
1460 if fuse.version().version_compare('>=3.8')
1462 fuse_lseek = declare_dependency()
1463 elif get_option('fuse_lseek').enabled()
1465 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1467 error('fuse-lseek requires libfuse, which was not found')
1473 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1474 if libbpf.found() and not cc.links('''
1475 #include <bpf/libbpf.h>
1478 bpf_object__destroy_skeleton(NULL);
1480 }''', dependencies: libbpf)
1482 if get_option('bpf').enabled()
1483 error('libbpf skeleton test failed')
1485 warning('libbpf skeleton test failed, disabling')
1493 audio_drivers_selected = []
1495 audio_drivers_available = {
1496 'alsa': alsa.found(),
1497 'coreaudio': coreaudio.found(),
1498 'dsound': dsound.found(),
1499 'jack': jack.found(),
1501 'pa': pulse.found(),
1504 foreach k, v: audio_drivers_available
1505 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1508 # Default to native drivers first, OSS second, SDL third
1509 audio_drivers_priority = \
1510 [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
1511 (targetos == 'linux' ? [] : [ 'sdl' ])
1512 audio_drivers_default = []
1513 foreach k: audio_drivers_priority
1514 if audio_drivers_available[k]
1515 audio_drivers_default += k
1519 foreach k: get_option('audio_drv_list')
1521 audio_drivers_selected += audio_drivers_default
1522 elif not audio_drivers_available[k]
1523 error('Audio driver "@0@" not available.'.format(k))
1525 audio_drivers_selected += k
1529 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1530 '"' + '", "'.join(audio_drivers_selected) + '", ')
1532 if get_option('cfi')
1534 # Check for dependency on LTO
1535 if not get_option('b_lto')
1536 error('Selected Control-Flow Integrity but LTO is disabled')
1538 if config_host.has_key('CONFIG_MODULES')
1539 error('Selected Control-Flow Integrity is not compatible with modules')
1541 # Check for cfi flags. CFI requires LTO so we can't use
1542 # get_supported_arguments, but need a more complex "compiles" which allows
1544 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1545 args: ['-flto', '-fsanitize=cfi-icall'] )
1546 cfi_flags += '-fsanitize=cfi-icall'
1548 error('-fsanitize=cfi-icall is not supported by the compiler')
1550 if cc.compiles('int main () { return 0; }',
1551 name: '-fsanitize-cfi-icall-generalize-pointers',
1552 args: ['-flto', '-fsanitize=cfi-icall',
1553 '-fsanitize-cfi-icall-generalize-pointers'] )
1554 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1556 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1558 if get_option('cfi_debug')
1559 if cc.compiles('int main () { return 0; }',
1560 name: '-fno-sanitize-trap=cfi-icall',
1561 args: ['-flto', '-fsanitize=cfi-icall',
1562 '-fno-sanitize-trap=cfi-icall'] )
1563 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1565 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1568 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1569 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1572 have_host_block_device = (targetos != 'darwin' or
1573 cc.has_header('IOKit/storage/IOMedia.h'))
1575 # FIXME enable_modules shouldn't be necessary, but: https://github.com/mesonbuild/meson/issues/8333
1576 dbus_display = get_option('dbus_display') \
1577 .require(gio.version().version_compare('>=2.64'),
1578 error_message: '-display dbus requires glib>=2.64') \
1579 .require(enable_modules,
1580 error_message: '-display dbus requires --enable-modules') \
1581 .require(gdbus_codegen.found(),
1582 error_message: '-display dbus requires gdbus-codegen') \
1585 have_virtfs = get_option('virtfs') \
1586 .require(targetos == 'linux' or targetos == 'darwin',
1587 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
1588 .require(targetos == 'linux' or cc.has_function('pthread_fchdir_np'),
1589 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
1590 .require(targetos == 'darwin' or (libattr.found() and libcap_ng.found()),
1591 error_message: 'virtio-9p (virtfs) on Linux requires libcap-ng-devel and libattr-devel') \
1592 .disable_auto_if(not have_tools and not have_system) \
1595 have_virtfs_proxy_helper = targetos != 'darwin' and have_virtfs and have_tools
1597 foreach k : get_option('trace_backends')
1598 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1600 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1601 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
1603 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
1605 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1606 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1607 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1608 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1609 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1610 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1611 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1612 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1613 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1614 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1615 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1616 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1618 have_slirp_smbd = get_option('slirp_smbd') \
1619 .require(targetos != 'windows', error_message: 'Host smbd not supported on this platform.') \
1622 smbd_path = get_option('smbd')
1624 smbd_path = (targetos == 'solaris' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
1626 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
1629 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
1631 if get_option('module_upgrades') and not enable_modules
1632 error('Cannot enable module-upgrades as modules are not enabled')
1634 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
1636 config_host_data.set('CONFIG_ATTR', libattr.found())
1637 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
1638 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1639 config_host_data.set('CONFIG_COCOA', cocoa.found())
1640 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1641 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1642 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1643 config_host_data.set('CONFIG_LZO', lzo.found())
1644 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1645 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1646 config_host_data.set('CONFIG_CURL', curl.found())
1647 config_host_data.set('CONFIG_CURSES', curses.found())
1648 config_host_data.set('CONFIG_GBM', gbm.found())
1649 config_host_data.set('CONFIG_GIO', gio.found())
1650 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1651 if glusterfs.found()
1652 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1653 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1654 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1655 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1656 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1657 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1659 config_host_data.set('CONFIG_GTK', gtk.found())
1660 config_host_data.set('CONFIG_VTE', vte.found())
1661 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1662 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1663 config_host_data.set('CONFIG_EBPF', libbpf.found())
1664 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1665 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1666 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1667 config_host_data.set('CONFIG_LIBSSH', libssh.found())
1668 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1669 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1670 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1671 config_host_data.set('CONFIG_NUMA', numa.found())
1672 config_host_data.set('CONFIG_OPENGL', opengl.found())
1673 config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
1674 config_host_data.set('CONFIG_RBD', rbd.found())
1675 config_host_data.set('CONFIG_RDMA', rdma.found())
1676 config_host_data.set('CONFIG_SDL', sdl.found())
1677 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1678 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1679 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1680 config_host_data.set('CONFIG_TPM', have_tpm)
1681 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1682 config_host_data.set('CONFIG_VDE', vde.found())
1683 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1684 config_host_data.set('CONFIG_PNG', png.found())
1685 config_host_data.set('CONFIG_VNC', vnc.found())
1686 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1687 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1688 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1689 config_host_data.set('CONFIG_VTE', vte.found())
1690 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1691 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1692 config_host_data.set('CONFIG_GETTID', has_gettid)
1693 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1694 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1695 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1696 config_host_data.set('CONFIG_NETTLE', nettle.found())
1697 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1698 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1699 config_host_data.set('CONFIG_STATX', has_statx)
1700 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
1701 config_host_data.set('CONFIG_ZSTD', zstd.found())
1702 config_host_data.set('CONFIG_FUSE', fuse.found())
1703 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1704 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1705 if spice_protocol.found()
1706 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
1707 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
1708 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
1710 config_host_data.set('CONFIG_SPICE', spice.found())
1711 config_host_data.set('CONFIG_X11', x11.found())
1712 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
1713 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1714 config_host_data.set('CONFIG_SELINUX', selinux.found())
1715 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
1717 # protect from xen.version() having less than three components
1718 xen_version = xen.version().split('.') + ['0', '0']
1719 xen_ctrl_version = xen_version[0] + \
1720 ('0' + xen_version[1]).substring(-2) + \
1721 ('0' + xen_version[2]).substring(-2)
1722 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
1724 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1725 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1726 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1727 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1729 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1730 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1732 have_coroutine_pool = get_option('coroutine_pool')
1733 if get_option('debug_stack_usage') and have_coroutine_pool
1734 message('Disabling coroutine pool to measure stack usage')
1735 have_coroutine_pool = false
1737 config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool)
1738 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
1739 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
1740 config_host_data.set('CONFIG_GPROF', get_option('gprof'))
1741 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
1742 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
1743 config_host_data.set('CONFIG_REPLICATION', get_option('live_block_migration').allowed())
1746 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1747 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1748 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1749 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1750 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1751 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1752 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1753 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1754 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1757 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1758 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1759 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1760 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1761 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1762 # Note that we need to specify prefix: here to avoid incorrectly
1763 # thinking that Windows has posix_memalign()
1764 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
1765 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
1766 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
1767 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
1768 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1769 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1770 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
1771 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1772 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1773 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1774 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1775 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1776 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1777 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
1778 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1779 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1780 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1782 config_host_data.set('HAVE_IBV_ADVISE_MR',
1783 cc.has_function('ibv_advise_mr',
1785 prefix: '#include <infiniband/verbs.h>'))
1789 config_host_data.set('CONFIG_BYTESWAP_H',
1790 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1791 config_host_data.set('CONFIG_EPOLL_CREATE1',
1792 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1793 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1794 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1795 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1796 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1797 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1798 config_host_data.set('CONFIG_FIEMAP',
1799 cc.has_header('linux/fiemap.h') and
1800 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1801 config_host_data.set('CONFIG_GETRANDOM',
1802 cc.has_function('getrandom') and
1803 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1804 config_host_data.set('CONFIG_INOTIFY',
1805 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1806 config_host_data.set('CONFIG_INOTIFY1',
1807 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1808 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1809 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1810 prefix: '''#include <sys/endian.h>
1811 #include <sys/types.h>'''))
1812 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1813 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1814 config_host_data.set('CONFIG_RTNETLINK',
1815 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1816 config_host_data.set('CONFIG_SYSMACROS',
1817 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1818 config_host_data.set('HAVE_OPTRESET',
1819 cc.has_header_symbol('getopt.h', 'optreset'))
1820 config_host_data.set('HAVE_IPPROTO_MPTCP',
1821 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1824 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1825 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1826 prefix: '#include <signal.h>'))
1827 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1828 cc.has_member('struct stat', 'st_atim',
1829 prefix: '#include <sys/stat.h>'))
1832 config_host_data.set('CONFIG_IOVEC',
1833 cc.has_type('struct iovec',
1834 prefix: '#include <sys/uio.h>'))
1835 config_host_data.set('HAVE_UTMPX',
1836 cc.has_type('struct utmpx',
1837 prefix: '#include <utmpx.h>'))
1839 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1840 #include <sys/eventfd.h>
1841 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1842 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1845 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1846 return fdatasync(0);
1848 #error Not supported
1852 has_madvise = cc.links(gnu_source_prefix + '''
1853 #include <sys/types.h>
1854 #include <sys/mman.h>
1856 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
1857 missing_madvise_proto = false
1859 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
1860 # but forget to prototype it. In this case, has_madvise will be true (the
1861 # test program links despite a compile warning). To detect the
1862 # missing-prototype case, we try again with a definitely-bogus prototype.
1863 # This will only compile if the system headers don't provide the prototype;
1864 # otherwise the conflicting prototypes will cause a compiler error.
1865 missing_madvise_proto = cc.links(gnu_source_prefix + '''
1866 #include <sys/types.h>
1867 #include <sys/mman.h>
1869 extern int madvise(int);
1870 int main(void) { return madvise(0); }''')
1872 config_host_data.set('CONFIG_MADVISE', has_madvise)
1873 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
1875 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1876 #include <sys/mman.h>
1877 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1878 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1880 #if !defined(AT_EMPTY_PATH)
1881 # error missing definition
1883 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1885 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1892 return pipe2(pipefd, O_CLOEXEC);
1894 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1895 #include <sys/mman.h>
1897 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1899 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
1900 #include <pthread.h>
1902 static void *f(void *p) { return NULL; }
1906 pthread_create(&thread, 0, f, 0);
1907 pthread_setname_np(thread, "QEMU");
1909 }''', dependencies: threads))
1910 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
1911 #include <pthread.h>
1913 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
1917 pthread_create(&thread, 0, f, 0);
1919 }''', dependencies: threads))
1920 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
1921 #include <pthread.h>
1926 pthread_condattr_t attr
1927 pthread_condattr_init(&attr);
1928 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
1930 }''', dependencies: threads))
1932 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1933 #include <sys/signalfd.h>
1935 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1936 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1944 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1945 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1949 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
1950 #include <sys/mman.h>
1951 int main(int argc, char *argv[]) {
1952 return mlockall(MCL_FUTURE);
1956 if get_option('l2tpv3').allowed() and have_system
1957 have_l2tpv3 = cc.has_type('struct mmsghdr',
1958 prefix: gnu_source_prefix + '''
1959 #include <sys/socket.h>
1960 #include <linux/ip.h>''')
1962 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
1965 if get_option('netmap').allowed() and have_system
1966 have_netmap = cc.compiles('''
1967 #include <inttypes.h>
1969 #include <net/netmap.h>
1970 #include <net/netmap_user.h>
1971 #if (NETMAP_API < 11) || (NETMAP_API > 15)
1974 int main(void) { return 0; }''')
1975 if not have_netmap and get_option('netmap').enabled()
1976 error('Netmap headers not available')
1979 config_host_data.set('CONFIG_NETMAP', have_netmap)
1981 # Work around a system header bug with some kernel/XFS header
1982 # versions where they both try to define 'struct fsxattr':
1983 # xfs headers will not try to redefine structs from linux headers
1984 # if this macro is set.
1985 config_host_data.set('HAVE_FSXATTR', cc.links('''
1986 #include <linux/fs.h>
1992 # Some versions of Mac OS X incorrectly define SIZE_MAX
1993 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1996 int main(int argc, char *argv[]) {
1997 return printf("%zu", SIZE_MAX);
1998 }''', args: ['-Werror']))
2005 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2006 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2007 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2008 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2009 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2013 # See if 64-bit atomic operations are supported.
2014 # Note that without __atomic builtins, we can only
2015 # assume atomic loads/stores max at pointer size.
2016 config_host_data.set('CONFIG_ATOMIC64', cc.links(atomic_test.format('uint64_t')))
2018 has_int128 = cc.links('''
2028 config_host_data.set('CONFIG_INT128', has_int128)
2031 # "do we have 128-bit atomics which are handled inline and specifically not
2032 # via libatomic". The reason we can't use libatomic is documented in the
2033 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2034 has_atomic128 = cc.links(atomic_test.format('unsigned __int128'))
2036 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2038 if not has_atomic128
2039 has_cmpxchg128 = cc.links('''
2042 unsigned __int128 x = 0, y = 0;
2043 __sync_val_compare_and_swap_16(&x, y, x);
2048 config_host_data.set('CONFIG_CMPXCHG128', has_cmpxchg128)
2052 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2053 #include <sys/auxv.h>
2055 return getauxval(AT_HWCAP) == 0;
2058 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2059 #include <linux/usbdevice_fs.h>
2061 #ifndef USBDEVFS_GET_CAPABILITIES
2062 #error "USBDEVFS_GET_CAPABILITIES undefined"
2065 #ifndef USBDEVFS_DISCONNECT_CLAIM
2066 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2069 int main(void) { return 0; }'''))
2071 have_keyring = get_option('keyring') \
2072 .require(targetos == 'linux', error_message: 'keyring is only available on Linux') \
2073 .require(cc.compiles('''
2075 #include <asm/unistd.h>
2076 #include <linux/keyctl.h>
2077 #include <sys/syscall.h>
2080 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2081 }'''), error_message: 'keyctl syscall not available on this system').allowed()
2082 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2084 have_cpuid_h = cc.links('''
2087 unsigned a, b, c, d;
2088 unsigned max = __get_cpuid_max(0, 0);
2091 __cpuid(1, a, b, c, d);
2095 __cpuid_count(7, 0, a, b, c, d);
2100 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2102 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2103 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2104 .require(cc.links('''
2105 #pragma GCC push_options
2106 #pragma GCC target("avx2")
2108 #include <immintrin.h>
2109 static int bar(void *a) {
2110 __m256i x = *(__m256i *)a;
2111 return _mm256_testz_si256(x, x);
2113 int main(int argc, char *argv[]) { return bar(argv[0]); }
2114 '''), error_message: 'AVX2 not available').allowed())
2116 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2117 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2118 .require(cc.links('''
2119 #pragma GCC push_options
2120 #pragma GCC target("avx512f")
2122 #include <immintrin.h>
2123 static int bar(void *a) {
2124 __m512i x = *(__m512i *)a;
2125 return _mm512_test_epi64_mask(x, x);
2127 int main(int argc, char *argv[]) { return bar(argv[0]); }
2128 '''), error_message: 'AVX512F not available').allowed())
2130 have_pvrdma = get_option('pvrdma') \
2131 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
2132 .require(cc.compiles('''
2137 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2140 }'''), error_message: 'PVRDMA requires mremap').allowed()
2143 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.compiles('''
2144 #include <infiniband/verbs.h>
2148 struct ibv_pd *pd = NULL;
2154 mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2160 if get_option('membarrier').disabled()
2161 have_membarrier = false
2162 elif targetos == 'windows'
2163 have_membarrier = true
2164 elif targetos == 'linux'
2165 have_membarrier = cc.compiles('''
2166 #include <linux/membarrier.h>
2167 #include <sys/syscall.h>
2171 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2172 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2176 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2177 .require(have_membarrier, error_message: 'membarrier system call not available') \
2180 have_afalg = get_option('crypto_afalg') \
2181 .require(cc.compiles(gnu_source_prefix + '''
2183 #include <sys/types.h>
2184 #include <sys/socket.h>
2185 #include <linux/if_alg.h>
2188 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2191 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2192 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2194 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2195 'linux/vm_sockets.h', 'AF_VSOCK',
2196 prefix: '#include <sys/socket.h>',
2200 have_vss_sdk = false # old xp/2003 SDK
2201 if targetos == 'windows' and link_language == 'cpp'
2202 have_vss = cxx.compiles('''
2203 #define __MIDL_user_allocate_free_DEFINED__
2205 int main(void) { return VSS_CTX_BACKUP; }''')
2206 have_vss_sdk = cxx.has_header('vscoordint.h')
2208 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2210 ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target
2212 arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
2213 foreach k, v: config_host
2214 if ignored.contains(k)
2216 elif arrays.contains(k)
2218 v = '"' + '", "'.join(v.split()) + '", '
2220 config_host_data.set(k, v)
2221 elif k.startswith('CONFIG_')
2222 config_host_data.set(k, v == 'y' ? 1 : v)
2226 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2227 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2228 if targetos == 'windows'
2229 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2235 }''', name: '_lock_file and _unlock_file'))
2238 ########################
2239 # Target configuration #
2240 ########################
2242 minikconf = find_program('scripts/minikconf.py')
2244 config_all_devices = {}
2245 config_all_disas = {}
2246 config_devices_mak_list = []
2247 config_devices_h = {}
2248 config_target_h = {}
2249 config_target_mak = {}
2252 'alpha' : ['CONFIG_ALPHA_DIS'],
2253 'arm' : ['CONFIG_ARM_DIS'],
2254 'avr' : ['CONFIG_AVR_DIS'],
2255 'cris' : ['CONFIG_CRIS_DIS'],
2256 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2257 'hppa' : ['CONFIG_HPPA_DIS'],
2258 'i386' : ['CONFIG_I386_DIS'],
2259 'x86_64' : ['CONFIG_I386_DIS'],
2260 'm68k' : ['CONFIG_M68K_DIS'],
2261 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2262 'mips' : ['CONFIG_MIPS_DIS'],
2263 'nios2' : ['CONFIG_NIOS2_DIS'],
2264 'or1k' : ['CONFIG_OPENRISC_DIS'],
2265 'ppc' : ['CONFIG_PPC_DIS'],
2266 'riscv' : ['CONFIG_RISCV_DIS'],
2267 'rx' : ['CONFIG_RX_DIS'],
2268 's390' : ['CONFIG_S390_DIS'],
2269 'sh4' : ['CONFIG_SH4_DIS'],
2270 'sparc' : ['CONFIG_SPARC_DIS'],
2271 'xtensa' : ['CONFIG_XTENSA_DIS'],
2273 if link_language == 'cpp'
2275 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
2276 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
2277 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
2281 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2283 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2284 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2285 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2286 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2287 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2288 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2289 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
2290 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2291 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2292 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2293 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
2294 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
2295 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
2297 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2299 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2300 actual_target_dirs = []
2302 foreach target : target_dirs
2303 config_target = { 'TARGET_NAME': target.split('-')[0] }
2304 if target.endswith('linux-user')
2305 if targetos != 'linux'
2309 error('Target @0@ is only available on a Linux host'.format(target))
2311 config_target += { 'CONFIG_LINUX_USER': 'y' }
2312 elif target.endswith('bsd-user')
2313 if 'CONFIG_BSD' not in config_host
2317 error('Target @0@ is only available on a BSD host'.format(target))
2319 config_target += { 'CONFIG_BSD_USER': 'y' }
2320 elif target.endswith('softmmu')
2321 config_target += { 'CONFIG_SOFTMMU': 'y' }
2323 if target.endswith('-user')
2325 'CONFIG_USER_ONLY': 'y',
2326 'CONFIG_QEMU_INTERP_PREFIX':
2327 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
2332 foreach sym: accelerators
2333 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2334 config_target += { sym: 'y' }
2335 config_all += { sym: 'y' }
2336 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
2337 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
2339 if target in modular_tcg
2340 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2342 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2344 accel_kconfig += [ sym + '=y' ]
2347 if accel_kconfig.length() == 0
2351 error('No accelerator available for target @0@'.format(target))
2354 actual_target_dirs += target
2355 config_target += keyval.load('configs/targets' / target + '.mak')
2356 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
2358 if 'TARGET_NEED_FDT' in config_target
2359 fdt_required += target
2363 if 'TARGET_BASE_ARCH' not in config_target
2364 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2366 if 'TARGET_ABI_DIR' not in config_target
2367 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2369 if 'TARGET_BIG_ENDIAN' not in config_target
2370 config_target += {'TARGET_BIG_ENDIAN': 'n'}
2373 foreach k, v: disassemblers
2374 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
2376 config_target += { sym: 'y' }
2377 config_all_disas += { sym: 'y' }
2382 config_target_data = configuration_data()
2383 foreach k, v: config_target
2384 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2386 elif ignored.contains(k)
2388 elif k == 'TARGET_BASE_ARCH'
2389 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2390 # not used to select files from sourcesets.
2391 config_target_data.set('TARGET_' + v.to_upper(), 1)
2392 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
2393 config_target_data.set_quoted(k, v)
2395 config_target_data.set(k, 1)
2397 config_target_data.set(k, 0)
2399 config_target_data.set(k, v)
2402 config_target_data.set('QEMU_ARCH',
2403 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
2404 config_target_h += {target: configure_file(output: target + '-config-target.h',
2405 configuration: config_target_data)}
2407 if target.endswith('-softmmu')
2408 config_input = meson.get_external_property(target, 'default')
2409 config_devices_mak = target + '-config-devices.mak'
2410 config_devices_mak = configure_file(
2411 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2412 output: config_devices_mak,
2413 depfile: config_devices_mak + '.d',
2415 command: [minikconf,
2416 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2417 config_devices_mak, '@DEPFILE@', '@INPUT@',
2418 host_kconfig, accel_kconfig,
2419 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
2421 config_devices_data = configuration_data()
2422 config_devices = keyval.load(config_devices_mak)
2423 foreach k, v: config_devices
2424 config_devices_data.set(k, 1)
2426 config_devices_mak_list += config_devices_mak
2427 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2428 configuration: config_devices_data)}
2429 config_target += config_devices
2430 config_all_devices += config_devices
2432 config_target_mak += {target: config_target}
2434 target_dirs = actual_target_dirs
2436 # This configuration is used to build files that are shared by
2437 # multiple binaries, and then extracted out of the "common"
2438 # static_library target.
2440 # We do not use all_sources()/all_dependencies(), because it would
2441 # build literally all source files, including devices only used by
2442 # targets that are not built for this compilation. The CONFIG_ALL
2443 # pseudo symbol replaces it.
2445 config_all += config_all_devices
2446 config_all += config_host
2447 config_all += config_all_disas
2449 'CONFIG_XEN': xen.found(),
2450 'CONFIG_SOFTMMU': have_system,
2451 'CONFIG_USER_ONLY': have_user,
2455 target_configs_h = []
2456 foreach target: target_dirs
2457 target_configs_h += config_target_h[target]
2458 target_configs_h += config_devices_h.get(target, [])
2460 genh += custom_target('config-poison.h',
2461 input: [target_configs_h],
2462 output: 'config-poison.h',
2464 command: [find_program('scripts/make-config-poison.sh'),
2471 capstone = not_found
2472 capstone_opt = get_option('capstone')
2473 if capstone_opt in ['enabled', 'auto', 'system']
2474 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
2475 capstone = dependency('capstone', version: '>=4.0',
2476 kwargs: static_kwargs, method: 'pkg-config',
2477 required: capstone_opt == 'system' or
2478 capstone_opt == 'enabled' and not have_internal)
2480 # Some versions of capstone have broken pkg-config file
2481 # that reports a wrong -I path, causing the #include to
2482 # fail later. If the system has such a broken version
2484 if capstone.found() and not cc.compiles('#include <capstone.h>',
2485 dependencies: [capstone])
2486 capstone = not_found
2487 if capstone_opt == 'system'
2488 error('system capstone requested, it does not appear to work')
2493 capstone_opt = 'system'
2495 capstone_opt = 'internal'
2497 capstone_opt = 'disabled'
2500 if capstone_opt == 'internal'
2501 capstone_data = configuration_data()
2502 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
2504 capstone_files = files(
2506 'capstone/MCInst.c',
2507 'capstone/MCInstrDesc.c',
2508 'capstone/MCRegisterInfo.c',
2509 'capstone/SStream.c',
2513 if 'CONFIG_ARM_DIS' in config_all_disas
2514 capstone_data.set('CAPSTONE_HAS_ARM', '1')
2515 capstone_files += files(
2516 'capstone/arch/ARM/ARMDisassembler.c',
2517 'capstone/arch/ARM/ARMInstPrinter.c',
2518 'capstone/arch/ARM/ARMMapping.c',
2519 'capstone/arch/ARM/ARMModule.c'
2523 # FIXME: This config entry currently depends on a c++ compiler.
2524 # Which is needed for building libvixl, but not for capstone.
2525 if 'CONFIG_ARM_A64_DIS' in config_all_disas
2526 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
2527 capstone_files += files(
2528 'capstone/arch/AArch64/AArch64BaseInfo.c',
2529 'capstone/arch/AArch64/AArch64Disassembler.c',
2530 'capstone/arch/AArch64/AArch64InstPrinter.c',
2531 'capstone/arch/AArch64/AArch64Mapping.c',
2532 'capstone/arch/AArch64/AArch64Module.c'
2536 if 'CONFIG_PPC_DIS' in config_all_disas
2537 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
2538 capstone_files += files(
2539 'capstone/arch/PowerPC/PPCDisassembler.c',
2540 'capstone/arch/PowerPC/PPCInstPrinter.c',
2541 'capstone/arch/PowerPC/PPCMapping.c',
2542 'capstone/arch/PowerPC/PPCModule.c'
2546 if 'CONFIG_S390_DIS' in config_all_disas
2547 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
2548 capstone_files += files(
2549 'capstone/arch/SystemZ/SystemZDisassembler.c',
2550 'capstone/arch/SystemZ/SystemZInstPrinter.c',
2551 'capstone/arch/SystemZ/SystemZMapping.c',
2552 'capstone/arch/SystemZ/SystemZModule.c',
2553 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
2557 if 'CONFIG_I386_DIS' in config_all_disas
2558 capstone_data.set('CAPSTONE_HAS_X86', 1)
2559 capstone_files += files(
2560 'capstone/arch/X86/X86Disassembler.c',
2561 'capstone/arch/X86/X86DisassemblerDecoder.c',
2562 'capstone/arch/X86/X86ATTInstPrinter.c',
2563 'capstone/arch/X86/X86IntelInstPrinter.c',
2564 'capstone/arch/X86/X86InstPrinterCommon.c',
2565 'capstone/arch/X86/X86Mapping.c',
2566 'capstone/arch/X86/X86Module.c'
2570 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
2573 # FIXME: There does not seem to be a way to completely replace the c_args
2574 # that come from add_project_arguments() -- we can only add to them.
2575 # So: disable all warnings with a big hammer.
2578 # Include all configuration defines via a header file, which will wind up
2579 # as a dependency on the object file, and thus changes here will result
2581 '-include', 'capstone-defs.h'
2584 libcapstone = static_library('capstone',
2585 build_by_default: false,
2586 sources: capstone_files,
2587 c_args: capstone_cargs,
2588 include_directories: 'capstone/include')
2589 capstone = declare_dependency(link_with: libcapstone,
2590 include_directories: 'capstone/include/capstone')
2594 slirp_opt = 'disabled'
2596 slirp_opt = get_option('slirp')
2597 if slirp_opt in ['enabled', 'auto', 'system']
2598 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2599 slirp = dependency('slirp', kwargs: static_kwargs,
2600 method: 'pkg-config',
2601 required: slirp_opt == 'system' or
2602 slirp_opt == 'enabled' and not have_internal)
2604 slirp_opt = 'system'
2606 slirp_opt = 'internal'
2608 slirp_opt = 'disabled'
2611 if slirp_opt == 'internal'
2613 if targetos == 'windows'
2614 slirp_deps = cc.find_library('iphlpapi')
2615 elif targetos == 'darwin'
2616 slirp_deps = cc.find_library('resolv')
2618 slirp_conf = configuration_data()
2619 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2620 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2621 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2622 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2623 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2625 'slirp/src/arp_table.c',
2626 'slirp/src/bootp.c',
2627 'slirp/src/cksum.c',
2628 'slirp/src/dhcpv6.c',
2629 'slirp/src/dnssearch.c',
2631 'slirp/src/ip6_icmp.c',
2632 'slirp/src/ip6_input.c',
2633 'slirp/src/ip6_output.c',
2634 'slirp/src/ip_icmp.c',
2635 'slirp/src/ip_input.c',
2636 'slirp/src/ip_output.c',
2640 'slirp/src/ndp_table.c',
2642 'slirp/src/slirp.c',
2643 'slirp/src/socket.c',
2644 'slirp/src/state.c',
2645 'slirp/src/stream.c',
2646 'slirp/src/tcp_input.c',
2647 'slirp/src/tcp_output.c',
2648 'slirp/src/tcp_subr.c',
2649 'slirp/src/tcp_timer.c',
2654 'slirp/src/version.c',
2655 'slirp/src/vmstate.c',
2659 input : 'slirp/src/libslirp-version.h.in',
2660 output : 'libslirp-version.h',
2661 configuration: slirp_conf)
2663 slirp_inc = include_directories('slirp', 'slirp/src')
2664 libslirp = static_library('slirp',
2665 build_by_default: false,
2666 sources: slirp_files,
2667 c_args: slirp_cargs,
2668 include_directories: slirp_inc)
2669 slirp = declare_dependency(link_with: libslirp,
2670 dependencies: slirp_deps,
2671 include_directories: slirp_inc)
2675 # For CFI, we need to compile slirp as a static library together with qemu.
2676 # This is because we register slirp functions as callbacks for QEMU Timers.
2677 # When using a system-wide shared libslirp, the type information for the
2678 # callback is missing and the timer call produces a false positive with CFI.
2680 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2681 # with control-flow integrity.
2682 if get_option('cfi') and slirp_opt == 'system'
2683 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2684 + ' Please configure with --enable-slirp=git')
2689 fdt_opt = get_option('fdt')
2690 if fdt_opt in ['enabled', 'auto', 'system']
2691 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2692 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2693 required: fdt_opt == 'system' or
2694 fdt_opt == 'enabled' and not have_internal)
2695 if fdt.found() and cc.links('''
2697 #include <libfdt_env.h>
2698 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2701 elif fdt_opt == 'system'
2702 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2704 fdt_opt = 'internal'
2706 fdt_opt = 'disabled'
2710 if fdt_opt == 'internal'
2713 'dtc/libfdt/fdt_ro.c',
2714 'dtc/libfdt/fdt_wip.c',
2715 'dtc/libfdt/fdt_sw.c',
2716 'dtc/libfdt/fdt_rw.c',
2717 'dtc/libfdt/fdt_strerror.c',
2718 'dtc/libfdt/fdt_empty_tree.c',
2719 'dtc/libfdt/fdt_addresses.c',
2720 'dtc/libfdt/fdt_overlay.c',
2721 'dtc/libfdt/fdt_check.c',
2724 fdt_inc = include_directories('dtc/libfdt')
2725 libfdt = static_library('fdt',
2726 build_by_default: false,
2728 include_directories: fdt_inc)
2729 fdt = declare_dependency(link_with: libfdt,
2730 include_directories: fdt_inc)
2733 fdt_opt = 'disabled'
2735 if not fdt.found() and fdt_required.length() > 0
2736 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2739 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2740 config_host_data.set('CONFIG_FDT', fdt.found())
2741 config_host_data.set('CONFIG_SLIRP', slirp.found())
2743 #####################
2744 # Generated sources #
2745 #####################
2747 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2749 hxtool = find_program('scripts/hxtool')
2750 shaderinclude = find_program('scripts/shaderinclude.pl')
2751 qapi_gen = find_program('scripts/qapi-gen.py')
2752 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2753 meson.current_source_dir() / 'scripts/qapi/commands.py',
2754 meson.current_source_dir() / 'scripts/qapi/common.py',
2755 meson.current_source_dir() / 'scripts/qapi/error.py',
2756 meson.current_source_dir() / 'scripts/qapi/events.py',
2757 meson.current_source_dir() / 'scripts/qapi/expr.py',
2758 meson.current_source_dir() / 'scripts/qapi/gen.py',
2759 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2760 meson.current_source_dir() / 'scripts/qapi/parser.py',
2761 meson.current_source_dir() / 'scripts/qapi/schema.py',
2762 meson.current_source_dir() / 'scripts/qapi/source.py',
2763 meson.current_source_dir() / 'scripts/qapi/types.py',
2764 meson.current_source_dir() / 'scripts/qapi/visit.py',
2765 meson.current_source_dir() / 'scripts/qapi/common.py',
2766 meson.current_source_dir() / 'scripts/qapi-gen.py'
2770 python, files('scripts/tracetool.py'),
2771 '--backend=' + ','.join(get_option('trace_backends'))
2773 tracetool_depends = files(
2774 'scripts/tracetool/backend/log.py',
2775 'scripts/tracetool/backend/__init__.py',
2776 'scripts/tracetool/backend/dtrace.py',
2777 'scripts/tracetool/backend/ftrace.py',
2778 'scripts/tracetool/backend/simple.py',
2779 'scripts/tracetool/backend/syslog.py',
2780 'scripts/tracetool/backend/ust.py',
2781 'scripts/tracetool/format/ust_events_c.py',
2782 'scripts/tracetool/format/ust_events_h.py',
2783 'scripts/tracetool/format/__init__.py',
2784 'scripts/tracetool/format/d.py',
2785 'scripts/tracetool/format/simpletrace_stap.py',
2786 'scripts/tracetool/format/c.py',
2787 'scripts/tracetool/format/h.py',
2788 'scripts/tracetool/format/log_stap.py',
2789 'scripts/tracetool/format/stap.py',
2790 'scripts/tracetool/__init__.py',
2791 'scripts/tracetool/transform.py',
2792 'scripts/tracetool/vcpu.py'
2795 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2796 meson.current_source_dir(),
2797 config_host['PKGVERSION'], meson.project_version()]
2798 qemu_version = custom_target('qemu-version.h',
2799 output: 'qemu-version.h',
2800 command: qemu_version_cmd,
2802 build_by_default: true,
2803 build_always_stale: true)
2804 genh += qemu_version
2808 ['qemu-options.hx', 'qemu-options.def'],
2809 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2813 ['hmp-commands.hx', 'hmp-commands.h'],
2814 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2817 foreach d : hx_headers
2818 hxdep += custom_target(d[1],
2822 build_by_default: true, # to be removed when added to a target
2823 command: [hxtool, '-h', '@INPUT0@'])
2831 authz_ss = ss.source_set()
2832 blockdev_ss = ss.source_set()
2833 block_ss = ss.source_set()
2834 chardev_ss = ss.source_set()
2835 common_ss = ss.source_set()
2836 crypto_ss = ss.source_set()
2837 hwcore_ss = ss.source_set()
2838 io_ss = ss.source_set()
2839 qmp_ss = ss.source_set()
2840 qom_ss = ss.source_set()
2841 softmmu_ss = ss.source_set()
2842 specific_fuzz_ss = ss.source_set()
2843 specific_ss = ss.source_set()
2844 stub_ss = ss.source_set()
2845 trace_ss = ss.source_set()
2846 user_ss = ss.source_set()
2847 util_ss = ss.source_set()
2850 qtest_module_ss = ss.source_set()
2851 tcg_module_ss = ss.source_set()
2857 target_softmmu_arch = {}
2858 target_user_arch = {}
2864 # TODO: add each directory to the subdirs from its own meson.build, once
2866 trace_events_subdirs = [
2874 trace_events_subdirs += [ 'linux-user' ]
2877 trace_events_subdirs += [ 'bsd-user' ]
2880 trace_events_subdirs += [
2889 trace_events_subdirs += [
2903 'hw/block/dataplane',
2953 if have_system or have_user
2954 trace_events_subdirs += [
2972 vhost_user = not_found
2973 if targetos == 'linux' and 'CONFIG_VHOST_USER' in config_host
2974 libvhost_user = subproject('libvhost-user')
2975 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2978 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
2979 # that is filled in by qapi/.
2992 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2993 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2996 stub_ss = stub_ss.apply(config_all, strict: false)
2998 util_ss.add_all(trace_ss)
2999 util_ss = util_ss.apply(config_all, strict: false)
3000 libqemuutil = static_library('qemuutil',
3001 sources: util_ss.sources() + stub_ss.sources() + genh,
3002 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
3003 qemuutil = declare_dependency(link_with: libqemuutil,
3004 sources: genh + version_res)
3006 if have_system or have_user
3007 decodetree = generator(find_program('scripts/decodetree.py'),
3008 output: 'decode-@BASENAME@.c.inc',
3009 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3010 subdir('libdecnumber')
3027 if config_host_data.get('CONFIG_REPLICATION')
3028 block_ss.add(files('replication.c'))
3035 blockdev_ss.add(files(
3042 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3043 # os-win32.c does not
3044 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
3045 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
3048 common_ss.add(files('cpus-common.c'))
3052 common_ss.add(capstone)
3053 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
3055 # Work around a gcc bug/misfeature wherein constant propagation looks
3057 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3058 # to guess that a const variable is always zero. Without lto, this is
3059 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
3060 # without lto, not even the alias is required -- we simply use different
3061 # declarations in different compilation units.
3062 pagevary = files('page-vary-common.c')
3063 if get_option('b_lto')
3064 pagevary_flags = ['-fno-lto']
3065 if get_option('cfi')
3066 pagevary_flags += '-fno-sanitize=cfi-icall'
3068 pagevary = static_library('page-vary-common', sources: pagevary + genh,
3069 c_args: pagevary_flags)
3070 pagevary = declare_dependency(link_with: pagevary)
3072 common_ss.add(pagevary)
3073 specific_ss.add(files('page-vary.c'))
3081 subdir('semihosting')
3089 common_user_inc = []
3091 subdir('common-user')
3093 subdir('linux-user')
3095 # needed for fuzzing binaries
3096 subdir('tests/qtest/libqos')
3097 subdir('tests/qtest/fuzz')
3100 tcg_real_module_ss = ss.source_set()
3101 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3102 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3103 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3104 'tcg': tcg_real_module_ss }}
3106 ########################
3107 # Library dependencies #
3108 ########################
3110 modinfo_collect = find_program('scripts/modinfo-collect.py')
3111 modinfo_generate = find_program('scripts/modinfo-generate.py')
3116 foreach d, list : modules
3117 foreach m, module_ss : list
3118 if enable_modules and targetos != 'windows'
3119 module_ss = module_ss.apply(config_all, strict: false)
3120 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3121 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3127 if module_ss.sources() != []
3128 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3129 # input. Sources can be used multiple times but objects are
3130 # unique when it comes to lookup in compile_commands.json.
3131 # Depnds on a mesion version with
3132 # https://github.com/mesonbuild/meson/pull/8900
3133 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3134 output: d + '-' + m + '.modinfo',
3135 input: module_ss.sources() + genh,
3137 command: [modinfo_collect, module_ss.sources()])
3141 block_ss.add_all(module_ss)
3143 softmmu_ss.add_all(module_ss)
3149 foreach d, list : target_modules
3150 foreach m, module_ss : list
3151 if enable_modules and targetos != 'windows'
3152 foreach target : target_dirs
3153 if target.endswith('-softmmu')
3154 config_target = config_target_mak[target]
3155 config_target += config_host
3156 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3157 c_args = ['-DNEED_CPU_H',
3158 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3159 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3160 target_module_ss = module_ss.apply(config_target, strict: false)
3161 if target_module_ss.sources() != []
3162 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3163 sl = static_library(module_name,
3164 [genh, target_module_ss.sources()],
3165 dependencies: [modulecommon, target_module_ss.dependencies()],
3166 include_directories: target_inc,
3170 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3171 modinfo_files += custom_target(module_name + '.modinfo',
3172 output: module_name + '.modinfo',
3173 input: target_module_ss.sources() + genh,
3175 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3180 specific_ss.add_all(module_ss)
3186 modinfo_src = custom_target('modinfo.c',
3187 output: 'modinfo.c',
3188 input: modinfo_files,
3189 command: [modinfo_generate, '@INPUT@'],
3191 modinfo_lib = static_library('modinfo', modinfo_src)
3192 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
3193 softmmu_ss.add(modinfo_dep)
3196 nm = find_program('nm')
3197 undefsym = find_program('scripts/undefsym.py')
3198 block_syms = custom_target('block.syms', output: 'block.syms',
3199 input: [libqemuutil, block_mods],
3201 command: [undefsym, nm, '@INPUT@'])
3202 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3203 input: [libqemuutil, softmmu_mods],
3205 command: [undefsym, nm, '@INPUT@'])
3207 qom_ss = qom_ss.apply(config_host, strict: false)
3208 libqom = static_library('qom', qom_ss.sources() + genh,
3209 dependencies: [qom_ss.dependencies()],
3212 qom = declare_dependency(link_whole: libqom)
3214 authz_ss = authz_ss.apply(config_host, strict: false)
3215 libauthz = static_library('authz', authz_ss.sources() + genh,
3216 dependencies: [authz_ss.dependencies()],
3218 build_by_default: false)
3220 authz = declare_dependency(link_whole: libauthz,
3223 crypto_ss = crypto_ss.apply(config_host, strict: false)
3224 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3225 dependencies: [crypto_ss.dependencies()],
3227 build_by_default: false)
3229 crypto = declare_dependency(link_whole: libcrypto,
3230 dependencies: [authz, qom])
3232 io_ss = io_ss.apply(config_host, strict: false)
3233 libio = static_library('io', io_ss.sources() + genh,
3234 dependencies: [io_ss.dependencies()],
3235 link_with: libqemuutil,
3237 build_by_default: false)
3239 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3241 libmigration = static_library('migration', sources: migration_files + genh,
3243 build_by_default: false)
3244 migration = declare_dependency(link_with: libmigration,
3245 dependencies: [zlib, qom, io])
3246 softmmu_ss.add(migration)
3248 block_ss = block_ss.apply(config_host, strict: false)
3249 libblock = static_library('block', block_ss.sources() + genh,
3250 dependencies: block_ss.dependencies(),
3251 link_depends: block_syms,
3253 build_by_default: false)
3255 block = declare_dependency(link_whole: [libblock],
3256 link_args: '@block.syms',
3257 dependencies: [crypto, io])
3259 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
3260 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3261 dependencies: blockdev_ss.dependencies(),
3263 build_by_default: false)
3265 blockdev = declare_dependency(link_whole: [libblockdev],
3266 dependencies: [block])
3268 qmp_ss = qmp_ss.apply(config_host, strict: false)
3269 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3270 dependencies: qmp_ss.dependencies(),
3272 build_by_default: false)
3274 qmp = declare_dependency(link_whole: [libqmp])
3276 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3278 dependencies: chardev_ss.dependencies(),
3279 build_by_default: false)
3281 chardev = declare_dependency(link_whole: libchardev)
3283 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
3284 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3286 build_by_default: false)
3287 hwcore = declare_dependency(link_whole: libhwcore)
3288 common_ss.add(hwcore)
3294 emulator_modules = []
3295 foreach m : block_mods + softmmu_mods
3296 emulator_modules += shared_module(m.name(),
3297 build_by_default: true,
3301 install_dir: qemu_moddir)
3304 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3305 common_ss.add(qom, qemuutil)
3307 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
3308 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3310 common_all = common_ss.apply(config_all, strict: false)
3311 common_all = static_library('common',
3312 build_by_default: false,
3313 sources: common_all.sources() + genh,
3314 include_directories: common_user_inc,
3315 implicit_include_directories: false,
3316 dependencies: common_all.dependencies(),
3319 feature_to_c = find_program('scripts/feature_to_c.sh')
3321 if targetos == 'darwin'
3322 entitlement = find_program('scripts/entitlement.sh')
3326 foreach target : target_dirs
3327 config_target = config_target_mak[target]
3328 target_name = config_target['TARGET_NAME']
3329 target_base_arch = config_target['TARGET_BASE_ARCH']
3330 arch_srcs = [config_target_h[target]]
3332 c_args = ['-DNEED_CPU_H',
3333 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3334 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3335 link_args = emulator_link_args
3337 config_target += config_host
3338 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3339 if targetos == 'linux'
3340 target_inc += include_directories('linux-headers', is_system: true)
3342 if target.endswith('-softmmu')
3343 qemu_target_name = 'qemu-system-' + target_name
3344 target_type='system'
3345 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3346 arch_srcs += t.sources()
3347 arch_deps += t.dependencies()
3349 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3350 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3351 arch_srcs += hw.sources()
3352 arch_deps += hw.dependencies()
3354 arch_srcs += config_devices_h[target]
3355 link_args += ['@block.syms', '@qemu.syms']
3357 abi = config_target['TARGET_ABI_DIR']
3359 target_inc += common_user_inc
3360 qemu_target_name = 'qemu-' + target_name
3361 if target_base_arch in target_user_arch
3362 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3363 arch_srcs += t.sources()
3364 arch_deps += t.dependencies()
3366 if 'CONFIG_LINUX_USER' in config_target
3367 base_dir = 'linux-user'
3369 if 'CONFIG_BSD_USER' in config_target
3370 base_dir = 'bsd-user'
3371 target_inc += include_directories('bsd-user/' / targetos)
3372 target_inc += include_directories('bsd-user/host/' / host_arch)
3373 dir = base_dir / abi
3374 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3376 target_inc += include_directories(
3380 if 'CONFIG_LINUX_USER' in config_target
3381 dir = base_dir / abi
3382 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3383 if config_target.has_key('TARGET_SYSTBL_ABI')
3385 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3386 extra_args : config_target['TARGET_SYSTBL_ABI'])
3391 if 'TARGET_XML_FILES' in config_target
3392 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3393 output: target + '-gdbstub-xml.c',
3394 input: files(config_target['TARGET_XML_FILES'].split()),
3395 command: [feature_to_c, '@INPUT@'],
3397 arch_srcs += gdbstub_xml
3400 t = target_arch[target_base_arch].apply(config_target, strict: false)
3401 arch_srcs += t.sources()
3402 arch_deps += t.dependencies()
3404 target_common = common_ss.apply(config_target, strict: false)
3405 objects = common_all.extract_objects(target_common.sources())
3406 deps = target_common.dependencies()
3408 target_specific = specific_ss.apply(config_target, strict: false)
3409 arch_srcs += target_specific.sources()
3410 arch_deps += target_specific.dependencies()
3412 lib = static_library('qemu-' + target,
3413 sources: arch_srcs + genh,
3414 dependencies: arch_deps,
3416 include_directories: target_inc,
3418 build_by_default: false,
3421 if target.endswith('-softmmu')
3423 'name': 'qemu-system-' + target_name,
3424 'win_subsystem': 'console',
3425 'sources': files('softmmu/main.c'),
3428 if targetos == 'windows' and (sdl.found() or gtk.found())
3430 'name': 'qemu-system-' + target_name + 'w',
3431 'win_subsystem': 'windows',
3432 'sources': files('softmmu/main.c'),
3436 if get_option('fuzzing')
3437 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3439 'name': 'qemu-fuzz-' + target_name,
3440 'win_subsystem': 'console',
3441 'sources': specific_fuzz.sources(),
3442 'dependencies': specific_fuzz.dependencies(),
3447 'name': 'qemu-' + target_name,
3448 'win_subsystem': 'console',
3454 exe_name = exe['name']
3455 if targetos == 'darwin'
3456 exe_name += '-unsigned'
3459 emulator = executable(exe_name, exe['sources'],
3462 dependencies: arch_deps + deps + exe['dependencies'],
3463 objects: lib.extract_all_objects(recursive: true),
3464 link_language: link_language,
3465 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3466 link_args: link_args,
3467 win_subsystem: exe['win_subsystem'])
3469 if targetos == 'darwin'
3470 icon = 'pc-bios/qemu.rsrc'
3471 build_input = [emulator, files(icon)]
3473 get_option('bindir') / exe_name,
3474 meson.current_source_dir() / icon
3476 if 'CONFIG_HVF' in config_target
3477 entitlements = 'accel/hvf/entitlements.plist'
3478 build_input += files(entitlements)
3479 install_input += meson.current_source_dir() / entitlements
3482 emulators += {exe['name'] : custom_target(exe['name'],
3484 output: exe['name'],
3485 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3488 meson.add_install_script(entitlement, '--install',
3489 get_option('bindir') / exe['name'],
3492 emulators += {exe['name']: emulator}
3497 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3498 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3499 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3500 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3502 custom_target(exe['name'] + stp['ext'],
3503 input: trace_events_all,
3504 output: exe['name'] + stp['ext'],
3505 install: stp['install'],
3506 install_dir: get_option('datadir') / 'systemtap/tapset',
3508 tracetool, '--group=all', '--format=' + stp['fmt'],
3509 '--binary=' + stp['bin'],
3510 '--target-name=' + target_name,
3511 '--target-type=' + target_type,
3512 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3513 '@INPUT@', '@OUTPUT@'
3515 depend_files: tracetool_depends)
3521 # Other build targets
3523 if 'CONFIG_PLUGIN' in config_host
3524 install_headers('include/qemu/qemu-plugin.h')
3529 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3530 # when we don't build tools or system
3531 if xkbcommon.found()
3532 # used for the update-keymaps target, so include rules even if !have_tools
3533 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3534 dependencies: [qemuutil, xkbcommon], install: have_tools)
3538 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3539 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3540 qemu_io = executable('qemu-io', files('qemu-io.c'),
3541 dependencies: [block, qemuutil], install: true)
3542 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3543 dependencies: [blockdev, qemuutil, gnutls, selinux],
3546 subdir('storage-daemon')
3547 subdir('contrib/rdmacm-mux')
3548 subdir('contrib/elf2dmp')
3550 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3551 dependencies: qemuutil,
3554 if 'CONFIG_VHOST_USER' in config_host
3555 subdir('contrib/vhost-user-blk')
3556 subdir('contrib/vhost-user-gpu')
3557 subdir('contrib/vhost-user-input')
3558 subdir('contrib/vhost-user-scsi')
3561 if targetos == 'linux'
3562 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3563 dependencies: [qemuutil, libcap_ng],
3565 install_dir: get_option('libexecdir'))
3567 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3568 dependencies: [authz, crypto, io, qom, qemuutil,
3569 libcap_ng, mpathpersist],
3574 subdir('contrib/ivshmem-client')
3575 subdir('contrib/ivshmem-server')
3588 if host_machine.system() == 'windows'
3590 find_program('scripts/nsis.py'),
3592 get_option('prefix'),
3593 meson.current_source_dir(),
3596 '-DDISPLAYVERSION=' + meson.project_version(),
3599 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3602 nsis_cmd += '-DCONFIG_GTK=y'
3605 nsis = custom_target('nsis',
3606 output: 'qemu-setup-' + meson.project_version() + '.exe',
3607 input: files('qemu.nsi'),
3608 build_always_stale: true,
3609 command: nsis_cmd + ['@INPUT@'])
3610 alias_target('installer', nsis)
3613 #########################
3614 # Configuration summary #
3615 #########################
3619 summary_info += {'Install prefix': get_option('prefix')}
3620 summary_info += {'BIOS directory': qemu_datadir}
3621 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
3622 summary_info += {'binary directory': get_option('bindir')}
3623 summary_info += {'library directory': get_option('libdir')}
3624 summary_info += {'module directory': qemu_moddir}
3625 summary_info += {'libexec directory': get_option('libexecdir')}
3626 summary_info += {'include directory': get_option('includedir')}
3627 summary_info += {'config directory': get_option('sysconfdir')}
3628 if targetos != 'windows'
3629 summary_info += {'local state directory': get_option('localstatedir')}
3630 summary_info += {'Manual directory': get_option('mandir')}
3632 summary_info += {'local state directory': 'queried at runtime'}
3634 summary_info += {'Doc directory': get_option('docdir')}
3635 summary_info += {'Build directory': meson.current_build_dir()}
3636 summary_info += {'Source path': meson.current_source_dir()}
3637 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3638 summary(summary_info, bool_yn: true, section: 'Directories')
3642 summary_info += {'git': config_host['GIT']}
3643 summary_info += {'make': config_host['MAKE']}
3644 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3645 summary_info += {'sphinx-build': sphinx_build}
3646 if config_host.has_key('HAVE_GDB_BIN')
3647 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3649 summary_info += {'iasl': iasl}
3650 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3651 if targetos == 'windows' and have_ga
3652 summary_info += {'wixl': wixl}
3654 if slirp_opt != 'disabled' and have_system
3655 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
3657 summary(summary_info, bool_yn: true, section: 'Host binaries')
3659 # Configurable features
3661 summary_info += {'Documentation': build_docs}
3662 summary_info += {'system-mode emulation': have_system}
3663 summary_info += {'user-mode emulation': have_user}
3664 summary_info += {'block layer': have_block}
3665 summary_info += {'Install blobs': get_option('install_blobs')}
3666 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3667 if config_host.has_key('CONFIG_MODULES')
3668 summary_info += {'alternative module path': get_option('module_upgrades')}
3670 summary_info += {'fuzzing support': get_option('fuzzing')}
3672 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3674 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3675 if 'simple' in get_option('trace_backends')
3676 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3678 summary_info += {'D-Bus display': dbus_display}
3679 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
3680 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
3681 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
3682 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
3683 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
3684 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
3685 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
3686 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3687 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
3688 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
3689 summary_info += {'build guest agent': have_ga}
3690 summary(summary_info, bool_yn: true, section: 'Configurable features')
3692 # Compilation information
3694 summary_info += {'host CPU': cpu}
3695 summary_info += {'host endianness': build_machine.endian()}
3696 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3697 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3698 if link_language == 'cpp'
3699 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3701 summary_info += {'C++ compiler': false}
3703 if targetos == 'darwin'
3704 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3706 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3707 + ['-O' + get_option('optimization')]
3708 + (get_option('debug') ? ['-g'] : []))}
3709 if link_language == 'cpp'
3710 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3711 + ['-O' + get_option('optimization')]
3712 + (get_option('debug') ? ['-g'] : []))}
3714 if targetos == 'darwin'
3715 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args')
3716 + ['-O' + get_option('optimization')]
3717 + (get_option('debug') ? ['-g'] : []))}
3719 link_args = get_option(link_language + '_link_args')
3720 if link_args.length() > 0
3721 summary_info += {'LDFLAGS': ' '.join(link_args)}
3723 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_cflags)}
3724 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_cxxflags)}
3725 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_objcflags)}
3726 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
3727 summary_info += {'profiler': get_option('profiler')}
3728 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3729 summary_info += {'PIE': get_option('b_pie')}
3730 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3731 summary_info += {'malloc trim support': has_malloc_trim}
3732 summary_info += {'membarrier': have_membarrier}
3733 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
3734 summary_info += {'mutex debugging': get_option('debug_mutex')}
3735 summary_info += {'memory allocator': get_option('malloc')}
3736 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
3737 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
3738 summary_info += {'gprof enabled': get_option('gprof')}
3739 summary_info += {'gcov': get_option('b_coverage')}
3740 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3741 summary_info += {'CFI support': get_option('cfi')}
3742 if get_option('cfi')
3743 summary_info += {'CFI debug support': get_option('cfi_debug')}
3745 summary_info += {'strip binaries': get_option('strip')}
3746 summary_info += {'sparse': sparse}
3747 summary_info += {'mingw32 support': targetos == 'windows'}
3749 # snarf the cross-compilation information for tests
3750 foreach target: target_dirs
3751 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3752 if fs.exists(tcg_mak)
3753 config_cross_tcg = keyval.load(tcg_mak)
3754 target = config_cross_tcg['TARGET_NAME']
3756 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3757 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3758 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3759 elif 'CROSS_CC_GUEST' in config_cross_tcg
3760 summary_info += {target + ' tests'
3761 : config_cross_tcg['CROSS_CC_GUEST'] }
3766 summary(summary_info, bool_yn: true, section: 'Compilation')
3768 # Targets and accelerators
3771 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3772 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3773 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3774 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3775 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3776 summary_info += {'Xen support': xen.found()}
3778 summary_info += {'xen ctrl version': xen.version()}
3781 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3782 if config_all.has_key('CONFIG_TCG')
3783 if get_option('tcg_interpreter')
3784 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
3786 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3788 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3789 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3791 summary_info += {'target list': ' '.join(target_dirs)}
3793 summary_info += {'default devices': get_option('default_devices')}
3794 summary_info += {'out of process emulation': multiprocess_allowed}
3796 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3800 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3801 summary_info += {'coroutine pool': have_coroutine_pool}
3803 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3804 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3805 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
3806 summary_info += {'VirtFS support': have_virtfs}
3807 summary_info += {'build virtiofs daemon': have_virtiofsd}
3808 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
3809 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
3810 summary_info += {'bochs support': get_option('bochs').allowed()}
3811 summary_info += {'cloop support': get_option('cloop').allowed()}
3812 summary_info += {'dmg support': get_option('dmg').allowed()}
3813 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
3814 summary_info += {'vdi support': get_option('vdi').allowed()}
3815 summary_info += {'vvfat support': get_option('vvfat').allowed()}
3816 summary_info += {'qed support': get_option('qed').allowed()}
3817 summary_info += {'parallels support': get_option('parallels').allowed()}
3818 summary_info += {'FUSE exports': fuse}
3820 summary(summary_info, bool_yn: true, section: 'Block layer support')
3824 summary_info += {'TLS priority': get_option('tls_priority')}
3825 summary_info += {'GNUTLS support': gnutls}
3827 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3829 summary_info += {'libgcrypt': gcrypt}
3830 summary_info += {'nettle': nettle}
3832 summary_info += {' XTS': xts != 'private'}
3834 summary_info += {'AF_ALG support': have_afalg}
3835 summary_info += {'rng-none': get_option('rng_none')}
3836 summary_info += {'Linux keyring': have_keyring}
3837 summary(summary_info, bool_yn: true, section: 'Crypto')
3841 if targetos == 'darwin'
3842 summary_info += {'Cocoa support': cocoa}
3844 summary_info += {'SDL support': sdl}
3845 summary_info += {'SDL image support': sdl_image}
3846 summary_info += {'GTK support': gtk}
3847 summary_info += {'pixman': pixman}
3848 summary_info += {'VTE support': vte}
3849 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3850 summary_info += {'libtasn1': tasn1}
3851 summary_info += {'PAM': pam}
3852 summary_info += {'iconv support': iconv}
3853 summary_info += {'curses support': curses}
3854 summary_info += {'virgl support': virgl}
3855 summary_info += {'curl support': curl}
3856 summary_info += {'Multipath support': mpathpersist}
3857 summary_info += {'PNG support': png}
3858 summary_info += {'VNC support': vnc}
3860 summary_info += {'VNC SASL support': sasl}
3861 summary_info += {'VNC JPEG support': jpeg}
3863 if targetos not in ['darwin', 'haiku', 'windows']
3864 summary_info += {'OSS support': oss}
3865 elif targetos == 'darwin'
3866 summary_info += {'CoreAudio support': coreaudio}
3867 elif targetos == 'windows'
3868 summary_info += {'DirectSound support': dsound}
3870 if targetos == 'linux'
3871 summary_info += {'ALSA support': alsa}
3872 summary_info += {'PulseAudio support': pulse}
3874 summary_info += {'JACK support': jack}
3875 summary_info += {'brlapi support': brlapi}
3876 summary_info += {'vde support': vde}
3877 summary_info += {'netmap support': have_netmap}
3878 summary_info += {'l2tpv3 support': have_l2tpv3}
3879 summary_info += {'Linux AIO support': libaio}
3880 summary_info += {'Linux io_uring support': linux_io_uring}
3881 summary_info += {'ATTR/XATTR support': libattr}
3882 summary_info += {'RDMA support': rdma}
3883 summary_info += {'PVRDMA support': have_pvrdma}
3884 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3885 summary_info += {'libcap-ng support': libcap_ng}
3886 summary_info += {'bpf support': libbpf}
3887 summary_info += {'spice protocol support': spice_protocol}
3888 if spice_protocol.found()
3889 summary_info += {' spice server support': spice}
3891 summary_info += {'rbd support': rbd}
3892 summary_info += {'smartcard support': cacard}
3893 summary_info += {'U2F support': u2f}
3894 summary_info += {'libusb': libusb}
3895 summary_info += {'usb net redir': usbredir}
3896 summary_info += {'OpenGL support (epoxy)': opengl}
3897 summary_info += {'GBM': gbm}
3898 summary_info += {'libiscsi support': libiscsi}
3899 summary_info += {'libnfs support': libnfs}
3900 if targetos == 'windows'
3902 summary_info += {'QGA VSS support': have_qga_vss}
3905 summary_info += {'seccomp support': seccomp}
3906 summary_info += {'GlusterFS support': glusterfs}
3907 summary_info += {'TPM support': have_tpm}
3908 summary_info += {'libssh support': libssh}
3909 summary_info += {'lzo support': lzo}
3910 summary_info += {'snappy support': snappy}
3911 summary_info += {'bzip2 support': libbzip2}
3912 summary_info += {'lzfse support': liblzfse}
3913 summary_info += {'zstd support': zstd}
3914 summary_info += {'NUMA host support': numa}
3915 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3916 summary_info += {'libpmem support': libpmem}
3917 summary_info += {'libdaxctl support': libdaxctl}
3918 summary_info += {'libudev': libudev}
3919 # Dummy dependency, keep .found()
3920 summary_info += {'FUSE lseek': fuse_lseek.found()}
3921 summary_info += {'selinux': selinux}
3922 summary(summary_info, bool_yn: true, section: 'Dependencies')
3924 if not supported_cpus.contains(cpu)
3926 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3928 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3929 message('The QEMU project intends to remove support for this host CPU in')
3930 message('a future release if nobody volunteers to maintain it and to')
3931 message('provide a build host for our continuous integration setup.')
3932 message('configure has succeeded and you can continue to build, but')
3933 message('if you care about QEMU on this platform you should contact')
3934 message('us upstream at qemu-devel@nongnu.org.')
3937 if not supported_oses.contains(targetos)
3939 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3941 message('Host OS ' + targetos + 'support is not currently maintained.')
3942 message('The QEMU project intends to remove support for this host OS in')
3943 message('a future release if nobody volunteers to maintain it and to')
3944 message('provide a build host for our continuous integration setup.')
3945 message('configure has succeeded and you can continue to build, but')
3946 message('if you care about QEMU on this platform you should contact')
3947 message('us upstream at qemu-devel@nongnu.org.')