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: true, 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 if get_option('fuzzing')
480 # Specify a filter to only instrument code that is directly related to
482 configure_file(output: 'instrumentation-filter',
483 input: 'scripts/oss-fuzz/instrumentation-filter-template',
486 if cc.compiles('int main () { return 0; }',
487 name: '-fsanitize-coverage-allowlist=/dev/null',
488 args: ['-fsanitize-coverage-allowlist=/dev/null',
489 '-fsanitize-coverage=trace-pc'] )
490 qemu_common_flags += ['-fsanitize-coverage-allowlist=instrumentation-filter']
493 if get_option('fuzzing_engine') == ''
494 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
495 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
496 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
497 # unable to bind the fuzzer-related callbacks added by instrumentation.
498 qemu_common_flags += ['-fsanitize=fuzzer-no-link']
499 qemu_ldflags += ['-fsanitize=fuzzer-no-link']
500 # For the actual fuzzer binaries, we need to link against the libfuzzer
501 # library. They need to be configurable, to support OSS-Fuzz
502 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
504 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
505 # the needed CFLAGS have already been provided
506 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
512 # Check for dependency on LTO
513 if not get_option('b_lto')
514 error('Selected Control-Flow Integrity but LTO is disabled')
517 error('Selected Control-Flow Integrity is not compatible with modules')
519 # Check for cfi flags. CFI requires LTO so we can't use
520 # get_supported_arguments, but need a more complex "compiles" which allows
522 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
523 args: ['-flto', '-fsanitize=cfi-icall'] )
524 cfi_flags += '-fsanitize=cfi-icall'
526 error('-fsanitize=cfi-icall is not supported by the compiler')
528 if cc.compiles('int main () { return 0; }',
529 name: '-fsanitize-cfi-icall-generalize-pointers',
530 args: ['-flto', '-fsanitize=cfi-icall',
531 '-fsanitize-cfi-icall-generalize-pointers'] )
532 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
534 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
536 if get_option('cfi_debug')
537 if cc.compiles('int main () { return 0; }',
538 name: '-fno-sanitize-trap=cfi-icall',
539 args: ['-flto', '-fsanitize=cfi-icall',
540 '-fno-sanitize-trap=cfi-icall'] )
541 cfi_flags += '-fno-sanitize-trap=cfi-icall'
543 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
546 add_global_arguments(cfi_flags, native: false, language: all_languages)
547 add_global_link_arguments(cfi_flags, native: false, language: all_languages)
550 # Check further flags that make QEMU more robust against malicious parties
553 # Initialize all stack variables to zero. This makes
554 # it harder to take advantage of uninitialized stack
555 # data to drive exploits
556 '-ftrivial-auto-var-init=zero',
559 # Zero out registers used during a function call
560 # upon its return. This makes it harder to assemble
561 # ROP gadgets into something usable
563 # NB: Clang 17 is broken and SEGVs
564 # https://github.com/llvm/llvm-project/issues/75168
565 if cc.compiles('extern struct { void (*cb)(void); } s; void f(void) { s.cb(); }',
566 name: '-fzero-call-used-regs=used-gpr',
567 args: ['-O2', '-fzero-call-used-regs=used-gpr'])
568 hardening_flags += '-fzero-call-used-regs=used-gpr'
571 qemu_common_flags += cc.get_supported_arguments(hardening_flags)
573 add_global_arguments(qemu_common_flags, native: false, language: all_languages)
574 add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
576 # Collect warning flags we want to set, sorted alphabetically
578 # First enable interesting warnings
581 '-Wexpansion-to-defined',
584 '-Wignored-qualifiers',
585 '-Wimplicit-fallthrough=2',
587 '-Wmissing-format-attribute',
588 '-Wmissing-prototypes',
590 '-Wold-style-declaration',
591 '-Wold-style-definition',
594 '-Wstrict-prototypes',
600 # Then disable some undesirable warnings
601 '-Wno-gnu-variable-sized-type-not-at-end',
602 '-Wno-initializer-overrides',
603 '-Wno-missing-include-dirs',
605 '-Wno-shift-negative-value',
606 '-Wno-string-plus-int',
607 '-Wno-tautological-type-limit-compare',
608 '-Wno-typedef-redefinition',
611 if host_os != 'darwin'
612 warn_flags += ['-Wthread-safety']
615 # Set up C++ compiler flags
617 if 'cpp' in all_languages
618 qemu_cxxflags = ['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'] + qemu_cflags
621 add_project_arguments(qemu_cflags, native: false, language: 'c')
622 add_project_arguments(cc.get_supported_arguments(warn_flags), native: false, language: 'c')
623 if 'cpp' in all_languages
624 add_project_arguments(qemu_cxxflags, native: false, language: 'cpp')
625 add_project_arguments(cxx.get_supported_arguments(warn_flags), native: false, language: 'cpp')
627 if 'objc' in all_languages
628 # Note sanitizer flags are not applied to Objective-C sources!
629 add_project_arguments(objc.get_supported_arguments(warn_flags), native: false, language: 'objc')
631 if host_os == 'linux'
632 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
633 '-isystem', 'linux-headers',
634 language: all_languages)
637 add_project_arguments('-iquote', '.',
638 '-iquote', meson.current_source_dir(),
639 '-iquote', meson.current_source_dir() / 'include',
640 language: all_languages)
642 # If a host-specific include directory exists, list that first...
643 host_include = meson.current_source_dir() / 'host/include/'
644 if fs.is_dir(host_include / host_arch)
645 add_project_arguments('-iquote', host_include / host_arch,
646 language: all_languages)
648 # ... followed by the generic fallback.
649 add_project_arguments('-iquote', host_include / 'generic',
650 language: all_languages)
652 sparse = find_program('cgcc', required: get_option('sparse'))
655 command: [find_program('scripts/check_sparse.py'),
656 'compile_commands.json', sparse.full_path(), '-Wbitwise',
657 '-Wno-transparent-union', '-Wno-old-initializer',
658 '-Wno-non-pointer-null'])
661 #####################################
662 # Host-specific libraries and flags #
663 #####################################
665 libm = cc.find_library('m', required: false)
666 threads = dependency('threads')
667 util = cc.find_library('util', required: false)
673 emulator_link_args = []
678 if host_os == 'windows'
679 midl = find_program('midl', required: false)
680 widl = find_program('widl', required: false)
681 pathcch = cc.find_library('pathcch')
682 socket = cc.find_library('ws2_32')
683 winmm = cc.find_library('winmm')
685 win = import('windows')
686 version_res = win.compile_resources('version.rc',
687 depend_files: files('pc-bios/qemu-nsis.ico'),
688 include_directories: include_directories('.'))
690 elif host_os == 'darwin'
691 coref = dependency('appleframeworks', modules: 'CoreFoundation')
692 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
693 host_dsosuf = '.dylib'
694 elif host_os == 'sunos'
695 socket = [cc.find_library('socket'),
696 cc.find_library('nsl'),
697 cc.find_library('resolv')]
698 elif host_os == 'haiku'
699 socket = [cc.find_library('posix_error_mapper'),
700 cc.find_library('network'),
701 cc.find_library('bsd')]
702 elif host_os == 'openbsd'
703 if get_option('tcg').allowed() and target_dirs.length() > 0
704 # Disable OpenBSD W^X if available
705 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
709 ###############################################
710 # Host-specific configuration of accelerators #
711 ###############################################
714 if get_option('kvm').allowed() and host_os == 'linux'
715 accelerators += 'CONFIG_KVM'
717 if get_option('whpx').allowed() and host_os == 'windows'
718 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
719 error('WHPX requires 64-bit host')
720 elif cc.has_header('winhvplatform.h', required: get_option('whpx')) and \
721 cc.has_header('winhvemulation.h', required: get_option('whpx'))
722 accelerators += 'CONFIG_WHPX'
727 if get_option('hvf').allowed()
728 hvf = dependency('appleframeworks', modules: 'Hypervisor',
729 required: get_option('hvf'))
731 accelerators += 'CONFIG_HVF'
736 if host_os == 'netbsd'
737 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
739 accelerators += 'CONFIG_NVMM'
744 if get_option('tcg').allowed()
745 if host_arch == 'unknown'
746 if not get_option('tcg_interpreter')
747 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
749 elif get_option('tcg_interpreter')
750 warning('Use of the TCG interpreter is not recommended on this host')
751 warning('architecture. There is a native TCG execution backend available')
752 warning('which provides substantially better performance and reliability.')
753 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
754 warning('configuration option on this architecture to use the native')
757 if get_option('tcg_interpreter')
759 elif host_arch == 'x86_64'
761 elif host_arch == 'ppc64'
764 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
765 language: all_languages)
767 accelerators += 'CONFIG_TCG'
770 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
771 error('KVM not available on this platform')
773 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
774 error('HVF not available on this platform')
776 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
777 error('NVMM not available on this platform')
779 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
780 error('WHPX not available on this platform')
784 if get_option('xen').enabled() or (get_option('xen').auto() and have_system)
785 xencontrol = dependency('xencontrol', required: false,
786 method: 'pkg-config')
787 if xencontrol.found()
788 xen_pc = declare_dependency(version: xencontrol.version(),
791 # disabler: true makes xen_pc.found() return false if any is not found
792 dependency('xenstore', required: false,
793 method: 'pkg-config',
795 dependency('xenforeignmemory', required: false,
796 method: 'pkg-config',
798 dependency('xengnttab', required: false,
799 method: 'pkg-config',
801 dependency('xenevtchn', required: false,
802 method: 'pkg-config',
804 dependency('xendevicemodel', required: false,
805 method: 'pkg-config',
807 # optional, no "disabler: true"
808 dependency('xentoolcore', required: false,
809 method: 'pkg-config')])
815 xen_tests = [ '4.11.0', '4.10.0', '4.9.0', '4.8.0', '4.7.1' ]
817 '4.11.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
818 '4.10.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
819 '4.9.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
820 '4.8.0': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
821 '4.7.1': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
824 foreach ver: xen_tests
825 # cache the various library tests to avoid polluting the logs
827 foreach l: xen_libs[ver]
829 xen_deps += { l: cc.find_library(l, required: false) }
831 xen_test_deps += xen_deps[l]
834 # Use -D to pick just one of the test programs in scripts/xen-detect.c
835 xen_version = ver.split('.')
836 xen_ctrl_version = xen_version[0] + \
837 ('0' + xen_version[1]).substring(-2) + \
838 ('0' + xen_version[2]).substring(-2)
839 if cc.links(files('scripts/xen-detect.c'),
840 args: '-DCONFIG_XEN_CTRL_INTERFACE_VERSION=' + xen_ctrl_version,
841 dependencies: xen_test_deps)
842 xen = declare_dependency(version: ver, dependencies: xen_test_deps)
848 accelerators += 'CONFIG_XEN'
849 elif get_option('xen').enabled()
850 error('could not compile and link Xen test program')
853 have_xen_pci_passthrough = get_option('xen_pci_passthrough') \
854 .require(xen.found(),
855 error_message: 'Xen PCI passthrough requested but Xen not enabled') \
856 .require(host_os == 'linux',
857 error_message: 'Xen PCI passthrough not available on this platform') \
858 .require(cpu == 'x86' or cpu == 'x86_64',
859 error_message: 'Xen PCI passthrough not available on this platform') \
866 # When bumping glib minimum version, please check also whether to increase
867 # the _WIN32_WINNT setting in osdep.h according to the value from glib
868 glib_req_ver = '>=2.56.0'
869 glib_pc = dependency('glib-2.0', version: glib_req_ver, required: true,
870 method: 'pkg-config')
873 gmodule = dependency('gmodule-export-2.0', version: glib_req_ver, required: true,
874 method: 'pkg-config')
875 elif get_option('plugins')
876 gmodule = dependency('gmodule-no-export-2.0', version: glib_req_ver, required: true,
877 method: 'pkg-config')
882 # This workaround is required due to a bug in pkg-config file for glib as it
883 # doesn't define GLIB_STATIC_COMPILATION for pkg-config --static
884 if host_os == 'windows' and get_option('prefer_static')
885 glib_cflags += ['-DGLIB_STATIC_COMPILATION']
888 # Sanity check that the current size_t matches the
889 # size that glib thinks it should be. This catches
890 # problems on multi-arch where people try to build
891 # 32-bit QEMU while pointing at 64-bit glib headers
893 if not cc.compiles('''
897 #define QEMU_BUILD_BUG_ON(x) \
898 typedef char qemu_build_bug_on[(x)?-1:1] __attribute__((unused));
901 QEMU_BUILD_BUG_ON(sizeof(size_t) != GLIB_SIZEOF_SIZE_T);
903 }''', dependencies: glib_pc, args: glib_cflags)
904 error('''sizeof(size_t) doesn't match GLIB_SIZEOF_SIZE_T.
905 You probably need to set PKG_CONFIG_LIBDIR" to point
906 to the right pkg-config files for your build target.''')
909 # Silence clang warnings triggered by glib < 2.57.2
910 if not cc.compiles('''
915 static void foo_free(Foo *f)
919 G_DEFINE_AUTOPTR_CLEANUP_FUNC(Foo, foo_free)
920 int main(void) { return 0; }''', dependencies: glib_pc, args: ['-Wunused-function', '-Werror'])
921 glib_cflags += cc.get_supported_arguments('-Wno-unused-function')
923 glib = declare_dependency(dependencies: [glib_pc, gmodule],
924 compile_args: glib_cflags,
925 version: glib_pc.version())
927 # Check whether glib has gslice, which we have to avoid for correctness.
928 # TODO: remove this check and the corresponding workaround (qtree) when
929 # the minimum supported glib is >= 2.75.3
930 glib_has_gslice = glib.version().version_compare('<2.75.3')
932 # override glib dep to include the above refinements
933 meson.override_dependency('glib-2.0', glib)
935 # The path to glib.h is added to all compilation commands.
936 add_project_dependencies(glib.partial_dependency(compile_args: true, includes: true),
937 native: false, language: all_languages)
940 gdbus_codegen = not_found
941 gdbus_codegen_error = '@0@ requires gdbus-codegen, please install libgio'
942 if not get_option('gio').auto() or have_system
943 gio = dependency('gio-2.0', required: get_option('gio'),
944 method: 'pkg-config')
945 if gio.found() and not cc.links('''
949 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
951 }''', dependencies: [glib, gio])
952 if get_option('gio').enabled()
953 error('The installed libgio is broken for static linking')
958 gdbus_codegen = find_program(gio.get_variable('gdbus_codegen'),
959 required: get_option('gio'))
960 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
961 method: 'pkg-config')
962 gio = declare_dependency(dependencies: [gio, gio_unix],
963 version: gio.version())
966 if gdbus_codegen.found() and get_option('cfi')
967 gdbus_codegen = not_found
968 gdbus_codegen_error = '@0@ uses gdbus-codegen, which does not support control flow integrity'
971 xml_pp = find_program('scripts/xml-preprocess.py')
974 if 'ust' in get_option('trace_backends')
975 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
976 method: 'pkg-config')
979 if not get_option('pixman').auto() or have_system or have_tools
980 pixman = dependency('pixman-1', required: get_option('pixman'), version:'>=0.21.8',
981 method: 'pkg-config')
984 zlib = dependency('zlib', required: true)
987 if not get_option('linux_aio').auto() or have_block
988 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
989 required: get_option('linux_aio'))
992 linux_io_uring_test = '''
993 #include <liburing.h>
994 #include <linux/errqueue.h>
996 int main(void) { return 0; }'''
998 linux_io_uring = not_found
999 if not get_option('linux_io_uring').auto() or have_block
1000 linux_io_uring = dependency('liburing', version: '>=0.3',
1001 required: get_option('linux_io_uring'),
1002 method: 'pkg-config')
1003 if not cc.links(linux_io_uring_test)
1004 linux_io_uring = not_found
1009 if not get_option('libnfs').auto() or have_block
1010 libnfs = dependency('libnfs', version: '>=1.9.3',
1011 required: get_option('libnfs'),
1012 method: 'pkg-config')
1017 #include <sys/types.h>
1018 #ifdef CONFIG_LIBATTR
1019 #include <attr/xattr.h>
1021 #include <sys/xattr.h>
1023 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
1026 have_old_libattr = false
1027 if get_option('attr').allowed()
1028 if cc.links(libattr_test)
1029 libattr = declare_dependency()
1031 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
1032 required: get_option('attr'))
1033 if libattr.found() and not \
1034 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
1036 if get_option('attr').enabled()
1037 error('could not link libattr')
1039 warning('could not link libattr, disabling')
1042 have_old_libattr = libattr.found()
1047 cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
1048 required: get_option('cocoa'))
1050 vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
1051 if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
1052 'VMNET_BRIDGED_MODE',
1053 dependencies: vmnet)
1055 if get_option('vmnet').enabled()
1056 error('vmnet.framework API is outdated')
1058 warning('vmnet.framework API is outdated, disabling')
1063 seccomp_has_sysrawrc = false
1064 if not get_option('seccomp').auto() or have_system or have_tools
1065 seccomp = dependency('libseccomp', version: '>=2.3.0',
1066 required: get_option('seccomp'),
1067 method: 'pkg-config')
1069 seccomp_has_sysrawrc = cc.has_header_symbol('seccomp.h',
1070 'SCMP_FLTATR_API_SYSRAWRC',
1071 dependencies: seccomp)
1075 libcap_ng = not_found
1076 if not get_option('cap_ng').auto() or have_system or have_tools
1077 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
1078 required: get_option('cap_ng'))
1080 if libcap_ng.found() and not cc.links('''
1084 capng_capability_to_name(CAPNG_EFFECTIVE);
1086 }''', dependencies: libcap_ng)
1087 libcap_ng = not_found
1088 if get_option('cap_ng').enabled()
1089 error('could not link libcap-ng')
1091 warning('could not link libcap-ng, disabling')
1095 if get_option('xkbcommon').auto() and not have_system and not have_tools
1096 xkbcommon = not_found
1098 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
1099 method: 'pkg-config')
1103 if not get_option('slirp').auto() or have_system
1104 slirp = dependency('slirp', required: get_option('slirp'),
1105 method: 'pkg-config')
1106 # slirp < 4.7 is incompatible with CFI support in QEMU. This is because
1107 # it passes function pointers within libslirp as callbacks for timers.
1108 # When using a system-wide shared libslirp, the type information for the
1109 # callback is missing and the timer call produces a false positive with CFI.
1110 # Do not use the "version" keyword argument to produce a better error.
1111 # with control-flow integrity.
1112 if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
1113 if get_option('slirp').enabled()
1114 error('Control-Flow Integrity requires libslirp 4.7.')
1116 warning('Cannot use libslirp since Control-Flow Integrity requires libslirp >= 4.7.')
1123 if not get_option('vde').auto() or have_system or have_tools
1124 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
1125 required: get_option('vde'))
1127 if vde.found() and not cc.links('''
1128 #include <libvdeplug.h>
1131 struct vde_open_args a = {0, 0, 0};
1135 }''', dependencies: vde)
1137 if get_option('cap_ng').enabled()
1138 error('could not link libvdeplug')
1140 warning('could not link libvdeplug, disabling')
1145 if not get_option('pa').auto() or (host_os == 'linux' and have_system)
1146 pulse = dependency('libpulse', required: get_option('pa'),
1147 method: 'pkg-config')
1150 if not get_option('alsa').auto() or (host_os == 'linux' and have_system)
1151 alsa = dependency('alsa', required: get_option('alsa'),
1152 method: 'pkg-config')
1155 if not get_option('jack').auto() or have_system
1156 jack = dependency('jack', required: get_option('jack'),
1157 method: 'pkg-config')
1159 pipewire = not_found
1160 if not get_option('pipewire').auto() or (host_os == 'linux' and have_system)
1161 pipewire = dependency('libpipewire-0.3', version: '>=0.3.60',
1162 required: get_option('pipewire'),
1163 method: 'pkg-config')
1166 if not get_option('sndio').auto() or have_system
1167 sndio = dependency('sndio', required: get_option('sndio'),
1168 method: 'pkg-config')
1171 spice_protocol = not_found
1172 if not get_option('spice_protocol').auto() or have_system
1173 spice_protocol = dependency('spice-protocol', version: '>=0.14.0',
1174 required: get_option('spice_protocol'),
1175 method: 'pkg-config')
1178 if get_option('spice') \
1179 .disable_auto_if(not have_system) \
1180 .require(pixman.found(),
1181 error_message: 'cannot enable SPICE if pixman is not available') \
1183 spice = dependency('spice-server', version: '>=0.14.0',
1184 required: get_option('spice'),
1185 method: 'pkg-config')
1187 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
1189 rt = cc.find_library('rt', required: false)
1191 libiscsi = not_found
1192 if not get_option('libiscsi').auto() or have_block
1193 libiscsi = dependency('libiscsi', version: '>=1.9.0',
1194 required: get_option('libiscsi'),
1195 method: 'pkg-config')
1198 if not get_option('zstd').auto() or have_block
1199 zstd = dependency('libzstd', version: '>=1.4.0',
1200 required: get_option('zstd'),
1201 method: 'pkg-config')
1205 have_vhost_user_gpu = have_tools and host_os == 'linux' and pixman.found()
1206 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
1207 virgl = dependency('virglrenderer',
1208 method: 'pkg-config',
1209 required: get_option('virglrenderer'))
1211 rutabaga = not_found
1212 if not get_option('rutabaga_gfx').auto() or have_system or have_vhost_user_gpu
1213 rutabaga = dependency('rutabaga_gfx_ffi',
1214 method: 'pkg-config',
1215 required: get_option('rutabaga_gfx'))
1218 if not get_option('blkio').auto() or have_block
1219 blkio = dependency('blkio',
1220 method: 'pkg-config',
1221 required: get_option('blkio'))
1224 if not get_option('curl').auto() or have_block
1225 curl = dependency('libcurl', version: '>=7.29.0',
1226 method: 'pkg-config',
1227 required: get_option('curl'))
1230 if host_os == 'linux' and (have_system or have_tools)
1231 libudev = dependency('libudev',
1232 method: 'pkg-config',
1233 required: get_option('libudev'))
1236 mpathlibs = [libudev]
1237 mpathpersist = not_found
1238 if host_os == 'linux' and have_tools and get_option('mpath').allowed()
1239 mpath_test_source = '''
1240 #include <libudev.h>
1241 #include <mpath_persist.h>
1242 unsigned mpath_mx_alloc_len = 1024;
1244 static struct config *multipath_conf;
1245 extern struct udev *udev;
1246 extern struct config *get_multipath_config(void);
1247 extern void put_multipath_config(struct config *conf);
1249 struct config *get_multipath_config(void) { return multipath_conf; }
1250 void put_multipath_config(struct config *conf) { }
1253 multipath_conf = mpath_lib_init();
1256 libmpathpersist = cc.find_library('mpathpersist',
1257 required: get_option('mpath'))
1258 if libmpathpersist.found()
1259 mpathlibs += libmpathpersist
1260 if get_option('prefer_static')
1261 mpathlibs += cc.find_library('devmapper',
1262 required: get_option('mpath'))
1264 mpathlibs += cc.find_library('multipath',
1265 required: get_option('mpath'))
1266 foreach lib: mpathlibs
1272 if mpathlibs.length() == 0
1273 msg = 'Dependencies missing for libmpathpersist'
1274 elif cc.links(mpath_test_source, dependencies: mpathlibs)
1275 mpathpersist = declare_dependency(dependencies: mpathlibs)
1277 msg = 'Cannot detect libmpathpersist API'
1279 if not mpathpersist.found()
1280 if get_option('mpath').enabled()
1283 warning(msg + ', disabling')
1291 if have_system and get_option('curses').allowed()
1293 #if defined(__APPLE__) || defined(__OpenBSD__)
1294 #define _XOPEN_SOURCE_EXTENDED 1
1301 setlocale(LC_ALL, "");
1303 addwstr(L"wide chars\n");
1305 add_wch(WACS_DEGREE);
1309 curses_dep_list = host_os == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
1310 curses = dependency(curses_dep_list,
1312 method: 'pkg-config')
1313 msg = get_option('curses').enabled() ? 'curses library not found' : ''
1314 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
1316 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
1317 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses],
1318 version: curses.version())
1320 msg = 'curses package not usable'
1324 if not curses.found()
1325 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1326 if host_os != 'windows' and not has_curses_h
1327 message('Trying with /usr/include/ncursesw')
1328 curses_compile_args += ['-I/usr/include/ncursesw']
1329 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1332 curses_libname_list = (host_os == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
1333 foreach curses_libname : curses_libname_list
1334 libcurses = cc.find_library(curses_libname,
1336 if libcurses.found()
1337 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
1338 curses = declare_dependency(compile_args: curses_compile_args,
1339 dependencies: [libcurses])
1342 msg = 'curses library not usable'
1348 if get_option('iconv').allowed()
1349 foreach link_args : [ ['-liconv'], [] ]
1350 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
1351 # We need to use libiconv if available because mixing libiconv's headers with
1352 # the system libc does not work.
1353 # However, without adding glib to the dependencies -L/usr/local/lib will not be
1354 # included in the command line and libiconv will not be found.
1358 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
1359 return conv != (iconv_t) -1;
1360 }''', args: link_args, dependencies: glib)
1361 iconv = declare_dependency(link_args: link_args, dependencies: glib)
1366 if curses.found() and not iconv.found()
1367 if get_option('iconv').enabled()
1368 error('iconv not available')
1370 msg = 'iconv required for curses UI but not available'
1373 if not curses.found() and msg != ''
1374 if get_option('curses').enabled()
1377 warning(msg + ', disabling')
1383 if not get_option('brlapi').auto() or have_system
1384 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
1385 required: get_option('brlapi'))
1386 if brlapi.found() and not cc.links('''
1389 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
1391 if get_option('brlapi').enabled()
1392 error('could not link brlapi')
1394 warning('could not link brlapi, disabling')
1400 if not get_option('sdl').auto() or have_system
1401 sdl = dependency('sdl2', required: get_option('sdl'))
1402 sdl_image = not_found
1405 # Some versions of SDL have problems with -Wundef
1406 if not cc.compiles('''
1408 #include <SDL_syswm.h>
1409 int main(int argc, char *argv[]) { return 0; }
1410 ''', dependencies: sdl, args: '-Werror=undef')
1411 sdl = declare_dependency(compile_args: '-Wno-undef',
1413 version: sdl.version())
1415 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
1416 method: 'pkg-config')
1418 if get_option('sdl_image').enabled()
1419 error('sdl-image required, but SDL was @0@'.format(
1420 get_option('sdl').disabled() ? 'disabled' : 'not found'))
1422 sdl_image = not_found
1426 if not get_option('rbd').auto() or have_block
1427 librados = cc.find_library('rados', required: get_option('rbd'))
1428 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
1429 required: get_option('rbd'))
1430 if librados.found() and librbd.found()
1433 #include <rbd/librbd.h>
1436 rados_create(&cluster, NULL);
1437 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
1441 }''', dependencies: [librbd, librados])
1442 rbd = declare_dependency(dependencies: [librbd, librados])
1443 elif get_option('rbd').enabled()
1444 error('librbd >= 1.12.0 required')
1446 warning('librbd >= 1.12.0 not found, disabling')
1451 glusterfs = not_found
1452 glusterfs_ftruncate_has_stat = false
1453 glusterfs_iocb_has_stat = false
1454 if not get_option('glusterfs').auto() or have_block
1455 glusterfs = dependency('glusterfs-api', version: '>=3',
1456 required: get_option('glusterfs'),
1457 method: 'pkg-config')
1458 if glusterfs.found()
1459 glusterfs_ftruncate_has_stat = cc.links('''
1460 #include <glusterfs/api/glfs.h>
1465 /* new glfs_ftruncate() passes two additional args */
1466 return glfs_ftruncate(NULL, 0, NULL, NULL);
1468 ''', dependencies: glusterfs)
1469 glusterfs_iocb_has_stat = cc.links('''
1470 #include <glusterfs/api/glfs.h>
1472 /* new glfs_io_cbk() passes two additional glfs_stat structs */
1474 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
1480 glfs_io_cbk iocb = &glusterfs_iocb;
1481 iocb(NULL, 0 , NULL, NULL, NULL);
1484 ''', dependencies: glusterfs)
1489 if get_option('hv_balloon').allowed() and have_system
1492 #include <gmodule.h>
1496 tree = g_tree_new((GCompareFunc)strcmp);
1497 (void)g_tree_node_first(tree);
1498 g_tree_destroy(tree);
1501 ''', dependencies: glib)
1504 if get_option('hv_balloon').enabled()
1505 error('could not enable hv-balloon, update your glib')
1507 warning('could not find glib support for hv-balloon, disabling')
1513 if not get_option('libssh').auto() or have_block
1514 libssh = dependency('libssh', version: '>=0.8.7',
1515 method: 'pkg-config',
1516 required: get_option('libssh'))
1519 libbzip2 = not_found
1520 if not get_option('bzip2').auto() or have_block
1521 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
1522 required: get_option('bzip2'))
1523 if libbzip2.found() and not cc.links('''
1525 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
1526 libbzip2 = not_found
1527 if get_option('bzip2').enabled()
1528 error('could not link libbzip2')
1530 warning('could not link libbzip2, disabling')
1535 liblzfse = not_found
1536 if not get_option('lzfse').auto() or have_block
1537 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
1538 required: get_option('lzfse'))
1540 if liblzfse.found() and not cc.links('''
1542 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
1543 liblzfse = not_found
1544 if get_option('lzfse').enabled()
1545 error('could not link liblzfse')
1547 warning('could not link liblzfse, disabling')
1552 if get_option('oss').allowed() and have_system
1553 if not cc.has_header('sys/soundcard.h')
1555 elif host_os == 'netbsd'
1556 oss = cc.find_library('ossaudio', required: get_option('oss'))
1558 oss = declare_dependency()
1562 if get_option('oss').enabled()
1563 error('OSS not found')
1568 if not get_option('dsound').auto() or (host_os == 'windows' and have_system)
1569 if cc.has_header('dsound.h')
1570 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
1573 if not dsound.found()
1574 if get_option('dsound').enabled()
1575 error('DirectSound not found')
1580 coreaudio = not_found
1581 if not get_option('coreaudio').auto() or (host_os == 'darwin' and have_system)
1582 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
1583 required: get_option('coreaudio'))
1587 if not get_option('opengl').auto() or have_system or have_vhost_user_gpu
1588 epoxy = dependency('epoxy', method: 'pkg-config',
1589 required: get_option('opengl'))
1590 if cc.has_header('epoxy/egl.h', dependencies: epoxy)
1592 elif get_option('opengl').enabled()
1593 error('epoxy/egl.h not found')
1597 if (have_system or have_tools) and (virgl.found() or opengl.found())
1598 gbm = dependency('gbm', method: 'pkg-config', required: false)
1600 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and opengl.found() and gbm.found()
1603 gnutls_crypto = not_found
1604 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1605 # For general TLS support our min gnutls matches
1606 # that implied by our platform support matrix
1608 # For the crypto backends, we look for a newer
1611 # Version 3.6.8 is needed to get XTS
1612 # Version 3.6.13 is needed to get PBKDF
1613 # Version 3.6.14 is needed to get HW accelerated XTS
1615 # If newer enough gnutls isn't available, we can
1616 # still use a different crypto backend to satisfy
1617 # the platform support requirements
1618 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1619 method: 'pkg-config',
1621 if gnutls_crypto.found()
1622 gnutls = gnutls_crypto
1624 # Our min version if all we need is TLS
1625 gnutls = dependency('gnutls', version: '>=3.5.18',
1626 method: 'pkg-config',
1627 required: get_option('gnutls'))
1631 # We prefer use of gnutls for crypto, unless the options
1632 # explicitly asked for nettle or gcrypt.
1634 # If gnutls isn't available for crypto, then we'll prefer
1635 # gcrypt over nettle for performance reasons.
1639 crypto_sm4 = not_found
1642 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1643 error('Only one of gcrypt & nettle can be enabled')
1646 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1647 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1648 gnutls_crypto = not_found
1651 if not gnutls_crypto.found()
1652 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1653 gcrypt = dependency('libgcrypt', version: '>=1.8',
1654 method: 'config-tool',
1655 required: get_option('gcrypt'))
1656 # Debian has removed -lgpg-error from libgcrypt-config
1657 # as it "spreads unnecessary dependencies" which in
1658 # turn breaks static builds...
1659 if gcrypt.found() and get_option('prefer_static')
1660 gcrypt = declare_dependency(dependencies:
1662 cc.find_library('gpg-error', required: true)],
1663 version: gcrypt.version())
1666 # SM4 ALG is available in libgcrypt >= 1.9
1667 if gcrypt.found() and not cc.links('''
1670 gcry_cipher_hd_t handler;
1671 gcry_cipher_open(&handler, GCRY_CIPHER_SM4, GCRY_CIPHER_MODE_ECB, 0);
1673 }''', dependencies: gcrypt)
1674 crypto_sm4 = not_found
1677 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1678 nettle = dependency('nettle', version: '>=3.4',
1679 method: 'pkg-config',
1680 required: get_option('nettle'))
1681 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1685 # SM4 ALG is available in nettle >= 3.9
1686 if nettle.found() and not cc.links('''
1687 #include <nettle/sm4.h>
1690 unsigned char key[16] = {0};
1691 sm4_set_encrypt_key(&ctx, key);
1693 }''', dependencies: nettle)
1694 crypto_sm4 = not_found
1699 capstone = not_found
1700 if not get_option('capstone').auto() or have_system or have_user
1701 capstone = dependency('capstone', version: '>=3.0.5',
1702 method: 'pkg-config',
1703 required: get_option('capstone'))
1705 # Some versions of capstone have broken pkg-config file
1706 # that reports a wrong -I path, causing the #include to
1707 # fail later. If the system has such a broken version
1709 if capstone.found() and not cc.compiles('#include <capstone.h>',
1710 dependencies: [capstone])
1711 capstone = not_found
1712 if get_option('capstone').enabled()
1713 error('capstone requested, but it does not appear to work')
1718 gmp = dependency('gmp', required: false, method: 'pkg-config')
1719 if nettle.found() and gmp.found()
1720 hogweed = dependency('hogweed', version: '>=3.4',
1721 method: 'pkg-config',
1722 required: get_option('nettle'))
1729 have_gtk_clipboard = get_option('gtk_clipboard').enabled()
1731 if get_option('gtk') \
1732 .disable_auto_if(not have_system) \
1733 .require(pixman.found(),
1734 error_message: 'cannot enable GTK if pixman is not available') \
1736 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1737 method: 'pkg-config',
1738 required: get_option('gtk'))
1740 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1741 method: 'pkg-config',
1743 gtk = declare_dependency(dependencies: [gtk, gtkx11],
1744 version: gtk.version())
1746 if not get_option('vte').auto() or have_system
1747 vte = dependency('vte-2.91',
1748 method: 'pkg-config',
1749 required: get_option('vte'))
1751 elif have_gtk_clipboard
1752 error('GTK clipboard requested, but GTK not found')
1758 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found())
1761 if get_option('png').allowed() and have_system
1762 png = dependency('libpng', version: '>=1.6.34', required: get_option('png'),
1763 method: 'pkg-config')
1768 if get_option('vnc') \
1769 .disable_auto_if(not have_system) \
1770 .require(pixman.found(),
1771 error_message: 'cannot enable VNC if pixman is not available') \
1773 vnc = declare_dependency() # dummy dependency
1774 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1775 method: 'pkg-config')
1776 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1777 required: get_option('vnc_sasl'))
1779 sasl = declare_dependency(dependencies: sasl,
1780 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1785 if not get_option('auth_pam').auto() or have_system
1786 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1787 required: get_option('auth_pam'))
1789 if pam.found() and not cc.links('''
1791 #include <security/pam_appl.h>
1793 const char *service_name = "qemu";
1794 const char *user = "frank";
1795 const struct pam_conv pam_conv = { 0 };
1796 pam_handle_t *pamh = NULL;
1797 pam_start(service_name, user, &pam_conv, &pamh);
1799 }''', dependencies: pam)
1801 if get_option('auth_pam').enabled()
1802 error('could not link libpam')
1804 warning('could not link libpam, disabling')
1809 if not get_option('snappy').auto() or have_system
1810 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1811 required: get_option('snappy'))
1813 if snappy.found() and not cc.links('''
1814 #include <snappy-c.h>
1815 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1817 if get_option('snappy').enabled()
1818 error('could not link libsnappy')
1820 warning('could not link libsnappy, disabling')
1825 if not get_option('lzo').auto() or have_system
1826 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1827 required: get_option('lzo'))
1829 if lzo.found() and not cc.links('''
1830 #include <lzo/lzo1x.h>
1831 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1833 if get_option('lzo').enabled()
1834 error('could not link liblzo2')
1836 warning('could not link liblzo2, disabling')
1841 if not get_option('numa').auto() or have_system or have_tools
1842 numa = cc.find_library('numa', has_headers: ['numa.h'],
1843 required: get_option('numa'))
1845 if numa.found() and not cc.links('''
1847 int main(void) { return numa_available(); }
1848 ''', dependencies: numa)
1850 if get_option('numa').enabled()
1851 error('could not link numa')
1853 warning('could not link numa, disabling')
1858 if not get_option('rdma').auto() or have_system
1859 libumad = cc.find_library('ibumad', required: get_option('rdma'))
1860 rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'],
1861 required: get_option('rdma')),
1862 cc.find_library('ibverbs', required: get_option('rdma')),
1864 rdma = declare_dependency(dependencies: rdma_libs)
1865 foreach lib: rdma_libs
1873 if not get_option('smartcard').auto() or have_system
1874 cacard = dependency('libcacard', required: get_option('smartcard'),
1875 version: '>=2.5.1', method: 'pkg-config')
1878 if not get_option('u2f').auto() or have_system
1879 u2f = dependency('u2f-emu', required: get_option('u2f'),
1880 method: 'pkg-config')
1883 if not get_option('canokey').auto() or have_system
1884 canokey = dependency('canokey-qemu', required: get_option('canokey'),
1885 method: 'pkg-config')
1887 usbredir = not_found
1888 if not get_option('usb_redir').auto() or have_system
1889 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1890 version: '>=0.6', method: 'pkg-config')
1893 if not get_option('libusb').auto() or have_system
1894 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1895 version: '>=1.0.13', method: 'pkg-config')
1899 if not get_option('libpmem').auto() or have_system
1900 libpmem = dependency('libpmem', required: get_option('libpmem'),
1901 method: 'pkg-config')
1903 libdaxctl = not_found
1904 if not get_option('libdaxctl').auto() or have_system
1905 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1906 version: '>=57', method: 'pkg-config')
1910 tasn1 = dependency('libtasn1',
1911 method: 'pkg-config')
1913 keyutils = not_found
1914 if not get_option('libkeyutils').auto() or have_block
1915 keyutils = dependency('libkeyutils', required: get_option('libkeyutils'),
1916 method: 'pkg-config')
1919 has_gettid = cc.has_function('gettid')
1922 selinux = dependency('libselinux',
1923 required: get_option('selinux'),
1924 method: 'pkg-config')
1929 if get_option('malloc') == 'system'
1931 get_option('malloc_trim').allowed() and \
1932 cc.has_function('malloc_trim', prefix: '#include <malloc.h>')
1934 has_malloc_trim = false
1935 malloc = cc.find_library(get_option('malloc'), required: true)
1937 if not has_malloc_trim and get_option('malloc_trim').enabled()
1938 if get_option('malloc') == 'system'
1939 error('malloc_trim not available on this platform.')
1941 error('malloc_trim not available with non-libc memory allocator')
1945 gnu_source_prefix = '''
1951 # Check whether the glibc provides STATX_BASIC_STATS
1953 has_statx = cc.has_header_symbol('sys/stat.h', 'STATX_BASIC_STATS', prefix: gnu_source_prefix)
1955 # Check whether statx() provides mount ID information
1957 has_statx_mnt_id = cc.has_header_symbol('sys/stat.h', 'STATX_MNT_ID', prefix: gnu_source_prefix)
1959 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
1960 .require(host_os == 'linux',
1961 error_message: 'vhost_user_blk_server requires linux') \
1962 .require(have_vhost_user,
1963 error_message: 'vhost_user_blk_server requires vhost-user support') \
1964 .disable_auto_if(not have_tools and not have_system) \
1967 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1968 error('Cannot enable fuse-lseek while fuse is disabled')
1971 fuse = dependency('fuse3', required: get_option('fuse'),
1972 version: '>=3.1', method: 'pkg-config')
1974 fuse_lseek = not_found
1975 if get_option('fuse_lseek').allowed()
1976 if fuse.version().version_compare('>=3.8')
1978 fuse_lseek = declare_dependency()
1979 elif get_option('fuse_lseek').enabled()
1981 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1983 error('fuse-lseek requires libfuse, which was not found')
1988 have_libvduse = (host_os == 'linux')
1989 if get_option('libvduse').enabled()
1990 if host_os != 'linux'
1991 error('libvduse requires linux')
1993 elif get_option('libvduse').disabled()
1994 have_libvduse = false
1997 have_vduse_blk_export = (have_libvduse and host_os == 'linux')
1998 if get_option('vduse_blk_export').enabled()
1999 if host_os != 'linux'
2000 error('vduse_blk_export requires linux')
2001 elif not have_libvduse
2002 error('vduse_blk_export requires libvduse support')
2004 elif get_option('vduse_blk_export').disabled()
2005 have_vduse_blk_export = false
2009 bpf_version = '1.1.0'
2010 libbpf = dependency('libbpf', version: '>=' + bpf_version, required: get_option('bpf'), method: 'pkg-config')
2011 if libbpf.found() and not cc.links('''
2012 #include <bpf/libbpf.h>
2013 #include <linux/bpf.h>
2016 // check flag availability
2017 int flag = BPF_F_MMAPABLE;
2018 bpf_object__destroy_skeleton(NULL);
2020 }''', dependencies: libbpf)
2022 if get_option('bpf').enabled()
2023 error('libbpf skeleton/mmaping test failed')
2025 warning('libbpf skeleton/mmaping test failed, disabling')
2031 if not get_option('af_xdp').auto() or have_system
2032 libxdp = dependency('libxdp', required: get_option('af_xdp'),
2033 version: '>=1.4.0', method: 'pkg-config')
2038 if not get_option('libdw').auto() or \
2039 (not get_option('prefer_static') and (have_system or have_user))
2040 libdw = dependency('libdw',
2041 method: 'pkg-config',
2042 required: get_option('libdw'))
2049 config_host_data = configuration_data()
2051 audio_drivers_selected = []
2053 audio_drivers_available = {
2054 'alsa': alsa.found(),
2055 'coreaudio': coreaudio.found(),
2056 'dsound': dsound.found(),
2057 'jack': jack.found(),
2059 'pa': pulse.found(),
2060 'pipewire': pipewire.found(),
2062 'sndio': sndio.found(),
2064 foreach k, v: audio_drivers_available
2065 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
2068 # Default to native drivers first, OSS second, SDL third
2069 audio_drivers_priority = \
2070 [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \
2071 (host_os == 'linux' ? [] : [ 'sdl' ])
2072 audio_drivers_default = []
2073 foreach k: audio_drivers_priority
2074 if audio_drivers_available[k]
2075 audio_drivers_default += k
2079 foreach k: get_option('audio_drv_list')
2081 audio_drivers_selected += audio_drivers_default
2082 elif not audio_drivers_available[k]
2083 error('Audio driver "@0@" not available.'.format(k))
2085 audio_drivers_selected += k
2089 config_host_data.set('CONFIG_AUDIO_DRIVERS',
2090 '"' + '", "'.join(audio_drivers_selected) + '", ')
2092 have_host_block_device = (host_os != 'darwin' or
2093 cc.has_header('IOKit/storage/IOMedia.h'))
2095 dbus_display = get_option('dbus_display') \
2096 .require(gio.version().version_compare('>=2.64'),
2097 error_message: '-display dbus requires glib>=2.64') \
2098 .require(gdbus_codegen.found(),
2099 error_message: gdbus_codegen_error.format('-display dbus')) \
2102 have_virtfs = get_option('virtfs') \
2103 .require(host_os == 'linux' or host_os == 'darwin',
2104 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
2105 .require(host_os == 'linux' or cc.has_function('pthread_fchdir_np'),
2106 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
2107 .require(host_os == 'darwin' or libattr.found(),
2108 error_message: 'virtio-9p (virtfs) on Linux requires libattr-devel') \
2109 .disable_auto_if(not have_tools and not have_system) \
2112 have_virtfs_proxy_helper = get_option('virtfs_proxy_helper') \
2113 .require(host_os != 'darwin', error_message: 'the virtfs proxy helper is incompatible with macOS') \
2114 .require(have_virtfs, error_message: 'the virtfs proxy helper requires that virtfs is enabled') \
2115 .disable_auto_if(not have_tools) \
2116 .require(libcap_ng.found(), error_message: 'the virtfs proxy helper requires libcap-ng') \
2119 if get_option('block_drv_ro_whitelist') == ''
2120 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
2122 config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
2123 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
2125 if get_option('block_drv_rw_whitelist') == ''
2126 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
2128 config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
2129 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
2132 foreach k : get_option('trace_backends')
2133 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
2135 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
2136 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
2138 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
2140 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
2141 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
2142 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
2143 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
2144 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
2146 qemu_firmwarepath = ''
2147 foreach k : get_option('qemu_firmwarepath')
2148 qemu_firmwarepath += '"' + get_option('prefix') / k + '", '
2150 config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath)
2152 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
2153 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
2154 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
2155 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
2156 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
2157 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
2160 config_host_data.set('CONFIG_STAMP', run_command(
2161 meson.current_source_dir() / 'scripts/qemu-stamp.py',
2162 meson.project_version(), get_option('pkgversion'), '--',
2163 meson.current_source_dir() / 'configure',
2164 capture: true, check: true).stdout().strip())
2167 have_slirp_smbd = get_option('slirp_smbd') \
2168 .require(host_os != 'windows', error_message: 'Host smbd not supported on this platform.') \
2171 smbd_path = get_option('smbd')
2173 smbd_path = (host_os == 'sunos' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
2175 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
2178 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
2180 kvm_targets_c = '""'
2181 if get_option('kvm').allowed() and host_os == 'linux'
2182 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
2184 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
2186 if get_option('module_upgrades') and not enable_modules
2187 error('Cannot enable module-upgrades as modules are not enabled')
2189 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
2191 config_host_data.set('CONFIG_ATTR', libattr.found())
2192 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
2193 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
2194 config_host_data.set('CONFIG_BSD', host_os in bsd_oses)
2195 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2196 config_host_data.set('CONFIG_COCOA', cocoa.found())
2197 config_host_data.set('CONFIG_DARWIN', host_os == 'darwin')
2198 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
2199 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
2200 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
2201 config_host_data.set('CONFIG_LINUX', host_os == 'linux')
2202 config_host_data.set('CONFIG_POSIX', host_os != 'windows')
2203 config_host_data.set('CONFIG_WIN32', host_os == 'windows')
2204 config_host_data.set('CONFIG_LZO', lzo.found())
2205 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
2206 config_host_data.set('CONFIG_BLKIO', blkio.found())
2208 config_host_data.set('CONFIG_BLKIO_VHOST_VDPA_FD',
2209 blkio.version().version_compare('>=1.3.0'))
2211 config_host_data.set('CONFIG_CURL', curl.found())
2212 config_host_data.set('CONFIG_CURSES', curses.found())
2213 config_host_data.set('CONFIG_GBM', gbm.found())
2214 config_host_data.set('CONFIG_GIO', gio.found())
2215 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
2216 if glusterfs.found()
2217 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
2218 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
2219 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
2220 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
2221 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
2222 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
2224 config_host_data.set('CONFIG_GTK', gtk.found())
2225 config_host_data.set('CONFIG_VTE', vte.found())
2226 config_host_data.set('CONFIG_GTK_CLIPBOARD', have_gtk_clipboard)
2227 config_host_data.set('CONFIG_HEXAGON_IDEF_PARSER', get_option('hexagon_idef_parser'))
2228 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
2229 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
2230 config_host_data.set('CONFIG_EBPF', libbpf.found())
2231 config_host_data.set('CONFIG_AF_XDP', libxdp.found())
2232 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
2233 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
2234 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
2235 config_host_data.set('CONFIG_LIBSSH', libssh.found())
2236 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
2237 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
2238 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
2239 config_host_data.set('CONFIG_MODULES', enable_modules)
2240 config_host_data.set('CONFIG_NUMA', numa.found())
2242 config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY',
2243 cc.has_function('numa_has_preferred_many',
2244 dependencies: numa))
2246 config_host_data.set('CONFIG_OPENGL', opengl.found())
2247 config_host_data.set('CONFIG_PLUGIN', get_option('plugins'))
2248 config_host_data.set('CONFIG_RBD', rbd.found())
2249 config_host_data.set('CONFIG_RDMA', rdma.found())
2250 config_host_data.set('CONFIG_RELOCATABLE', get_option('relocatable'))
2251 config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack'))
2252 config_host_data.set('CONFIG_SDL', sdl.found())
2253 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
2254 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
2256 config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc)
2258 config_host_data.set('CONFIG_PIXMAN', pixman.found())
2259 config_host_data.set('CONFIG_SLIRP', slirp.found())
2260 config_host_data.set('CONFIG_SNAPPY', snappy.found())
2261 config_host_data.set('CONFIG_SOLARIS', host_os == 'sunos')
2262 if get_option('tcg').allowed()
2263 config_host_data.set('CONFIG_TCG', 1)
2264 config_host_data.set('CONFIG_TCG_INTERPRETER', tcg_arch == 'tci')
2266 config_host_data.set('CONFIG_TPM', have_tpm)
2267 config_host_data.set('CONFIG_TSAN', get_option('tsan'))
2268 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
2269 config_host_data.set('CONFIG_VDE', vde.found())
2270 config_host_data.set('CONFIG_VHOST', have_vhost)
2271 config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
2272 config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
2273 config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)
2274 config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
2275 config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
2276 config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
2277 config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
2278 config_host_data.set('CONFIG_VMNET', vmnet.found())
2279 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
2280 config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export)
2281 config_host_data.set('CONFIG_PNG', png.found())
2282 config_host_data.set('CONFIG_VNC', vnc.found())
2283 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
2284 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
2286 config_host_data.set('HAVE_VIRGL_D3D_INFO_EXT',
2287 cc.has_member('struct virgl_renderer_resource_info_ext', 'd3d_tex2d',
2288 prefix: '#include <virglrenderer.h>',
2289 dependencies: virgl))
2291 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
2292 config_host_data.set('CONFIG_VTE', vte.found())
2293 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
2294 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
2295 config_host_data.set('CONFIG_GETTID', has_gettid)
2296 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
2297 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
2298 config_host_data.set('CONFIG_TASN1', tasn1.found())
2299 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
2300 config_host_data.set('CONFIG_NETTLE', nettle.found())
2301 config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found())
2302 config_host_data.set('CONFIG_HOGWEED', hogweed.found())
2303 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
2304 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
2305 config_host_data.set('CONFIG_STATX', has_statx)
2306 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
2307 config_host_data.set('CONFIG_ZSTD', zstd.found())
2308 config_host_data.set('CONFIG_FUSE', fuse.found())
2309 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
2310 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
2311 if spice_protocol.found()
2312 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
2313 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
2314 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
2316 config_host_data.set('CONFIG_SPICE', spice.found())
2317 config_host_data.set('CONFIG_X11', x11.found())
2318 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
2319 config_host_data.set('CONFIG_CFI', get_option('cfi'))
2320 config_host_data.set('CONFIG_SELINUX', selinux.found())
2321 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
2322 config_host_data.set('CONFIG_LIBDW', libdw.found())
2324 # protect from xen.version() having less than three components
2325 xen_version = xen.version().split('.') + ['0', '0']
2326 xen_ctrl_version = xen_version[0] + \
2327 ('0' + xen_version[1]).substring(-2) + \
2328 ('0' + xen_version[2]).substring(-2)
2329 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
2331 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
2332 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
2333 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
2334 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
2336 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
2337 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
2339 have_coroutine_pool = get_option('coroutine_pool')
2340 if get_option('debug_stack_usage') and have_coroutine_pool
2341 message('Disabling coroutine pool to measure stack usage')
2342 have_coroutine_pool = false
2344 config_host_data.set('CONFIG_COROUTINE_POOL', have_coroutine_pool)
2345 config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock'))
2346 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
2347 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
2348 config_host_data.set('CONFIG_DEBUG_TCG', get_option('debug_tcg'))
2349 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
2350 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
2351 config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
2354 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
2355 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
2356 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
2357 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
2358 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
2359 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
2360 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
2361 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
2362 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
2363 if host_os == 'windows'
2364 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h'))
2368 config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range'))
2369 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
2370 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
2371 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
2372 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
2373 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
2374 config_host_data.set('CONFIG_GETCPU', cc.has_function('getcpu', prefix: gnu_source_prefix))
2375 config_host_data.set('CONFIG_SCHED_GETCPU', cc.has_function('sched_getcpu', prefix: '#include <sched.h>'))
2376 # Note that we need to specify prefix: here to avoid incorrectly
2377 # thinking that Windows has posix_memalign()
2378 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
2379 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
2380 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
2381 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
2382 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
2383 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
2384 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
2385 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
2386 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
2387 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
2388 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
2389 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
2390 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
2391 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
2392 config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice)
2393 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
2394 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
2395 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
2397 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
2398 cc.has_function('rbd_namespace_exists',
2400 prefix: '#include <rbd/librbd.h>'))
2403 config_host_data.set('HAVE_IBV_ADVISE_MR',
2404 cc.has_function('ibv_advise_mr',
2406 prefix: '#include <infiniband/verbs.h>'))
2409 have_asan_fiber = false
2410 if get_option('sanitizers') and \
2411 not cc.has_function('__sanitizer_start_switch_fiber',
2412 args: '-fsanitize=address',
2413 prefix: '#include <sanitizer/asan_interface.h>')
2414 warning('Missing ASAN due to missing fiber annotation interface')
2415 warning('Without code annotation, the report may be inferior.')
2417 have_asan_fiber = true
2419 config_host_data.set('CONFIG_ASAN_IFACE_FIBER', have_asan_fiber)
2421 have_inotify_init = cc.has_header_symbol('sys/inotify.h', 'inotify_init')
2422 have_inotify_init1 = cc.has_header_symbol('sys/inotify.h', 'inotify_init1')
2424 if (have_inotify_init or have_inotify_init1) and host_os == 'freebsd'
2426 inotify = cc.find_library('inotify')
2427 if have_inotify_init
2428 have_inotify_init = inotify.found()
2430 if have_inotify_init1
2431 have_inotify_init1 = inotify.found()
2434 config_host_data.set('CONFIG_INOTIFY', have_inotify_init)
2435 config_host_data.set('CONFIG_INOTIFY1', have_inotify_init1)
2438 config_host_data.set('CONFIG_BLKZONED',
2439 cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE'))
2440 config_host_data.set('CONFIG_EPOLL_CREATE1',
2441 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
2442 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
2443 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
2444 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
2445 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
2446 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
2447 config_host_data.set('CONFIG_FIEMAP',
2448 cc.has_header('linux/fiemap.h') and
2449 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
2450 config_host_data.set('CONFIG_GETRANDOM',
2451 cc.has_function('getrandom') and
2452 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
2453 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
2454 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
2455 config_host_data.set('CONFIG_RTNETLINK',
2456 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
2457 config_host_data.set('CONFIG_SYSMACROS',
2458 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
2459 config_host_data.set('HAVE_OPTRESET',
2460 cc.has_header_symbol('getopt.h', 'optreset'))
2461 config_host_data.set('HAVE_IPPROTO_MPTCP',
2462 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
2465 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
2466 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
2467 prefix: '#include <signal.h>'))
2468 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
2469 cc.has_member('struct stat', 'st_atim',
2470 prefix: '#include <sys/stat.h>'))
2471 config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY',
2472 cc.has_member('struct blk_zone', 'capacity',
2473 prefix: '#include <linux/blkzoned.h>'))
2476 config_host_data.set('CONFIG_IOVEC',
2477 cc.has_type('struct iovec',
2478 prefix: '#include <sys/uio.h>'))
2479 config_host_data.set('HAVE_UTMPX',
2480 cc.has_type('struct utmpx',
2481 prefix: '#include <utmpx.h>'))
2483 config_host_data.set('CONFIG_EVENTFD', cc.links('''
2484 #include <sys/eventfd.h>
2485 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
2486 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
2489 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
2490 return fdatasync(0);
2492 #error Not supported
2496 has_madvise = cc.links(gnu_source_prefix + '''
2497 #include <sys/types.h>
2498 #include <sys/mman.h>
2500 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
2501 missing_madvise_proto = false
2503 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
2504 # but forget to prototype it. In this case, has_madvise will be true (the
2505 # test program links despite a compile warning). To detect the
2506 # missing-prototype case, we try again with a definitely-bogus prototype.
2507 # This will only compile if the system headers don't provide the prototype;
2508 # otherwise the conflicting prototypes will cause a compiler error.
2509 missing_madvise_proto = cc.links(gnu_source_prefix + '''
2510 #include <sys/types.h>
2511 #include <sys/mman.h>
2513 extern int madvise(int);
2514 int main(void) { return madvise(0); }''')
2516 config_host_data.set('CONFIG_MADVISE', has_madvise)
2517 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
2519 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
2520 #include <sys/mman.h>
2521 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
2522 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
2524 #if !defined(AT_EMPTY_PATH)
2525 # error missing definition
2527 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
2529 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
2530 #include <sys/mman.h>
2532 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
2534 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
2535 #include <pthread.h>
2537 static void *f(void *p) { return NULL; }
2541 pthread_create(&thread, 0, f, 0);
2542 pthread_setname_np(thread, "QEMU");
2544 }''', dependencies: threads))
2545 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
2546 #include <pthread.h>
2548 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
2552 pthread_create(&thread, 0, f, 0);
2554 }''', dependencies: threads))
2555 config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(gnu_source_prefix + '''
2556 #include <pthread.h>
2557 #include <pthread_np.h>
2559 static void *f(void *p) { return NULL; }
2563 pthread_create(&thread, 0, f, 0);
2564 pthread_set_name_np(thread, "QEMU");
2566 }''', dependencies: threads))
2567 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
2568 #include <pthread.h>
2573 pthread_condattr_t attr
2574 pthread_condattr_init(&attr);
2575 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
2577 }''', dependencies: threads))
2578 config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(gnu_source_prefix + '''
2579 #include <pthread.h>
2581 static void *f(void *p) { return NULL; }
2584 int setsize = CPU_ALLOC_SIZE(64);
2587 pthread_create(&thread, 0, f, 0);
2588 cpuset = CPU_ALLOC(64);
2589 CPU_ZERO_S(setsize, cpuset);
2590 pthread_setaffinity_np(thread, setsize, cpuset);
2591 pthread_getaffinity_np(thread, setsize, cpuset);
2594 }''', dependencies: threads))
2595 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
2596 #include <sys/signalfd.h>
2598 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
2599 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
2607 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
2608 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
2612 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
2613 #include <sys/mman.h>
2615 return mlockall(MCL_FUTURE);
2619 if get_option('l2tpv3').allowed() and have_system
2620 have_l2tpv3 = cc.has_type('struct mmsghdr',
2621 prefix: gnu_source_prefix + '''
2622 #include <sys/socket.h>
2623 #include <linux/ip.h>''')
2625 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2628 if get_option('netmap').allowed() and have_system
2629 have_netmap = cc.compiles('''
2630 #include <inttypes.h>
2632 #include <net/netmap.h>
2633 #include <net/netmap_user.h>
2634 #if (NETMAP_API < 11) || (NETMAP_API > 15)
2637 int main(void) { return 0; }''')
2638 if not have_netmap and get_option('netmap').enabled()
2639 error('Netmap headers not available')
2642 config_host_data.set('CONFIG_NETMAP', have_netmap)
2644 # Work around a system header bug with some kernel/XFS header
2645 # versions where they both try to define 'struct fsxattr':
2646 # xfs headers will not try to redefine structs from linux headers
2647 # if this macro is set.
2648 config_host_data.set('HAVE_FSXATTR', cc.links('''
2649 #include <linux/fs.h>
2655 # Some versions of Mac OS X incorrectly define SIZE_MAX
2656 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2660 return printf("%zu", SIZE_MAX);
2661 }''', args: ['-Werror']))
2663 # See if 64-bit atomic operations are supported.
2664 # Note that without __atomic builtins, we can only
2665 # assume atomic loads/stores max at pointer size.
2666 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
2670 uint64_t x = 0, y = 0;
2671 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2672 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2673 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2674 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2675 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2679 has_int128_type = cc.compiles('''
2682 int main(void) { b = a; }''')
2683 config_host_data.set('CONFIG_INT128_TYPE', has_int128_type)
2685 has_int128 = has_int128_type and cc.links('''
2694 config_host_data.set('CONFIG_INT128', has_int128)
2697 # "do we have 128-bit atomics which are handled inline and specifically not
2698 # via libatomic". The reason we can't use libatomic is documented in the
2699 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2700 # We only care about these operations on 16-byte aligned pointers, so
2701 # force 16-byte alignment of the pointer, which may be greater than
2702 # __alignof(unsigned __int128) for the host.
2703 atomic_test_128 = '''
2704 int main(int ac, char **av) {
2705 __uint128_t *p = __builtin_assume_aligned(av[ac - 1], 16);
2706 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED);
2707 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED);
2708 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2711 has_atomic128 = cc.links(atomic_test_128)
2713 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2715 if not has_atomic128
2716 # Even with __builtin_assume_aligned, the above test may have failed
2717 # without optimization enabled. Try again with optimizations locally
2718 # enabled for the function. See
2719 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389
2720 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128)
2721 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt)
2723 if not has_atomic128_opt
2724 config_host_data.set('CONFIG_CMPXCHG128', cc.links('''
2727 __uint128_t x = 0, y = 0;
2728 __sync_val_compare_and_swap_16(&x, y, x);
2736 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2737 #include <sys/auxv.h>
2739 return getauxval(AT_HWCAP) == 0;
2742 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2743 #include <linux/usbdevice_fs.h>
2745 #ifndef USBDEVFS_GET_CAPABILITIES
2746 #error "USBDEVFS_GET_CAPABILITIES undefined"
2749 #ifndef USBDEVFS_DISCONNECT_CLAIM
2750 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2753 int main(void) { return 0; }'''))
2755 have_keyring = get_option('keyring') \
2756 .require(host_os == 'linux', error_message: 'keyring is only available on Linux') \
2757 .require(cc.compiles('''
2759 #include <asm/unistd.h>
2760 #include <linux/keyctl.h>
2761 #include <sys/syscall.h>
2764 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2765 }'''), error_message: 'keyctl syscall not available on this system').allowed()
2766 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2768 have_cpuid_h = cc.links('''
2771 unsigned a, b, c, d;
2772 unsigned max = __get_cpuid_max(0, 0);
2775 __cpuid(1, a, b, c, d);
2779 __cpuid_count(7, 0, a, b, c, d);
2784 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2786 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2787 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2788 .require(cc.links('''
2790 #include <immintrin.h>
2791 static int __attribute__((target("avx2"))) bar(void *a) {
2792 __m256i x = *(__m256i *)a;
2793 return _mm256_testz_si256(x, x);
2795 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2796 '''), error_message: 'AVX2 not available').allowed())
2798 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2799 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2800 .require(cc.links('''
2802 #include <immintrin.h>
2803 static int __attribute__((target("avx512f"))) bar(void *a) {
2804 __m512i x = *(__m512i *)a;
2805 return _mm512_test_epi64_mask(x, x);
2807 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2808 '''), error_message: 'AVX512F not available').allowed())
2810 config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \
2811 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \
2812 .require(cc.links('''
2814 #include <immintrin.h>
2815 static int __attribute__((target("avx512bw"))) bar(void *a) {
2817 __m512i res= _mm512_abs_epi8(*x);
2820 int main(int argc, char *argv[]) { return bar(argv[0]); }
2821 '''), error_message: 'AVX512BW not available').allowed())
2823 # For both AArch64 and AArch32, detect if builtins are available.
2824 config_host_data.set('CONFIG_ARM_AES_BUILTIN', cc.compiles('''
2825 #include <arm_neon.h>
2826 #ifndef __ARM_FEATURE_AES
2827 __attribute__((target("+crypto")))
2829 void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); }
2832 have_pvrdma = get_option('pvrdma') \
2833 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
2834 .require(cc.compiles(gnu_source_prefix + '''
2835 #include <sys/mman.h>
2840 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2843 }'''), error_message: 'PVRDMA requires mremap').allowed()
2846 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.links('''
2847 #include <infiniband/verbs.h>
2851 struct ibv_pd *pd = NULL;
2857 mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2863 if get_option('membarrier').disabled()
2864 have_membarrier = false
2865 elif host_os == 'windows'
2866 have_membarrier = true
2867 elif host_os == 'linux'
2868 have_membarrier = cc.compiles('''
2869 #include <linux/membarrier.h>
2870 #include <sys/syscall.h>
2874 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2875 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2879 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2880 .require(have_membarrier, error_message: 'membarrier system call not available') \
2883 have_afalg = get_option('crypto_afalg') \
2884 .require(cc.compiles(gnu_source_prefix + '''
2886 #include <sys/types.h>
2887 #include <sys/socket.h>
2888 #include <linux/if_alg.h>
2891 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2894 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2895 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2897 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2898 'linux/vm_sockets.h', 'AF_VSOCK',
2899 prefix: '#include <sys/socket.h>',
2903 have_vss_sdk = false # old xp/2003 SDK
2904 if host_os == 'windows' and 'cpp' in all_languages
2905 have_vss = cxx.compiles('''
2906 #define __MIDL_user_allocate_free_DEFINED__
2908 int main(void) { return VSS_CTX_BACKUP; }''')
2909 have_vss_sdk = cxx.has_header('vscoordint.h')
2911 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2913 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2914 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2915 if host_os == 'windows'
2916 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2922 }''', name: '_lock_file and _unlock_file'))
2925 if host_os == 'windows'
2926 mingw_has_setjmp_longjmp = cc.links('''
2930 * These functions are not available in setjmp header, but may be
2931 * available at link time, from libmingwex.a.
2933 extern int __mingw_setjmp(jmp_buf);
2934 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
2936 __mingw_setjmp(env);
2937 __mingw_longjmp(env, 0);
2939 ''', name: 'mingw setjmp and longjmp')
2941 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp
2942 error('mingw must provide setjmp/longjmp for windows-arm64')
2946 ########################
2947 # Target configuration #
2948 ########################
2950 minikconf = find_program('scripts/minikconf.py')
2952 config_all_accel = {}
2953 config_all_devices = {}
2954 config_devices_mak_list = []
2955 config_devices_h = {}
2956 config_target_h = {}
2957 config_target_mak = {}
2960 'alpha' : ['CONFIG_ALPHA_DIS'],
2961 'avr' : ['CONFIG_AVR_DIS'],
2962 'cris' : ['CONFIG_CRIS_DIS'],
2963 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2964 'hppa' : ['CONFIG_HPPA_DIS'],
2965 'i386' : ['CONFIG_I386_DIS'],
2966 'x86_64' : ['CONFIG_I386_DIS'],
2967 'm68k' : ['CONFIG_M68K_DIS'],
2968 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2969 'mips' : ['CONFIG_MIPS_DIS'],
2970 'nios2' : ['CONFIG_NIOS2_DIS'],
2971 'or1k' : ['CONFIG_OPENRISC_DIS'],
2972 'ppc' : ['CONFIG_PPC_DIS'],
2973 'riscv' : ['CONFIG_RISCV_DIS'],
2974 'rx' : ['CONFIG_RX_DIS'],
2975 's390' : ['CONFIG_S390_DIS'],
2976 'sh4' : ['CONFIG_SH4_DIS'],
2977 'sparc' : ['CONFIG_SPARC_DIS'],
2978 'xtensa' : ['CONFIG_XTENSA_DIS'],
2979 'loongarch' : ['CONFIG_LOONGARCH_DIS'],
2982 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2984 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2985 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2986 (pixman.found() ? ['CONFIG_PIXMAN=y'] : []) + \
2987 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2988 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2989 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2990 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2991 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
2992 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2993 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2994 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2995 (host_os == 'linux' ? ['CONFIG_LINUX=y'] : []) + \
2996 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
2997 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
2998 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \
2999 (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : [])
3001 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
3003 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
3004 actual_target_dirs = []
3006 foreach target : target_dirs
3007 config_target = { 'TARGET_NAME': target.split('-')[0] }
3008 if target.endswith('linux-user')
3009 if host_os != 'linux'
3013 error('Target @0@ is only available on a Linux host'.format(target))
3015 config_target += { 'CONFIG_LINUX_USER': 'y' }
3016 elif target.endswith('bsd-user')
3017 if host_os not in bsd_oses
3021 error('Target @0@ is only available on a BSD host'.format(target))
3023 config_target += { 'CONFIG_BSD_USER': 'y' }
3024 elif target.endswith('softmmu')
3025 config_target += { 'CONFIG_SYSTEM_ONLY': 'y' }
3026 config_target += { 'CONFIG_SOFTMMU': 'y' }
3028 if target.endswith('-user')
3030 'CONFIG_USER_ONLY': 'y',
3031 'CONFIG_QEMU_INTERP_PREFIX':
3032 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
3037 foreach sym: accelerators
3038 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
3039 config_target += { sym: 'y' }
3040 config_all_accel += { sym: 'y' }
3041 if target in modular_tcg
3042 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
3044 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
3046 accel_kconfig += [ sym + '=y' ]
3049 if accel_kconfig.length() == 0
3053 error('No accelerator available for target @0@'.format(target))
3056 actual_target_dirs += target
3057 config_target += keyval.load('configs/targets' / target + '.mak')
3058 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
3060 if 'TARGET_NEED_FDT' in config_target
3061 fdt_required += target
3065 if 'TARGET_BASE_ARCH' not in config_target
3066 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
3068 if 'TARGET_ABI_DIR' not in config_target
3069 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
3071 if 'TARGET_BIG_ENDIAN' not in config_target
3072 config_target += {'TARGET_BIG_ENDIAN': 'n'}
3075 foreach k, v: disassemblers
3076 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
3078 config_target += { sym: 'y' }
3083 config_target_data = configuration_data()
3084 foreach k, v: config_target
3085 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
3087 elif ignored.contains(k)
3089 elif k == 'TARGET_BASE_ARCH'
3090 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
3091 # not used to select files from sourcesets.
3092 config_target_data.set('TARGET_' + v.to_upper(), 1)
3093 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
3094 config_target_data.set_quoted(k, v)
3096 config_target_data.set(k, 1)
3098 config_target_data.set(k, 0)
3100 config_target_data.set(k, v)
3103 config_target_data.set('QEMU_ARCH',
3104 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
3105 config_target_h += {target: configure_file(output: target + '-config-target.h',
3106 configuration: config_target_data)}
3108 if target.endswith('-softmmu')
3109 config_input = meson.get_external_property(target, 'default')
3110 config_devices_mak = target + '-config-devices.mak'
3111 config_devices_mak = configure_file(
3112 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
3113 output: config_devices_mak,
3114 depfile: config_devices_mak + '.d',
3116 command: [minikconf,
3117 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
3118 config_devices_mak, '@DEPFILE@', '@INPUT@',
3119 host_kconfig, accel_kconfig,
3120 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
3122 config_devices_data = configuration_data()
3123 config_devices = keyval.load(config_devices_mak)
3124 foreach k, v: config_devices
3125 config_devices_data.set(k, 1)
3127 config_devices_mak_list += config_devices_mak
3128 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
3129 configuration: config_devices_data)}
3130 config_target += config_devices
3131 config_all_devices += config_devices
3133 config_target_mak += {target: config_target}
3135 target_dirs = actual_target_dirs
3137 target_configs_h = []
3138 foreach target: target_dirs
3139 target_configs_h += config_target_h[target]
3140 target_configs_h += config_devices_h.get(target, [])
3142 genh += custom_target('config-poison.h',
3143 input: [target_configs_h],
3144 output: 'config-poison.h',
3146 command: [find_program('scripts/make-config-poison.sh'),
3153 libvfio_user_dep = not_found
3154 if have_system and vfio_user_server_allowed
3155 libvfio_user_proj = subproject('libvfio-user', required: true)
3156 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep')
3160 fdt_opt = get_option('fdt')
3161 if fdt_required.length() > 0 or fdt_opt == 'enabled'
3162 if fdt_opt == 'disabled'
3163 error('fdt disabled but required by targets ' + ', '.join(fdt_required))
3166 if fdt_opt in ['enabled', 'auto', 'system']
3167 if get_option('wrap_mode') == 'nodownload'
3170 fdt = cc.find_library('fdt', required: fdt_opt == 'system')
3171 if fdt.found() and cc.links('''
3173 #include <libfdt_env.h>
3174 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
3177 elif fdt_opt == 'system'
3178 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
3180 fdt_opt = 'internal'
3185 assert(fdt_opt == 'internal')
3186 libfdt_proj = subproject('dtc', required: true,
3187 default_options: ['tools=false', 'yaml=disabled',
3188 'python=disabled', 'default_library=static'])
3189 fdt = libfdt_proj.get_variable('libfdt_dep')
3192 fdt_opt = 'disabled'
3195 config_host_data.set('CONFIG_FDT', fdt.found())
3197 vhost_user = not_found
3198 if host_os == 'linux' and have_vhost_user
3199 libvhost_user = subproject('libvhost-user')
3200 vhost_user = libvhost_user.get_variable('vhost_user_dep')
3203 libvduse = not_found
3205 libvduse_proj = subproject('libvduse')
3206 libvduse = libvduse_proj.get_variable('libvduse_dep')
3209 #####################
3210 # Generated sources #
3211 #####################
3213 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
3215 hxtool = find_program('scripts/hxtool')
3216 shaderinclude = find_program('scripts/shaderinclude.py')
3217 qapi_gen = find_program('scripts/qapi-gen.py')
3218 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
3219 meson.current_source_dir() / 'scripts/qapi/commands.py',
3220 meson.current_source_dir() / 'scripts/qapi/common.py',
3221 meson.current_source_dir() / 'scripts/qapi/error.py',
3222 meson.current_source_dir() / 'scripts/qapi/events.py',
3223 meson.current_source_dir() / 'scripts/qapi/expr.py',
3224 meson.current_source_dir() / 'scripts/qapi/gen.py',
3225 meson.current_source_dir() / 'scripts/qapi/introspect.py',
3226 meson.current_source_dir() / 'scripts/qapi/main.py',
3227 meson.current_source_dir() / 'scripts/qapi/parser.py',
3228 meson.current_source_dir() / 'scripts/qapi/schema.py',
3229 meson.current_source_dir() / 'scripts/qapi/source.py',
3230 meson.current_source_dir() / 'scripts/qapi/types.py',
3231 meson.current_source_dir() / 'scripts/qapi/visit.py',
3232 meson.current_source_dir() / 'scripts/qapi-gen.py'
3236 python, files('scripts/tracetool.py'),
3237 '--backend=' + ','.join(get_option('trace_backends'))
3239 tracetool_depends = files(
3240 'scripts/tracetool/backend/log.py',
3241 'scripts/tracetool/backend/__init__.py',
3242 'scripts/tracetool/backend/dtrace.py',
3243 'scripts/tracetool/backend/ftrace.py',
3244 'scripts/tracetool/backend/simple.py',
3245 'scripts/tracetool/backend/syslog.py',
3246 'scripts/tracetool/backend/ust.py',
3247 'scripts/tracetool/format/ust_events_c.py',
3248 'scripts/tracetool/format/ust_events_h.py',
3249 'scripts/tracetool/format/__init__.py',
3250 'scripts/tracetool/format/d.py',
3251 'scripts/tracetool/format/simpletrace_stap.py',
3252 'scripts/tracetool/format/c.py',
3253 'scripts/tracetool/format/h.py',
3254 'scripts/tracetool/format/log_stap.py',
3255 'scripts/tracetool/format/stap.py',
3256 'scripts/tracetool/__init__.py',
3257 'scripts/tracetool/vcpu.py'
3260 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
3261 meson.current_source_dir(),
3262 get_option('pkgversion'), meson.project_version()]
3263 qemu_version = custom_target('qemu-version.h',
3264 output: 'qemu-version.h',
3265 command: qemu_version_cmd,
3267 build_by_default: true,
3268 build_always_stale: true)
3269 genh += qemu_version
3273 ['qemu-options.hx', 'qemu-options.def'],
3274 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
3278 ['hmp-commands.hx', 'hmp-commands.h'],
3279 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
3282 foreach d : hx_headers
3283 hxdep += custom_target(d[1],
3287 command: [hxtool, '-h', '@INPUT0@'])
3295 # TODO: add each directory to the subdirs from its own meson.build, once
3297 trace_events_subdirs = [
3306 trace_events_subdirs += [ 'linux-user' ]
3309 trace_events_subdirs += [ 'bsd-user' ]
3312 trace_events_subdirs += [
3321 trace_events_subdirs += [
3386 if have_system or have_user
3387 trace_events_subdirs += [
3410 authz_ss = ss.source_set()
3411 blockdev_ss = ss.source_set()
3412 block_ss = ss.source_set()
3413 chardev_ss = ss.source_set()
3414 common_ss = ss.source_set()
3415 crypto_ss = ss.source_set()
3416 hwcore_ss = ss.source_set()
3417 io_ss = ss.source_set()
3418 qmp_ss = ss.source_set()
3419 qom_ss = ss.source_set()
3420 system_ss = ss.source_set()
3421 specific_fuzz_ss = ss.source_set()
3422 specific_ss = ss.source_set()
3423 stub_ss = ss.source_set()
3424 trace_ss = ss.source_set()
3425 user_ss = ss.source_set()
3426 util_ss = ss.source_set()
3429 qtest_module_ss = ss.source_set()
3430 tcg_module_ss = ss.source_set()
3436 target_system_arch = {}
3437 target_user_arch = {}
3439 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3440 # that is filled in by qapi/.
3454 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3455 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3458 qom_ss = qom_ss.apply({})
3459 libqom = static_library('qom', qom_ss.sources() + genh,
3460 dependencies: [qom_ss.dependencies()],
3462 build_by_default: false)
3463 qom = declare_dependency(link_whole: libqom)
3465 event_loop_base = files('event-loop-base.c')
3466 event_loop_base = static_library('event-loop-base',
3467 sources: event_loop_base + genh,
3469 build_by_default: false)
3470 event_loop_base = declare_dependency(link_whole: event_loop_base,
3471 dependencies: [qom])
3473 stub_ss = stub_ss.apply({})
3475 util_ss.add_all(trace_ss)
3476 util_ss = util_ss.apply({})
3477 libqemuutil = static_library('qemuutil',
3478 build_by_default: false,
3479 sources: util_ss.sources() + stub_ss.sources() + genh,
3480 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
3481 qemuutil = declare_dependency(link_with: libqemuutil,
3482 sources: genh + version_res,
3483 dependencies: [event_loop_base])
3485 if have_system or have_user
3486 decodetree = generator(find_program('scripts/decodetree.py'),
3487 output: 'decode-@BASENAME@.c.inc',
3488 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3489 subdir('libdecnumber')
3506 if config_host_data.get('CONFIG_REPLICATION')
3507 block_ss.add(files('replication.c'))
3514 blockdev_ss.add(files(
3521 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3522 # os-win32.c does not
3523 if host_os == 'windows'
3524 system_ss.add(files('os-win32.c'))
3526 blockdev_ss.add(files('os-posix.c'))
3530 common_ss.add(files('cpu-common.c'))
3531 specific_ss.add(files('cpu-target.c'))
3535 # Work around a gcc bug/misfeature wherein constant propagation looks
3537 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3538 # to guess that a const variable is always zero. Without lto, this is
3539 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
3540 # without lto, not even the alias is required -- we simply use different
3541 # declarations in different compilation units.
3542 pagevary = files('page-vary-common.c')
3543 if get_option('b_lto')
3544 pagevary_flags = ['-fno-lto']
3545 if get_option('cfi')
3546 pagevary_flags += '-fno-sanitize=cfi-icall'
3548 pagevary = static_library('page-vary-common', sources: pagevary + genh,
3549 c_args: pagevary_flags)
3550 pagevary = declare_dependency(link_with: pagevary)
3552 common_ss.add(pagevary)
3553 specific_ss.add(files('page-vary-target.c'))
3561 subdir('semihosting')
3569 common_user_inc = []
3571 subdir('common-user')
3573 subdir('linux-user')
3575 # needed for fuzzing binaries
3576 subdir('tests/qtest/libqos')
3577 subdir('tests/qtest/fuzz')
3580 tcg_real_module_ss = ss.source_set()
3581 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3582 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3583 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3584 'tcg': tcg_real_module_ss }}
3586 ##############################################
3587 # Internal static_libraries and dependencies #
3588 ##############################################
3590 modinfo_collect = find_program('scripts/modinfo-collect.py')
3591 modinfo_generate = find_program('scripts/modinfo-generate.py')
3596 foreach d, list : modules
3597 if not (d == 'block' ? have_block : have_system)
3601 foreach m, module_ss : list
3603 module_ss = module_ss.apply(config_all_devices, strict: false)
3604 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3605 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3611 if module_ss.sources() != []
3612 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3613 # input. Sources can be used multiple times but objects are
3614 # unique when it comes to lookup in compile_commands.json.
3615 # Depnds on a mesion version with
3616 # https://github.com/mesonbuild/meson/pull/8900
3617 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3618 output: d + '-' + m + '.modinfo',
3619 input: module_ss.sources() + genh,
3621 command: [modinfo_collect, module_ss.sources()])
3625 block_ss.add_all(module_ss)
3627 system_ss.add_all(module_ss)
3633 foreach d, list : target_modules
3634 foreach m, module_ss : list
3636 foreach target : target_dirs
3637 if target.endswith('-softmmu')
3638 config_target = config_target_mak[target]
3639 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3640 c_args = ['-DNEED_CPU_H',
3641 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3642 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3643 target_module_ss = module_ss.apply(config_target, strict: false)
3644 if target_module_ss.sources() != []
3645 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3646 sl = static_library(module_name,
3647 [genh, target_module_ss.sources()],
3648 dependencies: [modulecommon, target_module_ss.dependencies()],
3649 include_directories: target_inc,
3653 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3654 modinfo_files += custom_target(module_name + '.modinfo',
3655 output: module_name + '.modinfo',
3656 input: target_module_ss.sources() + genh,
3658 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3663 specific_ss.add_all(module_ss)
3669 foreach target : target_dirs
3670 if target.endswith('-softmmu')
3671 config_target = config_target_mak[target]
3672 config_devices_mak = target + '-config-devices.mak'
3673 modinfo_src = custom_target('modinfo-' + target + '.c',
3674 output: 'modinfo-' + target + '.c',
3675 input: modinfo_files,
3676 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'],
3679 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
3680 modinfo_dep = declare_dependency(link_with: modinfo_lib)
3682 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH']
3683 hw_arch[arch].add(modinfo_dep)
3688 nm = find_program('nm')
3689 undefsym = find_program('scripts/undefsym.py')
3690 block_syms = custom_target('block.syms', output: 'block.syms',
3691 input: [libqemuutil, block_mods],
3693 command: [undefsym, nm, '@INPUT@'])
3694 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3695 input: [libqemuutil, system_mods],
3697 command: [undefsym, nm, '@INPUT@'])
3699 authz_ss = authz_ss.apply({})
3700 libauthz = static_library('authz', authz_ss.sources() + genh,
3701 dependencies: [authz_ss.dependencies()],
3703 build_by_default: false)
3705 authz = declare_dependency(link_whole: libauthz,
3708 crypto_ss = crypto_ss.apply({})
3709 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3710 dependencies: [crypto_ss.dependencies()],
3712 build_by_default: false)
3714 crypto = declare_dependency(link_whole: libcrypto,
3715 dependencies: [authz, qom])
3717 io_ss = io_ss.apply({})
3718 libio = static_library('io', io_ss.sources() + genh,
3719 dependencies: [io_ss.dependencies()],
3720 link_with: libqemuutil,
3722 build_by_default: false)
3724 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3726 libmigration = static_library('migration', sources: migration_files + genh,
3728 build_by_default: false)
3729 migration = declare_dependency(link_with: libmigration,
3730 dependencies: [zlib, qom, io])
3731 system_ss.add(migration)
3733 block_ss = block_ss.apply({})
3734 libblock = static_library('block', block_ss.sources() + genh,
3735 dependencies: block_ss.dependencies(),
3736 link_depends: block_syms,
3738 build_by_default: false)
3740 block = declare_dependency(link_whole: [libblock],
3741 link_args: '@block.syms',
3742 dependencies: [crypto, io])
3744 blockdev_ss = blockdev_ss.apply({})
3745 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3746 dependencies: blockdev_ss.dependencies(),
3748 build_by_default: false)
3750 blockdev = declare_dependency(link_whole: [libblockdev],
3751 dependencies: [block, event_loop_base])
3753 qmp_ss = qmp_ss.apply({})
3754 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3755 dependencies: qmp_ss.dependencies(),
3757 build_by_default: false)
3759 qmp = declare_dependency(link_whole: [libqmp])
3761 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3763 dependencies: chardev_ss.dependencies(),
3764 build_by_default: false)
3766 chardev = declare_dependency(link_whole: libchardev)
3768 hwcore_ss = hwcore_ss.apply({})
3769 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3771 build_by_default: false)
3772 hwcore = declare_dependency(link_whole: libhwcore)
3773 common_ss.add(hwcore)
3779 emulator_modules = []
3780 foreach m : block_mods + system_mods
3781 emulator_modules += shared_module(m.name(),
3782 build_by_default: true,
3786 install_dir: qemu_moddir)
3788 if emulator_modules.length() > 0
3789 alias_target('modules', emulator_modules)
3792 system_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3793 common_ss.add(qom, qemuutil)
3795 common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss])
3796 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3798 # Note that this library is never used directly (only through extract_objects)
3799 # and is not built by default; therefore, source files not used by the build
3800 # configuration will be in build.ninja, but are never built by default.
3801 common_all = static_library('common',
3802 build_by_default: false,
3803 sources: common_ss.all_sources() + genh,
3804 include_directories: common_user_inc,
3805 implicit_include_directories: false,
3806 dependencies: common_ss.all_dependencies(),
3809 feature_to_c = find_program('scripts/feature_to_c.py')
3811 if host_os == 'darwin'
3812 entitlement = find_program('scripts/entitlement.sh')
3817 foreach target : target_dirs
3818 config_target = config_target_mak[target]
3819 target_name = config_target['TARGET_NAME']
3820 target_base_arch = config_target['TARGET_BASE_ARCH']
3821 arch_srcs = [config_target_h[target]]
3823 c_args = ['-DNEED_CPU_H',
3824 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3825 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3826 link_args = emulator_link_args
3828 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3829 if host_os == 'linux'
3830 target_inc += include_directories('linux-headers', is_system: true)
3832 if target.endswith('-softmmu')
3833 target_type='system'
3834 t = target_system_arch[target_base_arch].apply(config_target, strict: false)
3835 arch_srcs += t.sources()
3836 arch_deps += t.dependencies()
3838 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3839 if hw_arch.has_key(hw_dir)
3840 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3841 arch_srcs += hw.sources()
3842 arch_deps += hw.dependencies()
3845 arch_srcs += config_devices_h[target]
3846 link_args += ['@block.syms', '@qemu.syms']
3848 abi = config_target['TARGET_ABI_DIR']
3850 target_inc += common_user_inc
3851 if target_base_arch in target_user_arch
3852 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3853 arch_srcs += t.sources()
3854 arch_deps += t.dependencies()
3856 if 'CONFIG_LINUX_USER' in config_target
3857 base_dir = 'linux-user'
3859 if 'CONFIG_BSD_USER' in config_target
3860 base_dir = 'bsd-user'
3861 target_inc += include_directories('bsd-user/' / host_os)
3862 target_inc += include_directories('bsd-user/host/' / host_arch)
3863 dir = base_dir / abi
3864 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3866 target_inc += include_directories(
3870 if 'CONFIG_LINUX_USER' in config_target
3871 dir = base_dir / abi
3872 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3873 if config_target.has_key('TARGET_SYSTBL_ABI')
3875 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3876 extra_args : config_target['TARGET_SYSTBL_ABI'])
3881 if 'TARGET_XML_FILES' in config_target
3882 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3883 output: target + '-gdbstub-xml.c',
3884 input: files(config_target['TARGET_XML_FILES'].split()),
3885 command: [feature_to_c, '@INPUT@'],
3887 arch_srcs += gdbstub_xml
3890 t = target_arch[target_base_arch].apply(config_target, strict: false)
3891 arch_srcs += t.sources()
3892 arch_deps += t.dependencies()
3894 target_common = common_ss.apply(config_target, strict: false)
3895 objects = common_all.extract_objects(target_common.sources())
3896 deps = target_common.dependencies()
3898 target_specific = specific_ss.apply(config_target, strict: false)
3899 arch_srcs += target_specific.sources()
3900 arch_deps += target_specific.dependencies()
3902 lib = static_library('qemu-' + target,
3903 sources: arch_srcs + genh,
3904 dependencies: arch_deps,
3906 include_directories: target_inc,
3908 build_by_default: false,
3911 if target.endswith('-softmmu')
3913 'name': 'qemu-system-' + target_name,
3914 'win_subsystem': 'console',
3915 'sources': files('system/main.c'),
3918 if host_os == 'windows' and (sdl.found() or gtk.found())
3920 'name': 'qemu-system-' + target_name + 'w',
3921 'win_subsystem': 'windows',
3922 'sources': files('system/main.c'),
3926 if get_option('fuzzing')
3927 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3929 'name': 'qemu-fuzz-' + target_name,
3930 'win_subsystem': 'console',
3931 'sources': specific_fuzz.sources(),
3932 'dependencies': specific_fuzz.dependencies(),
3937 'name': 'qemu-' + target_name,
3938 'win_subsystem': 'console',
3944 exe_name = exe['name']
3945 if host_os == 'darwin'
3946 exe_name += '-unsigned'
3949 emulator = executable(exe_name, exe['sources'],
3952 dependencies: arch_deps + deps + exe['dependencies'],
3953 objects: lib.extract_all_objects(recursive: true),
3954 link_depends: [block_syms, qemu_syms],
3955 link_args: link_args,
3956 win_subsystem: exe['win_subsystem'])
3958 if host_os == 'darwin'
3959 icon = 'pc-bios/qemu.rsrc'
3960 build_input = [emulator, files(icon)]
3962 get_option('bindir') / exe_name,
3963 meson.current_source_dir() / icon
3965 if 'CONFIG_HVF' in config_target
3966 entitlements = 'accel/hvf/entitlements.plist'
3967 build_input += files(entitlements)
3968 install_input += meson.current_source_dir() / entitlements
3971 emulators += {exe['name'] : custom_target(exe['name'],
3973 output: exe['name'],
3974 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3977 meson.add_install_script(entitlement, '--install',
3978 get_option('bindir') / exe['name'],
3981 emulators += {exe['name']: emulator}
3986 'probe-prefix': 'qemu.' + target_type + '.' + target_name,
3992 # Other build targets
3994 if get_option('plugins')
3995 install_headers('include/qemu/qemu-plugin.h')
3996 if host_os == 'windows'
3997 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer,
3998 # so that plugin authors can compile against it.
3999 install_data(win32_qemu_plugin_api_lib, install_dir: 'lib')
4005 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
4006 # when we don't build tools or system
4007 if xkbcommon.found()
4008 # used for the update-keymaps target, so include rules even if !have_tools
4009 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
4010 dependencies: [qemuutil, xkbcommon], install: have_tools)
4014 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
4015 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
4016 qemu_io = executable('qemu-io', files('qemu-io.c'),
4017 dependencies: [block, qemuutil], install: true)
4018 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
4019 dependencies: [blockdev, qemuutil, gnutls, selinux],
4022 subdir('storage-daemon')
4024 foreach exe: [ 'qemu-img', 'qemu-io', 'qemu-nbd', 'qemu-storage-daemon']
4027 'probe-prefix': 'qemu.' + exe.substring(5).replace('-', '_')
4031 subdir('contrib/rdmacm-mux')
4032 subdir('contrib/elf2dmp')
4034 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
4035 dependencies: qemuutil,
4039 subdir('contrib/vhost-user-blk')
4040 subdir('contrib/vhost-user-gpu')
4041 subdir('contrib/vhost-user-input')
4042 subdir('contrib/vhost-user-scsi')
4045 if host_os == 'linux'
4046 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
4047 dependencies: [qemuutil, libcap_ng],
4049 install_dir: get_option('libexecdir'))
4051 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
4052 dependencies: [authz, crypto, io, qom, qemuutil,
4053 libcap_ng, mpathpersist],
4058 subdir('contrib/ivshmem-client')
4059 subdir('contrib/ivshmem-server')
4064 foreach t: traceable
4066 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / t['exe'], 'install': false},
4067 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / t['exe'], 'install': true},
4068 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
4069 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
4072 tracetool, '--group=all', '--format=' + stp['fmt'],
4073 '--binary=' + stp['bin'],
4074 '--probe-prefix=' + t['probe-prefix'],
4075 '@INPUT@', '@OUTPUT@'
4078 custom_target(t['exe'] + stp['ext'],
4079 input: trace_events_all,
4080 output: t['exe'] + stp['ext'],
4081 install: stp['install'],
4082 install_dir: get_option('datadir') / 'systemtap/tapset',
4084 depend_files: tracetool_depends)
4098 if host_machine.system() == 'windows'
4100 find_program('scripts/nsis.py'),
4102 get_option('prefix'),
4103 meson.current_source_dir(),
4104 glib_pc.get_variable('bindir'),
4107 '-DDISPLAYVERSION=' + meson.project_version(),
4110 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
4113 nsis_cmd += '-DCONFIG_GTK=y'
4116 nsis = custom_target('nsis',
4117 output: 'qemu-setup-' + meson.project_version() + '.exe',
4118 input: files('qemu.nsi'),
4119 build_always_stale: true,
4120 command: nsis_cmd + ['@INPUT@'])
4121 alias_target('installer', nsis)
4124 #########################
4125 # Configuration summary #
4126 #########################
4130 summary_info += {'Build directory': meson.current_build_dir()}
4131 summary_info += {'Source path': meson.current_source_dir()}
4132 summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'}
4133 summary(summary_info, bool_yn: true, section: 'Build environment')
4136 summary_info += {'Install prefix': get_option('prefix')}
4137 summary_info += {'BIOS directory': qemu_datadir}
4138 pathsep = host_os == 'windows' ? ';' : ':'
4139 summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))}
4140 summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
4141 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
4142 summary_info += {'module directory': qemu_moddir}
4143 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
4144 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
4145 summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')}
4146 if host_os != 'windows'
4147 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
4148 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')}
4150 summary_info += {'local state directory': 'queried at runtime'}
4152 summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
4153 summary(summary_info, bool_yn: true, section: 'Directories')
4157 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
4158 summary_info += {'sphinx-build': sphinx_build}
4160 # FIXME: the [binaries] section of machine files, which can be probed
4161 # with find_program(), would be great for passing gdb and genisoimage
4162 # paths from configure to Meson. However, there seems to be no way to
4163 # hide a program (for example if gdb is too old).
4164 if config_host.has_key('GDB')
4165 summary_info += {'gdb': config_host['GDB']}
4167 summary_info += {'iasl': iasl}
4168 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
4169 if host_os == 'windows' and have_ga
4170 summary_info += {'wixl': wixl}
4172 if slirp.found() and have_system
4173 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
4175 summary(summary_info, bool_yn: true, section: 'Host binaries')
4177 # Configurable features
4179 summary_info += {'Documentation': build_docs}
4180 summary_info += {'system-mode emulation': have_system}
4181 summary_info += {'user-mode emulation': have_user}
4182 summary_info += {'block layer': have_block}
4183 summary_info += {'Install blobs': get_option('install_blobs')}
4184 summary_info += {'module support': enable_modules}
4186 summary_info += {'alternative module path': get_option('module_upgrades')}
4188 summary_info += {'fuzzing support': get_option('fuzzing')}
4190 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
4192 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
4193 if 'simple' in get_option('trace_backends')
4194 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
4196 summary_info += {'D-Bus display': dbus_display}
4197 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
4198 summary_info += {'Relocatable install': get_option('relocatable')}
4199 summary_info += {'vhost-kernel support': have_vhost_kernel}
4200 summary_info += {'vhost-net support': have_vhost_net}
4201 summary_info += {'vhost-user support': have_vhost_user}
4202 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
4203 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
4204 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
4205 summary_info += {'build guest agent': have_ga}
4206 summary(summary_info, bool_yn: true, section: 'Configurable features')
4208 # Compilation information
4210 summary_info += {'host CPU': cpu}
4211 summary_info += {'host endianness': build_machine.endian()}
4212 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
4213 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
4214 if 'cpp' in all_languages
4215 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
4217 summary_info += {'C++ compiler': false}
4219 if 'objc' in all_languages
4220 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
4222 summary_info += {'Objective-C compiler': false}
4224 option_cflags = (get_option('debug') ? ['-g'] : [])
4225 if get_option('optimization') != 'plain'
4226 option_cflags += ['-O' + get_option('optimization')]
4228 summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)}
4229 if 'cpp' in all_languages
4230 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)}
4232 if 'objc' in all_languages
4233 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)}
4235 link_args = get_option('c_link_args')
4236 if link_args.length() > 0
4237 summary_info += {'LDFLAGS': ' '.join(link_args)}
4239 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)}
4240 if 'cpp' in all_languages
4241 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)}
4243 if 'objc' in all_languages
4244 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)}
4246 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
4247 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
4248 summary_info += {'PIE': get_option('b_pie')}
4249 summary_info += {'static build': get_option('prefer_static')}
4250 summary_info += {'malloc trim support': has_malloc_trim}
4251 summary_info += {'membarrier': have_membarrier}
4252 summary_info += {'debug graph lock': get_option('debug_graph_lock')}
4253 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
4254 summary_info += {'mutex debugging': get_option('debug_mutex')}
4255 summary_info += {'memory allocator': get_option('malloc')}
4256 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
4257 summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')}
4258 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
4259 summary_info += {'gcov': get_option('b_coverage')}
4260 summary_info += {'thread sanitizer': get_option('tsan')}
4261 summary_info += {'CFI support': get_option('cfi')}
4262 if get_option('cfi')
4263 summary_info += {'CFI debug support': get_option('cfi_debug')}
4265 summary_info += {'strip binaries': get_option('strip')}
4266 summary_info += {'sparse': sparse}
4267 summary_info += {'mingw32 support': host_os == 'windows'}
4268 summary(summary_info, bool_yn: true, section: 'Compilation')
4270 # snarf the cross-compilation information for tests
4273 foreach target: target_dirs
4274 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak'
4275 if fs.exists(tcg_mak)
4276 config_cross_tcg = keyval.load(tcg_mak)
4277 if 'CC' in config_cross_tcg
4278 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']}
4284 summary(summary_info, bool_yn: true, section: 'Cross compilers')
4287 # Targets and accelerators
4290 summary_info += {'KVM support': config_all_accel.has_key('CONFIG_KVM')}
4291 summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')}
4292 summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')}
4293 summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')}
4294 summary_info += {'Xen support': xen.found()}
4296 summary_info += {'xen ctrl version': xen.version()}
4298 summary_info += {'Xen emulation': config_all_devices.has_key('CONFIG_XEN_EMU')}
4300 summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')}
4301 if config_all_accel.has_key('CONFIG_TCG')
4302 if get_option('tcg_interpreter')
4303 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
4305 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
4307 summary_info += {'TCG plugins': get_option('plugins')}
4308 summary_info += {'TCG debug enabled': get_option('debug_tcg')}
4310 summary_info += {'target list': ' '.join(target_dirs)}
4312 summary_info += {'default devices': get_option('default_devices')}
4313 summary_info += {'out of process emulation': multiprocess_allowed}
4314 summary_info += {'vfio-user server': vfio_user_server_allowed}
4316 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
4320 summary_info += {'coroutine backend': coroutine_backend}
4321 summary_info += {'coroutine pool': have_coroutine_pool}
4323 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
4324 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
4325 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
4326 summary_info += {'VirtFS (9P) support': have_virtfs}
4327 summary_info += {'VirtFS (9P) Proxy Helper support (deprecated)': have_virtfs_proxy_helper}
4328 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
4329 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
4330 summary_info += {'bochs support': get_option('bochs').allowed()}
4331 summary_info += {'cloop support': get_option('cloop').allowed()}
4332 summary_info += {'dmg support': get_option('dmg').allowed()}
4333 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
4334 summary_info += {'vdi support': get_option('vdi').allowed()}
4335 summary_info += {'vhdx support': get_option('vhdx').allowed()}
4336 summary_info += {'vmdk support': get_option('vmdk').allowed()}
4337 summary_info += {'vpc support': get_option('vpc').allowed()}
4338 summary_info += {'vvfat support': get_option('vvfat').allowed()}
4339 summary_info += {'qed support': get_option('qed').allowed()}
4340 summary_info += {'parallels support': get_option('parallels').allowed()}
4341 summary_info += {'FUSE exports': fuse}
4342 summary_info += {'VDUSE block exports': have_vduse_blk_export}
4344 summary(summary_info, bool_yn: true, section: 'Block layer support')
4348 summary_info += {'TLS priority': get_option('tls_priority')}
4349 summary_info += {'GNUTLS support': gnutls}
4351 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
4353 summary_info += {'libgcrypt': gcrypt}
4354 summary_info += {'nettle': nettle}
4356 summary_info += {' XTS': xts != 'private'}
4358 summary_info += {'SM4 ALG support': crypto_sm4}
4359 summary_info += {'AF_ALG support': have_afalg}
4360 summary_info += {'rng-none': get_option('rng_none')}
4361 summary_info += {'Linux keyring': have_keyring}
4362 summary_info += {'Linux keyutils': keyutils}
4363 summary(summary_info, bool_yn: true, section: 'Crypto')
4367 if host_os == 'darwin'
4368 summary_info += {'Cocoa support': cocoa}
4370 summary_info += {'SDL support': sdl}
4371 summary_info += {'SDL image support': sdl_image}
4372 summary_info += {'GTK support': gtk}
4373 summary_info += {'pixman': pixman}
4374 summary_info += {'VTE support': vte}
4375 summary_info += {'PNG support': png}
4376 summary_info += {'VNC support': vnc}
4378 summary_info += {'VNC SASL support': sasl}
4379 summary_info += {'VNC JPEG support': jpeg}
4381 summary_info += {'spice protocol support': spice_protocol}
4382 if spice_protocol.found()
4383 summary_info += {' spice server support': spice}
4385 summary_info += {'curses support': curses}
4386 summary_info += {'brlapi support': brlapi}
4387 summary(summary_info, bool_yn: true, section: 'User interface')
4391 summary_info += {'VirGL support': virgl}
4392 summary_info += {'Rutabaga support': rutabaga}
4393 summary(summary_info, bool_yn: true, section: 'Graphics backends')
4397 if host_os not in ['darwin', 'haiku', 'windows']
4398 summary_info += {'OSS support': oss}
4399 summary_info += {'sndio support': sndio}
4400 elif host_os == 'darwin'
4401 summary_info += {'CoreAudio support': coreaudio}
4402 elif host_os == 'windows'
4403 summary_info += {'DirectSound support': dsound}
4405 if host_os == 'linux'
4406 summary_info += {'ALSA support': alsa}
4407 summary_info += {'PulseAudio support': pulse}
4409 summary_info += {'PipeWire support': pipewire}
4410 summary_info += {'JACK support': jack}
4411 summary(summary_info, bool_yn: true, section: 'Audio backends')
4415 if host_os == 'darwin'
4416 summary_info += {'vmnet.framework support': vmnet}
4418 summary_info += {'AF_XDP support': libxdp}
4419 summary_info += {'slirp support': slirp}
4420 summary_info += {'vde support': vde}
4421 summary_info += {'netmap support': have_netmap}
4422 summary_info += {'l2tpv3 support': have_l2tpv3}
4423 summary(summary_info, bool_yn: true, section: 'Network backends')
4427 summary_info += {'libtasn1': tasn1}
4428 summary_info += {'PAM': pam}
4429 summary_info += {'iconv support': iconv}
4430 summary_info += {'blkio support': blkio}
4431 summary_info += {'curl support': curl}
4432 summary_info += {'Multipath support': mpathpersist}
4433 summary_info += {'Linux AIO support': libaio}
4434 summary_info += {'Linux io_uring support': linux_io_uring}
4435 summary_info += {'ATTR/XATTR support': libattr}
4436 summary_info += {'RDMA support': rdma}
4437 summary_info += {'PVRDMA support': have_pvrdma}
4438 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
4439 summary_info += {'libcap-ng support': libcap_ng}
4440 summary_info += {'bpf support': libbpf}
4441 summary_info += {'rbd support': rbd}
4442 summary_info += {'smartcard support': cacard}
4443 summary_info += {'U2F support': u2f}
4444 summary_info += {'libusb': libusb}
4445 summary_info += {'usb net redir': usbredir}
4446 summary_info += {'OpenGL support (epoxy)': opengl}
4447 summary_info += {'GBM': gbm}
4448 summary_info += {'libiscsi support': libiscsi}
4449 summary_info += {'libnfs support': libnfs}
4450 if host_os == 'windows'
4452 summary_info += {'QGA VSS support': have_qga_vss}
4455 summary_info += {'seccomp support': seccomp}
4456 summary_info += {'GlusterFS support': glusterfs}
4457 summary_info += {'hv-balloon support': hv_balloon}
4458 summary_info += {'TPM support': have_tpm}
4459 summary_info += {'libssh support': libssh}
4460 summary_info += {'lzo support': lzo}
4461 summary_info += {'snappy support': snappy}
4462 summary_info += {'bzip2 support': libbzip2}
4463 summary_info += {'lzfse support': liblzfse}
4464 summary_info += {'zstd support': zstd}
4465 summary_info += {'NUMA host support': numa}
4466 summary_info += {'capstone': capstone}
4467 summary_info += {'libpmem support': libpmem}
4468 summary_info += {'libdaxctl support': libdaxctl}
4469 summary_info += {'libudev': libudev}
4470 # Dummy dependency, keep .found()
4471 summary_info += {'FUSE lseek': fuse_lseek.found()}
4472 summary_info += {'selinux': selinux}
4473 summary_info += {'libdw': libdw}
4474 if host_os == 'freebsd'
4475 summary_info += {'libinotify-kqueue': inotify}
4477 summary(summary_info, bool_yn: true, section: 'Dependencies')
4479 if host_arch == 'unknown'
4481 warning('UNSUPPORTED HOST CPU')
4483 message('Support for CPU host architecture ' + cpu + ' is not currently')
4484 message('maintained. The QEMU project does not guarantee that QEMU will')
4485 message('compile or work on this host CPU. You can help by volunteering')
4486 message('to maintain it and providing a build host for our continuous')
4487 message('integration setup.')
4488 if get_option('tcg').allowed() and target_dirs.length() > 0
4490 message('configure has succeeded and you can continue to build, but')
4491 message('QEMU will use a slow interpreter to emulate the target CPU.')
4495 if not supported_oses.contains(host_os)
4497 warning('UNSUPPORTED HOST OS')
4499 message('Support for host OS ' + host_os + 'is not currently maintained.')
4500 message('configure has succeeded and you can continue to build, but')
4501 message('the QEMU project does not guarantee that QEMU will compile or')
4502 message('work on this operating system. You can help by volunteering')
4503 message('to maintain it and providing a build host for our continuous')
4504 message('integration setup. This will ensure that future versions of QEMU')
4505 message('will keep working on ' + host_os + '.')
4508 if host_arch == 'unknown' or not supported_oses.contains(host_os)
4510 message('If you want to help supporting QEMU on this platform, please')
4511 message('contact the developers at qemu-devel@nongnu.org.')
4514 actually_reloc = get_option('relocatable')
4515 # check if get_relocated_path() is actually able to relocate paths
4516 if get_option('relocatable') and \
4517 not (get_option('prefix') / get_option('bindir')).startswith(get_option('prefix') / '')
4519 warning('bindir not included within prefix, the installation will not be relocatable.')
4520 actually_reloc = false
4522 if not actually_reloc and (host_os == 'windows' or get_option('relocatable'))
4523 if host_os == 'windows'
4525 warning('Windows installs should usually be relocatable.')
4528 message('QEMU will have to be installed under ' + get_option('prefix') + '.')
4529 message('Use --disable-relocatable to remove this warning.')