1 project('qemu', ['c'], meson_version: '>=0.63.0',
2 default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
3 'b_staticpic=false', 'stdsplit=false', 'optimization=2', 'b_pie=true'],
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 meson.add_postconf_script(find_program('scripts/symlink-install-tree.py'))
16 not_found = dependency('', required: false)
17 keyval = import('keyval')
18 ss = import('sourceset')
21 host_os = host_machine.system()
22 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
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'
44 qapi_trace_events = []
46 bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
47 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
48 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
49 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64']
51 cpu = host_machine.cpu_family()
53 target_dirs = config_host['TARGET_DIRS'].split()
59 sh = find_program('sh')
60 python = import('python').find_installation()
62 cc = meson.get_compiler('c')
64 if host_os == 'windows' and add_languages('cpp', required: false, native: false)
65 all_languages += ['cpp']
66 cxx = meson.get_compiler('cpp')
68 if host_os == 'darwin' and \
69 add_languages('objc', required: get_option('cocoa'), native: false)
70 all_languages += ['objc']
71 objc = meson.get_compiler('objc')
76 if 'dtrace' in get_option('trace_backends')
77 dtrace = find_program('dtrace', required: true)
78 stap = find_program('stap', required: false)
80 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
81 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
82 # instead. QEMU --enable-modules depends on this because the SystemTap
83 # semaphores are linked into the main binary and not the module's shared
85 add_global_arguments('-DSTAP_SDT_V2',
86 native: false, language: all_languages)
90 if get_option('iasl') == ''
91 iasl = find_program('iasl', required: false)
93 iasl = find_program(get_option('iasl'), required: true)
96 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
97 unpack_edk2_blobs = false
98 foreach target : edk2_targets
99 if target in target_dirs
100 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
101 unpack_edk2_blobs = bzip2.found()
106 #####################
107 # Option validation #
108 #####################
111 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
114 #include <sys/types.h>
115 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
116 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
118 args: ['-Werror', '-fsanitize=fuzzer'])
119 error('Your compiler does not support -fsanitize=fuzzer')
123 if 'ftrace' in get_option('trace_backends') and host_os != 'linux'
124 error('ftrace is supported only on Linux')
126 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
129 openlog("qemu", LOG_PID, LOG_DAEMON);
130 syslog(LOG_INFO, "configure");
133 error('syslog is not supported on this system')
136 # Miscellaneous Linux-only features
137 get_option('mpath') \
138 .require(host_os == 'linux', error_message: 'Multipath is supported only on Linux')
140 multiprocess_allowed = get_option('multiprocess') \
141 .require(host_os == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
144 vfio_user_server_allowed = get_option('vfio_user_server') \
145 .require(host_os == 'linux', error_message: 'vfio-user server is supported only on Linux') \
148 have_tpm = get_option('tpm') \
149 .require(host_os != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
153 have_vhost_user = get_option('vhost_user') \
154 .disable_auto_if(host_os != 'linux') \
155 .require(host_os != 'windows',
156 error_message: 'vhost-user is not available on Windows').allowed()
157 have_vhost_vdpa = get_option('vhost_vdpa') \
158 .require(host_os == 'linux',
159 error_message: 'vhost-vdpa is only available on Linux').allowed()
160 have_vhost_kernel = get_option('vhost_kernel') \
161 .require(host_os == 'linux',
162 error_message: 'vhost-kernel is only available on Linux').allowed()
163 have_vhost_user_crypto = get_option('vhost_crypto') \
164 .require(have_vhost_user,
165 error_message: 'vhost-crypto requires vhost-user to be enabled').allowed()
167 have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel
169 have_vhost_net_user = have_vhost_user and get_option('vhost_net').allowed()
170 have_vhost_net_vdpa = have_vhost_vdpa and get_option('vhost_net').allowed()
171 have_vhost_net_kernel = have_vhost_kernel and get_option('vhost_net').allowed()
172 have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_vdpa
174 # type of binaries to build
175 have_linux_user = false
176 have_bsd_user = false
178 foreach target : target_dirs
179 have_linux_user = have_linux_user or target.endswith('linux-user')
180 have_bsd_user = have_bsd_user or target.endswith('bsd-user')
181 have_system = have_system or target.endswith('-softmmu')
183 have_user = have_linux_user or have_bsd_user
185 have_tools = get_option('tools') \
186 .disable_auto_if(not have_system) \
188 have_ga = get_option('guest_agent') \
189 .disable_auto_if(not have_system and not have_tools) \
190 .require(host_os in ['sunos', 'linux', 'windows', 'freebsd', 'netbsd', 'openbsd'],
191 error_message: 'unsupported OS for QEMU guest agent') \
193 have_block = have_system or have_tools
195 enable_modules = get_option('modules') \
196 .require(host_os != 'windows',
197 error_message: 'Modules are not available for Windows') \
198 .require(not get_option('prefer_static'),
199 error_message: 'Modules are incompatible with static linking') \
202 #######################################
203 # Variables for host and accelerators #
204 #######################################
206 if cpu not in supported_cpus
207 host_arch = 'unknown'
212 elif cpu in ['riscv32', 'riscv64']
218 if cpu in ['x86', 'x86_64']
219 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
220 elif cpu == 'aarch64'
221 kvm_targets = ['aarch64-softmmu']
223 kvm_targets = ['s390x-softmmu']
224 elif cpu in ['ppc', 'ppc64']
225 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
226 elif cpu in ['mips', 'mips64']
227 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
228 elif cpu in ['riscv32']
229 kvm_targets = ['riscv32-softmmu']
230 elif cpu in ['riscv64']
231 kvm_targets = ['riscv64-softmmu']
232 elif cpu in ['loongarch64']
233 kvm_targets = ['loongarch64-softmmu']
237 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
239 if cpu in ['x86', 'x86_64']
240 xen_targets = ['i386-softmmu', 'x86_64-softmmu']
241 elif cpu in ['arm', 'aarch64']
242 # i386 emulator provides xenpv machine type for multiple architectures
243 xen_targets = ['i386-softmmu', 'x86_64-softmmu', 'aarch64-softmmu']
247 accelerator_targets += { 'CONFIG_XEN': xen_targets }
249 if cpu in ['aarch64']
250 accelerator_targets += {
251 'CONFIG_HVF': ['aarch64-softmmu']
255 if cpu in ['x86', 'x86_64']
256 accelerator_targets += {
257 'CONFIG_HVF': ['x86_64-softmmu'],
258 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
259 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
264 # Darwin does not support references to thread-local variables in modules
265 if host_os != 'darwin'
266 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
273 foreach lang : all_languages
274 compiler = meson.get_compiler(lang)
275 if compiler.get_id() == 'gcc' and compiler.version().version_compare('>=7.4')
277 elif compiler.get_id() == 'clang' and compiler.compiles('''
278 #ifdef __apple_build_version__
279 # if __clang_major__ < 12 || (__clang_major__ == 12 && __clang_minor__ < 0)
280 # error You need at least XCode Clang v12.0 to compile QEMU
283 # if __clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 0)
284 # error You need at least Clang v10.0 to compile QEMU
289 error('You either need GCC v7.4 or Clang v10.0 (or XCode Clang v12.0) to compile QEMU')
293 # default flags for all hosts
294 # We use -fwrapv to tell the compiler that we require a C dialect where
295 # left shift of signed integers is well defined and has the expected
296 # 2s-complement style results. (Both clang and gcc agree that it
297 # provides these semantics.)
299 qemu_common_flags = [
300 '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE',
301 '-fno-strict-aliasing', '-fno-common', '-fwrapv' ]
305 if host_os == 'darwin'
306 # Disable attempts to use ObjectiveC features in os/object.h since they
307 # won't work when we're compiling with gcc as a C compiler.
308 if compiler.get_id() == 'gcc'
309 qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
311 elif host_os == 'sunos'
312 # needed for CMSG_ macros in sys/socket.h
313 qemu_common_flags += '-D_XOPEN_SOURCE=600'
314 # needed for TIOCWIN* defines in termios.h
315 qemu_common_flags += '-D__EXTENSIONS__'
316 elif host_os == 'haiku'
317 qemu_common_flags += ['-DB_USE_POSITIVE_POSIX_ERRORS', '-D_BSD_SOURCE', '-fPIC']
320 # __sync_fetch_and_and requires at least -march=i486. Many toolchains
321 # use i686 as default anyway, but for those that don't, an explicit
322 # specification is necessary
323 if host_arch == 'i386' and not cc.links('''
324 static int sfaa(int *ptr)
326 return __sync_fetch_and_and(ptr, 0);
332 val = __sync_val_compare_and_swap(&val, 0, 1);
336 qemu_common_flags = ['-march=i486'] + qemu_common_flags
339 if get_option('prefer_static')
340 qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
343 # Meson currently only handles pie as a boolean for now, so if the user
344 # has explicitly disabled PIE we need to extend our cflags.
346 # -no-pie is supposedly a linker flag that has no effect on the compiler
347 # command line, but some distros, that didn't quite know what they were
348 # doing, made local changes to gcc's specs file that turned it into
349 # a compiler command-line flag.
351 # What about linker flags? For a static build, no PIE is implied by -static
352 # which we added above (and if it's not because of the same specs patching,
353 # there's nothing we can do: compilation will fail, report a bug to your
354 # distro and do not use --disable-pie in the meanwhile). For dynamic linking,
355 # instead, we can't add -no-pie because it overrides -shared: the linker then
356 # tries to build an executable instead of a shared library and fails. So
357 # don't add -no-pie anywhere and cross fingers. :(
358 if not get_option('b_pie')
359 qemu_common_flags += cc.get_supported_arguments('-fno-pie', '-no-pie')
362 if not get_option('stack_protector').disabled()
363 stack_protector_probe = '''
364 int main(int argc, char *argv[])
366 char arr[64], *p = arr, *c = argv[argc - 1];
372 have_stack_protector = false
373 foreach arg : ['-fstack-protector-strong', '-fstack-protector-all']
374 # We need to check both a compile and a link, since some compiler
375 # setups fail only on a .c->.o compile and some only at link time
376 if cc.compiles(stack_protector_probe, args: ['-Werror', arg]) and \
377 cc.links(stack_protector_probe, args: ['-Werror', arg])
378 have_stack_protector = true
384 get_option('stack_protector') \
385 .require(have_stack_protector, error_message: 'Stack protector not supported')
388 coroutine_backend = get_option('coroutine_backend')
390 #include <ucontext.h>
391 #ifdef __stub_makecontext
392 #error Ignoring glibc stub makecontext which will always fail
394 int main(void) { makecontext(0, 0, 0); return 0; }'''
396 # On Windows the only valid backend is the Windows specific one.
397 # For POSIX prefer ucontext, but it's not always possible. The fallback
399 supported_backends = []
400 if host_os == 'windows'
401 supported_backends += ['windows']
403 if host_os != 'darwin' and cc.links(ucontext_probe)
404 supported_backends += ['ucontext']
406 supported_backends += ['sigaltstack']
409 if coroutine_backend == 'auto'
410 coroutine_backend = supported_backends[0]
411 elif coroutine_backend not in supported_backends
412 error('"@0@" backend requested but not available. Available backends: @1@' \
413 .format(coroutine_backend, ', '.join(supported_backends)))
416 # Compiles if SafeStack *not* enabled
417 safe_stack_probe = '''
420 #if defined(__has_feature)
421 #if __has_feature(safe_stack)
422 #error SafeStack Enabled
427 if get_option('safe_stack') != not cc.compiles(safe_stack_probe)
428 safe_stack_arg = get_option('safe_stack') ? '-fsanitize=safe-stack' : '-fno-sanitize=safe-stack'
429 if get_option('safe_stack') != not cc.compiles(safe_stack_probe, args: safe_stack_arg)
430 error(get_option('safe_stack') \
431 ? 'SafeStack not supported by your compiler' \
432 : 'Cannot disable SafeStack')
434 qemu_cflags += safe_stack_arg
435 qemu_ldflags += safe_stack_arg
437 if get_option('safe_stack') and coroutine_backend != 'ucontext'
438 error('SafeStack is only supported with the ucontext coroutine backend')
441 if get_option('sanitizers')
442 if cc.has_argument('-fsanitize=address')
443 qemu_cflags = ['-fsanitize=address'] + qemu_cflags
444 qemu_ldflags = ['-fsanitize=address'] + qemu_ldflags
447 # Detect static linking issue with ubsan - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84285
448 if cc.links('int main(int argc, char **argv) { return argc + 1; }',
449 args: [qemu_ldflags, '-fsanitize=undefined'])
450 qemu_cflags = ['-fsanitize=undefined'] + qemu_cflags
451 qemu_ldflags = ['-fsanitize=undefined'] + qemu_ldflags
455 # Thread sanitizer is, for now, much noisier than the other sanitizers;
456 # keep it separate until that is not the case.
457 if get_option('tsan')
458 if get_option('sanitizers')
459 error('TSAN is not supported with other sanitizers')
461 if not cc.has_function('__tsan_create_fiber',
462 args: '-fsanitize=thread',
463 prefix: '#include <sanitizer/tsan_interface.h>')
464 error('Cannot enable TSAN due to missing fiber annotation interface')
466 qemu_cflags = ['-fsanitize=thread'] + qemu_cflags
467 qemu_ldflags = ['-fsanitize=thread'] + qemu_ldflags
470 # Detect support for PT_GNU_RELRO + DT_BIND_NOW.
471 # The combination is known as "full relro", because .got.plt is read-only too.
472 qemu_ldflags += cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now')
474 if host_os == 'windows'
475 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat')
476 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase', '-Wl,--high-entropy-va')
479 # Exclude --warn-common with TSan to suppress warnings from the TSan libraries.
480 if host_os != 'sunos' and not get_option('tsan')
481 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--warn-common')
484 if get_option('fuzzing')
485 # Specify a filter to only instrument code that is directly related to
487 configure_file(output: 'instrumentation-filter',
488 input: 'scripts/oss-fuzz/instrumentation-filter-template',
491 if cc.compiles('int main () { return 0; }',
492 name: '-fsanitize-coverage-allowlist=/dev/null',
493 args: ['-fsanitize-coverage-allowlist=/dev/null',
494 '-fsanitize-coverage=trace-pc'] )
495 qemu_common_flags += ['-fsanitize-coverage-allowlist=instrumentation-filter']
498 if get_option('fuzzing_engine') == ''
499 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
500 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
501 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
502 # unable to bind the fuzzer-related callbacks added by instrumentation.
503 qemu_common_flags += ['-fsanitize=fuzzer-no-link']
504 qemu_ldflags += ['-fsanitize=fuzzer-no-link']
505 # For the actual fuzzer binaries, we need to link against the libfuzzer
506 # library. They need to be configurable, to support OSS-Fuzz
507 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
509 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
510 # the needed CFLAGS have already been provided
511 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
517 # Check for dependency on LTO
518 if not get_option('b_lto')
519 error('Selected Control-Flow Integrity but LTO is disabled')
522 error('Selected Control-Flow Integrity is not compatible with modules')
524 # Check for cfi flags. CFI requires LTO so we can't use
525 # get_supported_arguments, but need a more complex "compiles" which allows
527 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
528 args: ['-flto', '-fsanitize=cfi-icall'] )
529 cfi_flags += '-fsanitize=cfi-icall'
531 error('-fsanitize=cfi-icall is not supported by the compiler')
533 if cc.compiles('int main () { return 0; }',
534 name: '-fsanitize-cfi-icall-generalize-pointers',
535 args: ['-flto', '-fsanitize=cfi-icall',
536 '-fsanitize-cfi-icall-generalize-pointers'] )
537 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
539 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
541 if get_option('cfi_debug')
542 if cc.compiles('int main () { return 0; }',
543 name: '-fno-sanitize-trap=cfi-icall',
544 args: ['-flto', '-fsanitize=cfi-icall',
545 '-fno-sanitize-trap=cfi-icall'] )
546 cfi_flags += '-fno-sanitize-trap=cfi-icall'
548 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
551 add_global_arguments(cfi_flags, native: false, language: all_languages)
552 add_global_link_arguments(cfi_flags, native: false, language: all_languages)
555 # Check further flags that make QEMU more robust against malicious parties
558 # Zero out registers used during a function call
559 # upon its return. This makes it harder to assemble
560 # ROP gadgets into something usable
561 '-fzero-call-used-regs=used-gpr',
563 # Initialize all stack variables to zero. This makes
564 # it harder to take advantage of uninitialized stack
565 # data to drive exploits
566 '-ftrivial-auto-var-init=zero',
569 qemu_common_flags += cc.get_supported_arguments(hardening_flags)
571 add_global_arguments(qemu_common_flags, native: false, language: all_languages)
572 add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
574 # Collect warning flags we want to set, sorted alphabetically
576 # First enable interesting warnings
579 '-Wexpansion-to-defined',
582 '-Wignored-qualifiers',
583 '-Wimplicit-fallthrough=2',
585 '-Wmissing-format-attribute',
586 '-Wmissing-prototypes',
588 '-Wold-style-declaration',
589 '-Wold-style-definition',
592 '-Wstrict-prototypes',
598 # Then disable some undesirable warnings
599 '-Wno-gnu-variable-sized-type-not-at-end',
600 '-Wno-initializer-overrides',
601 '-Wno-missing-include-dirs',
603 '-Wno-shift-negative-value',
604 '-Wno-string-plus-int',
605 '-Wno-tautological-type-limit-compare',
606 '-Wno-typedef-redefinition',
609 if host_os != 'darwin'
610 warn_flags += ['-Wthread-safety']
613 # Set up C++ compiler flags
615 if 'cpp' in all_languages
616 qemu_cxxflags = ['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'] + qemu_cflags
619 add_project_arguments(qemu_cflags, native: false, language: 'c')
620 add_project_arguments(cc.get_supported_arguments(warn_flags), native: false, language: 'c')
621 if 'cpp' in all_languages
622 add_project_arguments(qemu_cxxflags, native: false, language: 'cpp')
623 add_project_arguments(cxx.get_supported_arguments(warn_flags), native: false, language: 'cpp')
625 if 'objc' in all_languages
626 # Note sanitizer flags are not applied to Objective-C sources!
627 add_project_arguments(objc.get_supported_arguments(warn_flags), native: false, language: 'objc')
629 if host_os == 'linux'
630 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
631 '-isystem', 'linux-headers',
632 language: all_languages)
635 add_project_arguments('-iquote', '.',
636 '-iquote', meson.current_source_dir(),
637 '-iquote', meson.current_source_dir() / 'include',
638 language: all_languages)
640 # If a host-specific include directory exists, list that first...
641 host_include = meson.current_source_dir() / 'host/include/'
642 if fs.is_dir(host_include / host_arch)
643 add_project_arguments('-iquote', host_include / host_arch,
644 language: all_languages)
646 # ... followed by the generic fallback.
647 add_project_arguments('-iquote', host_include / 'generic',
648 language: all_languages)
650 sparse = find_program('cgcc', required: get_option('sparse'))
653 command: [find_program('scripts/check_sparse.py'),
654 'compile_commands.json', sparse.full_path(), '-Wbitwise',
655 '-Wno-transparent-union', '-Wno-old-initializer',
656 '-Wno-non-pointer-null'])
659 #####################################
660 # Host-specific libraries and flags #
661 #####################################
663 libm = cc.find_library('m', required: false)
664 threads = dependency('threads')
665 util = cc.find_library('util', required: false)
671 emulator_link_args = []
676 if host_os == 'windows'
677 midl = find_program('midl', required: false)
678 widl = find_program('widl', required: false)
679 pathcch = cc.find_library('pathcch')
680 socket = cc.find_library('ws2_32')
681 winmm = cc.find_library('winmm')
683 win = import('windows')
684 version_res = win.compile_resources('version.rc',
685 depend_files: files('pc-bios/qemu-nsis.ico'),
686 include_directories: include_directories('.'))
688 elif host_os == 'darwin'
689 coref = dependency('appleframeworks', modules: 'CoreFoundation')
690 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
691 host_dsosuf = '.dylib'
692 elif host_os == 'sunos'
693 socket = [cc.find_library('socket'),
694 cc.find_library('nsl'),
695 cc.find_library('resolv')]
696 elif host_os == 'haiku'
697 socket = [cc.find_library('posix_error_mapper'),
698 cc.find_library('network'),
699 cc.find_library('bsd')]
700 elif host_os == 'openbsd'
701 if get_option('tcg').allowed() and target_dirs.length() > 0
702 # Disable OpenBSD W^X if available
703 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
707 ###############################################
708 # Host-specific configuration of accelerators #
709 ###############################################
712 if get_option('kvm').allowed() and host_os == 'linux'
713 accelerators += 'CONFIG_KVM'
715 if get_option('whpx').allowed() and host_os == 'windows'
716 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
717 error('WHPX requires 64-bit host')
718 elif cc.has_header('winhvplatform.h', required: get_option('whpx')) and \
719 cc.has_header('winhvemulation.h', required: get_option('whpx'))
720 accelerators += 'CONFIG_WHPX'
725 if get_option('hvf').allowed()
726 hvf = dependency('appleframeworks', modules: 'Hypervisor',
727 required: get_option('hvf'))
729 accelerators += 'CONFIG_HVF'
734 if host_os == 'netbsd'
735 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
737 accelerators += 'CONFIG_NVMM'
742 if get_option('tcg').allowed()
743 if host_arch == 'unknown'
744 if not get_option('tcg_interpreter')
745 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
747 elif get_option('tcg_interpreter')
748 warning('Use of the TCG interpreter is not recommended on this host')
749 warning('architecture. There is a native TCG execution backend available')
750 warning('which provides substantially better performance and reliability.')
751 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
752 warning('configuration option on this architecture to use the native')
755 if get_option('tcg_interpreter')
757 elif host_arch == 'x86_64'
759 elif host_arch == 'ppc64'
762 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
763 language: all_languages)
765 accelerators += 'CONFIG_TCG'
768 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
769 error('KVM not available on this platform')
771 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
772 error('HVF not available on this platform')
774 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
775 error('NVMM not available on this platform')
777 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
778 error('WHPX not available on this platform')
782 if get_option('xen').enabled() or (get_option('xen').auto() and have_system)
783 xencontrol = dependency('xencontrol', required: false,
784 method: 'pkg-config')
785 if xencontrol.found()
786 xen_pc = declare_dependency(version: xencontrol.version(),
789 # disabler: true makes xen_pc.found() return false if any is not found
790 dependency('xenstore', required: false,
791 method: 'pkg-config',
793 dependency('xenforeignmemory', required: false,
794 method: 'pkg-config',
796 dependency('xengnttab', required: false,
797 method: 'pkg-config',
799 dependency('xenevtchn', required: false,
800 method: 'pkg-config',
802 dependency('xendevicemodel', required: false,
803 method: 'pkg-config',
805 # optional, no "disabler: true"
806 dependency('xentoolcore', required: false,
807 method: 'pkg-config')])
813 xen_tests = [ '4.11.0', '4.10.0', '4.9.0', '4.8.0', '4.7.1' ]
815 '4.11.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
816 '4.10.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
817 '4.9.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
818 '4.8.0': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
819 '4.7.1': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
822 foreach ver: xen_tests
823 # cache the various library tests to avoid polluting the logs
825 foreach l: xen_libs[ver]
827 xen_deps += { l: cc.find_library(l, required: false) }
829 xen_test_deps += xen_deps[l]
832 # Use -D to pick just one of the test programs in scripts/xen-detect.c
833 xen_version = ver.split('.')
834 xen_ctrl_version = xen_version[0] + \
835 ('0' + xen_version[1]).substring(-2) + \
836 ('0' + xen_version[2]).substring(-2)
837 if cc.links(files('scripts/xen-detect.c'),
838 args: '-DCONFIG_XEN_CTRL_INTERFACE_VERSION=' + xen_ctrl_version,
839 dependencies: xen_test_deps)
840 xen = declare_dependency(version: ver, dependencies: xen_test_deps)
846 accelerators += 'CONFIG_XEN'
847 elif get_option('xen').enabled()
848 error('could not compile and link Xen test program')
851 have_xen_pci_passthrough = get_option('xen_pci_passthrough') \
852 .require(xen.found(),
853 error_message: 'Xen PCI passthrough requested but Xen not enabled') \
854 .require(host_os == 'linux',
855 error_message: 'Xen PCI passthrough not available on this platform') \
856 .require(cpu == 'x86' or cpu == 'x86_64',
857 error_message: 'Xen PCI passthrough not available on this platform') \
864 # When bumping glib minimum version, please check also whether to increase
865 # the _WIN32_WINNT setting in osdep.h according to the value from glib
866 glib_req_ver = '>=2.56.0'
867 glib_pc = dependency('glib-2.0', version: glib_req_ver, required: true,
868 method: 'pkg-config')
871 gmodule = dependency('gmodule-export-2.0', version: glib_req_ver, required: true,
872 method: 'pkg-config')
873 elif get_option('plugins')
874 gmodule = dependency('gmodule-no-export-2.0', version: glib_req_ver, required: true,
875 method: 'pkg-config')
880 # This workaround is required due to a bug in pkg-config file for glib as it
881 # doesn't define GLIB_STATIC_COMPILATION for pkg-config --static
882 if host_os == 'windows' and get_option('prefer_static')
883 glib_cflags += ['-DGLIB_STATIC_COMPILATION']
886 # Sanity check that the current size_t matches the
887 # size that glib thinks it should be. This catches
888 # problems on multi-arch where people try to build
889 # 32-bit QEMU while pointing at 64-bit glib headers
891 if not cc.compiles('''
895 #define QEMU_BUILD_BUG_ON(x) \
896 typedef char qemu_build_bug_on[(x)?-1:1] __attribute__((unused));
899 QEMU_BUILD_BUG_ON(sizeof(size_t) != GLIB_SIZEOF_SIZE_T);
901 }''', dependencies: glib_pc, args: glib_cflags)
902 error('''sizeof(size_t) doesn't match GLIB_SIZEOF_SIZE_T.
903 You probably need to set PKG_CONFIG_LIBDIR" to point
904 to the right pkg-config files for your build target.''')
907 # Silence clang warnings triggered by glib < 2.57.2
908 if not cc.compiles('''
913 static void foo_free(Foo *f)
917 G_DEFINE_AUTOPTR_CLEANUP_FUNC(Foo, foo_free)
918 int main(void) { return 0; }''', dependencies: glib_pc, args: ['-Wunused-function', '-Werror'])
919 glib_cflags += cc.get_supported_arguments('-Wno-unused-function')
921 glib = declare_dependency(dependencies: [glib_pc, gmodule],
922 compile_args: glib_cflags,
923 version: glib_pc.version())
925 # Check whether glib has gslice, which we have to avoid for correctness.
926 # TODO: remove this check and the corresponding workaround (qtree) when
927 # the minimum supported glib is >= 2.75.3
928 glib_has_gslice = glib.version().version_compare('<2.75.3')
930 # override glib dep to include the above refinements
931 meson.override_dependency('glib-2.0', glib)
933 # The path to glib.h is added to all compilation commands.
934 add_project_dependencies(glib.partial_dependency(compile_args: true, includes: true),
935 native: false, language: all_languages)
938 gdbus_codegen = not_found
939 gdbus_codegen_error = '@0@ requires gdbus-codegen, please install libgio'
940 if not get_option('gio').auto() or have_system
941 gio = dependency('gio-2.0', required: get_option('gio'),
942 method: 'pkg-config')
943 if gio.found() and not cc.links('''
947 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
949 }''', dependencies: [glib, gio])
950 if get_option('gio').enabled()
951 error('The installed libgio is broken for static linking')
956 gdbus_codegen = find_program(gio.get_variable('gdbus_codegen'),
957 required: get_option('gio'))
958 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
959 method: 'pkg-config')
960 gio = declare_dependency(dependencies: [gio, gio_unix],
961 version: gio.version())
964 if gdbus_codegen.found() and get_option('cfi')
965 gdbus_codegen = not_found
966 gdbus_codegen_error = '@0@ uses gdbus-codegen, which does not support control flow integrity'
969 xml_pp = find_program('scripts/xml-preprocess.py')
972 if 'ust' in get_option('trace_backends')
973 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
974 method: 'pkg-config')
977 if not get_option('pixman').auto() or have_system or have_tools
978 pixman = dependency('pixman-1', required: get_option('pixman'), version:'>=0.21.8',
979 method: 'pkg-config')
982 zlib = dependency('zlib', required: true)
985 if not get_option('linux_aio').auto() or have_block
986 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
987 required: get_option('linux_aio'))
990 linux_io_uring_test = '''
991 #include <liburing.h>
992 #include <linux/errqueue.h>
994 int main(void) { return 0; }'''
996 linux_io_uring = not_found
997 if not get_option('linux_io_uring').auto() or have_block
998 linux_io_uring = dependency('liburing', version: '>=0.3',
999 required: get_option('linux_io_uring'),
1000 method: 'pkg-config')
1001 if not cc.links(linux_io_uring_test)
1002 linux_io_uring = not_found
1007 if not get_option('libnfs').auto() or have_block
1008 libnfs = dependency('libnfs', version: '>=1.9.3',
1009 required: get_option('libnfs'),
1010 method: 'pkg-config')
1015 #include <sys/types.h>
1016 #ifdef CONFIG_LIBATTR
1017 #include <attr/xattr.h>
1019 #include <sys/xattr.h>
1021 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
1024 have_old_libattr = false
1025 if get_option('attr').allowed()
1026 if cc.links(libattr_test)
1027 libattr = declare_dependency()
1029 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
1030 required: get_option('attr'))
1031 if libattr.found() and not \
1032 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
1034 if get_option('attr').enabled()
1035 error('could not link libattr')
1037 warning('could not link libattr, disabling')
1040 have_old_libattr = libattr.found()
1045 cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
1046 required: get_option('cocoa'))
1048 vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
1049 if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
1050 'VMNET_BRIDGED_MODE',
1051 dependencies: vmnet)
1053 if get_option('vmnet').enabled()
1054 error('vmnet.framework API is outdated')
1056 warning('vmnet.framework API is outdated, disabling')
1061 seccomp_has_sysrawrc = false
1062 if not get_option('seccomp').auto() or have_system or have_tools
1063 seccomp = dependency('libseccomp', version: '>=2.3.0',
1064 required: get_option('seccomp'),
1065 method: 'pkg-config')
1067 seccomp_has_sysrawrc = cc.has_header_symbol('seccomp.h',
1068 'SCMP_FLTATR_API_SYSRAWRC',
1069 dependencies: seccomp)
1073 libcap_ng = not_found
1074 if not get_option('cap_ng').auto() or have_system or have_tools
1075 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
1076 required: get_option('cap_ng'))
1078 if libcap_ng.found() and not cc.links('''
1082 capng_capability_to_name(CAPNG_EFFECTIVE);
1084 }''', dependencies: libcap_ng)
1085 libcap_ng = not_found
1086 if get_option('cap_ng').enabled()
1087 error('could not link libcap-ng')
1089 warning('could not link libcap-ng, disabling')
1093 if get_option('xkbcommon').auto() and not have_system and not have_tools
1094 xkbcommon = not_found
1096 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
1097 method: 'pkg-config')
1101 if not get_option('slirp').auto() or have_system
1102 slirp = dependency('slirp', required: get_option('slirp'),
1103 method: 'pkg-config')
1104 # slirp < 4.7 is incompatible with CFI support in QEMU. This is because
1105 # it passes function pointers within libslirp as callbacks for timers.
1106 # When using a system-wide shared libslirp, the type information for the
1107 # callback is missing and the timer call produces a false positive with CFI.
1108 # Do not use the "version" keyword argument to produce a better error.
1109 # with control-flow integrity.
1110 if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
1111 if get_option('slirp').enabled()
1112 error('Control-Flow Integrity requires libslirp 4.7.')
1114 warning('Cannot use libslirp since Control-Flow Integrity requires libslirp >= 4.7.')
1121 if not get_option('vde').auto() or have_system or have_tools
1122 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
1123 required: get_option('vde'))
1125 if vde.found() and not cc.links('''
1126 #include <libvdeplug.h>
1129 struct vde_open_args a = {0, 0, 0};
1133 }''', dependencies: vde)
1135 if get_option('cap_ng').enabled()
1136 error('could not link libvdeplug')
1138 warning('could not link libvdeplug, disabling')
1143 if not get_option('pa').auto() or (host_os == 'linux' and have_system)
1144 pulse = dependency('libpulse', required: get_option('pa'),
1145 method: 'pkg-config')
1148 if not get_option('alsa').auto() or (host_os == 'linux' and have_system)
1149 alsa = dependency('alsa', required: get_option('alsa'),
1150 method: 'pkg-config')
1153 if not get_option('jack').auto() or have_system
1154 jack = dependency('jack', required: get_option('jack'),
1155 method: 'pkg-config')
1157 pipewire = not_found
1158 if not get_option('pipewire').auto() or (host_os == 'linux' and have_system)
1159 pipewire = dependency('libpipewire-0.3', version: '>=0.3.60',
1160 required: get_option('pipewire'),
1161 method: 'pkg-config')
1164 if not get_option('sndio').auto() or have_system
1165 sndio = dependency('sndio', required: get_option('sndio'),
1166 method: 'pkg-config')
1169 spice_protocol = not_found
1170 if not get_option('spice_protocol').auto() or have_system
1171 spice_protocol = dependency('spice-protocol', version: '>=0.14.0',
1172 required: get_option('spice_protocol'),
1173 method: 'pkg-config')
1176 if get_option('spice') \
1177 .disable_auto_if(not have_system) \
1178 .require(pixman.found(),
1179 error_message: 'cannot enable SPICE if pixman is not available') \
1181 spice = dependency('spice-server', version: '>=0.14.0',
1182 required: get_option('spice'),
1183 method: 'pkg-config')
1185 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
1187 rt = cc.find_library('rt', required: false)
1189 libiscsi = not_found
1190 if not get_option('libiscsi').auto() or have_block
1191 libiscsi = dependency('libiscsi', version: '>=1.9.0',
1192 required: get_option('libiscsi'),
1193 method: 'pkg-config')
1196 if not get_option('zstd').auto() or have_block
1197 zstd = dependency('libzstd', version: '>=1.4.0',
1198 required: get_option('zstd'),
1199 method: 'pkg-config')
1203 have_vhost_user_gpu = have_tools and host_os == 'linux' and pixman.found()
1204 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
1205 virgl = dependency('virglrenderer',
1206 method: 'pkg-config',
1207 required: get_option('virglrenderer'))
1209 rutabaga = not_found
1210 if not get_option('rutabaga_gfx').auto() or have_system or have_vhost_user_gpu
1211 rutabaga = dependency('rutabaga_gfx_ffi',
1212 method: 'pkg-config',
1213 required: get_option('rutabaga_gfx'))
1216 if not get_option('blkio').auto() or have_block
1217 blkio = dependency('blkio',
1218 method: 'pkg-config',
1219 required: get_option('blkio'))
1222 if not get_option('curl').auto() or have_block
1223 curl = dependency('libcurl', version: '>=7.29.0',
1224 method: 'pkg-config',
1225 required: get_option('curl'))
1228 if host_os == 'linux' and (have_system or have_tools)
1229 libudev = dependency('libudev',
1230 method: 'pkg-config',
1231 required: get_option('libudev'))
1234 mpathlibs = [libudev]
1235 mpathpersist = not_found
1236 if host_os == 'linux' and have_tools and get_option('mpath').allowed()
1237 mpath_test_source = '''
1238 #include <libudev.h>
1239 #include <mpath_persist.h>
1240 unsigned mpath_mx_alloc_len = 1024;
1242 static struct config *multipath_conf;
1243 extern struct udev *udev;
1244 extern struct config *get_multipath_config(void);
1245 extern void put_multipath_config(struct config *conf);
1247 struct config *get_multipath_config(void) { return multipath_conf; }
1248 void put_multipath_config(struct config *conf) { }
1251 multipath_conf = mpath_lib_init();
1254 libmpathpersist = cc.find_library('mpathpersist',
1255 required: get_option('mpath'))
1256 if libmpathpersist.found()
1257 mpathlibs += libmpathpersist
1258 if get_option('prefer_static')
1259 mpathlibs += cc.find_library('devmapper',
1260 required: get_option('mpath'))
1262 mpathlibs += cc.find_library('multipath',
1263 required: get_option('mpath'))
1264 foreach lib: mpathlibs
1270 if mpathlibs.length() == 0
1271 msg = 'Dependencies missing for libmpathpersist'
1272 elif cc.links(mpath_test_source, dependencies: mpathlibs)
1273 mpathpersist = declare_dependency(dependencies: mpathlibs)
1275 msg = 'Cannot detect libmpathpersist API'
1277 if not mpathpersist.found()
1278 if get_option('mpath').enabled()
1281 warning(msg + ', disabling')
1289 if have_system and get_option('curses').allowed()
1291 #if defined(__APPLE__) || defined(__OpenBSD__)
1292 #define _XOPEN_SOURCE_EXTENDED 1
1299 setlocale(LC_ALL, "");
1301 addwstr(L"wide chars\n");
1303 add_wch(WACS_DEGREE);
1307 curses_dep_list = host_os == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
1308 curses = dependency(curses_dep_list,
1310 method: 'pkg-config')
1311 msg = get_option('curses').enabled() ? 'curses library not found' : ''
1312 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
1314 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
1315 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses],
1316 version: curses.version())
1318 msg = 'curses package not usable'
1322 if not curses.found()
1323 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1324 if host_os != 'windows' and not has_curses_h
1325 message('Trying with /usr/include/ncursesw')
1326 curses_compile_args += ['-I/usr/include/ncursesw']
1327 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1330 curses_libname_list = (host_os == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
1331 foreach curses_libname : curses_libname_list
1332 libcurses = cc.find_library(curses_libname,
1334 if libcurses.found()
1335 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
1336 curses = declare_dependency(compile_args: curses_compile_args,
1337 dependencies: [libcurses])
1340 msg = 'curses library not usable'
1346 if get_option('iconv').allowed()
1347 foreach link_args : [ ['-liconv'], [] ]
1348 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
1349 # We need to use libiconv if available because mixing libiconv's headers with
1350 # the system libc does not work.
1351 # However, without adding glib to the dependencies -L/usr/local/lib will not be
1352 # included in the command line and libiconv will not be found.
1356 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
1357 return conv != (iconv_t) -1;
1358 }''', args: link_args, dependencies: glib)
1359 iconv = declare_dependency(link_args: link_args, dependencies: glib)
1364 if curses.found() and not iconv.found()
1365 if get_option('iconv').enabled()
1366 error('iconv not available')
1368 msg = 'iconv required for curses UI but not available'
1371 if not curses.found() and msg != ''
1372 if get_option('curses').enabled()
1375 warning(msg + ', disabling')
1381 if not get_option('brlapi').auto() or have_system
1382 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
1383 required: get_option('brlapi'))
1384 if brlapi.found() and not cc.links('''
1387 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
1389 if get_option('brlapi').enabled()
1390 error('could not link brlapi')
1392 warning('could not link brlapi, disabling')
1398 if not get_option('sdl').auto() or have_system
1399 sdl = dependency('sdl2', required: get_option('sdl'))
1400 sdl_image = not_found
1403 # Some versions of SDL have problems with -Wundef
1404 if not cc.compiles('''
1406 #include <SDL_syswm.h>
1407 int main(int argc, char *argv[]) { return 0; }
1408 ''', dependencies: sdl, args: '-Werror=undef')
1409 sdl = declare_dependency(compile_args: '-Wno-undef',
1411 version: sdl.version())
1413 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
1414 method: 'pkg-config')
1416 if get_option('sdl_image').enabled()
1417 error('sdl-image required, but SDL was @0@'.format(
1418 get_option('sdl').disabled() ? 'disabled' : 'not found'))
1420 sdl_image = not_found
1424 if not get_option('rbd').auto() or have_block
1425 librados = cc.find_library('rados', required: get_option('rbd'))
1426 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
1427 required: get_option('rbd'))
1428 if librados.found() and librbd.found()
1431 #include <rbd/librbd.h>
1434 rados_create(&cluster, NULL);
1435 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
1439 }''', dependencies: [librbd, librados])
1440 rbd = declare_dependency(dependencies: [librbd, librados])
1441 elif get_option('rbd').enabled()
1442 error('librbd >= 1.12.0 required')
1444 warning('librbd >= 1.12.0 not found, disabling')
1449 glusterfs = not_found
1450 glusterfs_ftruncate_has_stat = false
1451 glusterfs_iocb_has_stat = false
1452 if not get_option('glusterfs').auto() or have_block
1453 glusterfs = dependency('glusterfs-api', version: '>=3',
1454 required: get_option('glusterfs'),
1455 method: 'pkg-config')
1456 if glusterfs.found()
1457 glusterfs_ftruncate_has_stat = cc.links('''
1458 #include <glusterfs/api/glfs.h>
1463 /* new glfs_ftruncate() passes two additional args */
1464 return glfs_ftruncate(NULL, 0, NULL, NULL);
1466 ''', dependencies: glusterfs)
1467 glusterfs_iocb_has_stat = cc.links('''
1468 #include <glusterfs/api/glfs.h>
1470 /* new glfs_io_cbk() passes two additional glfs_stat structs */
1472 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
1478 glfs_io_cbk iocb = &glusterfs_iocb;
1479 iocb(NULL, 0 , NULL, NULL, NULL);
1482 ''', dependencies: glusterfs)
1487 if get_option('hv_balloon').allowed() and have_system
1490 #include <gmodule.h>
1494 tree = g_tree_new((GCompareFunc)strcmp);
1495 (void)g_tree_node_first(tree);
1496 g_tree_destroy(tree);
1499 ''', dependencies: glib)
1502 if get_option('hv_balloon').enabled()
1503 error('could not enable hv-balloon, update your glib')
1505 warning('could not find glib support for hv-balloon, disabling')
1511 if not get_option('libssh').auto() or have_block
1512 libssh = dependency('libssh', version: '>=0.8.7',
1513 method: 'pkg-config',
1514 required: get_option('libssh'))
1517 libbzip2 = not_found
1518 if not get_option('bzip2').auto() or have_block
1519 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
1520 required: get_option('bzip2'))
1521 if libbzip2.found() and not cc.links('''
1523 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
1524 libbzip2 = not_found
1525 if get_option('bzip2').enabled()
1526 error('could not link libbzip2')
1528 warning('could not link libbzip2, disabling')
1533 liblzfse = not_found
1534 if not get_option('lzfse').auto() or have_block
1535 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
1536 required: get_option('lzfse'))
1538 if liblzfse.found() and not cc.links('''
1540 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
1541 liblzfse = not_found
1542 if get_option('lzfse').enabled()
1543 error('could not link liblzfse')
1545 warning('could not link liblzfse, disabling')
1550 if get_option('oss').allowed() and have_system
1551 if not cc.has_header('sys/soundcard.h')
1553 elif host_os == 'netbsd'
1554 oss = cc.find_library('ossaudio', required: get_option('oss'))
1556 oss = declare_dependency()
1560 if get_option('oss').enabled()
1561 error('OSS not found')
1566 if not get_option('dsound').auto() or (host_os == 'windows' and have_system)
1567 if cc.has_header('dsound.h')
1568 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
1571 if not dsound.found()
1572 if get_option('dsound').enabled()
1573 error('DirectSound not found')
1578 coreaudio = not_found
1579 if not get_option('coreaudio').auto() or (host_os == 'darwin' and have_system)
1580 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
1581 required: get_option('coreaudio'))
1585 if not get_option('opengl').auto() or have_system or have_vhost_user_gpu
1586 epoxy = dependency('epoxy', method: 'pkg-config',
1587 required: get_option('opengl'))
1588 if cc.has_header('epoxy/egl.h', dependencies: epoxy)
1590 elif get_option('opengl').enabled()
1591 error('epoxy/egl.h not found')
1595 if (have_system or have_tools) and (virgl.found() or opengl.found())
1596 gbm = dependency('gbm', method: 'pkg-config', required: false)
1598 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and opengl.found() and gbm.found()
1601 gnutls_crypto = not_found
1602 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1603 # For general TLS support our min gnutls matches
1604 # that implied by our platform support matrix
1606 # For the crypto backends, we look for a newer
1609 # Version 3.6.8 is needed to get XTS
1610 # Version 3.6.13 is needed to get PBKDF
1611 # Version 3.6.14 is needed to get HW accelerated XTS
1613 # If newer enough gnutls isn't available, we can
1614 # still use a different crypto backend to satisfy
1615 # the platform support requirements
1616 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1617 method: 'pkg-config',
1619 if gnutls_crypto.found()
1620 gnutls = gnutls_crypto
1622 # Our min version if all we need is TLS
1623 gnutls = dependency('gnutls', version: '>=3.5.18',
1624 method: 'pkg-config',
1625 required: get_option('gnutls'))
1629 # We prefer use of gnutls for crypto, unless the options
1630 # explicitly asked for nettle or gcrypt.
1632 # If gnutls isn't available for crypto, then we'll prefer
1633 # gcrypt over nettle for performance reasons.
1637 crypto_sm4 = not_found
1640 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1641 error('Only one of gcrypt & nettle can be enabled')
1644 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1645 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1646 gnutls_crypto = not_found
1649 if not gnutls_crypto.found()
1650 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1651 gcrypt = dependency('libgcrypt', version: '>=1.8',
1652 method: 'config-tool',
1653 required: get_option('gcrypt'))
1654 # Debian has removed -lgpg-error from libgcrypt-config
1655 # as it "spreads unnecessary dependencies" which in
1656 # turn breaks static builds...
1657 if gcrypt.found() and get_option('prefer_static')
1658 gcrypt = declare_dependency(dependencies:
1660 cc.find_library('gpg-error', required: true)],
1661 version: gcrypt.version())
1664 # SM4 ALG is available in libgcrypt >= 1.9
1665 if gcrypt.found() and not cc.links('''
1668 gcry_cipher_hd_t handler;
1669 gcry_cipher_open(&handler, GCRY_CIPHER_SM4, GCRY_CIPHER_MODE_ECB, 0);
1671 }''', dependencies: gcrypt)
1672 crypto_sm4 = not_found
1675 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1676 nettle = dependency('nettle', version: '>=3.4',
1677 method: 'pkg-config',
1678 required: get_option('nettle'))
1679 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1683 # SM4 ALG is available in nettle >= 3.9
1684 if nettle.found() and not cc.links('''
1685 #include <nettle/sm4.h>
1688 unsigned char key[16] = {0};
1689 sm4_set_encrypt_key(&ctx, key);
1691 }''', dependencies: nettle)
1692 crypto_sm4 = not_found
1697 capstone = not_found
1698 if not get_option('capstone').auto() or have_system or have_user
1699 capstone = dependency('capstone', version: '>=3.0.5',
1700 method: 'pkg-config',
1701 required: get_option('capstone'))
1703 # Some versions of capstone have broken pkg-config file
1704 # that reports a wrong -I path, causing the #include to
1705 # fail later. If the system has such a broken version
1707 if capstone.found() and not cc.compiles('#include <capstone.h>',
1708 dependencies: [capstone])
1709 capstone = not_found
1710 if get_option('capstone').enabled()
1711 error('capstone requested, but it does not appear to work')
1716 gmp = dependency('gmp', required: false, method: 'pkg-config')
1717 if nettle.found() and gmp.found()
1718 hogweed = dependency('hogweed', version: '>=3.4',
1719 method: 'pkg-config',
1720 required: get_option('nettle'))
1727 have_gtk_clipboard = get_option('gtk_clipboard').enabled()
1729 if get_option('gtk') \
1730 .disable_auto_if(not have_system) \
1731 .require(pixman.found(),
1732 error_message: 'cannot enable GTK if pixman is not available') \
1734 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1735 method: 'pkg-config',
1736 required: get_option('gtk'))
1738 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1739 method: 'pkg-config',
1741 gtk = declare_dependency(dependencies: [gtk, gtkx11],
1742 version: gtk.version())
1744 if not get_option('vte').auto() or have_system
1745 vte = dependency('vte-2.91',
1746 method: 'pkg-config',
1747 required: get_option('vte'))
1749 elif have_gtk_clipboard
1750 error('GTK clipboard requested, but GTK not found')
1756 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found())
1759 if get_option('png').allowed() and have_system
1760 png = dependency('libpng', version: '>=1.6.34', required: get_option('png'),
1761 method: 'pkg-config')
1766 if get_option('vnc') \
1767 .disable_auto_if(not have_system) \
1768 .require(pixman.found(),
1769 error_message: 'cannot enable VNC if pixman is not available') \
1771 vnc = declare_dependency() # dummy dependency
1772 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1773 method: 'pkg-config')
1774 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1775 required: get_option('vnc_sasl'))
1777 sasl = declare_dependency(dependencies: sasl,
1778 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1783 if not get_option('auth_pam').auto() or have_system
1784 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1785 required: get_option('auth_pam'))
1787 if pam.found() and not cc.links('''
1789 #include <security/pam_appl.h>
1791 const char *service_name = "qemu";
1792 const char *user = "frank";
1793 const struct pam_conv pam_conv = { 0 };
1794 pam_handle_t *pamh = NULL;
1795 pam_start(service_name, user, &pam_conv, &pamh);
1797 }''', dependencies: pam)
1799 if get_option('auth_pam').enabled()
1800 error('could not link libpam')
1802 warning('could not link libpam, disabling')
1807 if not get_option('snappy').auto() or have_system
1808 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1809 required: get_option('snappy'))
1811 if snappy.found() and not cc.links('''
1812 #include <snappy-c.h>
1813 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1815 if get_option('snappy').enabled()
1816 error('could not link libsnappy')
1818 warning('could not link libsnappy, disabling')
1823 if not get_option('lzo').auto() or have_system
1824 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1825 required: get_option('lzo'))
1827 if lzo.found() and not cc.links('''
1828 #include <lzo/lzo1x.h>
1829 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1831 if get_option('lzo').enabled()
1832 error('could not link liblzo2')
1834 warning('could not link liblzo2, disabling')
1839 if not get_option('numa').auto() or have_system or have_tools
1840 numa = cc.find_library('numa', has_headers: ['numa.h'],
1841 required: get_option('numa'))
1843 if numa.found() and not cc.links('''
1845 int main(void) { return numa_available(); }
1846 ''', dependencies: numa)
1848 if get_option('numa').enabled()
1849 error('could not link numa')
1851 warning('could not link numa, disabling')
1856 if not get_option('rdma').auto() or have_system
1857 libumad = cc.find_library('ibumad', required: get_option('rdma'))
1858 rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'],
1859 required: get_option('rdma')),
1860 cc.find_library('ibverbs', required: get_option('rdma')),
1862 rdma = declare_dependency(dependencies: rdma_libs)
1863 foreach lib: rdma_libs
1871 if not get_option('smartcard').auto() or have_system
1872 cacard = dependency('libcacard', required: get_option('smartcard'),
1873 version: '>=2.5.1', method: 'pkg-config')
1876 if not get_option('u2f').auto() or have_system
1877 u2f = dependency('u2f-emu', required: get_option('u2f'),
1878 method: 'pkg-config')
1881 if not get_option('canokey').auto() or have_system
1882 canokey = dependency('canokey-qemu', required: get_option('canokey'),
1883 method: 'pkg-config')
1885 usbredir = not_found
1886 if not get_option('usb_redir').auto() or have_system
1887 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1888 version: '>=0.6', method: 'pkg-config')
1891 if not get_option('libusb').auto() or have_system
1892 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1893 version: '>=1.0.13', method: 'pkg-config')
1897 if not get_option('libpmem').auto() or have_system
1898 libpmem = dependency('libpmem', required: get_option('libpmem'),
1899 method: 'pkg-config')
1901 libdaxctl = not_found
1902 if not get_option('libdaxctl').auto() or have_system
1903 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1904 version: '>=57', method: 'pkg-config')
1908 tasn1 = dependency('libtasn1',
1909 method: 'pkg-config')
1911 keyutils = not_found
1912 if not get_option('libkeyutils').auto() or have_block
1913 keyutils = dependency('libkeyutils', required: get_option('libkeyutils'),
1914 method: 'pkg-config')
1917 has_gettid = cc.has_function('gettid')
1920 selinux = dependency('libselinux',
1921 required: get_option('selinux'),
1922 method: 'pkg-config')
1927 if get_option('malloc') == 'system'
1929 get_option('malloc_trim').allowed() and \
1930 cc.has_function('malloc_trim', prefix: '#include <malloc.h>')
1932 has_malloc_trim = false
1933 malloc = cc.find_library(get_option('malloc'), required: true)
1935 if not has_malloc_trim and get_option('malloc_trim').enabled()
1936 if get_option('malloc') == 'system'
1937 error('malloc_trim not available on this platform.')
1939 error('malloc_trim not available with non-libc memory allocator')
1943 gnu_source_prefix = '''
1949 # Check whether the glibc provides STATX_BASIC_STATS
1951 has_statx = cc.has_header_symbol('sys/stat.h', 'STATX_BASIC_STATS', prefix: gnu_source_prefix)
1953 # Check whether statx() provides mount ID information
1955 has_statx_mnt_id = cc.has_header_symbol('sys/stat.h', 'STATX_MNT_ID', prefix: gnu_source_prefix)
1957 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
1958 .require(host_os == 'linux',
1959 error_message: 'vhost_user_blk_server requires linux') \
1960 .require(have_vhost_user,
1961 error_message: 'vhost_user_blk_server requires vhost-user support') \
1962 .disable_auto_if(not have_tools and not have_system) \
1965 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1966 error('Cannot enable fuse-lseek while fuse is disabled')
1969 fuse = dependency('fuse3', required: get_option('fuse'),
1970 version: '>=3.1', method: 'pkg-config')
1972 fuse_lseek = not_found
1973 if get_option('fuse_lseek').allowed()
1974 if fuse.version().version_compare('>=3.8')
1976 fuse_lseek = declare_dependency()
1977 elif get_option('fuse_lseek').enabled()
1979 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1981 error('fuse-lseek requires libfuse, which was not found')
1986 have_libvduse = (host_os == 'linux')
1987 if get_option('libvduse').enabled()
1988 if host_os != 'linux'
1989 error('libvduse requires linux')
1991 elif get_option('libvduse').disabled()
1992 have_libvduse = false
1995 have_vduse_blk_export = (have_libvduse and host_os == 'linux')
1996 if get_option('vduse_blk_export').enabled()
1997 if host_os != 'linux'
1998 error('vduse_blk_export requires linux')
1999 elif not have_libvduse
2000 error('vduse_blk_export requires libvduse support')
2002 elif get_option('vduse_blk_export').disabled()
2003 have_vduse_blk_export = false
2007 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
2008 if libbpf.found() and not cc.links('''
2009 #include <bpf/libbpf.h>
2012 bpf_object__destroy_skeleton(NULL);
2014 }''', dependencies: libbpf)
2016 if get_option('bpf').enabled()
2017 error('libbpf skeleton test failed')
2019 warning('libbpf skeleton test failed, disabling')
2025 if not get_option('af_xdp').auto() or have_system
2026 libxdp = dependency('libxdp', required: get_option('af_xdp'),
2027 version: '>=1.4.0', method: 'pkg-config')
2032 if not get_option('libdw').auto() or \
2033 (not get_option('prefer_static') and (have_system or have_user))
2034 libdw = dependency('libdw',
2035 method: 'pkg-config',
2036 required: get_option('libdw'))
2043 config_host_data = configuration_data()
2045 audio_drivers_selected = []
2047 audio_drivers_available = {
2048 'alsa': alsa.found(),
2049 'coreaudio': coreaudio.found(),
2050 'dsound': dsound.found(),
2051 'jack': jack.found(),
2053 'pa': pulse.found(),
2054 'pipewire': pipewire.found(),
2056 'sndio': sndio.found(),
2058 foreach k, v: audio_drivers_available
2059 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
2062 # Default to native drivers first, OSS second, SDL third
2063 audio_drivers_priority = \
2064 [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \
2065 (host_os == 'linux' ? [] : [ 'sdl' ])
2066 audio_drivers_default = []
2067 foreach k: audio_drivers_priority
2068 if audio_drivers_available[k]
2069 audio_drivers_default += k
2073 foreach k: get_option('audio_drv_list')
2075 audio_drivers_selected += audio_drivers_default
2076 elif not audio_drivers_available[k]
2077 error('Audio driver "@0@" not available.'.format(k))
2079 audio_drivers_selected += k
2083 config_host_data.set('CONFIG_AUDIO_DRIVERS',
2084 '"' + '", "'.join(audio_drivers_selected) + '", ')
2086 have_host_block_device = (host_os != 'darwin' or
2087 cc.has_header('IOKit/storage/IOMedia.h'))
2089 dbus_display = get_option('dbus_display') \
2090 .require(gio.version().version_compare('>=2.64'),
2091 error_message: '-display dbus requires glib>=2.64') \
2092 .require(gdbus_codegen.found(),
2093 error_message: gdbus_codegen_error.format('-display dbus')) \
2096 have_virtfs = get_option('virtfs') \
2097 .require(host_os == 'linux' or host_os == 'darwin',
2098 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
2099 .require(host_os == 'linux' or cc.has_function('pthread_fchdir_np'),
2100 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
2101 .require(host_os == 'darwin' or libattr.found(),
2102 error_message: 'virtio-9p (virtfs) on Linux requires libattr-devel') \
2103 .disable_auto_if(not have_tools and not have_system) \
2106 have_virtfs_proxy_helper = get_option('virtfs_proxy_helper') \
2107 .require(host_os != 'darwin', error_message: 'the virtfs proxy helper is incompatible with macOS') \
2108 .require(have_virtfs, error_message: 'the virtfs proxy helper requires that virtfs is enabled') \
2109 .disable_auto_if(not have_tools) \
2110 .require(libcap_ng.found(), error_message: 'the virtfs proxy helper requires libcap-ng') \
2113 if get_option('block_drv_ro_whitelist') == ''
2114 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
2116 config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
2117 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
2119 if get_option('block_drv_rw_whitelist') == ''
2120 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
2122 config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
2123 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
2126 foreach k : get_option('trace_backends')
2127 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
2129 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
2130 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
2132 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
2134 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
2135 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
2136 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
2137 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
2138 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
2140 qemu_firmwarepath = ''
2141 foreach k : get_option('qemu_firmwarepath')
2142 qemu_firmwarepath += '"' + get_option('prefix') / k + '", '
2144 config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath)
2146 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
2147 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
2148 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
2149 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
2150 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
2151 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
2154 config_host_data.set('CONFIG_STAMP', run_command(
2155 meson.current_source_dir() / 'scripts/qemu-stamp.py',
2156 meson.project_version(), get_option('pkgversion'), '--',
2157 meson.current_source_dir() / 'configure',
2158 capture: true, check: true).stdout().strip())
2161 have_slirp_smbd = get_option('slirp_smbd') \
2162 .require(host_os != 'windows', error_message: 'Host smbd not supported on this platform.') \
2165 smbd_path = get_option('smbd')
2167 smbd_path = (host_os == 'sunos' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
2169 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
2172 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
2174 kvm_targets_c = '""'
2175 if get_option('kvm').allowed() and host_os == 'linux'
2176 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
2178 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
2180 if get_option('module_upgrades') and not enable_modules
2181 error('Cannot enable module-upgrades as modules are not enabled')
2183 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
2185 config_host_data.set('CONFIG_ATTR', libattr.found())
2186 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
2187 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
2188 config_host_data.set('CONFIG_BSD', host_os in bsd_oses)
2189 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2190 config_host_data.set('CONFIG_COCOA', cocoa.found())
2191 config_host_data.set('CONFIG_DARWIN', host_os == 'darwin')
2192 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
2193 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
2194 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
2195 config_host_data.set('CONFIG_LINUX', host_os == 'linux')
2196 config_host_data.set('CONFIG_POSIX', host_os != 'windows')
2197 config_host_data.set('CONFIG_WIN32', host_os == 'windows')
2198 config_host_data.set('CONFIG_LZO', lzo.found())
2199 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
2200 config_host_data.set('CONFIG_BLKIO', blkio.found())
2202 config_host_data.set('CONFIG_BLKIO_VHOST_VDPA_FD',
2203 blkio.version().version_compare('>=1.3.0'))
2205 config_host_data.set('CONFIG_CURL', curl.found())
2206 config_host_data.set('CONFIG_CURSES', curses.found())
2207 config_host_data.set('CONFIG_GBM', gbm.found())
2208 config_host_data.set('CONFIG_GIO', gio.found())
2209 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
2210 if glusterfs.found()
2211 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
2212 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
2213 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
2214 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
2215 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
2216 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
2218 config_host_data.set('CONFIG_GTK', gtk.found())
2219 config_host_data.set('CONFIG_VTE', vte.found())
2220 config_host_data.set('CONFIG_GTK_CLIPBOARD', have_gtk_clipboard)
2221 config_host_data.set('CONFIG_HEXAGON_IDEF_PARSER', get_option('hexagon_idef_parser'))
2222 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
2223 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
2224 config_host_data.set('CONFIG_EBPF', libbpf.found())
2225 config_host_data.set('CONFIG_AF_XDP', libxdp.found())
2226 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
2227 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
2228 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
2229 config_host_data.set('CONFIG_LIBSSH', libssh.found())
2230 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
2231 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
2232 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
2233 config_host_data.set('CONFIG_MODULES', enable_modules)
2234 config_host_data.set('CONFIG_NUMA', numa.found())
2236 config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY',
2237 cc.has_function('numa_has_preferred_many',
2238 dependencies: numa))
2240 config_host_data.set('CONFIG_OPENGL', opengl.found())
2241 config_host_data.set('CONFIG_PLUGIN', get_option('plugins'))
2242 config_host_data.set('CONFIG_RBD', rbd.found())
2243 config_host_data.set('CONFIG_RDMA', rdma.found())
2244 config_host_data.set('CONFIG_RELOCATABLE', get_option('relocatable'))
2245 config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack'))
2246 config_host_data.set('CONFIG_SDL', sdl.found())
2247 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
2248 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
2250 config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc)
2252 config_host_data.set('CONFIG_PIXMAN', pixman.found())
2253 config_host_data.set('CONFIG_SLIRP', slirp.found())
2254 config_host_data.set('CONFIG_SNAPPY', snappy.found())
2255 config_host_data.set('CONFIG_SOLARIS', host_os == 'sunos')
2256 if get_option('tcg').allowed()
2257 config_host_data.set('CONFIG_TCG', 1)
2258 config_host_data.set('CONFIG_TCG_INTERPRETER', tcg_arch == 'tci')
2260 config_host_data.set('CONFIG_TPM', have_tpm)
2261 config_host_data.set('CONFIG_TSAN', get_option('tsan'))
2262 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
2263 config_host_data.set('CONFIG_VDE', vde.found())
2264 config_host_data.set('CONFIG_VHOST', have_vhost)
2265 config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
2266 config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
2267 config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)
2268 config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
2269 config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
2270 config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
2271 config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
2272 config_host_data.set('CONFIG_VMNET', vmnet.found())
2273 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
2274 config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export)
2275 config_host_data.set('CONFIG_PNG', png.found())
2276 config_host_data.set('CONFIG_VNC', vnc.found())
2277 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
2278 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
2280 config_host_data.set('HAVE_VIRGL_D3D_INFO_EXT',
2281 cc.has_member('struct virgl_renderer_resource_info_ext', 'd3d_tex2d',
2282 prefix: '#include <virglrenderer.h>',
2283 dependencies: virgl))
2285 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
2286 config_host_data.set('CONFIG_VTE', vte.found())
2287 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
2288 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
2289 config_host_data.set('CONFIG_GETTID', has_gettid)
2290 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
2291 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
2292 config_host_data.set('CONFIG_TASN1', tasn1.found())
2293 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
2294 config_host_data.set('CONFIG_NETTLE', nettle.found())
2295 config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found())
2296 config_host_data.set('CONFIG_HOGWEED', hogweed.found())
2297 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
2298 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
2299 config_host_data.set('CONFIG_STATX', has_statx)
2300 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
2301 config_host_data.set('CONFIG_ZSTD', zstd.found())
2302 config_host_data.set('CONFIG_FUSE', fuse.found())
2303 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
2304 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
2305 if spice_protocol.found()
2306 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
2307 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
2308 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
2310 config_host_data.set('CONFIG_SPICE', spice.found())
2311 config_host_data.set('CONFIG_X11', x11.found())
2312 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
2313 config_host_data.set('CONFIG_CFI', get_option('cfi'))
2314 config_host_data.set('CONFIG_SELINUX', selinux.found())
2315 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
2316 config_host_data.set('CONFIG_LIBDW', libdw.found())
2318 # protect from xen.version() having less than three components
2319 xen_version = xen.version().split('.') + ['0', '0']
2320 xen_ctrl_version = xen_version[0] + \
2321 ('0' + xen_version[1]).substring(-2) + \
2322 ('0' + xen_version[2]).substring(-2)
2323 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
2325 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
2326 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
2327 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
2328 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
2330 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
2331 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
2333 have_coroutine_pool = get_option('coroutine_pool')
2334 if get_option('debug_stack_usage') and have_coroutine_pool
2335 message('Disabling coroutine pool to measure stack usage')
2336 have_coroutine_pool = false
2338 config_host_data.set('CONFIG_COROUTINE_POOL', have_coroutine_pool)
2339 config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock'))
2340 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
2341 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
2342 config_host_data.set('CONFIG_DEBUG_TCG', get_option('debug_tcg'))
2343 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
2344 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
2345 config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
2348 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
2349 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
2350 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
2351 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
2352 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
2353 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
2354 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
2355 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
2356 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
2357 if host_os == 'windows'
2358 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h'))
2362 config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range'))
2363 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
2364 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
2365 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
2366 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
2367 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
2368 config_host_data.set('CONFIG_GETCPU', cc.has_function('getcpu', prefix: gnu_source_prefix))
2369 config_host_data.set('CONFIG_SCHED_GETCPU', cc.has_function('sched_getcpu', prefix: '#include <sched.h>'))
2370 # Note that we need to specify prefix: here to avoid incorrectly
2371 # thinking that Windows has posix_memalign()
2372 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
2373 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
2374 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
2375 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
2376 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
2377 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
2378 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
2379 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
2380 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
2381 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
2382 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
2383 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
2384 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
2385 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
2386 config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice)
2387 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
2388 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
2389 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
2391 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
2392 cc.has_function('rbd_namespace_exists',
2394 prefix: '#include <rbd/librbd.h>'))
2397 config_host_data.set('HAVE_IBV_ADVISE_MR',
2398 cc.has_function('ibv_advise_mr',
2400 prefix: '#include <infiniband/verbs.h>'))
2403 have_asan_fiber = false
2404 if get_option('sanitizers') and \
2405 not cc.has_function('__sanitizer_start_switch_fiber',
2406 args: '-fsanitize=address',
2407 prefix: '#include <sanitizer/asan_interface.h>')
2408 warning('Missing ASAN due to missing fiber annotation interface')
2409 warning('Without code annotation, the report may be inferior.')
2411 have_asan_fiber = true
2413 config_host_data.set('CONFIG_ASAN_IFACE_FIBER', have_asan_fiber)
2415 have_inotify_init = cc.has_header_symbol('sys/inotify.h', 'inotify_init')
2416 have_inotify_init1 = cc.has_header_symbol('sys/inotify.h', 'inotify_init1')
2418 if (have_inotify_init or have_inotify_init1) and host_os == 'freebsd'
2420 inotify = cc.find_library('inotify')
2421 if have_inotify_init
2422 have_inotify_init = inotify.found()
2424 if have_inotify_init1
2425 have_inotify_init1 = inotify.found()
2428 config_host_data.set('CONFIG_INOTIFY', have_inotify_init)
2429 config_host_data.set('CONFIG_INOTIFY1', have_inotify_init1)
2432 config_host_data.set('CONFIG_BLKZONED',
2433 cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE'))
2434 config_host_data.set('CONFIG_EPOLL_CREATE1',
2435 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
2436 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
2437 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
2438 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
2439 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
2440 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
2441 config_host_data.set('CONFIG_FIEMAP',
2442 cc.has_header('linux/fiemap.h') and
2443 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
2444 config_host_data.set('CONFIG_GETRANDOM',
2445 cc.has_function('getrandom') and
2446 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
2447 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
2448 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
2449 config_host_data.set('CONFIG_RTNETLINK',
2450 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
2451 config_host_data.set('CONFIG_SYSMACROS',
2452 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
2453 config_host_data.set('HAVE_OPTRESET',
2454 cc.has_header_symbol('getopt.h', 'optreset'))
2455 config_host_data.set('HAVE_IPPROTO_MPTCP',
2456 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
2459 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
2460 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
2461 prefix: '#include <signal.h>'))
2462 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
2463 cc.has_member('struct stat', 'st_atim',
2464 prefix: '#include <sys/stat.h>'))
2465 config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY',
2466 cc.has_member('struct blk_zone', 'capacity',
2467 prefix: '#include <linux/blkzoned.h>'))
2470 config_host_data.set('CONFIG_IOVEC',
2471 cc.has_type('struct iovec',
2472 prefix: '#include <sys/uio.h>'))
2473 config_host_data.set('HAVE_UTMPX',
2474 cc.has_type('struct utmpx',
2475 prefix: '#include <utmpx.h>'))
2477 config_host_data.set('CONFIG_EVENTFD', cc.links('''
2478 #include <sys/eventfd.h>
2479 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
2480 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
2483 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
2484 return fdatasync(0);
2486 #error Not supported
2490 has_madvise = cc.links(gnu_source_prefix + '''
2491 #include <sys/types.h>
2492 #include <sys/mman.h>
2494 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
2495 missing_madvise_proto = false
2497 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
2498 # but forget to prototype it. In this case, has_madvise will be true (the
2499 # test program links despite a compile warning). To detect the
2500 # missing-prototype case, we try again with a definitely-bogus prototype.
2501 # This will only compile if the system headers don't provide the prototype;
2502 # otherwise the conflicting prototypes will cause a compiler error.
2503 missing_madvise_proto = cc.links(gnu_source_prefix + '''
2504 #include <sys/types.h>
2505 #include <sys/mman.h>
2507 extern int madvise(int);
2508 int main(void) { return madvise(0); }''')
2510 config_host_data.set('CONFIG_MADVISE', has_madvise)
2511 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
2513 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
2514 #include <sys/mman.h>
2515 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
2516 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
2518 #if !defined(AT_EMPTY_PATH)
2519 # error missing definition
2521 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
2523 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
2524 #include <sys/mman.h>
2526 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
2528 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
2529 #include <pthread.h>
2531 static void *f(void *p) { return NULL; }
2535 pthread_create(&thread, 0, f, 0);
2536 pthread_setname_np(thread, "QEMU");
2538 }''', dependencies: threads))
2539 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
2540 #include <pthread.h>
2542 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
2546 pthread_create(&thread, 0, f, 0);
2548 }''', dependencies: threads))
2549 config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(gnu_source_prefix + '''
2550 #include <pthread.h>
2551 #include <pthread_np.h>
2553 static void *f(void *p) { return NULL; }
2557 pthread_create(&thread, 0, f, 0);
2558 pthread_set_name_np(thread, "QEMU");
2560 }''', dependencies: threads))
2561 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
2562 #include <pthread.h>
2567 pthread_condattr_t attr
2568 pthread_condattr_init(&attr);
2569 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
2571 }''', dependencies: threads))
2572 config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(gnu_source_prefix + '''
2573 #include <pthread.h>
2575 static void *f(void *p) { return NULL; }
2578 int setsize = CPU_ALLOC_SIZE(64);
2581 pthread_create(&thread, 0, f, 0);
2582 cpuset = CPU_ALLOC(64);
2583 CPU_ZERO_S(setsize, cpuset);
2584 pthread_setaffinity_np(thread, setsize, cpuset);
2585 pthread_getaffinity_np(thread, setsize, cpuset);
2588 }''', dependencies: threads))
2589 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
2590 #include <sys/signalfd.h>
2592 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
2593 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
2601 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
2602 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
2606 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
2607 #include <sys/mman.h>
2609 return mlockall(MCL_FUTURE);
2613 if get_option('l2tpv3').allowed() and have_system
2614 have_l2tpv3 = cc.has_type('struct mmsghdr',
2615 prefix: gnu_source_prefix + '''
2616 #include <sys/socket.h>
2617 #include <linux/ip.h>''')
2619 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2622 if get_option('netmap').allowed() and have_system
2623 have_netmap = cc.compiles('''
2624 #include <inttypes.h>
2626 #include <net/netmap.h>
2627 #include <net/netmap_user.h>
2628 #if (NETMAP_API < 11) || (NETMAP_API > 15)
2631 int main(void) { return 0; }''')
2632 if not have_netmap and get_option('netmap').enabled()
2633 error('Netmap headers not available')
2636 config_host_data.set('CONFIG_NETMAP', have_netmap)
2638 # Work around a system header bug with some kernel/XFS header
2639 # versions where they both try to define 'struct fsxattr':
2640 # xfs headers will not try to redefine structs from linux headers
2641 # if this macro is set.
2642 config_host_data.set('HAVE_FSXATTR', cc.links('''
2643 #include <linux/fs.h>
2649 # Some versions of Mac OS X incorrectly define SIZE_MAX
2650 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2654 return printf("%zu", SIZE_MAX);
2655 }''', args: ['-Werror']))
2657 # See if 64-bit atomic operations are supported.
2658 # Note that without __atomic builtins, we can only
2659 # assume atomic loads/stores max at pointer size.
2660 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
2664 uint64_t x = 0, y = 0;
2665 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2666 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2667 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2668 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2669 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2673 has_int128_type = cc.compiles('''
2676 int main(void) { b = a; }''')
2677 config_host_data.set('CONFIG_INT128_TYPE', has_int128_type)
2679 has_int128 = has_int128_type and cc.links('''
2688 config_host_data.set('CONFIG_INT128', has_int128)
2691 # "do we have 128-bit atomics which are handled inline and specifically not
2692 # via libatomic". The reason we can't use libatomic is documented in the
2693 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2694 # We only care about these operations on 16-byte aligned pointers, so
2695 # force 16-byte alignment of the pointer, which may be greater than
2696 # __alignof(unsigned __int128) for the host.
2697 atomic_test_128 = '''
2698 int main(int ac, char **av) {
2699 __uint128_t *p = __builtin_assume_aligned(av[ac - 1], 16);
2700 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED);
2701 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED);
2702 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2705 has_atomic128 = cc.links(atomic_test_128)
2707 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2709 if not has_atomic128
2710 # Even with __builtin_assume_aligned, the above test may have failed
2711 # without optimization enabled. Try again with optimizations locally
2712 # enabled for the function. See
2713 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389
2714 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128)
2715 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt)
2717 if not has_atomic128_opt
2718 config_host_data.set('CONFIG_CMPXCHG128', cc.links('''
2721 __uint128_t x = 0, y = 0;
2722 __sync_val_compare_and_swap_16(&x, y, x);
2730 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2731 #include <sys/auxv.h>
2733 return getauxval(AT_HWCAP) == 0;
2736 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2737 #include <linux/usbdevice_fs.h>
2739 #ifndef USBDEVFS_GET_CAPABILITIES
2740 #error "USBDEVFS_GET_CAPABILITIES undefined"
2743 #ifndef USBDEVFS_DISCONNECT_CLAIM
2744 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2747 int main(void) { return 0; }'''))
2749 have_keyring = get_option('keyring') \
2750 .require(host_os == 'linux', error_message: 'keyring is only available on Linux') \
2751 .require(cc.compiles('''
2753 #include <asm/unistd.h>
2754 #include <linux/keyctl.h>
2755 #include <sys/syscall.h>
2758 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2759 }'''), error_message: 'keyctl syscall not available on this system').allowed()
2760 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2762 have_cpuid_h = cc.links('''
2765 unsigned a, b, c, d;
2766 unsigned max = __get_cpuid_max(0, 0);
2769 __cpuid(1, a, b, c, d);
2773 __cpuid_count(7, 0, a, b, c, d);
2778 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2780 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2781 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2782 .require(cc.links('''
2784 #include <immintrin.h>
2785 static int __attribute__((target("avx2"))) bar(void *a) {
2786 __m256i x = *(__m256i *)a;
2787 return _mm256_testz_si256(x, x);
2789 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2790 '''), error_message: 'AVX2 not available').allowed())
2792 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2793 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2794 .require(cc.links('''
2796 #include <immintrin.h>
2797 static int __attribute__((target("avx512f"))) bar(void *a) {
2798 __m512i x = *(__m512i *)a;
2799 return _mm512_test_epi64_mask(x, x);
2801 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2802 '''), error_message: 'AVX512F not available').allowed())
2804 config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \
2805 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \
2806 .require(cc.links('''
2808 #include <immintrin.h>
2809 static int __attribute__((target("avx512bw"))) bar(void *a) {
2811 __m512i res= _mm512_abs_epi8(*x);
2814 int main(int argc, char *argv[]) { return bar(argv[0]); }
2815 '''), error_message: 'AVX512BW not available').allowed())
2817 # For both AArch64 and AArch32, detect if builtins are available.
2818 config_host_data.set('CONFIG_ARM_AES_BUILTIN', cc.compiles('''
2819 #include <arm_neon.h>
2820 #ifndef __ARM_FEATURE_AES
2821 __attribute__((target("+crypto")))
2823 void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); }
2826 have_pvrdma = get_option('pvrdma') \
2827 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
2828 .require(cc.compiles(gnu_source_prefix + '''
2829 #include <sys/mman.h>
2834 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2837 }'''), error_message: 'PVRDMA requires mremap').allowed()
2840 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.links('''
2841 #include <infiniband/verbs.h>
2845 struct ibv_pd *pd = NULL;
2851 mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2857 if get_option('membarrier').disabled()
2858 have_membarrier = false
2859 elif host_os == 'windows'
2860 have_membarrier = true
2861 elif host_os == 'linux'
2862 have_membarrier = cc.compiles('''
2863 #include <linux/membarrier.h>
2864 #include <sys/syscall.h>
2868 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2869 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2873 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2874 .require(have_membarrier, error_message: 'membarrier system call not available') \
2877 have_afalg = get_option('crypto_afalg') \
2878 .require(cc.compiles(gnu_source_prefix + '''
2880 #include <sys/types.h>
2881 #include <sys/socket.h>
2882 #include <linux/if_alg.h>
2885 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2888 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2889 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2891 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2892 'linux/vm_sockets.h', 'AF_VSOCK',
2893 prefix: '#include <sys/socket.h>',
2897 have_vss_sdk = false # old xp/2003 SDK
2898 if host_os == 'windows' and 'cpp' in all_languages
2899 have_vss = cxx.compiles('''
2900 #define __MIDL_user_allocate_free_DEFINED__
2902 int main(void) { return VSS_CTX_BACKUP; }''')
2903 have_vss_sdk = cxx.has_header('vscoordint.h')
2905 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2907 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2908 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2909 if host_os == 'windows'
2910 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2916 }''', name: '_lock_file and _unlock_file'))
2919 if host_os == 'windows'
2920 mingw_has_setjmp_longjmp = cc.links('''
2924 * These functions are not available in setjmp header, but may be
2925 * available at link time, from libmingwex.a.
2927 extern int __mingw_setjmp(jmp_buf);
2928 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
2930 __mingw_setjmp(env);
2931 __mingw_longjmp(env, 0);
2933 ''', name: 'mingw setjmp and longjmp')
2935 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp
2936 error('mingw must provide setjmp/longjmp for windows-arm64')
2940 ########################
2941 # Target configuration #
2942 ########################
2944 minikconf = find_program('scripts/minikconf.py')
2946 config_all_accel = {}
2947 config_all_devices = {}
2948 config_devices_mak_list = []
2949 config_devices_h = {}
2950 config_target_h = {}
2951 config_target_mak = {}
2954 'alpha' : ['CONFIG_ALPHA_DIS'],
2955 'avr' : ['CONFIG_AVR_DIS'],
2956 'cris' : ['CONFIG_CRIS_DIS'],
2957 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2958 'hppa' : ['CONFIG_HPPA_DIS'],
2959 'i386' : ['CONFIG_I386_DIS'],
2960 'x86_64' : ['CONFIG_I386_DIS'],
2961 'm68k' : ['CONFIG_M68K_DIS'],
2962 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2963 'mips' : ['CONFIG_MIPS_DIS'],
2964 'nios2' : ['CONFIG_NIOS2_DIS'],
2965 'or1k' : ['CONFIG_OPENRISC_DIS'],
2966 'ppc' : ['CONFIG_PPC_DIS'],
2967 'riscv' : ['CONFIG_RISCV_DIS'],
2968 'rx' : ['CONFIG_RX_DIS'],
2969 's390' : ['CONFIG_S390_DIS'],
2970 'sh4' : ['CONFIG_SH4_DIS'],
2971 'sparc' : ['CONFIG_SPARC_DIS'],
2972 'xtensa' : ['CONFIG_XTENSA_DIS'],
2973 'loongarch' : ['CONFIG_LOONGARCH_DIS'],
2976 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2978 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2979 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2980 (pixman.found() ? ['CONFIG_PIXMAN=y'] : []) + \
2981 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2982 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2983 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2984 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2985 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
2986 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2987 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2988 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2989 (host_os == 'linux' ? ['CONFIG_LINUX=y'] : []) + \
2990 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
2991 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
2992 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \
2993 (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : [])
2995 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2997 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2998 actual_target_dirs = []
3000 foreach target : target_dirs
3001 config_target = { 'TARGET_NAME': target.split('-')[0] }
3002 if target.endswith('linux-user')
3003 if host_os != 'linux'
3007 error('Target @0@ is only available on a Linux host'.format(target))
3009 config_target += { 'CONFIG_LINUX_USER': 'y' }
3010 elif target.endswith('bsd-user')
3011 if host_os not in bsd_oses
3015 error('Target @0@ is only available on a BSD host'.format(target))
3017 config_target += { 'CONFIG_BSD_USER': 'y' }
3018 elif target.endswith('softmmu')
3019 config_target += { 'CONFIG_SYSTEM_ONLY': 'y' }
3020 config_target += { 'CONFIG_SOFTMMU': 'y' }
3022 if target.endswith('-user')
3024 'CONFIG_USER_ONLY': 'y',
3025 'CONFIG_QEMU_INTERP_PREFIX':
3026 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
3031 foreach sym: accelerators
3032 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
3033 config_target += { sym: 'y' }
3034 config_all_accel += { sym: 'y' }
3035 if target in modular_tcg
3036 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
3038 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
3040 accel_kconfig += [ sym + '=y' ]
3043 if accel_kconfig.length() == 0
3047 error('No accelerator available for target @0@'.format(target))
3050 actual_target_dirs += target
3051 config_target += keyval.load('configs/targets' / target + '.mak')
3052 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
3054 if 'TARGET_NEED_FDT' in config_target
3055 fdt_required += target
3059 if 'TARGET_BASE_ARCH' not in config_target
3060 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
3062 if 'TARGET_ABI_DIR' not in config_target
3063 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
3065 if 'TARGET_BIG_ENDIAN' not in config_target
3066 config_target += {'TARGET_BIG_ENDIAN': 'n'}
3069 foreach k, v: disassemblers
3070 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
3072 config_target += { sym: 'y' }
3077 config_target_data = configuration_data()
3078 foreach k, v: config_target
3079 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
3081 elif ignored.contains(k)
3083 elif k == 'TARGET_BASE_ARCH'
3084 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
3085 # not used to select files from sourcesets.
3086 config_target_data.set('TARGET_' + v.to_upper(), 1)
3087 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
3088 config_target_data.set_quoted(k, v)
3090 config_target_data.set(k, 1)
3092 config_target_data.set(k, 0)
3094 config_target_data.set(k, v)
3097 config_target_data.set('QEMU_ARCH',
3098 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
3099 config_target_h += {target: configure_file(output: target + '-config-target.h',
3100 configuration: config_target_data)}
3102 if target.endswith('-softmmu')
3103 config_input = meson.get_external_property(target, 'default')
3104 config_devices_mak = target + '-config-devices.mak'
3105 config_devices_mak = configure_file(
3106 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
3107 output: config_devices_mak,
3108 depfile: config_devices_mak + '.d',
3110 command: [minikconf,
3111 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
3112 config_devices_mak, '@DEPFILE@', '@INPUT@',
3113 host_kconfig, accel_kconfig,
3114 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
3116 config_devices_data = configuration_data()
3117 config_devices = keyval.load(config_devices_mak)
3118 foreach k, v: config_devices
3119 config_devices_data.set(k, 1)
3121 config_devices_mak_list += config_devices_mak
3122 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
3123 configuration: config_devices_data)}
3124 config_target += config_devices
3125 config_all_devices += config_devices
3127 config_target_mak += {target: config_target}
3129 target_dirs = actual_target_dirs
3131 target_configs_h = []
3132 foreach target: target_dirs
3133 target_configs_h += config_target_h[target]
3134 target_configs_h += config_devices_h.get(target, [])
3136 genh += custom_target('config-poison.h',
3137 input: [target_configs_h],
3138 output: 'config-poison.h',
3140 command: [find_program('scripts/make-config-poison.sh'),
3147 libvfio_user_dep = not_found
3148 if have_system and vfio_user_server_allowed
3149 libvfio_user_proj = subproject('libvfio-user', required: true)
3150 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep')
3154 fdt_opt = get_option('fdt')
3155 if fdt_required.length() > 0 or fdt_opt == 'enabled'
3156 if fdt_opt == 'disabled'
3157 error('fdt disabled but required by targets ' + ', '.join(fdt_required))
3160 if fdt_opt in ['enabled', 'auto', 'system']
3161 if get_option('wrap_mode') == 'nodownload'
3164 fdt = cc.find_library('fdt', required: fdt_opt == 'system')
3165 if fdt.found() and cc.links('''
3167 #include <libfdt_env.h>
3168 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
3171 elif fdt_opt == 'system'
3172 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
3174 fdt_opt = 'internal'
3179 assert(fdt_opt == 'internal')
3180 libfdt_proj = subproject('dtc', required: true,
3181 default_options: ['tools=false', 'yaml=disabled',
3182 'python=disabled', 'default_library=static'])
3183 fdt = libfdt_proj.get_variable('libfdt_dep')
3186 fdt_opt = 'disabled'
3189 config_host_data.set('CONFIG_FDT', fdt.found())
3191 vhost_user = not_found
3192 if host_os == 'linux' and have_vhost_user
3193 libvhost_user = subproject('libvhost-user')
3194 vhost_user = libvhost_user.get_variable('vhost_user_dep')
3197 libvduse = not_found
3199 libvduse_proj = subproject('libvduse')
3200 libvduse = libvduse_proj.get_variable('libvduse_dep')
3203 #####################
3204 # Generated sources #
3205 #####################
3207 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
3209 hxtool = find_program('scripts/hxtool')
3210 shaderinclude = find_program('scripts/shaderinclude.py')
3211 qapi_gen = find_program('scripts/qapi-gen.py')
3212 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
3213 meson.current_source_dir() / 'scripts/qapi/commands.py',
3214 meson.current_source_dir() / 'scripts/qapi/common.py',
3215 meson.current_source_dir() / 'scripts/qapi/error.py',
3216 meson.current_source_dir() / 'scripts/qapi/events.py',
3217 meson.current_source_dir() / 'scripts/qapi/expr.py',
3218 meson.current_source_dir() / 'scripts/qapi/gen.py',
3219 meson.current_source_dir() / 'scripts/qapi/introspect.py',
3220 meson.current_source_dir() / 'scripts/qapi/main.py',
3221 meson.current_source_dir() / 'scripts/qapi/parser.py',
3222 meson.current_source_dir() / 'scripts/qapi/schema.py',
3223 meson.current_source_dir() / 'scripts/qapi/source.py',
3224 meson.current_source_dir() / 'scripts/qapi/types.py',
3225 meson.current_source_dir() / 'scripts/qapi/visit.py',
3226 meson.current_source_dir() / 'scripts/qapi-gen.py'
3230 python, files('scripts/tracetool.py'),
3231 '--backend=' + ','.join(get_option('trace_backends'))
3233 tracetool_depends = files(
3234 'scripts/tracetool/backend/log.py',
3235 'scripts/tracetool/backend/__init__.py',
3236 'scripts/tracetool/backend/dtrace.py',
3237 'scripts/tracetool/backend/ftrace.py',
3238 'scripts/tracetool/backend/simple.py',
3239 'scripts/tracetool/backend/syslog.py',
3240 'scripts/tracetool/backend/ust.py',
3241 'scripts/tracetool/format/ust_events_c.py',
3242 'scripts/tracetool/format/ust_events_h.py',
3243 'scripts/tracetool/format/__init__.py',
3244 'scripts/tracetool/format/d.py',
3245 'scripts/tracetool/format/simpletrace_stap.py',
3246 'scripts/tracetool/format/c.py',
3247 'scripts/tracetool/format/h.py',
3248 'scripts/tracetool/format/log_stap.py',
3249 'scripts/tracetool/format/stap.py',
3250 'scripts/tracetool/__init__.py',
3251 'scripts/tracetool/vcpu.py'
3254 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
3255 meson.current_source_dir(),
3256 get_option('pkgversion'), meson.project_version()]
3257 qemu_version = custom_target('qemu-version.h',
3258 output: 'qemu-version.h',
3259 command: qemu_version_cmd,
3261 build_by_default: true,
3262 build_always_stale: true)
3263 genh += qemu_version
3267 ['qemu-options.hx', 'qemu-options.def'],
3268 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
3272 ['hmp-commands.hx', 'hmp-commands.h'],
3273 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
3276 foreach d : hx_headers
3277 hxdep += custom_target(d[1],
3281 command: [hxtool, '-h', '@INPUT0@'])
3289 # TODO: add each directory to the subdirs from its own meson.build, once
3291 trace_events_subdirs = [
3300 trace_events_subdirs += [ 'linux-user' ]
3303 trace_events_subdirs += [ 'bsd-user' ]
3306 trace_events_subdirs += [
3315 trace_events_subdirs += [
3380 if have_system or have_user
3381 trace_events_subdirs += [
3404 authz_ss = ss.source_set()
3405 blockdev_ss = ss.source_set()
3406 block_ss = ss.source_set()
3407 chardev_ss = ss.source_set()
3408 common_ss = ss.source_set()
3409 crypto_ss = ss.source_set()
3410 hwcore_ss = ss.source_set()
3411 io_ss = ss.source_set()
3412 qmp_ss = ss.source_set()
3413 qom_ss = ss.source_set()
3414 system_ss = ss.source_set()
3415 specific_fuzz_ss = ss.source_set()
3416 specific_ss = ss.source_set()
3417 stub_ss = ss.source_set()
3418 trace_ss = ss.source_set()
3419 user_ss = ss.source_set()
3420 util_ss = ss.source_set()
3423 qtest_module_ss = ss.source_set()
3424 tcg_module_ss = ss.source_set()
3430 target_system_arch = {}
3431 target_user_arch = {}
3433 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3434 # that is filled in by qapi/.
3448 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3449 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3452 qom_ss = qom_ss.apply({})
3453 libqom = static_library('qom', qom_ss.sources() + genh,
3454 dependencies: [qom_ss.dependencies()],
3456 build_by_default: false)
3457 qom = declare_dependency(link_whole: libqom)
3459 event_loop_base = files('event-loop-base.c')
3460 event_loop_base = static_library('event-loop-base',
3461 sources: event_loop_base + genh,
3463 build_by_default: false)
3464 event_loop_base = declare_dependency(link_whole: event_loop_base,
3465 dependencies: [qom])
3467 stub_ss = stub_ss.apply({})
3469 util_ss.add_all(trace_ss)
3470 util_ss = util_ss.apply({})
3471 libqemuutil = static_library('qemuutil',
3472 build_by_default: false,
3473 sources: util_ss.sources() + stub_ss.sources() + genh,
3474 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
3475 qemuutil = declare_dependency(link_with: libqemuutil,
3476 sources: genh + version_res,
3477 dependencies: [event_loop_base])
3479 if have_system or have_user
3480 decodetree = generator(find_program('scripts/decodetree.py'),
3481 output: 'decode-@BASENAME@.c.inc',
3482 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3483 subdir('libdecnumber')
3500 if config_host_data.get('CONFIG_REPLICATION')
3501 block_ss.add(files('replication.c'))
3508 blockdev_ss.add(files(
3515 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3516 # os-win32.c does not
3517 if host_os == 'windows'
3518 system_ss.add(files('os-win32.c'))
3520 blockdev_ss.add(files('os-posix.c'))
3524 common_ss.add(files('cpu-common.c'))
3525 specific_ss.add(files('cpu-target.c'))
3529 # Work around a gcc bug/misfeature wherein constant propagation looks
3531 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3532 # to guess that a const variable is always zero. Without lto, this is
3533 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
3534 # without lto, not even the alias is required -- we simply use different
3535 # declarations in different compilation units.
3536 pagevary = files('page-vary-common.c')
3537 if get_option('b_lto')
3538 pagevary_flags = ['-fno-lto']
3539 if get_option('cfi')
3540 pagevary_flags += '-fno-sanitize=cfi-icall'
3542 pagevary = static_library('page-vary-common', sources: pagevary + genh,
3543 c_args: pagevary_flags)
3544 pagevary = declare_dependency(link_with: pagevary)
3546 common_ss.add(pagevary)
3547 specific_ss.add(files('page-vary-target.c'))
3555 subdir('semihosting')
3563 common_user_inc = []
3565 subdir('common-user')
3567 subdir('linux-user')
3569 # needed for fuzzing binaries
3570 subdir('tests/qtest/libqos')
3571 subdir('tests/qtest/fuzz')
3574 tcg_real_module_ss = ss.source_set()
3575 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3576 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3577 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3578 'tcg': tcg_real_module_ss }}
3580 ##############################################
3581 # Internal static_libraries and dependencies #
3582 ##############################################
3584 modinfo_collect = find_program('scripts/modinfo-collect.py')
3585 modinfo_generate = find_program('scripts/modinfo-generate.py')
3590 foreach d, list : modules
3591 if not (d == 'block' ? have_block : have_system)
3595 foreach m, module_ss : list
3597 module_ss = module_ss.apply(config_all_devices, strict: false)
3598 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3599 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3605 if module_ss.sources() != []
3606 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3607 # input. Sources can be used multiple times but objects are
3608 # unique when it comes to lookup in compile_commands.json.
3609 # Depnds on a mesion version with
3610 # https://github.com/mesonbuild/meson/pull/8900
3611 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3612 output: d + '-' + m + '.modinfo',
3613 input: module_ss.sources() + genh,
3615 command: [modinfo_collect, module_ss.sources()])
3619 block_ss.add_all(module_ss)
3621 system_ss.add_all(module_ss)
3627 foreach d, list : target_modules
3628 foreach m, module_ss : list
3630 foreach target : target_dirs
3631 if target.endswith('-softmmu')
3632 config_target = config_target_mak[target]
3633 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3634 c_args = ['-DNEED_CPU_H',
3635 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3636 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3637 target_module_ss = module_ss.apply(config_target, strict: false)
3638 if target_module_ss.sources() != []
3639 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3640 sl = static_library(module_name,
3641 [genh, target_module_ss.sources()],
3642 dependencies: [modulecommon, target_module_ss.dependencies()],
3643 include_directories: target_inc,
3647 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3648 modinfo_files += custom_target(module_name + '.modinfo',
3649 output: module_name + '.modinfo',
3650 input: target_module_ss.sources() + genh,
3652 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3657 specific_ss.add_all(module_ss)
3663 foreach target : target_dirs
3664 if target.endswith('-softmmu')
3665 config_target = config_target_mak[target]
3666 config_devices_mak = target + '-config-devices.mak'
3667 modinfo_src = custom_target('modinfo-' + target + '.c',
3668 output: 'modinfo-' + target + '.c',
3669 input: modinfo_files,
3670 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'],
3673 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
3674 modinfo_dep = declare_dependency(link_with: modinfo_lib)
3676 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH']
3677 hw_arch[arch].add(modinfo_dep)
3682 nm = find_program('nm')
3683 undefsym = find_program('scripts/undefsym.py')
3684 block_syms = custom_target('block.syms', output: 'block.syms',
3685 input: [libqemuutil, block_mods],
3687 command: [undefsym, nm, '@INPUT@'])
3688 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3689 input: [libqemuutil, system_mods],
3691 command: [undefsym, nm, '@INPUT@'])
3693 authz_ss = authz_ss.apply({})
3694 libauthz = static_library('authz', authz_ss.sources() + genh,
3695 dependencies: [authz_ss.dependencies()],
3697 build_by_default: false)
3699 authz = declare_dependency(link_whole: libauthz,
3702 crypto_ss = crypto_ss.apply({})
3703 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3704 dependencies: [crypto_ss.dependencies()],
3706 build_by_default: false)
3708 crypto = declare_dependency(link_whole: libcrypto,
3709 dependencies: [authz, qom])
3711 io_ss = io_ss.apply({})
3712 libio = static_library('io', io_ss.sources() + genh,
3713 dependencies: [io_ss.dependencies()],
3714 link_with: libqemuutil,
3716 build_by_default: false)
3718 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3720 libmigration = static_library('migration', sources: migration_files + genh,
3722 build_by_default: false)
3723 migration = declare_dependency(link_with: libmigration,
3724 dependencies: [zlib, qom, io])
3725 system_ss.add(migration)
3727 block_ss = block_ss.apply({})
3728 libblock = static_library('block', block_ss.sources() + genh,
3729 dependencies: block_ss.dependencies(),
3730 link_depends: block_syms,
3732 build_by_default: false)
3734 block = declare_dependency(link_whole: [libblock],
3735 link_args: '@block.syms',
3736 dependencies: [crypto, io])
3738 blockdev_ss = blockdev_ss.apply({})
3739 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3740 dependencies: blockdev_ss.dependencies(),
3742 build_by_default: false)
3744 blockdev = declare_dependency(link_whole: [libblockdev],
3745 dependencies: [block, event_loop_base])
3747 qmp_ss = qmp_ss.apply({})
3748 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3749 dependencies: qmp_ss.dependencies(),
3751 build_by_default: false)
3753 qmp = declare_dependency(link_whole: [libqmp])
3755 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3757 dependencies: chardev_ss.dependencies(),
3758 build_by_default: false)
3760 chardev = declare_dependency(link_whole: libchardev)
3762 hwcore_ss = hwcore_ss.apply({})
3763 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3765 build_by_default: false)
3766 hwcore = declare_dependency(link_whole: libhwcore)
3767 common_ss.add(hwcore)
3773 emulator_modules = []
3774 foreach m : block_mods + system_mods
3775 emulator_modules += shared_module(m.name(),
3776 build_by_default: true,
3780 install_dir: qemu_moddir)
3782 if emulator_modules.length() > 0
3783 alias_target('modules', emulator_modules)
3786 system_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3787 common_ss.add(qom, qemuutil)
3789 common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss])
3790 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3792 # Note that this library is never used directly (only through extract_objects)
3793 # and is not built by default; therefore, source files not used by the build
3794 # configuration will be in build.ninja, but are never built by default.
3795 common_all = static_library('common',
3796 build_by_default: false,
3797 sources: common_ss.all_sources() + genh,
3798 include_directories: common_user_inc,
3799 implicit_include_directories: false,
3800 dependencies: common_ss.all_dependencies(),
3803 feature_to_c = find_program('scripts/feature_to_c.py')
3805 if host_os == 'darwin'
3806 entitlement = find_program('scripts/entitlement.sh')
3810 foreach target : target_dirs
3811 config_target = config_target_mak[target]
3812 target_name = config_target['TARGET_NAME']
3813 target_base_arch = config_target['TARGET_BASE_ARCH']
3814 arch_srcs = [config_target_h[target]]
3816 c_args = ['-DNEED_CPU_H',
3817 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3818 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3819 link_args = emulator_link_args
3821 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3822 if host_os == 'linux'
3823 target_inc += include_directories('linux-headers', is_system: true)
3825 if target.endswith('-softmmu')
3826 target_type='system'
3827 t = target_system_arch[target_base_arch].apply(config_target, strict: false)
3828 arch_srcs += t.sources()
3829 arch_deps += t.dependencies()
3831 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3832 if hw_arch.has_key(hw_dir)
3833 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3834 arch_srcs += hw.sources()
3835 arch_deps += hw.dependencies()
3838 arch_srcs += config_devices_h[target]
3839 link_args += ['@block.syms', '@qemu.syms']
3841 abi = config_target['TARGET_ABI_DIR']
3843 target_inc += common_user_inc
3844 if target_base_arch in target_user_arch
3845 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3846 arch_srcs += t.sources()
3847 arch_deps += t.dependencies()
3849 if 'CONFIG_LINUX_USER' in config_target
3850 base_dir = 'linux-user'
3852 if 'CONFIG_BSD_USER' in config_target
3853 base_dir = 'bsd-user'
3854 target_inc += include_directories('bsd-user/' / host_os)
3855 target_inc += include_directories('bsd-user/host/' / host_arch)
3856 dir = base_dir / abi
3857 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3859 target_inc += include_directories(
3863 if 'CONFIG_LINUX_USER' in config_target
3864 dir = base_dir / abi
3865 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3866 if config_target.has_key('TARGET_SYSTBL_ABI')
3868 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3869 extra_args : config_target['TARGET_SYSTBL_ABI'])
3874 if 'TARGET_XML_FILES' in config_target
3875 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3876 output: target + '-gdbstub-xml.c',
3877 input: files(config_target['TARGET_XML_FILES'].split()),
3878 command: [feature_to_c, '@INPUT@'],
3880 arch_srcs += gdbstub_xml
3883 t = target_arch[target_base_arch].apply(config_target, strict: false)
3884 arch_srcs += t.sources()
3885 arch_deps += t.dependencies()
3887 target_common = common_ss.apply(config_target, strict: false)
3888 objects = common_all.extract_objects(target_common.sources())
3889 deps = target_common.dependencies()
3891 target_specific = specific_ss.apply(config_target, strict: false)
3892 arch_srcs += target_specific.sources()
3893 arch_deps += target_specific.dependencies()
3895 lib = static_library('qemu-' + target,
3896 sources: arch_srcs + genh,
3897 dependencies: arch_deps,
3899 include_directories: target_inc,
3901 build_by_default: false,
3904 if target.endswith('-softmmu')
3906 'name': 'qemu-system-' + target_name,
3907 'win_subsystem': 'console',
3908 'sources': files('system/main.c'),
3911 if host_os == 'windows' and (sdl.found() or gtk.found())
3913 'name': 'qemu-system-' + target_name + 'w',
3914 'win_subsystem': 'windows',
3915 'sources': files('system/main.c'),
3919 if get_option('fuzzing')
3920 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3922 'name': 'qemu-fuzz-' + target_name,
3923 'win_subsystem': 'console',
3924 'sources': specific_fuzz.sources(),
3925 'dependencies': specific_fuzz.dependencies(),
3930 'name': 'qemu-' + target_name,
3931 'win_subsystem': 'console',
3937 exe_name = exe['name']
3938 if host_os == 'darwin'
3939 exe_name += '-unsigned'
3942 emulator = executable(exe_name, exe['sources'],
3945 dependencies: arch_deps + deps + exe['dependencies'],
3946 objects: lib.extract_all_objects(recursive: true),
3947 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3948 link_args: link_args,
3949 win_subsystem: exe['win_subsystem'])
3951 if host_os == 'darwin'
3952 icon = 'pc-bios/qemu.rsrc'
3953 build_input = [emulator, files(icon)]
3955 get_option('bindir') / exe_name,
3956 meson.current_source_dir() / icon
3958 if 'CONFIG_HVF' in config_target
3959 entitlements = 'accel/hvf/entitlements.plist'
3960 build_input += files(entitlements)
3961 install_input += meson.current_source_dir() / entitlements
3964 emulators += {exe['name'] : custom_target(exe['name'],
3966 output: exe['name'],
3967 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3970 meson.add_install_script(entitlement, '--install',
3971 get_option('bindir') / exe['name'],
3974 emulators += {exe['name']: emulator}
3979 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3980 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3981 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3982 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3984 custom_target(exe['name'] + stp['ext'],
3985 input: trace_events_all,
3986 output: exe['name'] + stp['ext'],
3987 install: stp['install'],
3988 install_dir: get_option('datadir') / 'systemtap/tapset',
3990 tracetool, '--group=all', '--format=' + stp['fmt'],
3991 '--binary=' + stp['bin'],
3992 '--target-name=' + target_name,
3993 '--target-type=' + target_type,
3994 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3995 '@INPUT@', '@OUTPUT@'
3997 depend_files: tracetool_depends)
4003 # Other build targets
4005 if get_option('plugins')
4006 install_headers('include/qemu/qemu-plugin.h')
4007 if host_os == 'windows'
4008 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer,
4009 # so that plugin authors can compile against it.
4010 install_data(win32_qemu_plugin_api_lib, install_dir: 'lib')
4016 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
4017 # when we don't build tools or system
4018 if xkbcommon.found()
4019 # used for the update-keymaps target, so include rules even if !have_tools
4020 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
4021 dependencies: [qemuutil, xkbcommon], install: have_tools)
4025 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
4026 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
4027 qemu_io = executable('qemu-io', files('qemu-io.c'),
4028 dependencies: [block, qemuutil], install: true)
4029 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
4030 dependencies: [blockdev, qemuutil, gnutls, selinux],
4033 subdir('storage-daemon')
4034 subdir('contrib/rdmacm-mux')
4035 subdir('contrib/elf2dmp')
4037 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
4038 dependencies: qemuutil,
4042 subdir('contrib/vhost-user-blk')
4043 subdir('contrib/vhost-user-gpu')
4044 subdir('contrib/vhost-user-input')
4045 subdir('contrib/vhost-user-scsi')
4048 if host_os == 'linux'
4049 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
4050 dependencies: [qemuutil, libcap_ng],
4052 install_dir: get_option('libexecdir'))
4054 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
4055 dependencies: [authz, crypto, io, qom, qemuutil,
4056 libcap_ng, mpathpersist],
4061 subdir('contrib/ivshmem-client')
4062 subdir('contrib/ivshmem-server')
4075 if host_machine.system() == 'windows'
4077 find_program('scripts/nsis.py'),
4079 get_option('prefix'),
4080 meson.current_source_dir(),
4081 glib_pc.get_variable('bindir'),
4084 '-DDISPLAYVERSION=' + meson.project_version(),
4087 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
4090 nsis_cmd += '-DCONFIG_GTK=y'
4093 nsis = custom_target('nsis',
4094 output: 'qemu-setup-' + meson.project_version() + '.exe',
4095 input: files('qemu.nsi'),
4096 build_always_stale: true,
4097 command: nsis_cmd + ['@INPUT@'])
4098 alias_target('installer', nsis)
4101 #########################
4102 # Configuration summary #
4103 #########################
4107 summary_info += {'Build directory': meson.current_build_dir()}
4108 summary_info += {'Source path': meson.current_source_dir()}
4109 summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'}
4110 summary(summary_info, bool_yn: true, section: 'Build environment')
4113 summary_info += {'Install prefix': get_option('prefix')}
4114 summary_info += {'BIOS directory': qemu_datadir}
4115 pathsep = host_os == 'windows' ? ';' : ':'
4116 summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))}
4117 summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
4118 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
4119 summary_info += {'module directory': qemu_moddir}
4120 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
4121 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
4122 summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')}
4123 if host_os != 'windows'
4124 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
4125 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')}
4127 summary_info += {'local state directory': 'queried at runtime'}
4129 summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
4130 summary(summary_info, bool_yn: true, section: 'Directories')
4134 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
4135 summary_info += {'sphinx-build': sphinx_build}
4137 # FIXME: the [binaries] section of machine files, which can be probed
4138 # with find_program(), would be great for passing gdb and genisoimage
4139 # paths from configure to Meson. However, there seems to be no way to
4140 # hide a program (for example if gdb is too old).
4141 if config_host.has_key('GDB')
4142 summary_info += {'gdb': config_host['GDB']}
4144 summary_info += {'iasl': iasl}
4145 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
4146 if host_os == 'windows' and have_ga
4147 summary_info += {'wixl': wixl}
4149 if slirp.found() and have_system
4150 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
4152 summary(summary_info, bool_yn: true, section: 'Host binaries')
4154 # Configurable features
4156 summary_info += {'Documentation': build_docs}
4157 summary_info += {'system-mode emulation': have_system}
4158 summary_info += {'user-mode emulation': have_user}
4159 summary_info += {'block layer': have_block}
4160 summary_info += {'Install blobs': get_option('install_blobs')}
4161 summary_info += {'module support': enable_modules}
4163 summary_info += {'alternative module path': get_option('module_upgrades')}
4165 summary_info += {'fuzzing support': get_option('fuzzing')}
4167 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
4169 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
4170 if 'simple' in get_option('trace_backends')
4171 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
4173 summary_info += {'D-Bus display': dbus_display}
4174 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
4175 summary_info += {'Relocatable install': get_option('relocatable')}
4176 summary_info += {'vhost-kernel support': have_vhost_kernel}
4177 summary_info += {'vhost-net support': have_vhost_net}
4178 summary_info += {'vhost-user support': have_vhost_user}
4179 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
4180 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
4181 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
4182 summary_info += {'build guest agent': have_ga}
4183 summary(summary_info, bool_yn: true, section: 'Configurable features')
4185 # Compilation information
4187 summary_info += {'host CPU': cpu}
4188 summary_info += {'host endianness': build_machine.endian()}
4189 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
4190 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
4191 if 'cpp' in all_languages
4192 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
4194 summary_info += {'C++ compiler': false}
4196 if 'objc' in all_languages
4197 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
4199 summary_info += {'Objective-C compiler': false}
4201 option_cflags = (get_option('debug') ? ['-g'] : [])
4202 if get_option('optimization') != 'plain'
4203 option_cflags += ['-O' + get_option('optimization')]
4205 summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)}
4206 if 'cpp' in all_languages
4207 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)}
4209 if 'objc' in all_languages
4210 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)}
4212 link_args = get_option('c_link_args')
4213 if link_args.length() > 0
4214 summary_info += {'LDFLAGS': ' '.join(link_args)}
4216 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)}
4217 if 'cpp' in all_languages
4218 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)}
4220 if 'objc' in all_languages
4221 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)}
4223 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
4224 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
4225 summary_info += {'PIE': get_option('b_pie')}
4226 summary_info += {'static build': get_option('prefer_static')}
4227 summary_info += {'malloc trim support': has_malloc_trim}
4228 summary_info += {'membarrier': have_membarrier}
4229 summary_info += {'debug graph lock': get_option('debug_graph_lock')}
4230 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
4231 summary_info += {'mutex debugging': get_option('debug_mutex')}
4232 summary_info += {'memory allocator': get_option('malloc')}
4233 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
4234 summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')}
4235 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
4236 summary_info += {'gcov': get_option('b_coverage')}
4237 summary_info += {'thread sanitizer': get_option('tsan')}
4238 summary_info += {'CFI support': get_option('cfi')}
4239 if get_option('cfi')
4240 summary_info += {'CFI debug support': get_option('cfi_debug')}
4242 summary_info += {'strip binaries': get_option('strip')}
4243 summary_info += {'sparse': sparse}
4244 summary_info += {'mingw32 support': host_os == 'windows'}
4245 summary(summary_info, bool_yn: true, section: 'Compilation')
4247 # snarf the cross-compilation information for tests
4250 foreach target: target_dirs
4251 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak'
4252 if fs.exists(tcg_mak)
4253 config_cross_tcg = keyval.load(tcg_mak)
4254 if 'CC' in config_cross_tcg
4255 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']}
4261 summary(summary_info, bool_yn: true, section: 'Cross compilers')
4264 # Targets and accelerators
4267 summary_info += {'KVM support': config_all_accel.has_key('CONFIG_KVM')}
4268 summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')}
4269 summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')}
4270 summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')}
4271 summary_info += {'Xen support': xen.found()}
4273 summary_info += {'xen ctrl version': xen.version()}
4275 summary_info += {'Xen emulation': config_all_devices.has_key('CONFIG_XEN_EMU')}
4277 summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')}
4278 if config_all_accel.has_key('CONFIG_TCG')
4279 if get_option('tcg_interpreter')
4280 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
4282 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
4284 summary_info += {'TCG plugins': get_option('plugins')}
4285 summary_info += {'TCG debug enabled': get_option('debug_tcg')}
4287 summary_info += {'target list': ' '.join(target_dirs)}
4289 summary_info += {'default devices': get_option('default_devices')}
4290 summary_info += {'out of process emulation': multiprocess_allowed}
4291 summary_info += {'vfio-user server': vfio_user_server_allowed}
4293 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
4297 summary_info += {'coroutine backend': coroutine_backend}
4298 summary_info += {'coroutine pool': have_coroutine_pool}
4300 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
4301 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
4302 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
4303 summary_info += {'VirtFS (9P) support': have_virtfs}
4304 summary_info += {'VirtFS (9P) Proxy Helper support (deprecated)': have_virtfs_proxy_helper}
4305 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
4306 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
4307 summary_info += {'bochs support': get_option('bochs').allowed()}
4308 summary_info += {'cloop support': get_option('cloop').allowed()}
4309 summary_info += {'dmg support': get_option('dmg').allowed()}
4310 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
4311 summary_info += {'vdi support': get_option('vdi').allowed()}
4312 summary_info += {'vhdx support': get_option('vhdx').allowed()}
4313 summary_info += {'vmdk support': get_option('vmdk').allowed()}
4314 summary_info += {'vpc support': get_option('vpc').allowed()}
4315 summary_info += {'vvfat support': get_option('vvfat').allowed()}
4316 summary_info += {'qed support': get_option('qed').allowed()}
4317 summary_info += {'parallels support': get_option('parallels').allowed()}
4318 summary_info += {'FUSE exports': fuse}
4319 summary_info += {'VDUSE block exports': have_vduse_blk_export}
4321 summary(summary_info, bool_yn: true, section: 'Block layer support')
4325 summary_info += {'TLS priority': get_option('tls_priority')}
4326 summary_info += {'GNUTLS support': gnutls}
4328 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
4330 summary_info += {'libgcrypt': gcrypt}
4331 summary_info += {'nettle': nettle}
4333 summary_info += {' XTS': xts != 'private'}
4335 summary_info += {'SM4 ALG support': crypto_sm4}
4336 summary_info += {'AF_ALG support': have_afalg}
4337 summary_info += {'rng-none': get_option('rng_none')}
4338 summary_info += {'Linux keyring': have_keyring}
4339 summary_info += {'Linux keyutils': keyutils}
4340 summary(summary_info, bool_yn: true, section: 'Crypto')
4344 if host_os == 'darwin'
4345 summary_info += {'Cocoa support': cocoa}
4347 summary_info += {'SDL support': sdl}
4348 summary_info += {'SDL image support': sdl_image}
4349 summary_info += {'GTK support': gtk}
4350 summary_info += {'pixman': pixman}
4351 summary_info += {'VTE support': vte}
4352 summary_info += {'PNG support': png}
4353 summary_info += {'VNC support': vnc}
4355 summary_info += {'VNC SASL support': sasl}
4356 summary_info += {'VNC JPEG support': jpeg}
4358 summary_info += {'spice protocol support': spice_protocol}
4359 if spice_protocol.found()
4360 summary_info += {' spice server support': spice}
4362 summary_info += {'curses support': curses}
4363 summary_info += {'brlapi support': brlapi}
4364 summary(summary_info, bool_yn: true, section: 'User interface')
4368 summary_info += {'VirGL support': virgl}
4369 summary_info += {'Rutabaga support': rutabaga}
4370 summary(summary_info, bool_yn: true, section: 'Graphics backends')
4374 if host_os not in ['darwin', 'haiku', 'windows']
4375 summary_info += {'OSS support': oss}
4376 summary_info += {'sndio support': sndio}
4377 elif host_os == 'darwin'
4378 summary_info += {'CoreAudio support': coreaudio}
4379 elif host_os == 'windows'
4380 summary_info += {'DirectSound support': dsound}
4382 if host_os == 'linux'
4383 summary_info += {'ALSA support': alsa}
4384 summary_info += {'PulseAudio support': pulse}
4386 summary_info += {'PipeWire support': pipewire}
4387 summary_info += {'JACK support': jack}
4388 summary(summary_info, bool_yn: true, section: 'Audio backends')
4392 if host_os == 'darwin'
4393 summary_info += {'vmnet.framework support': vmnet}
4395 summary_info += {'AF_XDP support': libxdp}
4396 summary_info += {'slirp support': slirp}
4397 summary_info += {'vde support': vde}
4398 summary_info += {'netmap support': have_netmap}
4399 summary_info += {'l2tpv3 support': have_l2tpv3}
4400 summary(summary_info, bool_yn: true, section: 'Network backends')
4404 summary_info += {'libtasn1': tasn1}
4405 summary_info += {'PAM': pam}
4406 summary_info += {'iconv support': iconv}
4407 summary_info += {'blkio support': blkio}
4408 summary_info += {'curl support': curl}
4409 summary_info += {'Multipath support': mpathpersist}
4410 summary_info += {'Linux AIO support': libaio}
4411 summary_info += {'Linux io_uring support': linux_io_uring}
4412 summary_info += {'ATTR/XATTR support': libattr}
4413 summary_info += {'RDMA support': rdma}
4414 summary_info += {'PVRDMA support': have_pvrdma}
4415 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
4416 summary_info += {'libcap-ng support': libcap_ng}
4417 summary_info += {'bpf support': libbpf}
4418 summary_info += {'rbd support': rbd}
4419 summary_info += {'smartcard support': cacard}
4420 summary_info += {'U2F support': u2f}
4421 summary_info += {'libusb': libusb}
4422 summary_info += {'usb net redir': usbredir}
4423 summary_info += {'OpenGL support (epoxy)': opengl}
4424 summary_info += {'GBM': gbm}
4425 summary_info += {'libiscsi support': libiscsi}
4426 summary_info += {'libnfs support': libnfs}
4427 if host_os == 'windows'
4429 summary_info += {'QGA VSS support': have_qga_vss}
4432 summary_info += {'seccomp support': seccomp}
4433 summary_info += {'GlusterFS support': glusterfs}
4434 summary_info += {'hv-balloon support': hv_balloon}
4435 summary_info += {'TPM support': have_tpm}
4436 summary_info += {'libssh support': libssh}
4437 summary_info += {'lzo support': lzo}
4438 summary_info += {'snappy support': snappy}
4439 summary_info += {'bzip2 support': libbzip2}
4440 summary_info += {'lzfse support': liblzfse}
4441 summary_info += {'zstd support': zstd}
4442 summary_info += {'NUMA host support': numa}
4443 summary_info += {'capstone': capstone}
4444 summary_info += {'libpmem support': libpmem}
4445 summary_info += {'libdaxctl support': libdaxctl}
4446 summary_info += {'libudev': libudev}
4447 # Dummy dependency, keep .found()
4448 summary_info += {'FUSE lseek': fuse_lseek.found()}
4449 summary_info += {'selinux': selinux}
4450 summary_info += {'libdw': libdw}
4451 if host_os == 'freebsd'
4452 summary_info += {'libinotify-kqueue': inotify}
4454 summary(summary_info, bool_yn: true, section: 'Dependencies')
4456 if host_arch == 'unknown'
4458 warning('UNSUPPORTED HOST CPU')
4460 message('Support for CPU host architecture ' + cpu + ' is not currently')
4461 message('maintained. The QEMU project does not guarantee that QEMU will')
4462 message('compile or work on this host CPU. You can help by volunteering')
4463 message('to maintain it and providing a build host for our continuous')
4464 message('integration setup.')
4465 if get_option('tcg').allowed() and target_dirs.length() > 0
4467 message('configure has succeeded and you can continue to build, but')
4468 message('QEMU will use a slow interpreter to emulate the target CPU.')
4472 if not supported_oses.contains(host_os)
4474 warning('UNSUPPORTED HOST OS')
4476 message('Support for host OS ' + host_os + 'is not currently maintained.')
4477 message('configure has succeeded and you can continue to build, but')
4478 message('the QEMU project does not guarantee that QEMU will compile or')
4479 message('work on this operating system. You can help by volunteering')
4480 message('to maintain it and providing a build host for our continuous')
4481 message('integration setup. This will ensure that future versions of QEMU')
4482 message('will keep working on ' + host_os + '.')
4485 if host_arch == 'unknown' or not supported_oses.contains(host_os)
4487 message('If you want to help supporting QEMU on this platform, please')
4488 message('contact the developers at qemu-devel@nongnu.org.')
4491 actually_reloc = get_option('relocatable')
4492 # check if get_relocated_path() is actually able to relocate paths
4493 if get_option('relocatable') and \
4494 not (get_option('prefix') / get_option('bindir')).startswith(get_option('prefix') / '')
4496 warning('bindir not included within prefix, the installation will not be relocatable.')
4497 actually_reloc = false
4499 if not actually_reloc and (host_os == 'windows' or get_option('relocatable'))
4500 if host_os == 'windows'
4502 warning('Windows installs should usually be relocatable.')
4505 message('QEMU will have to be installed under ' + get_option('prefix') + '.')
4506 message('Use --disable-relocatable to remove this warning.')