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', 'optimization=2'],
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 if get_option('block_drv_ro_whitelist') == ''
1598 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
1600 config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
1601 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
1603 if get_option('block_drv_rw_whitelist') == ''
1604 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
1606 config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
1607 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
1610 foreach k : get_option('trace_backends')
1611 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1613 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1614 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
1616 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
1618 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1619 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1620 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1621 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1622 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1623 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('prefix') / get_option('qemu_firmwarepath'))
1624 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1625 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1626 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1627 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1628 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1629 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1631 if config_host.has_key('CONFIG_MODULES')
1632 config_host_data.set('CONFIG_STAMP', run_command(
1633 meson.current_source_dir() / 'scripts/qemu-stamp.py',
1634 meson.project_version(), get_option('pkgversion'), '--',
1635 meson.current_source_dir() / 'configure',
1636 capture: true, check: true).stdout().strip())
1639 have_slirp_smbd = get_option('slirp_smbd') \
1640 .require(targetos != 'windows', error_message: 'Host smbd not supported on this platform.') \
1643 smbd_path = get_option('smbd')
1645 smbd_path = (targetos == 'solaris' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
1647 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
1650 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
1652 if get_option('module_upgrades') and not enable_modules
1653 error('Cannot enable module-upgrades as modules are not enabled')
1655 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
1657 config_host_data.set('CONFIG_ATTR', libattr.found())
1658 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
1659 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1660 config_host_data.set('CONFIG_COCOA', cocoa.found())
1661 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1662 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1663 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1664 config_host_data.set('CONFIG_LZO', lzo.found())
1665 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1666 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1667 config_host_data.set('CONFIG_CURL', curl.found())
1668 config_host_data.set('CONFIG_CURSES', curses.found())
1669 config_host_data.set('CONFIG_GBM', gbm.found())
1670 config_host_data.set('CONFIG_GIO', gio.found())
1671 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1672 if glusterfs.found()
1673 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1674 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1675 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1676 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1677 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1678 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1680 config_host_data.set('CONFIG_GTK', gtk.found())
1681 config_host_data.set('CONFIG_VTE', vte.found())
1682 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1683 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1684 config_host_data.set('CONFIG_EBPF', libbpf.found())
1685 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1686 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1687 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1688 config_host_data.set('CONFIG_LIBSSH', libssh.found())
1689 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1690 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1691 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1692 config_host_data.set('CONFIG_NUMA', numa.found())
1693 config_host_data.set('CONFIG_OPENGL', opengl.found())
1694 config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
1695 config_host_data.set('CONFIG_RBD', rbd.found())
1696 config_host_data.set('CONFIG_RDMA', rdma.found())
1697 config_host_data.set('CONFIG_SDL', sdl.found())
1698 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1699 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1700 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1701 config_host_data.set('CONFIG_TPM', have_tpm)
1702 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1703 config_host_data.set('CONFIG_VDE', vde.found())
1704 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1705 config_host_data.set('CONFIG_PNG', png.found())
1706 config_host_data.set('CONFIG_VNC', vnc.found())
1707 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1708 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1709 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1710 config_host_data.set('CONFIG_VTE', vte.found())
1711 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1712 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1713 config_host_data.set('CONFIG_GETTID', has_gettid)
1714 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1715 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1716 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1717 config_host_data.set('CONFIG_NETTLE', nettle.found())
1718 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1719 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1720 config_host_data.set('CONFIG_STATX', has_statx)
1721 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
1722 config_host_data.set('CONFIG_ZSTD', zstd.found())
1723 config_host_data.set('CONFIG_FUSE', fuse.found())
1724 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1725 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1726 if spice_protocol.found()
1727 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
1728 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
1729 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
1731 config_host_data.set('CONFIG_SPICE', spice.found())
1732 config_host_data.set('CONFIG_X11', x11.found())
1733 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
1734 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1735 config_host_data.set('CONFIG_SELINUX', selinux.found())
1736 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
1738 # protect from xen.version() having less than three components
1739 xen_version = xen.version().split('.') + ['0', '0']
1740 xen_ctrl_version = xen_version[0] + \
1741 ('0' + xen_version[1]).substring(-2) + \
1742 ('0' + xen_version[2]).substring(-2)
1743 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
1745 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1746 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1747 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1748 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1750 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1751 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1753 have_coroutine_pool = get_option('coroutine_pool')
1754 if get_option('debug_stack_usage') and have_coroutine_pool
1755 message('Disabling coroutine pool to measure stack usage')
1756 have_coroutine_pool = false
1758 config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool)
1759 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
1760 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
1761 config_host_data.set('CONFIG_GPROF', get_option('gprof'))
1762 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
1763 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
1764 config_host_data.set('CONFIG_REPLICATION', get_option('live_block_migration').allowed())
1767 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1768 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1769 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1770 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1771 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1772 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1773 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1774 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1775 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1778 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1779 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1780 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1781 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1782 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1783 # Note that we need to specify prefix: here to avoid incorrectly
1784 # thinking that Windows has posix_memalign()
1785 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
1786 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
1787 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
1788 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
1789 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1790 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1791 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
1792 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1793 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1794 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1795 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1796 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1797 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1798 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
1799 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1800 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1801 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1803 config_host_data.set('HAVE_IBV_ADVISE_MR',
1804 cc.has_function('ibv_advise_mr',
1806 prefix: '#include <infiniband/verbs.h>'))
1810 config_host_data.set('CONFIG_BYTESWAP_H',
1811 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1812 config_host_data.set('CONFIG_EPOLL_CREATE1',
1813 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1814 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1815 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1816 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1817 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1818 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1819 config_host_data.set('CONFIG_FIEMAP',
1820 cc.has_header('linux/fiemap.h') and
1821 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1822 config_host_data.set('CONFIG_GETRANDOM',
1823 cc.has_function('getrandom') and
1824 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1825 config_host_data.set('CONFIG_INOTIFY',
1826 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1827 config_host_data.set('CONFIG_INOTIFY1',
1828 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1829 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1830 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1831 prefix: '''#include <sys/endian.h>
1832 #include <sys/types.h>'''))
1833 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1834 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1835 config_host_data.set('CONFIG_RTNETLINK',
1836 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1837 config_host_data.set('CONFIG_SYSMACROS',
1838 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1839 config_host_data.set('HAVE_OPTRESET',
1840 cc.has_header_symbol('getopt.h', 'optreset'))
1841 config_host_data.set('HAVE_IPPROTO_MPTCP',
1842 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1845 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1846 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1847 prefix: '#include <signal.h>'))
1848 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1849 cc.has_member('struct stat', 'st_atim',
1850 prefix: '#include <sys/stat.h>'))
1853 config_host_data.set('CONFIG_IOVEC',
1854 cc.has_type('struct iovec',
1855 prefix: '#include <sys/uio.h>'))
1856 config_host_data.set('HAVE_UTMPX',
1857 cc.has_type('struct utmpx',
1858 prefix: '#include <utmpx.h>'))
1860 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1861 #include <sys/eventfd.h>
1862 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1863 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1866 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1867 return fdatasync(0);
1869 #error Not supported
1873 has_madvise = cc.links(gnu_source_prefix + '''
1874 #include <sys/types.h>
1875 #include <sys/mman.h>
1877 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
1878 missing_madvise_proto = false
1880 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
1881 # but forget to prototype it. In this case, has_madvise will be true (the
1882 # test program links despite a compile warning). To detect the
1883 # missing-prototype case, we try again with a definitely-bogus prototype.
1884 # This will only compile if the system headers don't provide the prototype;
1885 # otherwise the conflicting prototypes will cause a compiler error.
1886 missing_madvise_proto = cc.links(gnu_source_prefix + '''
1887 #include <sys/types.h>
1888 #include <sys/mman.h>
1890 extern int madvise(int);
1891 int main(void) { return madvise(0); }''')
1893 config_host_data.set('CONFIG_MADVISE', has_madvise)
1894 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
1896 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1897 #include <sys/mman.h>
1898 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1899 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1901 #if !defined(AT_EMPTY_PATH)
1902 # error missing definition
1904 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1906 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1913 return pipe2(pipefd, O_CLOEXEC);
1915 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1916 #include <sys/mman.h>
1918 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1920 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
1921 #include <pthread.h>
1923 static void *f(void *p) { return NULL; }
1927 pthread_create(&thread, 0, f, 0);
1928 pthread_setname_np(thread, "QEMU");
1930 }''', dependencies: threads))
1931 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
1932 #include <pthread.h>
1934 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
1938 pthread_create(&thread, 0, f, 0);
1940 }''', dependencies: threads))
1941 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
1942 #include <pthread.h>
1947 pthread_condattr_t attr
1948 pthread_condattr_init(&attr);
1949 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
1951 }''', dependencies: threads))
1953 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1954 #include <sys/signalfd.h>
1956 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1957 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1965 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1966 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1970 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
1971 #include <sys/mman.h>
1972 int main(int argc, char *argv[]) {
1973 return mlockall(MCL_FUTURE);
1977 if get_option('l2tpv3').allowed() and have_system
1978 have_l2tpv3 = cc.has_type('struct mmsghdr',
1979 prefix: gnu_source_prefix + '''
1980 #include <sys/socket.h>
1981 #include <linux/ip.h>''')
1983 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
1986 if get_option('netmap').allowed() and have_system
1987 have_netmap = cc.compiles('''
1988 #include <inttypes.h>
1990 #include <net/netmap.h>
1991 #include <net/netmap_user.h>
1992 #if (NETMAP_API < 11) || (NETMAP_API > 15)
1995 int main(void) { return 0; }''')
1996 if not have_netmap and get_option('netmap').enabled()
1997 error('Netmap headers not available')
2000 config_host_data.set('CONFIG_NETMAP', have_netmap)
2002 # Work around a system header bug with some kernel/XFS header
2003 # versions where they both try to define 'struct fsxattr':
2004 # xfs headers will not try to redefine structs from linux headers
2005 # if this macro is set.
2006 config_host_data.set('HAVE_FSXATTR', cc.links('''
2007 #include <linux/fs.h>
2013 # Some versions of Mac OS X incorrectly define SIZE_MAX
2014 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2017 int main(int argc, char *argv[]) {
2018 return printf("%zu", SIZE_MAX);
2019 }''', args: ['-Werror']))
2026 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2027 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2028 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2029 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2030 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2034 # See if 64-bit atomic operations are supported.
2035 # Note that without __atomic builtins, we can only
2036 # assume atomic loads/stores max at pointer size.
2037 config_host_data.set('CONFIG_ATOMIC64', cc.links(atomic_test.format('uint64_t')))
2039 has_int128 = cc.links('''
2049 config_host_data.set('CONFIG_INT128', has_int128)
2052 # "do we have 128-bit atomics which are handled inline and specifically not
2053 # via libatomic". The reason we can't use libatomic is documented in the
2054 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2055 has_atomic128 = cc.links(atomic_test.format('unsigned __int128'))
2057 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2059 if not has_atomic128
2060 has_cmpxchg128 = cc.links('''
2063 unsigned __int128 x = 0, y = 0;
2064 __sync_val_compare_and_swap_16(&x, y, x);
2069 config_host_data.set('CONFIG_CMPXCHG128', has_cmpxchg128)
2073 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2074 #include <sys/auxv.h>
2076 return getauxval(AT_HWCAP) == 0;
2079 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2080 #include <linux/usbdevice_fs.h>
2082 #ifndef USBDEVFS_GET_CAPABILITIES
2083 #error "USBDEVFS_GET_CAPABILITIES undefined"
2086 #ifndef USBDEVFS_DISCONNECT_CLAIM
2087 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2090 int main(void) { return 0; }'''))
2092 have_keyring = get_option('keyring') \
2093 .require(targetos == 'linux', error_message: 'keyring is only available on Linux') \
2094 .require(cc.compiles('''
2096 #include <asm/unistd.h>
2097 #include <linux/keyctl.h>
2098 #include <sys/syscall.h>
2101 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2102 }'''), error_message: 'keyctl syscall not available on this system').allowed()
2103 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2105 have_cpuid_h = cc.links('''
2108 unsigned a, b, c, d;
2109 unsigned max = __get_cpuid_max(0, 0);
2112 __cpuid(1, a, b, c, d);
2116 __cpuid_count(7, 0, a, b, c, d);
2121 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2123 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2124 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2125 .require(cc.links('''
2126 #pragma GCC push_options
2127 #pragma GCC target("avx2")
2129 #include <immintrin.h>
2130 static int bar(void *a) {
2131 __m256i x = *(__m256i *)a;
2132 return _mm256_testz_si256(x, x);
2134 int main(int argc, char *argv[]) { return bar(argv[0]); }
2135 '''), error_message: 'AVX2 not available').allowed())
2137 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2138 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2139 .require(cc.links('''
2140 #pragma GCC push_options
2141 #pragma GCC target("avx512f")
2143 #include <immintrin.h>
2144 static int bar(void *a) {
2145 __m512i x = *(__m512i *)a;
2146 return _mm512_test_epi64_mask(x, x);
2148 int main(int argc, char *argv[]) { return bar(argv[0]); }
2149 '''), error_message: 'AVX512F not available').allowed())
2151 have_pvrdma = get_option('pvrdma') \
2152 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
2153 .require(cc.compiles('''
2158 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2161 }'''), error_message: 'PVRDMA requires mremap').allowed()
2164 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.compiles('''
2165 #include <infiniband/verbs.h>
2169 struct ibv_pd *pd = NULL;
2175 mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2181 if get_option('membarrier').disabled()
2182 have_membarrier = false
2183 elif targetos == 'windows'
2184 have_membarrier = true
2185 elif targetos == 'linux'
2186 have_membarrier = cc.compiles('''
2187 #include <linux/membarrier.h>
2188 #include <sys/syscall.h>
2192 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2193 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2197 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2198 .require(have_membarrier, error_message: 'membarrier system call not available') \
2201 have_afalg = get_option('crypto_afalg') \
2202 .require(cc.compiles(gnu_source_prefix + '''
2204 #include <sys/types.h>
2205 #include <sys/socket.h>
2206 #include <linux/if_alg.h>
2209 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2212 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2213 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2215 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2216 'linux/vm_sockets.h', 'AF_VSOCK',
2217 prefix: '#include <sys/socket.h>',
2221 have_vss_sdk = false # old xp/2003 SDK
2222 if targetos == 'windows' and link_language == 'cpp'
2223 have_vss = cxx.compiles('''
2224 #define __MIDL_user_allocate_free_DEFINED__
2226 int main(void) { return VSS_CTX_BACKUP; }''')
2227 have_vss_sdk = cxx.has_header('vscoordint.h')
2229 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2231 foreach k, v: config_host
2232 if k.startswith('CONFIG_')
2233 config_host_data.set(k, v == 'y' ? 1 : v)
2237 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2238 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2239 if targetos == 'windows'
2240 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2246 }''', name: '_lock_file and _unlock_file'))
2249 ########################
2250 # Target configuration #
2251 ########################
2253 minikconf = find_program('scripts/minikconf.py')
2255 config_all_devices = {}
2256 config_all_disas = {}
2257 config_devices_mak_list = []
2258 config_devices_h = {}
2259 config_target_h = {}
2260 config_target_mak = {}
2263 'alpha' : ['CONFIG_ALPHA_DIS'],
2264 'arm' : ['CONFIG_ARM_DIS'],
2265 'avr' : ['CONFIG_AVR_DIS'],
2266 'cris' : ['CONFIG_CRIS_DIS'],
2267 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2268 'hppa' : ['CONFIG_HPPA_DIS'],
2269 'i386' : ['CONFIG_I386_DIS'],
2270 'x86_64' : ['CONFIG_I386_DIS'],
2271 'm68k' : ['CONFIG_M68K_DIS'],
2272 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2273 'mips' : ['CONFIG_MIPS_DIS'],
2274 'nios2' : ['CONFIG_NIOS2_DIS'],
2275 'or1k' : ['CONFIG_OPENRISC_DIS'],
2276 'ppc' : ['CONFIG_PPC_DIS'],
2277 'riscv' : ['CONFIG_RISCV_DIS'],
2278 'rx' : ['CONFIG_RX_DIS'],
2279 's390' : ['CONFIG_S390_DIS'],
2280 'sh4' : ['CONFIG_SH4_DIS'],
2281 'sparc' : ['CONFIG_SPARC_DIS'],
2282 'xtensa' : ['CONFIG_XTENSA_DIS'],
2284 if link_language == 'cpp'
2286 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
2287 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
2288 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
2292 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2294 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2295 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2296 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2297 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2298 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2299 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2300 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
2301 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2302 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2303 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2304 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
2305 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
2306 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
2308 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2310 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2311 actual_target_dirs = []
2313 foreach target : target_dirs
2314 config_target = { 'TARGET_NAME': target.split('-')[0] }
2315 if target.endswith('linux-user')
2316 if targetos != 'linux'
2320 error('Target @0@ is only available on a Linux host'.format(target))
2322 config_target += { 'CONFIG_LINUX_USER': 'y' }
2323 elif target.endswith('bsd-user')
2324 if 'CONFIG_BSD' not in config_host
2328 error('Target @0@ is only available on a BSD host'.format(target))
2330 config_target += { 'CONFIG_BSD_USER': 'y' }
2331 elif target.endswith('softmmu')
2332 config_target += { 'CONFIG_SOFTMMU': 'y' }
2334 if target.endswith('-user')
2336 'CONFIG_USER_ONLY': 'y',
2337 'CONFIG_QEMU_INTERP_PREFIX':
2338 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
2343 foreach sym: accelerators
2344 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2345 config_target += { sym: 'y' }
2346 config_all += { sym: 'y' }
2347 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
2348 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
2350 if target in modular_tcg
2351 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2353 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2355 accel_kconfig += [ sym + '=y' ]
2358 if accel_kconfig.length() == 0
2362 error('No accelerator available for target @0@'.format(target))
2365 actual_target_dirs += target
2366 config_target += keyval.load('configs/targets' / target + '.mak')
2367 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
2369 if 'TARGET_NEED_FDT' in config_target
2370 fdt_required += target
2374 if 'TARGET_BASE_ARCH' not in config_target
2375 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2377 if 'TARGET_ABI_DIR' not in config_target
2378 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2380 if 'TARGET_BIG_ENDIAN' not in config_target
2381 config_target += {'TARGET_BIG_ENDIAN': 'n'}
2384 foreach k, v: disassemblers
2385 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
2387 config_target += { sym: 'y' }
2388 config_all_disas += { sym: 'y' }
2393 config_target_data = configuration_data()
2394 foreach k, v: config_target
2395 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2397 elif ignored.contains(k)
2399 elif k == 'TARGET_BASE_ARCH'
2400 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2401 # not used to select files from sourcesets.
2402 config_target_data.set('TARGET_' + v.to_upper(), 1)
2403 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
2404 config_target_data.set_quoted(k, v)
2406 config_target_data.set(k, 1)
2408 config_target_data.set(k, 0)
2410 config_target_data.set(k, v)
2413 config_target_data.set('QEMU_ARCH',
2414 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
2415 config_target_h += {target: configure_file(output: target + '-config-target.h',
2416 configuration: config_target_data)}
2418 if target.endswith('-softmmu')
2419 config_input = meson.get_external_property(target, 'default')
2420 config_devices_mak = target + '-config-devices.mak'
2421 config_devices_mak = configure_file(
2422 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2423 output: config_devices_mak,
2424 depfile: config_devices_mak + '.d',
2426 command: [minikconf,
2427 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2428 config_devices_mak, '@DEPFILE@', '@INPUT@',
2429 host_kconfig, accel_kconfig,
2430 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
2432 config_devices_data = configuration_data()
2433 config_devices = keyval.load(config_devices_mak)
2434 foreach k, v: config_devices
2435 config_devices_data.set(k, 1)
2437 config_devices_mak_list += config_devices_mak
2438 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2439 configuration: config_devices_data)}
2440 config_target += config_devices
2441 config_all_devices += config_devices
2443 config_target_mak += {target: config_target}
2445 target_dirs = actual_target_dirs
2447 # This configuration is used to build files that are shared by
2448 # multiple binaries, and then extracted out of the "common"
2449 # static_library target.
2451 # We do not use all_sources()/all_dependencies(), because it would
2452 # build literally all source files, including devices only used by
2453 # targets that are not built for this compilation. The CONFIG_ALL
2454 # pseudo symbol replaces it.
2456 config_all += config_all_devices
2457 config_all += config_host
2458 config_all += config_all_disas
2460 'CONFIG_XEN': xen.found(),
2461 'CONFIG_SOFTMMU': have_system,
2462 'CONFIG_USER_ONLY': have_user,
2466 target_configs_h = []
2467 foreach target: target_dirs
2468 target_configs_h += config_target_h[target]
2469 target_configs_h += config_devices_h.get(target, [])
2471 genh += custom_target('config-poison.h',
2472 input: [target_configs_h],
2473 output: 'config-poison.h',
2475 command: [find_program('scripts/make-config-poison.sh'),
2482 capstone = not_found
2483 capstone_opt = get_option('capstone')
2484 if capstone_opt in ['enabled', 'auto', 'system']
2485 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
2486 capstone = dependency('capstone', version: '>=4.0',
2487 kwargs: static_kwargs, method: 'pkg-config',
2488 required: capstone_opt == 'system' or
2489 capstone_opt == 'enabled' and not have_internal)
2491 # Some versions of capstone have broken pkg-config file
2492 # that reports a wrong -I path, causing the #include to
2493 # fail later. If the system has such a broken version
2495 if capstone.found() and not cc.compiles('#include <capstone.h>',
2496 dependencies: [capstone])
2497 capstone = not_found
2498 if capstone_opt == 'system'
2499 error('system capstone requested, it does not appear to work')
2504 capstone_opt = 'system'
2506 capstone_opt = 'internal'
2508 capstone_opt = 'disabled'
2511 if capstone_opt == 'internal'
2512 capstone_data = configuration_data()
2513 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
2515 capstone_files = files(
2517 'capstone/MCInst.c',
2518 'capstone/MCInstrDesc.c',
2519 'capstone/MCRegisterInfo.c',
2520 'capstone/SStream.c',
2524 if 'CONFIG_ARM_DIS' in config_all_disas
2525 capstone_data.set('CAPSTONE_HAS_ARM', '1')
2526 capstone_files += files(
2527 'capstone/arch/ARM/ARMDisassembler.c',
2528 'capstone/arch/ARM/ARMInstPrinter.c',
2529 'capstone/arch/ARM/ARMMapping.c',
2530 'capstone/arch/ARM/ARMModule.c'
2534 # FIXME: This config entry currently depends on a c++ compiler.
2535 # Which is needed for building libvixl, but not for capstone.
2536 if 'CONFIG_ARM_A64_DIS' in config_all_disas
2537 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
2538 capstone_files += files(
2539 'capstone/arch/AArch64/AArch64BaseInfo.c',
2540 'capstone/arch/AArch64/AArch64Disassembler.c',
2541 'capstone/arch/AArch64/AArch64InstPrinter.c',
2542 'capstone/arch/AArch64/AArch64Mapping.c',
2543 'capstone/arch/AArch64/AArch64Module.c'
2547 if 'CONFIG_PPC_DIS' in config_all_disas
2548 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
2549 capstone_files += files(
2550 'capstone/arch/PowerPC/PPCDisassembler.c',
2551 'capstone/arch/PowerPC/PPCInstPrinter.c',
2552 'capstone/arch/PowerPC/PPCMapping.c',
2553 'capstone/arch/PowerPC/PPCModule.c'
2557 if 'CONFIG_S390_DIS' in config_all_disas
2558 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
2559 capstone_files += files(
2560 'capstone/arch/SystemZ/SystemZDisassembler.c',
2561 'capstone/arch/SystemZ/SystemZInstPrinter.c',
2562 'capstone/arch/SystemZ/SystemZMapping.c',
2563 'capstone/arch/SystemZ/SystemZModule.c',
2564 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
2568 if 'CONFIG_I386_DIS' in config_all_disas
2569 capstone_data.set('CAPSTONE_HAS_X86', 1)
2570 capstone_files += files(
2571 'capstone/arch/X86/X86Disassembler.c',
2572 'capstone/arch/X86/X86DisassemblerDecoder.c',
2573 'capstone/arch/X86/X86ATTInstPrinter.c',
2574 'capstone/arch/X86/X86IntelInstPrinter.c',
2575 'capstone/arch/X86/X86InstPrinterCommon.c',
2576 'capstone/arch/X86/X86Mapping.c',
2577 'capstone/arch/X86/X86Module.c'
2581 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
2584 # FIXME: There does not seem to be a way to completely replace the c_args
2585 # that come from add_project_arguments() -- we can only add to them.
2586 # So: disable all warnings with a big hammer.
2589 # Include all configuration defines via a header file, which will wind up
2590 # as a dependency on the object file, and thus changes here will result
2592 '-include', 'capstone-defs.h'
2595 libcapstone = static_library('capstone',
2596 build_by_default: false,
2597 sources: capstone_files,
2598 c_args: capstone_cargs,
2599 include_directories: 'capstone/include')
2600 capstone = declare_dependency(link_with: libcapstone,
2601 include_directories: 'capstone/include/capstone')
2605 slirp_opt = 'disabled'
2607 slirp_opt = get_option('slirp')
2608 if slirp_opt in ['enabled', 'auto', 'system']
2609 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2610 slirp = dependency('slirp', kwargs: static_kwargs,
2611 method: 'pkg-config',
2612 required: slirp_opt == 'system' or
2613 slirp_opt == 'enabled' and not have_internal)
2615 slirp_opt = 'system'
2617 slirp_opt = 'internal'
2619 slirp_opt = 'disabled'
2622 if slirp_opt == 'internal'
2624 if targetos == 'windows'
2625 slirp_deps = cc.find_library('iphlpapi')
2626 elif targetos == 'darwin'
2627 slirp_deps = cc.find_library('resolv')
2629 slirp_conf = configuration_data()
2630 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2631 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2632 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2633 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2634 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2636 'slirp/src/arp_table.c',
2637 'slirp/src/bootp.c',
2638 'slirp/src/cksum.c',
2639 'slirp/src/dhcpv6.c',
2640 'slirp/src/dnssearch.c',
2642 'slirp/src/ip6_icmp.c',
2643 'slirp/src/ip6_input.c',
2644 'slirp/src/ip6_output.c',
2645 'slirp/src/ip_icmp.c',
2646 'slirp/src/ip_input.c',
2647 'slirp/src/ip_output.c',
2651 'slirp/src/ndp_table.c',
2653 'slirp/src/slirp.c',
2654 'slirp/src/socket.c',
2655 'slirp/src/state.c',
2656 'slirp/src/stream.c',
2657 'slirp/src/tcp_input.c',
2658 'slirp/src/tcp_output.c',
2659 'slirp/src/tcp_subr.c',
2660 'slirp/src/tcp_timer.c',
2665 'slirp/src/version.c',
2666 'slirp/src/vmstate.c',
2670 input : 'slirp/src/libslirp-version.h.in',
2671 output : 'libslirp-version.h',
2672 configuration: slirp_conf)
2674 slirp_inc = include_directories('slirp', 'slirp/src')
2675 libslirp = static_library('slirp',
2676 build_by_default: false,
2677 sources: slirp_files,
2678 c_args: slirp_cargs,
2679 include_directories: slirp_inc)
2680 slirp = declare_dependency(link_with: libslirp,
2681 dependencies: slirp_deps,
2682 include_directories: slirp_inc)
2686 # For CFI, we need to compile slirp as a static library together with qemu.
2687 # This is because we register slirp functions as callbacks for QEMU Timers.
2688 # When using a system-wide shared libslirp, the type information for the
2689 # callback is missing and the timer call produces a false positive with CFI.
2691 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2692 # with control-flow integrity.
2693 if get_option('cfi') and slirp_opt == 'system'
2694 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2695 + ' Please configure with --enable-slirp=git')
2700 fdt_opt = get_option('fdt')
2701 if fdt_opt in ['enabled', 'auto', 'system']
2702 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2703 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2704 required: fdt_opt == 'system' or
2705 fdt_opt == 'enabled' and not have_internal)
2706 if fdt.found() and cc.links('''
2708 #include <libfdt_env.h>
2709 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2712 elif fdt_opt == 'system'
2713 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2715 fdt_opt = 'internal'
2717 fdt_opt = 'disabled'
2721 if fdt_opt == 'internal'
2724 'dtc/libfdt/fdt_ro.c',
2725 'dtc/libfdt/fdt_wip.c',
2726 'dtc/libfdt/fdt_sw.c',
2727 'dtc/libfdt/fdt_rw.c',
2728 'dtc/libfdt/fdt_strerror.c',
2729 'dtc/libfdt/fdt_empty_tree.c',
2730 'dtc/libfdt/fdt_addresses.c',
2731 'dtc/libfdt/fdt_overlay.c',
2732 'dtc/libfdt/fdt_check.c',
2735 fdt_inc = include_directories('dtc/libfdt')
2736 libfdt = static_library('fdt',
2737 build_by_default: false,
2739 include_directories: fdt_inc)
2740 fdt = declare_dependency(link_with: libfdt,
2741 include_directories: fdt_inc)
2744 fdt_opt = 'disabled'
2746 if not fdt.found() and fdt_required.length() > 0
2747 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2750 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2751 config_host_data.set('CONFIG_FDT', fdt.found())
2752 config_host_data.set('CONFIG_SLIRP', slirp.found())
2754 #####################
2755 # Generated sources #
2756 #####################
2758 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2760 hxtool = find_program('scripts/hxtool')
2761 shaderinclude = find_program('scripts/shaderinclude.pl')
2762 qapi_gen = find_program('scripts/qapi-gen.py')
2763 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2764 meson.current_source_dir() / 'scripts/qapi/commands.py',
2765 meson.current_source_dir() / 'scripts/qapi/common.py',
2766 meson.current_source_dir() / 'scripts/qapi/error.py',
2767 meson.current_source_dir() / 'scripts/qapi/events.py',
2768 meson.current_source_dir() / 'scripts/qapi/expr.py',
2769 meson.current_source_dir() / 'scripts/qapi/gen.py',
2770 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2771 meson.current_source_dir() / 'scripts/qapi/parser.py',
2772 meson.current_source_dir() / 'scripts/qapi/schema.py',
2773 meson.current_source_dir() / 'scripts/qapi/source.py',
2774 meson.current_source_dir() / 'scripts/qapi/types.py',
2775 meson.current_source_dir() / 'scripts/qapi/visit.py',
2776 meson.current_source_dir() / 'scripts/qapi/common.py',
2777 meson.current_source_dir() / 'scripts/qapi-gen.py'
2781 python, files('scripts/tracetool.py'),
2782 '--backend=' + ','.join(get_option('trace_backends'))
2784 tracetool_depends = files(
2785 'scripts/tracetool/backend/log.py',
2786 'scripts/tracetool/backend/__init__.py',
2787 'scripts/tracetool/backend/dtrace.py',
2788 'scripts/tracetool/backend/ftrace.py',
2789 'scripts/tracetool/backend/simple.py',
2790 'scripts/tracetool/backend/syslog.py',
2791 'scripts/tracetool/backend/ust.py',
2792 'scripts/tracetool/format/ust_events_c.py',
2793 'scripts/tracetool/format/ust_events_h.py',
2794 'scripts/tracetool/format/__init__.py',
2795 'scripts/tracetool/format/d.py',
2796 'scripts/tracetool/format/simpletrace_stap.py',
2797 'scripts/tracetool/format/c.py',
2798 'scripts/tracetool/format/h.py',
2799 'scripts/tracetool/format/log_stap.py',
2800 'scripts/tracetool/format/stap.py',
2801 'scripts/tracetool/__init__.py',
2802 'scripts/tracetool/transform.py',
2803 'scripts/tracetool/vcpu.py'
2806 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2807 meson.current_source_dir(),
2808 get_option('pkgversion'), meson.project_version()]
2809 qemu_version = custom_target('qemu-version.h',
2810 output: 'qemu-version.h',
2811 command: qemu_version_cmd,
2813 build_by_default: true,
2814 build_always_stale: true)
2815 genh += qemu_version
2819 ['qemu-options.hx', 'qemu-options.def'],
2820 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2824 ['hmp-commands.hx', 'hmp-commands.h'],
2825 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2828 foreach d : hx_headers
2829 hxdep += custom_target(d[1],
2833 build_by_default: true, # to be removed when added to a target
2834 command: [hxtool, '-h', '@INPUT0@'])
2842 authz_ss = ss.source_set()
2843 blockdev_ss = ss.source_set()
2844 block_ss = ss.source_set()
2845 chardev_ss = ss.source_set()
2846 common_ss = ss.source_set()
2847 crypto_ss = ss.source_set()
2848 hwcore_ss = ss.source_set()
2849 io_ss = ss.source_set()
2850 qmp_ss = ss.source_set()
2851 qom_ss = ss.source_set()
2852 softmmu_ss = ss.source_set()
2853 specific_fuzz_ss = ss.source_set()
2854 specific_ss = ss.source_set()
2855 stub_ss = ss.source_set()
2856 trace_ss = ss.source_set()
2857 user_ss = ss.source_set()
2858 util_ss = ss.source_set()
2861 qtest_module_ss = ss.source_set()
2862 tcg_module_ss = ss.source_set()
2868 target_softmmu_arch = {}
2869 target_user_arch = {}
2875 # TODO: add each directory to the subdirs from its own meson.build, once
2877 trace_events_subdirs = [
2885 trace_events_subdirs += [ 'linux-user' ]
2888 trace_events_subdirs += [ 'bsd-user' ]
2891 trace_events_subdirs += [
2900 trace_events_subdirs += [
2914 'hw/block/dataplane',
2964 if have_system or have_user
2965 trace_events_subdirs += [
2983 vhost_user = not_found
2984 if targetos == 'linux' and 'CONFIG_VHOST_USER' in config_host
2985 libvhost_user = subproject('libvhost-user')
2986 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2989 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
2990 # that is filled in by qapi/.
3003 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3004 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3007 stub_ss = stub_ss.apply(config_all, strict: false)
3009 util_ss.add_all(trace_ss)
3010 util_ss = util_ss.apply(config_all, strict: false)
3011 libqemuutil = static_library('qemuutil',
3012 sources: util_ss.sources() + stub_ss.sources() + genh,
3013 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
3014 qemuutil = declare_dependency(link_with: libqemuutil,
3015 sources: genh + version_res)
3017 if have_system or have_user
3018 decodetree = generator(find_program('scripts/decodetree.py'),
3019 output: 'decode-@BASENAME@.c.inc',
3020 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3021 subdir('libdecnumber')
3038 if config_host_data.get('CONFIG_REPLICATION')
3039 block_ss.add(files('replication.c'))
3046 blockdev_ss.add(files(
3053 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3054 # os-win32.c does not
3055 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
3056 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
3059 common_ss.add(files('cpus-common.c'))
3063 common_ss.add(capstone)
3064 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
3066 # Work around a gcc bug/misfeature wherein constant propagation looks
3068 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3069 # to guess that a const variable is always zero. Without lto, this is
3070 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
3071 # without lto, not even the alias is required -- we simply use different
3072 # declarations in different compilation units.
3073 pagevary = files('page-vary-common.c')
3074 if get_option('b_lto')
3075 pagevary_flags = ['-fno-lto']
3076 if get_option('cfi')
3077 pagevary_flags += '-fno-sanitize=cfi-icall'
3079 pagevary = static_library('page-vary-common', sources: pagevary + genh,
3080 c_args: pagevary_flags)
3081 pagevary = declare_dependency(link_with: pagevary)
3083 common_ss.add(pagevary)
3084 specific_ss.add(files('page-vary.c'))
3092 subdir('semihosting')
3100 common_user_inc = []
3102 subdir('common-user')
3104 subdir('linux-user')
3106 # needed for fuzzing binaries
3107 subdir('tests/qtest/libqos')
3108 subdir('tests/qtest/fuzz')
3111 tcg_real_module_ss = ss.source_set()
3112 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3113 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3114 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3115 'tcg': tcg_real_module_ss }}
3117 ########################
3118 # Library dependencies #
3119 ########################
3121 modinfo_collect = find_program('scripts/modinfo-collect.py')
3122 modinfo_generate = find_program('scripts/modinfo-generate.py')
3127 foreach d, list : modules
3128 foreach m, module_ss : list
3129 if enable_modules and targetos != 'windows'
3130 module_ss = module_ss.apply(config_all, strict: false)
3131 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3132 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3138 if module_ss.sources() != []
3139 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3140 # input. Sources can be used multiple times but objects are
3141 # unique when it comes to lookup in compile_commands.json.
3142 # Depnds on a mesion version with
3143 # https://github.com/mesonbuild/meson/pull/8900
3144 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3145 output: d + '-' + m + '.modinfo',
3146 input: module_ss.sources() + genh,
3148 command: [modinfo_collect, module_ss.sources()])
3152 block_ss.add_all(module_ss)
3154 softmmu_ss.add_all(module_ss)
3160 foreach d, list : target_modules
3161 foreach m, module_ss : list
3162 if enable_modules and targetos != 'windows'
3163 foreach target : target_dirs
3164 if target.endswith('-softmmu')
3165 config_target = config_target_mak[target]
3166 config_target += config_host
3167 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3168 c_args = ['-DNEED_CPU_H',
3169 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3170 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3171 target_module_ss = module_ss.apply(config_target, strict: false)
3172 if target_module_ss.sources() != []
3173 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3174 sl = static_library(module_name,
3175 [genh, target_module_ss.sources()],
3176 dependencies: [modulecommon, target_module_ss.dependencies()],
3177 include_directories: target_inc,
3181 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3182 modinfo_files += custom_target(module_name + '.modinfo',
3183 output: module_name + '.modinfo',
3184 input: target_module_ss.sources() + genh,
3186 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3191 specific_ss.add_all(module_ss)
3197 modinfo_src = custom_target('modinfo.c',
3198 output: 'modinfo.c',
3199 input: modinfo_files,
3200 command: [modinfo_generate, '@INPUT@'],
3202 modinfo_lib = static_library('modinfo', modinfo_src)
3203 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
3204 softmmu_ss.add(modinfo_dep)
3207 nm = find_program('nm')
3208 undefsym = find_program('scripts/undefsym.py')
3209 block_syms = custom_target('block.syms', output: 'block.syms',
3210 input: [libqemuutil, block_mods],
3212 command: [undefsym, nm, '@INPUT@'])
3213 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3214 input: [libqemuutil, softmmu_mods],
3216 command: [undefsym, nm, '@INPUT@'])
3218 qom_ss = qom_ss.apply(config_host, strict: false)
3219 libqom = static_library('qom', qom_ss.sources() + genh,
3220 dependencies: [qom_ss.dependencies()],
3223 qom = declare_dependency(link_whole: libqom)
3225 authz_ss = authz_ss.apply(config_host, strict: false)
3226 libauthz = static_library('authz', authz_ss.sources() + genh,
3227 dependencies: [authz_ss.dependencies()],
3229 build_by_default: false)
3231 authz = declare_dependency(link_whole: libauthz,
3234 crypto_ss = crypto_ss.apply(config_host, strict: false)
3235 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3236 dependencies: [crypto_ss.dependencies()],
3238 build_by_default: false)
3240 crypto = declare_dependency(link_whole: libcrypto,
3241 dependencies: [authz, qom])
3243 io_ss = io_ss.apply(config_host, strict: false)
3244 libio = static_library('io', io_ss.sources() + genh,
3245 dependencies: [io_ss.dependencies()],
3246 link_with: libqemuutil,
3248 build_by_default: false)
3250 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3252 libmigration = static_library('migration', sources: migration_files + genh,
3254 build_by_default: false)
3255 migration = declare_dependency(link_with: libmigration,
3256 dependencies: [zlib, qom, io])
3257 softmmu_ss.add(migration)
3259 block_ss = block_ss.apply(config_host, strict: false)
3260 libblock = static_library('block', block_ss.sources() + genh,
3261 dependencies: block_ss.dependencies(),
3262 link_depends: block_syms,
3264 build_by_default: false)
3266 block = declare_dependency(link_whole: [libblock],
3267 link_args: '@block.syms',
3268 dependencies: [crypto, io])
3270 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
3271 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3272 dependencies: blockdev_ss.dependencies(),
3274 build_by_default: false)
3276 blockdev = declare_dependency(link_whole: [libblockdev],
3277 dependencies: [block])
3279 qmp_ss = qmp_ss.apply(config_host, strict: false)
3280 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3281 dependencies: qmp_ss.dependencies(),
3283 build_by_default: false)
3285 qmp = declare_dependency(link_whole: [libqmp])
3287 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3289 dependencies: chardev_ss.dependencies(),
3290 build_by_default: false)
3292 chardev = declare_dependency(link_whole: libchardev)
3294 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
3295 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3297 build_by_default: false)
3298 hwcore = declare_dependency(link_whole: libhwcore)
3299 common_ss.add(hwcore)
3305 emulator_modules = []
3306 foreach m : block_mods + softmmu_mods
3307 emulator_modules += shared_module(m.name(),
3308 build_by_default: true,
3312 install_dir: qemu_moddir)
3315 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3316 common_ss.add(qom, qemuutil)
3318 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
3319 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3321 common_all = common_ss.apply(config_all, strict: false)
3322 common_all = static_library('common',
3323 build_by_default: false,
3324 sources: common_all.sources() + genh,
3325 include_directories: common_user_inc,
3326 implicit_include_directories: false,
3327 dependencies: common_all.dependencies(),
3330 feature_to_c = find_program('scripts/feature_to_c.sh')
3332 if targetos == 'darwin'
3333 entitlement = find_program('scripts/entitlement.sh')
3337 foreach target : target_dirs
3338 config_target = config_target_mak[target]
3339 target_name = config_target['TARGET_NAME']
3340 target_base_arch = config_target['TARGET_BASE_ARCH']
3341 arch_srcs = [config_target_h[target]]
3343 c_args = ['-DNEED_CPU_H',
3344 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3345 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3346 link_args = emulator_link_args
3348 config_target += config_host
3349 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3350 if targetos == 'linux'
3351 target_inc += include_directories('linux-headers', is_system: true)
3353 if target.endswith('-softmmu')
3354 qemu_target_name = 'qemu-system-' + target_name
3355 target_type='system'
3356 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3357 arch_srcs += t.sources()
3358 arch_deps += t.dependencies()
3360 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3361 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3362 arch_srcs += hw.sources()
3363 arch_deps += hw.dependencies()
3365 arch_srcs += config_devices_h[target]
3366 link_args += ['@block.syms', '@qemu.syms']
3368 abi = config_target['TARGET_ABI_DIR']
3370 target_inc += common_user_inc
3371 qemu_target_name = 'qemu-' + target_name
3372 if target_base_arch in target_user_arch
3373 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3374 arch_srcs += t.sources()
3375 arch_deps += t.dependencies()
3377 if 'CONFIG_LINUX_USER' in config_target
3378 base_dir = 'linux-user'
3380 if 'CONFIG_BSD_USER' in config_target
3381 base_dir = 'bsd-user'
3382 target_inc += include_directories('bsd-user/' / targetos)
3383 target_inc += include_directories('bsd-user/host/' / host_arch)
3384 dir = base_dir / abi
3385 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3387 target_inc += include_directories(
3391 if 'CONFIG_LINUX_USER' in config_target
3392 dir = base_dir / abi
3393 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3394 if config_target.has_key('TARGET_SYSTBL_ABI')
3396 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3397 extra_args : config_target['TARGET_SYSTBL_ABI'])
3402 if 'TARGET_XML_FILES' in config_target
3403 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3404 output: target + '-gdbstub-xml.c',
3405 input: files(config_target['TARGET_XML_FILES'].split()),
3406 command: [feature_to_c, '@INPUT@'],
3408 arch_srcs += gdbstub_xml
3411 t = target_arch[target_base_arch].apply(config_target, strict: false)
3412 arch_srcs += t.sources()
3413 arch_deps += t.dependencies()
3415 target_common = common_ss.apply(config_target, strict: false)
3416 objects = common_all.extract_objects(target_common.sources())
3417 deps = target_common.dependencies()
3419 target_specific = specific_ss.apply(config_target, strict: false)
3420 arch_srcs += target_specific.sources()
3421 arch_deps += target_specific.dependencies()
3423 lib = static_library('qemu-' + target,
3424 sources: arch_srcs + genh,
3425 dependencies: arch_deps,
3427 include_directories: target_inc,
3429 build_by_default: false,
3432 if target.endswith('-softmmu')
3434 'name': 'qemu-system-' + target_name,
3435 'win_subsystem': 'console',
3436 'sources': files('softmmu/main.c'),
3439 if targetos == 'windows' and (sdl.found() or gtk.found())
3441 'name': 'qemu-system-' + target_name + 'w',
3442 'win_subsystem': 'windows',
3443 'sources': files('softmmu/main.c'),
3447 if get_option('fuzzing')
3448 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3450 'name': 'qemu-fuzz-' + target_name,
3451 'win_subsystem': 'console',
3452 'sources': specific_fuzz.sources(),
3453 'dependencies': specific_fuzz.dependencies(),
3458 'name': 'qemu-' + target_name,
3459 'win_subsystem': 'console',
3465 exe_name = exe['name']
3466 if targetos == 'darwin'
3467 exe_name += '-unsigned'
3470 emulator = executable(exe_name, exe['sources'],
3473 dependencies: arch_deps + deps + exe['dependencies'],
3474 objects: lib.extract_all_objects(recursive: true),
3475 link_language: link_language,
3476 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3477 link_args: link_args,
3478 win_subsystem: exe['win_subsystem'])
3480 if targetos == 'darwin'
3481 icon = 'pc-bios/qemu.rsrc'
3482 build_input = [emulator, files(icon)]
3484 get_option('bindir') / exe_name,
3485 meson.current_source_dir() / icon
3487 if 'CONFIG_HVF' in config_target
3488 entitlements = 'accel/hvf/entitlements.plist'
3489 build_input += files(entitlements)
3490 install_input += meson.current_source_dir() / entitlements
3493 emulators += {exe['name'] : custom_target(exe['name'],
3495 output: exe['name'],
3496 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3499 meson.add_install_script(entitlement, '--install',
3500 get_option('bindir') / exe['name'],
3503 emulators += {exe['name']: emulator}
3508 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3509 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3510 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3511 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3513 custom_target(exe['name'] + stp['ext'],
3514 input: trace_events_all,
3515 output: exe['name'] + stp['ext'],
3516 install: stp['install'],
3517 install_dir: get_option('datadir') / 'systemtap/tapset',
3519 tracetool, '--group=all', '--format=' + stp['fmt'],
3520 '--binary=' + stp['bin'],
3521 '--target-name=' + target_name,
3522 '--target-type=' + target_type,
3523 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3524 '@INPUT@', '@OUTPUT@'
3526 depend_files: tracetool_depends)
3532 # Other build targets
3534 if 'CONFIG_PLUGIN' in config_host
3535 install_headers('include/qemu/qemu-plugin.h')
3540 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3541 # when we don't build tools or system
3542 if xkbcommon.found()
3543 # used for the update-keymaps target, so include rules even if !have_tools
3544 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3545 dependencies: [qemuutil, xkbcommon], install: have_tools)
3549 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3550 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3551 qemu_io = executable('qemu-io', files('qemu-io.c'),
3552 dependencies: [block, qemuutil], install: true)
3553 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3554 dependencies: [blockdev, qemuutil, gnutls, selinux],
3557 subdir('storage-daemon')
3558 subdir('contrib/rdmacm-mux')
3559 subdir('contrib/elf2dmp')
3561 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3562 dependencies: qemuutil,
3565 if 'CONFIG_VHOST_USER' in config_host
3566 subdir('contrib/vhost-user-blk')
3567 subdir('contrib/vhost-user-gpu')
3568 subdir('contrib/vhost-user-input')
3569 subdir('contrib/vhost-user-scsi')
3572 if targetos == 'linux'
3573 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3574 dependencies: [qemuutil, libcap_ng],
3576 install_dir: get_option('libexecdir'))
3578 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3579 dependencies: [authz, crypto, io, qom, qemuutil,
3580 libcap_ng, mpathpersist],
3585 subdir('contrib/ivshmem-client')
3586 subdir('contrib/ivshmem-server')
3599 if host_machine.system() == 'windows'
3601 find_program('scripts/nsis.py'),
3603 get_option('prefix'),
3604 meson.current_source_dir(),
3607 '-DDISPLAYVERSION=' + meson.project_version(),
3610 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3613 nsis_cmd += '-DCONFIG_GTK=y'
3616 nsis = custom_target('nsis',
3617 output: 'qemu-setup-' + meson.project_version() + '.exe',
3618 input: files('qemu.nsi'),
3619 build_always_stale: true,
3620 command: nsis_cmd + ['@INPUT@'])
3621 alias_target('installer', nsis)
3624 #########################
3625 # Configuration summary #
3626 #########################
3630 summary_info += {'Install prefix': get_option('prefix')}
3631 summary_info += {'BIOS directory': qemu_datadir}
3632 summary_info += {'firmware path': get_option('prefix') / get_option('qemu_firmwarepath')}
3633 summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
3634 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
3635 summary_info += {'module directory': qemu_moddir}
3636 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
3637 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
3638 summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')}
3639 if targetos != 'windows'
3640 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
3641 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')}
3643 summary_info += {'local state directory': 'queried at runtime'}
3645 summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
3646 summary_info += {'Build directory': meson.current_build_dir()}
3647 summary_info += {'Source path': meson.current_source_dir()}
3648 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3649 summary(summary_info, bool_yn: true, section: 'Directories')
3653 summary_info += {'git': config_host['GIT']}
3654 summary_info += {'make': config_host['MAKE']}
3655 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3656 summary_info += {'sphinx-build': sphinx_build}
3657 if config_host.has_key('HAVE_GDB_BIN')
3658 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3660 summary_info += {'iasl': iasl}
3661 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3662 if targetos == 'windows' and have_ga
3663 summary_info += {'wixl': wixl}
3665 if slirp_opt != 'disabled' and have_system
3666 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
3668 summary(summary_info, bool_yn: true, section: 'Host binaries')
3670 # Configurable features
3672 summary_info += {'Documentation': build_docs}
3673 summary_info += {'system-mode emulation': have_system}
3674 summary_info += {'user-mode emulation': have_user}
3675 summary_info += {'block layer': have_block}
3676 summary_info += {'Install blobs': get_option('install_blobs')}
3677 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3678 if config_host.has_key('CONFIG_MODULES')
3679 summary_info += {'alternative module path': get_option('module_upgrades')}
3681 summary_info += {'fuzzing support': get_option('fuzzing')}
3683 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3685 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3686 if 'simple' in get_option('trace_backends')
3687 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3689 summary_info += {'D-Bus display': dbus_display}
3690 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
3691 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
3692 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
3693 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
3694 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
3695 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
3696 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
3697 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3698 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
3699 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
3700 summary_info += {'build guest agent': have_ga}
3701 summary(summary_info, bool_yn: true, section: 'Configurable features')
3703 # Compilation information
3705 summary_info += {'host CPU': cpu}
3706 summary_info += {'host endianness': build_machine.endian()}
3707 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3708 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3709 if link_language == 'cpp'
3710 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3712 summary_info += {'C++ compiler': false}
3714 if targetos == 'darwin'
3715 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3717 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3718 + ['-O' + get_option('optimization')]
3719 + (get_option('debug') ? ['-g'] : []))}
3720 if link_language == 'cpp'
3721 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3722 + ['-O' + get_option('optimization')]
3723 + (get_option('debug') ? ['-g'] : []))}
3725 if targetos == 'darwin'
3726 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args')
3727 + ['-O' + get_option('optimization')]
3728 + (get_option('debug') ? ['-g'] : []))}
3730 link_args = get_option(link_language + '_link_args')
3731 if link_args.length() > 0
3732 summary_info += {'LDFLAGS': ' '.join(link_args)}
3734 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_cflags)}
3735 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_cxxflags)}
3736 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_objcflags)}
3737 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
3738 summary_info += {'profiler': get_option('profiler')}
3739 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3740 summary_info += {'PIE': get_option('b_pie')}
3741 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3742 summary_info += {'malloc trim support': has_malloc_trim}
3743 summary_info += {'membarrier': have_membarrier}
3744 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
3745 summary_info += {'mutex debugging': get_option('debug_mutex')}
3746 summary_info += {'memory allocator': get_option('malloc')}
3747 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
3748 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
3749 summary_info += {'gprof enabled': get_option('gprof')}
3750 summary_info += {'gcov': get_option('b_coverage')}
3751 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3752 summary_info += {'CFI support': get_option('cfi')}
3753 if get_option('cfi')
3754 summary_info += {'CFI debug support': get_option('cfi_debug')}
3756 summary_info += {'strip binaries': get_option('strip')}
3757 summary_info += {'sparse': sparse}
3758 summary_info += {'mingw32 support': targetos == 'windows'}
3760 # snarf the cross-compilation information for tests
3761 foreach target: target_dirs
3762 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3763 if fs.exists(tcg_mak)
3764 config_cross_tcg = keyval.load(tcg_mak)
3765 target = config_cross_tcg['TARGET_NAME']
3767 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3768 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3769 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3770 elif 'CROSS_CC_GUEST' in config_cross_tcg
3771 summary_info += {target + ' tests'
3772 : config_cross_tcg['CROSS_CC_GUEST'] }
3777 summary(summary_info, bool_yn: true, section: 'Compilation')
3779 # Targets and accelerators
3782 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3783 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3784 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3785 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3786 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3787 summary_info += {'Xen support': xen.found()}
3789 summary_info += {'xen ctrl version': xen.version()}
3792 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3793 if config_all.has_key('CONFIG_TCG')
3794 if get_option('tcg_interpreter')
3795 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
3797 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3799 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3800 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3802 summary_info += {'target list': ' '.join(target_dirs)}
3804 summary_info += {'default devices': get_option('default_devices')}
3805 summary_info += {'out of process emulation': multiprocess_allowed}
3807 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3811 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3812 summary_info += {'coroutine pool': have_coroutine_pool}
3814 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
3815 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
3816 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
3817 summary_info += {'VirtFS support': have_virtfs}
3818 summary_info += {'build virtiofs daemon': have_virtiofsd}
3819 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
3820 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
3821 summary_info += {'bochs support': get_option('bochs').allowed()}
3822 summary_info += {'cloop support': get_option('cloop').allowed()}
3823 summary_info += {'dmg support': get_option('dmg').allowed()}
3824 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
3825 summary_info += {'vdi support': get_option('vdi').allowed()}
3826 summary_info += {'vvfat support': get_option('vvfat').allowed()}
3827 summary_info += {'qed support': get_option('qed').allowed()}
3828 summary_info += {'parallels support': get_option('parallels').allowed()}
3829 summary_info += {'FUSE exports': fuse}
3831 summary(summary_info, bool_yn: true, section: 'Block layer support')
3835 summary_info += {'TLS priority': get_option('tls_priority')}
3836 summary_info += {'GNUTLS support': gnutls}
3838 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3840 summary_info += {'libgcrypt': gcrypt}
3841 summary_info += {'nettle': nettle}
3843 summary_info += {' XTS': xts != 'private'}
3845 summary_info += {'AF_ALG support': have_afalg}
3846 summary_info += {'rng-none': get_option('rng_none')}
3847 summary_info += {'Linux keyring': have_keyring}
3848 summary(summary_info, bool_yn: true, section: 'Crypto')
3852 if targetos == 'darwin'
3853 summary_info += {'Cocoa support': cocoa}
3855 summary_info += {'SDL support': sdl}
3856 summary_info += {'SDL image support': sdl_image}
3857 summary_info += {'GTK support': gtk}
3858 summary_info += {'pixman': pixman}
3859 summary_info += {'VTE support': vte}
3860 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3861 summary_info += {'libtasn1': tasn1}
3862 summary_info += {'PAM': pam}
3863 summary_info += {'iconv support': iconv}
3864 summary_info += {'curses support': curses}
3865 summary_info += {'virgl support': virgl}
3866 summary_info += {'curl support': curl}
3867 summary_info += {'Multipath support': mpathpersist}
3868 summary_info += {'PNG support': png}
3869 summary_info += {'VNC support': vnc}
3871 summary_info += {'VNC SASL support': sasl}
3872 summary_info += {'VNC JPEG support': jpeg}
3874 if targetos not in ['darwin', 'haiku', 'windows']
3875 summary_info += {'OSS support': oss}
3876 elif targetos == 'darwin'
3877 summary_info += {'CoreAudio support': coreaudio}
3878 elif targetos == 'windows'
3879 summary_info += {'DirectSound support': dsound}
3881 if targetos == 'linux'
3882 summary_info += {'ALSA support': alsa}
3883 summary_info += {'PulseAudio support': pulse}
3885 summary_info += {'JACK support': jack}
3886 summary_info += {'brlapi support': brlapi}
3887 summary_info += {'vde support': vde}
3888 summary_info += {'netmap support': have_netmap}
3889 summary_info += {'l2tpv3 support': have_l2tpv3}
3890 summary_info += {'Linux AIO support': libaio}
3891 summary_info += {'Linux io_uring support': linux_io_uring}
3892 summary_info += {'ATTR/XATTR support': libattr}
3893 summary_info += {'RDMA support': rdma}
3894 summary_info += {'PVRDMA support': have_pvrdma}
3895 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3896 summary_info += {'libcap-ng support': libcap_ng}
3897 summary_info += {'bpf support': libbpf}
3898 summary_info += {'spice protocol support': spice_protocol}
3899 if spice_protocol.found()
3900 summary_info += {' spice server support': spice}
3902 summary_info += {'rbd support': rbd}
3903 summary_info += {'smartcard support': cacard}
3904 summary_info += {'U2F support': u2f}
3905 summary_info += {'libusb': libusb}
3906 summary_info += {'usb net redir': usbredir}
3907 summary_info += {'OpenGL support (epoxy)': opengl}
3908 summary_info += {'GBM': gbm}
3909 summary_info += {'libiscsi support': libiscsi}
3910 summary_info += {'libnfs support': libnfs}
3911 if targetos == 'windows'
3913 summary_info += {'QGA VSS support': have_qga_vss}
3916 summary_info += {'seccomp support': seccomp}
3917 summary_info += {'GlusterFS support': glusterfs}
3918 summary_info += {'TPM support': have_tpm}
3919 summary_info += {'libssh support': libssh}
3920 summary_info += {'lzo support': lzo}
3921 summary_info += {'snappy support': snappy}
3922 summary_info += {'bzip2 support': libbzip2}
3923 summary_info += {'lzfse support': liblzfse}
3924 summary_info += {'zstd support': zstd}
3925 summary_info += {'NUMA host support': numa}
3926 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3927 summary_info += {'libpmem support': libpmem}
3928 summary_info += {'libdaxctl support': libdaxctl}
3929 summary_info += {'libudev': libudev}
3930 # Dummy dependency, keep .found()
3931 summary_info += {'FUSE lseek': fuse_lseek.found()}
3932 summary_info += {'selinux': selinux}
3933 summary(summary_info, bool_yn: true, section: 'Dependencies')
3935 if not supported_cpus.contains(cpu)
3937 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3939 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3940 message('The QEMU project intends to remove support for this host CPU in')
3941 message('a future release if nobody volunteers to maintain it and to')
3942 message('provide a build host for our continuous integration setup.')
3943 message('configure has succeeded and you can continue to build, but')
3944 message('if you care about QEMU on this platform you should contact')
3945 message('us upstream at qemu-devel@nongnu.org.')
3948 if not supported_oses.contains(targetos)
3950 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3952 message('Host OS ' + targetos + 'support is not currently maintained.')
3953 message('The QEMU project intends to remove support for this host OS in')
3954 message('a future release if nobody volunteers to maintain it and to')
3955 message('provide a build host for our continuous integration setup.')
3956 message('configure has succeeded and you can continue to build, but')
3957 message('if you care about QEMU on this platform you should contact')
3958 message('us upstream at qemu-devel@nongnu.org.')