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 # Assume x86-64-v2 (minus CMPXCHG16B for 32-bit code)
340 if host_arch == 'i386'
341 qemu_common_flags = ['-mfpmath=sse'] + qemu_common_flags
343 if host_arch in ['i386', 'x86_64']
344 qemu_common_flags = ['-mpopcnt', '-msse4.2'] + qemu_common_flags
346 if host_arch == 'x86_64'
347 qemu_common_flags = ['-mcx16'] + qemu_common_flags
350 if get_option('prefer_static')
351 qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
354 # Meson currently only handles pie as a boolean for now, so if the user
355 # has explicitly disabled PIE we need to extend our cflags.
357 # -no-pie is supposedly a linker flag that has no effect on the compiler
358 # command line, but some distros, that didn't quite know what they were
359 # doing, made local changes to gcc's specs file that turned it into
360 # a compiler command-line flag.
362 # What about linker flags? For a static build, no PIE is implied by -static
363 # which we added above (and if it's not because of the same specs patching,
364 # there's nothing we can do: compilation will fail, report a bug to your
365 # distro and do not use --disable-pie in the meanwhile). For dynamic linking,
366 # instead, we can't add -no-pie because it overrides -shared: the linker then
367 # tries to build an executable instead of a shared library and fails. So
368 # don't add -no-pie anywhere and cross fingers. :(
369 if not get_option('b_pie')
370 qemu_common_flags += cc.get_supported_arguments('-fno-pie', '-no-pie')
373 if not get_option('stack_protector').disabled()
374 stack_protector_probe = '''
375 int main(int argc, char *argv[])
377 char arr[64], *p = arr, *c = argv[argc - 1];
383 have_stack_protector = false
384 foreach arg : ['-fstack-protector-strong', '-fstack-protector-all']
385 # We need to check both a compile and a link, since some compiler
386 # setups fail only on a .c->.o compile and some only at link time
387 if cc.compiles(stack_protector_probe, args: ['-Werror', arg]) and \
388 cc.links(stack_protector_probe, args: ['-Werror', arg])
389 have_stack_protector = true
395 get_option('stack_protector') \
396 .require(have_stack_protector, error_message: 'Stack protector not supported')
399 coroutine_backend = get_option('coroutine_backend')
401 #include <ucontext.h>
402 #ifdef __stub_makecontext
403 #error Ignoring glibc stub makecontext which will always fail
405 int main(void) { makecontext(0, 0, 0); return 0; }'''
407 # On Windows the only valid backend is the Windows specific one.
408 # For POSIX prefer ucontext, but it's not always possible. The fallback
410 supported_backends = []
411 if host_os == 'windows'
412 supported_backends += ['windows']
414 if host_os != 'darwin' and cc.links(ucontext_probe)
415 supported_backends += ['ucontext']
417 supported_backends += ['sigaltstack']
420 if coroutine_backend == 'auto'
421 coroutine_backend = supported_backends[0]
422 elif coroutine_backend not in supported_backends
423 error('"@0@" backend requested but not available. Available backends: @1@' \
424 .format(coroutine_backend, ', '.join(supported_backends)))
427 # Compiles if SafeStack *not* enabled
428 safe_stack_probe = '''
431 #if defined(__has_feature)
432 #if __has_feature(safe_stack)
433 #error SafeStack Enabled
438 if get_option('safe_stack') != not cc.compiles(safe_stack_probe)
439 safe_stack_arg = get_option('safe_stack') ? '-fsanitize=safe-stack' : '-fno-sanitize=safe-stack'
440 if get_option('safe_stack') != not cc.compiles(safe_stack_probe, args: safe_stack_arg)
441 error(get_option('safe_stack') \
442 ? 'SafeStack not supported by your compiler' \
443 : 'Cannot disable SafeStack')
445 qemu_cflags += safe_stack_arg
446 qemu_ldflags += safe_stack_arg
448 if get_option('safe_stack') and coroutine_backend != 'ucontext'
449 error('SafeStack is only supported with the ucontext coroutine backend')
452 if get_option('sanitizers')
453 if cc.has_argument('-fsanitize=address')
454 qemu_cflags = ['-fsanitize=address'] + qemu_cflags
455 qemu_ldflags = ['-fsanitize=address'] + qemu_ldflags
458 # Detect static linking issue with ubsan - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84285
459 if cc.links('int main(int argc, char **argv) { return argc + 1; }',
460 args: [qemu_ldflags, '-fsanitize=undefined'])
461 qemu_cflags = ['-fsanitize=undefined'] + qemu_cflags
462 qemu_ldflags = ['-fsanitize=undefined'] + qemu_ldflags
466 # Thread sanitizer is, for now, much noisier than the other sanitizers;
467 # keep it separate until that is not the case.
468 if get_option('tsan')
469 if get_option('sanitizers')
470 error('TSAN is not supported with other sanitizers')
472 if not cc.has_function('__tsan_create_fiber',
473 args: '-fsanitize=thread',
474 prefix: '#include <sanitizer/tsan_interface.h>')
475 error('Cannot enable TSAN due to missing fiber annotation interface')
477 qemu_cflags = ['-fsanitize=thread'] + qemu_cflags
478 qemu_ldflags = ['-fsanitize=thread'] + qemu_ldflags
481 # Detect support for PT_GNU_RELRO + DT_BIND_NOW.
482 # The combination is known as "full relro", because .got.plt is read-only too.
483 qemu_ldflags += cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now')
485 if host_os == 'windows'
486 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat')
487 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase', '-Wl,--high-entropy-va')
490 if get_option('fuzzing')
491 # Specify a filter to only instrument code that is directly related to
493 configure_file(output: 'instrumentation-filter',
494 input: 'scripts/oss-fuzz/instrumentation-filter-template',
497 if cc.compiles('int main () { return 0; }',
498 name: '-fsanitize-coverage-allowlist=/dev/null',
499 args: ['-fsanitize-coverage-allowlist=/dev/null',
500 '-fsanitize-coverage=trace-pc'] )
501 qemu_common_flags += ['-fsanitize-coverage-allowlist=instrumentation-filter']
504 if get_option('fuzzing_engine') == ''
505 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
506 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
507 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
508 # unable to bind the fuzzer-related callbacks added by instrumentation.
509 qemu_common_flags += ['-fsanitize=fuzzer-no-link']
510 qemu_ldflags += ['-fsanitize=fuzzer-no-link']
511 # For the actual fuzzer binaries, we need to link against the libfuzzer
512 # library. They need to be configurable, to support OSS-Fuzz
513 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
515 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
516 # the needed CFLAGS have already been provided
517 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
523 # Check for dependency on LTO
524 if not get_option('b_lto')
525 error('Selected Control-Flow Integrity but LTO is disabled')
528 error('Selected Control-Flow Integrity is not compatible with modules')
530 # Check for cfi flags. CFI requires LTO so we can't use
531 # get_supported_arguments, but need a more complex "compiles" which allows
533 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
534 args: ['-flto', '-fsanitize=cfi-icall'] )
535 cfi_flags += '-fsanitize=cfi-icall'
537 error('-fsanitize=cfi-icall is not supported by the compiler')
539 if cc.compiles('int main () { return 0; }',
540 name: '-fsanitize-cfi-icall-generalize-pointers',
541 args: ['-flto', '-fsanitize=cfi-icall',
542 '-fsanitize-cfi-icall-generalize-pointers'] )
543 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
545 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
547 if get_option('cfi_debug')
548 if cc.compiles('int main () { return 0; }',
549 name: '-fno-sanitize-trap=cfi-icall',
550 args: ['-flto', '-fsanitize=cfi-icall',
551 '-fno-sanitize-trap=cfi-icall'] )
552 cfi_flags += '-fno-sanitize-trap=cfi-icall'
554 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
557 add_global_arguments(cfi_flags, native: false, language: all_languages)
558 add_global_link_arguments(cfi_flags, native: false, language: all_languages)
561 # Check further flags that make QEMU more robust against malicious parties
564 # Initialize all stack variables to zero. This makes
565 # it harder to take advantage of uninitialized stack
566 # data to drive exploits
567 '-ftrivial-auto-var-init=zero',
570 # Zero out registers used during a function call
571 # upon its return. This makes it harder to assemble
572 # ROP gadgets into something usable
574 # NB: Clang 17 is broken and SEGVs
575 # https://github.com/llvm/llvm-project/issues/75168
577 # NB2: This clashes with the "retguard" extension of OpenBSD's Clang
578 # https://gitlab.com/qemu-project/qemu/-/issues/2278
579 if host_os != 'openbsd' and \
580 cc.compiles('extern struct { void (*cb)(void); } s; void f(void) { s.cb(); }',
581 name: '-fzero-call-used-regs=used-gpr',
582 args: ['-O2', '-fzero-call-used-regs=used-gpr'])
583 hardening_flags += '-fzero-call-used-regs=used-gpr'
586 qemu_common_flags += cc.get_supported_arguments(hardening_flags)
588 add_global_arguments(qemu_common_flags, native: false, language: all_languages)
589 add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
591 # Collect warning flags we want to set, sorted alphabetically
593 # First enable interesting warnings
596 '-Wexpansion-to-defined',
599 '-Wignored-qualifiers',
600 '-Wimplicit-fallthrough=2',
602 '-Wmissing-format-attribute',
603 '-Wmissing-prototypes',
605 '-Wold-style-declaration',
606 '-Wold-style-definition',
609 '-Wstrict-prototypes',
615 # Then disable some undesirable warnings
616 '-Wno-gnu-variable-sized-type-not-at-end',
617 '-Wno-initializer-overrides',
618 '-Wno-missing-include-dirs',
620 '-Wno-shift-negative-value',
621 '-Wno-string-plus-int',
622 '-Wno-tautological-type-limit-compare',
623 '-Wno-typedef-redefinition',
626 if host_os != 'darwin'
627 warn_flags += ['-Wthread-safety']
630 # Set up C++ compiler flags
632 if 'cpp' in all_languages
633 qemu_cxxflags = ['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'] + qemu_cflags
636 add_project_arguments(qemu_cflags, native: false, language: 'c')
637 add_project_arguments(cc.get_supported_arguments(warn_flags), native: false, language: 'c')
638 if 'cpp' in all_languages
639 add_project_arguments(qemu_cxxflags, native: false, language: 'cpp')
640 add_project_arguments(cxx.get_supported_arguments(warn_flags), native: false, language: 'cpp')
642 if 'objc' in all_languages
643 # Note sanitizer flags are not applied to Objective-C sources!
644 add_project_arguments(objc.get_supported_arguments(warn_flags), native: false, language: 'objc')
646 if host_os == 'linux'
647 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
648 '-isystem', 'linux-headers',
649 language: all_languages)
652 add_project_arguments('-iquote', '.',
653 '-iquote', meson.current_source_dir(),
654 '-iquote', meson.current_source_dir() / 'include',
655 language: all_languages)
657 # If a host-specific include directory exists, list that first...
658 host_include = meson.current_source_dir() / 'host/include/'
659 if fs.is_dir(host_include / host_arch)
660 add_project_arguments('-iquote', host_include / host_arch,
661 language: all_languages)
663 # ... followed by the generic fallback.
664 add_project_arguments('-iquote', host_include / 'generic',
665 language: all_languages)
667 sparse = find_program('cgcc', required: get_option('sparse'))
670 command: [find_program('scripts/check_sparse.py'),
671 'compile_commands.json', sparse.full_path(), '-Wbitwise',
672 '-Wno-transparent-union', '-Wno-old-initializer',
673 '-Wno-non-pointer-null'])
676 #####################################
677 # Host-specific libraries and flags #
678 #####################################
680 libm = cc.find_library('m', required: false)
681 threads = dependency('threads')
682 util = cc.find_library('util', required: false)
688 emulator_link_args = []
693 if host_os == 'windows'
694 midl = find_program('midl', required: false)
695 widl = find_program('widl', required: false)
696 pathcch = cc.find_library('pathcch')
697 socket = cc.find_library('ws2_32')
698 winmm = cc.find_library('winmm')
700 win = import('windows')
701 version_res = win.compile_resources('version.rc',
702 depend_files: files('pc-bios/qemu-nsis.ico'),
703 include_directories: include_directories('.'))
705 elif host_os == 'darwin'
706 coref = dependency('appleframeworks', modules: 'CoreFoundation')
707 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
708 host_dsosuf = '.dylib'
709 elif host_os == 'sunos'
710 socket = [cc.find_library('socket'),
711 cc.find_library('nsl'),
712 cc.find_library('resolv')]
713 elif host_os == 'haiku'
714 socket = [cc.find_library('posix_error_mapper'),
715 cc.find_library('network'),
716 cc.find_library('bsd')]
717 elif host_os == 'openbsd'
718 if get_option('tcg').allowed() and target_dirs.length() > 0
719 # Disable OpenBSD W^X if available
720 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
724 ###############################################
725 # Host-specific configuration of accelerators #
726 ###############################################
729 if get_option('kvm').allowed() and host_os == 'linux'
730 accelerators += 'CONFIG_KVM'
732 if get_option('whpx').allowed() and host_os == 'windows'
733 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
734 error('WHPX requires 64-bit host')
735 elif cc.has_header('winhvplatform.h', required: get_option('whpx')) and \
736 cc.has_header('winhvemulation.h', required: get_option('whpx'))
737 accelerators += 'CONFIG_WHPX'
742 if get_option('hvf').allowed()
743 hvf = dependency('appleframeworks', modules: 'Hypervisor',
744 required: get_option('hvf'))
746 accelerators += 'CONFIG_HVF'
751 if host_os == 'netbsd'
752 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
754 accelerators += 'CONFIG_NVMM'
759 if get_option('tcg').allowed()
760 if host_arch == 'unknown'
761 if not get_option('tcg_interpreter')
762 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
764 elif get_option('tcg_interpreter')
765 warning('Use of the TCG interpreter is not recommended on this host')
766 warning('architecture. There is a native TCG execution backend available')
767 warning('which provides substantially better performance and reliability.')
768 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
769 warning('configuration option on this architecture to use the native')
772 if get_option('tcg_interpreter')
774 elif host_arch == 'x86_64'
776 elif host_arch == 'ppc64'
779 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
780 language: all_languages)
782 accelerators += 'CONFIG_TCG'
785 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
786 error('KVM not available on this platform')
788 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
789 error('HVF not available on this platform')
791 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
792 error('NVMM not available on this platform')
794 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
795 error('WHPX not available on this platform')
799 if get_option('xen').enabled() or (get_option('xen').auto() and have_system)
800 xencontrol = dependency('xencontrol', required: false,
801 method: 'pkg-config')
802 if xencontrol.found()
803 xen_pc = declare_dependency(version: xencontrol.version(),
806 # disabler: true makes xen_pc.found() return false if any is not found
807 dependency('xenstore', required: false,
808 method: 'pkg-config',
810 dependency('xenforeignmemory', required: false,
811 method: 'pkg-config',
813 dependency('xengnttab', required: false,
814 method: 'pkg-config',
816 dependency('xenevtchn', required: false,
817 method: 'pkg-config',
819 dependency('xendevicemodel', required: false,
820 method: 'pkg-config',
822 # optional, no "disabler: true"
823 dependency('xentoolcore', required: false,
824 method: 'pkg-config')])
830 xen_tests = [ '4.11.0', '4.10.0', '4.9.0', '4.8.0', '4.7.1' ]
832 '4.11.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
833 '4.10.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
834 '4.9.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
835 '4.8.0': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
836 '4.7.1': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
839 foreach ver: xen_tests
840 # cache the various library tests to avoid polluting the logs
842 foreach l: xen_libs[ver]
844 xen_deps += { l: cc.find_library(l, required: false) }
846 xen_test_deps += xen_deps[l]
849 # Use -D to pick just one of the test programs in scripts/xen-detect.c
850 xen_version = ver.split('.')
851 xen_ctrl_version = xen_version[0] + \
852 ('0' + xen_version[1]).substring(-2) + \
853 ('0' + xen_version[2]).substring(-2)
854 if cc.links(files('scripts/xen-detect.c'),
855 args: '-DCONFIG_XEN_CTRL_INTERFACE_VERSION=' + xen_ctrl_version,
856 dependencies: xen_test_deps)
857 xen = declare_dependency(version: ver, dependencies: xen_test_deps)
863 accelerators += 'CONFIG_XEN'
864 elif get_option('xen').enabled()
865 error('could not compile and link Xen test program')
868 have_xen_pci_passthrough = get_option('xen_pci_passthrough') \
869 .require(xen.found(),
870 error_message: 'Xen PCI passthrough requested but Xen not enabled') \
871 .require(host_os == 'linux',
872 error_message: 'Xen PCI passthrough not available on this platform') \
873 .require(cpu == 'x86' or cpu == 'x86_64',
874 error_message: 'Xen PCI passthrough not available on this platform') \
881 # When bumping glib minimum version, please check also whether to increase
882 # the _WIN32_WINNT setting in osdep.h according to the value from glib
883 glib_req_ver = '>=2.66.0'
884 glib_pc = dependency('glib-2.0', version: glib_req_ver, required: true,
885 method: 'pkg-config')
888 gmodule = dependency('gmodule-export-2.0', version: glib_req_ver, required: true,
889 method: 'pkg-config')
890 elif get_option('plugins')
891 gmodule = dependency('gmodule-no-export-2.0', version: glib_req_ver, required: true,
892 method: 'pkg-config')
897 # This workaround is required due to a bug in pkg-config file for glib as it
898 # doesn't define GLIB_STATIC_COMPILATION for pkg-config --static
899 if host_os == 'windows' and get_option('prefer_static')
900 glib_cflags += ['-DGLIB_STATIC_COMPILATION']
903 # Sanity check that the current size_t matches the
904 # size that glib thinks it should be. This catches
905 # problems on multi-arch where people try to build
906 # 32-bit QEMU while pointing at 64-bit glib headers
908 if not cc.compiles('''
912 #define QEMU_BUILD_BUG_ON(x) \
913 typedef char qemu_build_bug_on[(x)?-1:1] __attribute__((unused));
916 QEMU_BUILD_BUG_ON(sizeof(size_t) != GLIB_SIZEOF_SIZE_T);
918 }''', dependencies: glib_pc, args: glib_cflags)
919 error('''sizeof(size_t) doesn't match GLIB_SIZEOF_SIZE_T.
920 You probably need to set PKG_CONFIG_LIBDIR" to point
921 to the right pkg-config files for your build target.''')
924 glib = declare_dependency(dependencies: [glib_pc, gmodule],
925 compile_args: glib_cflags,
926 version: glib_pc.version())
928 # Check whether glib has gslice, which we have to avoid for correctness.
929 # TODO: remove this check and the corresponding workaround (qtree) when
930 # the minimum supported glib is >= 2.75.3
931 glib_has_gslice = glib.version().version_compare('<2.75.3')
933 # override glib dep to include the above refinements
934 meson.override_dependency('glib-2.0', glib)
936 # The path to glib.h is added to all compilation commands.
937 add_project_dependencies(glib.partial_dependency(compile_args: true, includes: true),
938 native: false, language: all_languages)
941 gdbus_codegen = not_found
942 gdbus_codegen_error = '@0@ requires gdbus-codegen, please install libgio'
943 if not get_option('gio').auto() or have_system
944 gio = dependency('gio-2.0', required: get_option('gio'),
945 method: 'pkg-config')
946 if gio.found() and not cc.links('''
950 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
952 }''', dependencies: [glib, gio])
953 if get_option('gio').enabled()
954 error('The installed libgio is broken for static linking')
959 gdbus_codegen = find_program(gio.get_variable('gdbus_codegen'),
960 required: get_option('gio'))
961 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
962 method: 'pkg-config')
963 gio = declare_dependency(dependencies: [gio, gio_unix],
964 version: gio.version())
967 if gdbus_codegen.found() and get_option('cfi')
968 gdbus_codegen = not_found
969 gdbus_codegen_error = '@0@ uses gdbus-codegen, which does not support control flow integrity'
972 xml_pp = find_program('scripts/xml-preprocess.py')
975 if 'ust' in get_option('trace_backends')
976 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
977 method: 'pkg-config')
980 if not get_option('pixman').auto() or have_system or have_tools
981 pixman = dependency('pixman-1', required: get_option('pixman'), version:'>=0.21.8',
982 method: 'pkg-config')
985 zlib = dependency('zlib', required: true)
988 if not get_option('linux_aio').auto() or have_block
989 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
990 required: get_option('linux_aio'))
993 linux_io_uring_test = '''
994 #include <liburing.h>
995 #include <linux/errqueue.h>
997 int main(void) { return 0; }'''
999 linux_io_uring = not_found
1000 if not get_option('linux_io_uring').auto() or have_block
1001 linux_io_uring = dependency('liburing', version: '>=0.3',
1002 required: get_option('linux_io_uring'),
1003 method: 'pkg-config')
1004 if not cc.links(linux_io_uring_test)
1005 linux_io_uring = not_found
1010 if not get_option('libnfs').auto() or have_block
1011 libnfs = dependency('libnfs', version: '>=1.9.3',
1012 required: get_option('libnfs'),
1013 method: 'pkg-config')
1018 #include <sys/types.h>
1019 #ifdef CONFIG_LIBATTR
1020 #include <attr/xattr.h>
1022 #include <sys/xattr.h>
1024 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
1027 have_old_libattr = false
1028 if get_option('attr').allowed()
1029 if cc.links(libattr_test)
1030 libattr = declare_dependency()
1032 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
1033 required: get_option('attr'))
1034 if libattr.found() and not \
1035 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
1037 if get_option('attr').enabled()
1038 error('could not link libattr')
1040 warning('could not link libattr, disabling')
1043 have_old_libattr = libattr.found()
1048 cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
1049 required: get_option('cocoa'))
1051 vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
1052 if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
1053 'VMNET_BRIDGED_MODE',
1054 dependencies: vmnet)
1056 if get_option('vmnet').enabled()
1057 error('vmnet.framework API is outdated')
1059 warning('vmnet.framework API is outdated, disabling')
1064 seccomp_has_sysrawrc = false
1065 if not get_option('seccomp').auto() or have_system or have_tools
1066 seccomp = dependency('libseccomp', version: '>=2.3.0',
1067 required: get_option('seccomp'),
1068 method: 'pkg-config')
1070 seccomp_has_sysrawrc = cc.has_header_symbol('seccomp.h',
1071 'SCMP_FLTATR_API_SYSRAWRC',
1072 dependencies: seccomp)
1076 libcap_ng = not_found
1077 if not get_option('cap_ng').auto() or have_system or have_tools
1078 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
1079 required: get_option('cap_ng'))
1081 if libcap_ng.found() and not cc.links('''
1085 capng_capability_to_name(CAPNG_EFFECTIVE);
1087 }''', dependencies: libcap_ng)
1088 libcap_ng = not_found
1089 if get_option('cap_ng').enabled()
1090 error('could not link libcap-ng')
1092 warning('could not link libcap-ng, disabling')
1096 if get_option('xkbcommon').auto() and not have_system and not have_tools
1097 xkbcommon = not_found
1099 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
1100 method: 'pkg-config')
1104 if not get_option('slirp').auto() or have_system
1105 slirp = dependency('slirp', required: get_option('slirp'),
1106 method: 'pkg-config')
1107 # slirp < 4.7 is incompatible with CFI support in QEMU. This is because
1108 # it passes function pointers within libslirp as callbacks for timers.
1109 # When using a system-wide shared libslirp, the type information for the
1110 # callback is missing and the timer call produces a false positive with CFI.
1111 # Do not use the "version" keyword argument to produce a better error.
1112 # with control-flow integrity.
1113 if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
1114 if get_option('slirp').enabled()
1115 error('Control-Flow Integrity requires libslirp 4.7.')
1117 warning('Cannot use libslirp since Control-Flow Integrity requires libslirp >= 4.7.')
1124 if not get_option('vde').auto() or have_system or have_tools
1125 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
1126 required: get_option('vde'))
1128 if vde.found() and not cc.links('''
1129 #include <libvdeplug.h>
1132 struct vde_open_args a = {0, 0, 0};
1136 }''', dependencies: vde)
1138 if get_option('cap_ng').enabled()
1139 error('could not link libvdeplug')
1141 warning('could not link libvdeplug, disabling')
1146 if not get_option('pa').auto() or (host_os == 'linux' and have_system)
1147 pulse = dependency('libpulse', required: get_option('pa'),
1148 method: 'pkg-config')
1151 if not get_option('alsa').auto() or (host_os == 'linux' and have_system)
1152 alsa = dependency('alsa', required: get_option('alsa'),
1153 method: 'pkg-config')
1156 if not get_option('jack').auto() or have_system
1157 jack = dependency('jack', required: get_option('jack'),
1158 method: 'pkg-config')
1160 pipewire = not_found
1161 if not get_option('pipewire').auto() or (host_os == 'linux' and have_system)
1162 pipewire = dependency('libpipewire-0.3', version: '>=0.3.60',
1163 required: get_option('pipewire'),
1164 method: 'pkg-config')
1167 if not get_option('sndio').auto() or have_system
1168 sndio = dependency('sndio', required: get_option('sndio'),
1169 method: 'pkg-config')
1172 spice_protocol = not_found
1173 if not get_option('spice_protocol').auto() or have_system
1174 spice_protocol = dependency('spice-protocol', version: '>=0.14.0',
1175 required: get_option('spice_protocol'),
1176 method: 'pkg-config')
1179 if get_option('spice') \
1180 .disable_auto_if(not have_system) \
1181 .require(pixman.found(),
1182 error_message: 'cannot enable SPICE if pixman is not available') \
1184 spice = dependency('spice-server', version: '>=0.14.0',
1185 required: get_option('spice'),
1186 method: 'pkg-config')
1188 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
1190 rt = cc.find_library('rt', required: false)
1192 libiscsi = not_found
1193 if not get_option('libiscsi').auto() or have_block
1194 libiscsi = dependency('libiscsi', version: '>=1.9.0',
1195 required: get_option('libiscsi'),
1196 method: 'pkg-config')
1199 if not get_option('zstd').auto() or have_block
1200 zstd = dependency('libzstd', version: '>=1.4.0',
1201 required: get_option('zstd'),
1202 method: 'pkg-config')
1205 if not get_option('qpl').auto() or have_system
1206 qpl = dependency('qpl', version: '>=1.5.0',
1207 required: get_option('qpl'),
1208 method: 'pkg-config')
1211 if not get_option('uadk').auto() or have_system
1212 libwd = dependency('libwd', version: '>=2.6',
1213 required: get_option('uadk'),
1214 method: 'pkg-config')
1215 libwd_comp = dependency('libwd_comp', version: '>=2.6',
1216 required: get_option('uadk'),
1217 method: 'pkg-config')
1218 if libwd.found() and libwd_comp.found()
1219 uadk = declare_dependency(dependencies: [libwd, libwd_comp])
1224 have_vhost_user_gpu = have_tools and host_os == 'linux' and pixman.found()
1225 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
1226 virgl = dependency('virglrenderer',
1227 method: 'pkg-config',
1228 required: get_option('virglrenderer'))
1230 rutabaga = not_found
1231 if not get_option('rutabaga_gfx').auto() or have_system or have_vhost_user_gpu
1232 rutabaga = dependency('rutabaga_gfx_ffi',
1233 method: 'pkg-config',
1234 required: get_option('rutabaga_gfx'))
1237 if not get_option('blkio').auto() or have_block
1238 blkio = dependency('blkio',
1239 method: 'pkg-config',
1240 required: get_option('blkio'))
1243 if not get_option('curl').auto() or have_block
1244 curl = dependency('libcurl', version: '>=7.29.0',
1245 method: 'pkg-config',
1246 required: get_option('curl'))
1249 if host_os == 'linux' and (have_system or have_tools)
1250 libudev = dependency('libudev',
1251 method: 'pkg-config',
1252 required: get_option('libudev'))
1255 mpathlibs = [libudev]
1256 mpathpersist = not_found
1257 if host_os == 'linux' and have_tools and get_option('mpath').allowed()
1258 mpath_test_source = '''
1259 #include <libudev.h>
1260 #include <mpath_persist.h>
1261 unsigned mpath_mx_alloc_len = 1024;
1263 static struct config *multipath_conf;
1264 extern struct udev *udev;
1265 extern struct config *get_multipath_config(void);
1266 extern void put_multipath_config(struct config *conf);
1268 struct config *get_multipath_config(void) { return multipath_conf; }
1269 void put_multipath_config(struct config *conf) { }
1272 multipath_conf = mpath_lib_init();
1275 libmpathpersist = cc.find_library('mpathpersist',
1276 required: get_option('mpath'))
1277 if libmpathpersist.found()
1278 mpathlibs += libmpathpersist
1279 if get_option('prefer_static')
1280 mpathlibs += cc.find_library('devmapper',
1281 required: get_option('mpath'))
1283 mpathlibs += cc.find_library('multipath',
1284 required: get_option('mpath'))
1285 foreach lib: mpathlibs
1291 if mpathlibs.length() == 0
1292 msg = 'Dependencies missing for libmpathpersist'
1293 elif cc.links(mpath_test_source, dependencies: mpathlibs)
1294 mpathpersist = declare_dependency(dependencies: mpathlibs)
1296 msg = 'Cannot detect libmpathpersist API'
1298 if not mpathpersist.found()
1299 if get_option('mpath').enabled()
1302 warning(msg + ', disabling')
1310 if have_system and get_option('curses').allowed()
1312 #if defined(__APPLE__) || defined(__OpenBSD__)
1313 #define _XOPEN_SOURCE_EXTENDED 1
1320 setlocale(LC_ALL, "");
1322 addwstr(L"wide chars\n");
1324 add_wch(WACS_DEGREE);
1328 curses_dep_list = host_os == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
1329 curses = dependency(curses_dep_list,
1331 method: 'pkg-config')
1332 msg = get_option('curses').enabled() ? 'curses library not found' : ''
1333 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
1335 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
1336 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses],
1337 version: curses.version())
1339 msg = 'curses package not usable'
1343 if not curses.found()
1344 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1345 if host_os != 'windows' and not has_curses_h
1346 message('Trying with /usr/include/ncursesw')
1347 curses_compile_args += ['-I/usr/include/ncursesw']
1348 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1351 curses_libname_list = (host_os == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
1352 foreach curses_libname : curses_libname_list
1353 libcurses = cc.find_library(curses_libname,
1355 if libcurses.found()
1356 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
1357 curses = declare_dependency(compile_args: curses_compile_args,
1358 dependencies: [libcurses])
1361 msg = 'curses library not usable'
1367 if get_option('iconv').allowed()
1368 foreach link_args : [ ['-liconv'], [] ]
1369 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
1370 # We need to use libiconv if available because mixing libiconv's headers with
1371 # the system libc does not work.
1372 # However, without adding glib to the dependencies -L/usr/local/lib will not be
1373 # included in the command line and libiconv will not be found.
1377 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
1378 return conv != (iconv_t) -1;
1379 }''', args: link_args, dependencies: glib)
1380 iconv = declare_dependency(link_args: link_args, dependencies: glib)
1385 if curses.found() and not iconv.found()
1386 if get_option('iconv').enabled()
1387 error('iconv not available')
1389 msg = 'iconv required for curses UI but not available'
1392 if not curses.found() and msg != ''
1393 if get_option('curses').enabled()
1396 warning(msg + ', disabling')
1402 if not get_option('brlapi').auto() or have_system
1403 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
1404 required: get_option('brlapi'))
1405 if brlapi.found() and not cc.links('''
1408 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
1410 if get_option('brlapi').enabled()
1411 error('could not link brlapi')
1413 warning('could not link brlapi, disabling')
1419 if not get_option('sdl').auto() or have_system
1420 sdl = dependency('sdl2', required: get_option('sdl'))
1421 sdl_image = not_found
1424 # Some versions of SDL have problems with -Wundef
1425 if not cc.compiles('''
1427 #include <SDL_syswm.h>
1428 int main(int argc, char *argv[]) { return 0; }
1429 ''', dependencies: sdl, args: '-Werror=undef')
1430 sdl = declare_dependency(compile_args: '-Wno-undef',
1432 version: sdl.version())
1434 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
1435 method: 'pkg-config')
1437 if get_option('sdl_image').enabled()
1438 error('sdl-image required, but SDL was @0@'.format(
1439 get_option('sdl').disabled() ? 'disabled' : 'not found'))
1441 sdl_image = not_found
1445 if not get_option('rbd').auto() or have_block
1446 librados = cc.find_library('rados', required: get_option('rbd'))
1447 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
1448 required: get_option('rbd'))
1449 if librados.found() and librbd.found()
1452 #include <rbd/librbd.h>
1455 rados_create(&cluster, NULL);
1456 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
1460 }''', dependencies: [librbd, librados])
1461 rbd = declare_dependency(dependencies: [librbd, librados])
1462 elif get_option('rbd').enabled()
1463 error('librbd >= 1.12.0 required')
1465 warning('librbd >= 1.12.0 not found, disabling')
1470 glusterfs = not_found
1471 glusterfs_ftruncate_has_stat = false
1472 glusterfs_iocb_has_stat = false
1473 if not get_option('glusterfs').auto() or have_block
1474 glusterfs = dependency('glusterfs-api', version: '>=3',
1475 required: get_option('glusterfs'),
1476 method: 'pkg-config')
1477 if glusterfs.found()
1478 glusterfs_ftruncate_has_stat = cc.links('''
1479 #include <glusterfs/api/glfs.h>
1484 /* new glfs_ftruncate() passes two additional args */
1485 return glfs_ftruncate(NULL, 0, NULL, NULL);
1487 ''', dependencies: glusterfs)
1488 glusterfs_iocb_has_stat = cc.links('''
1489 #include <glusterfs/api/glfs.h>
1491 /* new glfs_io_cbk() passes two additional glfs_stat structs */
1493 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
1499 glfs_io_cbk iocb = &glusterfs_iocb;
1500 iocb(NULL, 0 , NULL, NULL, NULL);
1503 ''', dependencies: glusterfs)
1508 if get_option('hv_balloon').allowed() and have_system
1511 #include <gmodule.h>
1515 tree = g_tree_new((GCompareFunc)strcmp);
1516 (void)g_tree_node_first(tree);
1517 g_tree_destroy(tree);
1520 ''', dependencies: glib)
1523 if get_option('hv_balloon').enabled()
1524 error('could not enable hv-balloon, update your glib')
1526 warning('could not find glib support for hv-balloon, disabling')
1532 if not get_option('libssh').auto() or have_block
1533 libssh = dependency('libssh', version: '>=0.8.7',
1534 method: 'pkg-config',
1535 required: get_option('libssh'))
1538 libbzip2 = not_found
1539 if not get_option('bzip2').auto() or have_block
1540 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
1541 required: get_option('bzip2'))
1542 if libbzip2.found() and not cc.links('''
1544 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
1545 libbzip2 = not_found
1546 if get_option('bzip2').enabled()
1547 error('could not link libbzip2')
1549 warning('could not link libbzip2, disabling')
1554 liblzfse = not_found
1555 if not get_option('lzfse').auto() or have_block
1556 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
1557 required: get_option('lzfse'))
1559 if liblzfse.found() and not cc.links('''
1561 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
1562 liblzfse = not_found
1563 if get_option('lzfse').enabled()
1564 error('could not link liblzfse')
1566 warning('could not link liblzfse, disabling')
1571 if get_option('oss').allowed() and have_system
1572 if not cc.has_header('sys/soundcard.h')
1574 elif host_os == 'netbsd'
1575 oss = cc.find_library('ossaudio', required: get_option('oss'))
1577 oss = declare_dependency()
1581 if get_option('oss').enabled()
1582 error('OSS not found')
1587 if not get_option('dsound').auto() or (host_os == 'windows' and have_system)
1588 if cc.has_header('dsound.h')
1589 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
1592 if not dsound.found()
1593 if get_option('dsound').enabled()
1594 error('DirectSound not found')
1599 coreaudio = not_found
1600 if not get_option('coreaudio').auto() or (host_os == 'darwin' and have_system)
1601 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
1602 required: get_option('coreaudio'))
1606 if not get_option('opengl').auto() or have_system or have_vhost_user_gpu
1607 epoxy = dependency('epoxy', method: 'pkg-config',
1608 required: get_option('opengl'))
1609 if cc.has_header('epoxy/egl.h', dependencies: epoxy)
1611 elif get_option('opengl').enabled()
1612 error('epoxy/egl.h not found')
1616 if (have_system or have_tools) and (virgl.found() or opengl.found())
1617 gbm = dependency('gbm', method: 'pkg-config', required: false)
1619 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and opengl.found() and gbm.found()
1622 gnutls_crypto = not_found
1623 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1624 # For general TLS support our min gnutls matches
1625 # that implied by our platform support matrix
1627 # For the crypto backends, we look for a newer
1630 # Version 3.6.8 is needed to get XTS
1631 # Version 3.6.13 is needed to get PBKDF
1632 # Version 3.6.14 is needed to get HW accelerated XTS
1634 # If newer enough gnutls isn't available, we can
1635 # still use a different crypto backend to satisfy
1636 # the platform support requirements
1637 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1638 method: 'pkg-config',
1640 if gnutls_crypto.found()
1641 gnutls = gnutls_crypto
1643 # Our min version if all we need is TLS
1644 gnutls = dependency('gnutls', version: '>=3.5.18',
1645 method: 'pkg-config',
1646 required: get_option('gnutls'))
1650 # We prefer use of gnutls for crypto, unless the options
1651 # explicitly asked for nettle or gcrypt.
1653 # If gnutls isn't available for crypto, then we'll prefer
1654 # gcrypt over nettle for performance reasons.
1658 crypto_sm4 = not_found
1661 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1662 error('Only one of gcrypt & nettle can be enabled')
1665 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1666 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1667 gnutls_crypto = not_found
1670 if not gnutls_crypto.found()
1671 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1672 gcrypt = dependency('libgcrypt', version: '>=1.8',
1673 method: 'config-tool',
1674 required: get_option('gcrypt'))
1675 # Debian has removed -lgpg-error from libgcrypt-config
1676 # as it "spreads unnecessary dependencies" which in
1677 # turn breaks static builds...
1678 if gcrypt.found() and get_option('prefer_static')
1679 gcrypt = declare_dependency(dependencies:
1681 cc.find_library('gpg-error', required: true)],
1682 version: gcrypt.version())
1685 # SM4 ALG is available in libgcrypt >= 1.9
1686 if gcrypt.found() and not cc.links('''
1689 gcry_cipher_hd_t handler;
1690 gcry_cipher_open(&handler, GCRY_CIPHER_SM4, GCRY_CIPHER_MODE_ECB, 0);
1692 }''', dependencies: gcrypt)
1693 crypto_sm4 = not_found
1696 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1697 nettle = dependency('nettle', version: '>=3.4',
1698 method: 'pkg-config',
1699 required: get_option('nettle'))
1700 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1704 # SM4 ALG is available in nettle >= 3.9
1705 if nettle.found() and not cc.links('''
1706 #include <nettle/sm4.h>
1709 unsigned char key[16] = {0};
1710 sm4_set_encrypt_key(&ctx, key);
1712 }''', dependencies: nettle)
1713 crypto_sm4 = not_found
1718 capstone = not_found
1719 if not get_option('capstone').auto() or have_system or have_user
1720 capstone = dependency('capstone', version: '>=3.0.5',
1721 method: 'pkg-config',
1722 required: get_option('capstone'))
1724 # Some versions of capstone have broken pkg-config file
1725 # that reports a wrong -I path, causing the #include to
1726 # fail later. If the system has such a broken version
1728 if capstone.found() and not cc.compiles('#include <capstone.h>',
1729 dependencies: [capstone])
1730 capstone = not_found
1731 if get_option('capstone').enabled()
1732 error('capstone requested, but it does not appear to work')
1737 gmp = dependency('gmp', required: false, method: 'pkg-config')
1738 if nettle.found() and gmp.found()
1739 hogweed = dependency('hogweed', version: '>=3.4',
1740 method: 'pkg-config',
1741 required: get_option('nettle'))
1748 have_gtk_clipboard = get_option('gtk_clipboard').enabled()
1750 if get_option('gtk') \
1751 .disable_auto_if(not have_system) \
1752 .require(pixman.found(),
1753 error_message: 'cannot enable GTK if pixman is not available') \
1755 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1756 method: 'pkg-config',
1757 required: get_option('gtk'))
1759 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1760 method: 'pkg-config',
1762 gtk = declare_dependency(dependencies: [gtk, gtkx11],
1763 version: gtk.version())
1765 if not get_option('vte').auto() or have_system
1766 vte = dependency('vte-2.91',
1767 method: 'pkg-config',
1768 required: get_option('vte'))
1770 elif have_gtk_clipboard
1771 error('GTK clipboard requested, but GTK not found')
1777 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found())
1780 if get_option('png').allowed() and have_system
1781 png = dependency('libpng', version: '>=1.6.34', required: get_option('png'),
1782 method: 'pkg-config')
1787 if get_option('vnc') \
1788 .disable_auto_if(not have_system) \
1789 .require(pixman.found(),
1790 error_message: 'cannot enable VNC if pixman is not available') \
1792 vnc = declare_dependency() # dummy dependency
1793 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1794 method: 'pkg-config')
1795 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1796 required: get_option('vnc_sasl'))
1798 sasl = declare_dependency(dependencies: sasl,
1799 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1804 if not get_option('auth_pam').auto() or have_system
1805 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1806 required: get_option('auth_pam'))
1808 if pam.found() and not cc.links('''
1810 #include <security/pam_appl.h>
1812 const char *service_name = "qemu";
1813 const char *user = "frank";
1814 const struct pam_conv pam_conv = { 0 };
1815 pam_handle_t *pamh = NULL;
1816 pam_start(service_name, user, &pam_conv, &pamh);
1818 }''', dependencies: pam)
1820 if get_option('auth_pam').enabled()
1821 error('could not link libpam')
1823 warning('could not link libpam, disabling')
1828 if not get_option('snappy').auto() or have_system
1829 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1830 required: get_option('snappy'))
1832 if snappy.found() and not cc.links('''
1833 #include <snappy-c.h>
1834 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1836 if get_option('snappy').enabled()
1837 error('could not link libsnappy')
1839 warning('could not link libsnappy, disabling')
1844 if not get_option('lzo').auto() or have_system
1845 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1846 required: get_option('lzo'))
1848 if lzo.found() and not cc.links('''
1849 #include <lzo/lzo1x.h>
1850 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1852 if get_option('lzo').enabled()
1853 error('could not link liblzo2')
1855 warning('could not link liblzo2, disabling')
1860 if not get_option('numa').auto() or have_system or have_tools
1861 numa = cc.find_library('numa', has_headers: ['numa.h'],
1862 required: get_option('numa'))
1864 if numa.found() and not cc.links('''
1866 int main(void) { return numa_available(); }
1867 ''', dependencies: numa)
1869 if get_option('numa').enabled()
1870 error('could not link numa')
1872 warning('could not link numa, disabling')
1877 fdt_opt = get_option('fdt')
1878 if fdt_opt == 'enabled' and get_option('wrap_mode') == 'nodownload'
1881 if fdt_opt in ['enabled', 'system'] or (fdt_opt == 'auto' and have_system)
1882 fdt = cc.find_library('fdt', required: fdt_opt == 'system')
1883 if fdt.found() and cc.links('''
1885 #include <libfdt_env.h>
1886 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
1889 elif fdt_opt != 'system'
1890 fdt_opt = get_option('wrap_mode') == 'nodownload' ? 'disabled' : 'internal'
1893 error('system libfdt is too old (1.5.1 or newer required)')
1896 if fdt_opt == 'internal'
1897 assert(not fdt.found())
1898 libfdt_proj = subproject('dtc', required: true,
1899 default_options: ['tools=false', 'yaml=disabled',
1900 'python=disabled', 'default_library=static'])
1901 fdt = libfdt_proj.get_variable('libfdt_dep')
1905 if not get_option('rdma').auto() or have_system
1906 rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'],
1907 required: get_option('rdma')),
1908 cc.find_library('ibverbs', required: get_option('rdma'))]
1909 rdma = declare_dependency(dependencies: rdma_libs)
1910 foreach lib: rdma_libs
1918 if not get_option('smartcard').auto() or have_system
1919 cacard = dependency('libcacard', required: get_option('smartcard'),
1920 version: '>=2.5.1', method: 'pkg-config')
1923 if not get_option('u2f').auto() or have_system
1924 u2f = dependency('u2f-emu', required: get_option('u2f'),
1925 method: 'pkg-config')
1928 if not get_option('canokey').auto() or have_system
1929 canokey = dependency('canokey-qemu', required: get_option('canokey'),
1930 method: 'pkg-config')
1932 usbredir = not_found
1933 if not get_option('usb_redir').auto() or have_system
1934 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1935 version: '>=0.6', method: 'pkg-config')
1938 if not get_option('libusb').auto() or have_system
1939 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1940 version: '>=1.0.13', method: 'pkg-config')
1944 if not get_option('libpmem').auto() or have_system
1945 libpmem = dependency('libpmem', required: get_option('libpmem'),
1946 method: 'pkg-config')
1948 libdaxctl = not_found
1949 if not get_option('libdaxctl').auto() or have_system
1950 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1951 version: '>=57', method: 'pkg-config')
1955 tasn1 = dependency('libtasn1',
1956 method: 'pkg-config')
1958 keyutils = not_found
1959 if not get_option('libkeyutils').auto() or have_block
1960 keyutils = dependency('libkeyutils', required: get_option('libkeyutils'),
1961 method: 'pkg-config')
1964 has_gettid = cc.has_function('gettid')
1967 selinux = dependency('libselinux',
1968 required: get_option('selinux'),
1969 method: 'pkg-config')
1974 if get_option('malloc') == 'system'
1976 get_option('malloc_trim').allowed() and \
1977 cc.has_function('malloc_trim', prefix: '#include <malloc.h>')
1979 has_malloc_trim = false
1980 malloc = cc.find_library(get_option('malloc'), required: true)
1982 if not has_malloc_trim and get_option('malloc_trim').enabled()
1983 if get_option('malloc') == 'system'
1984 error('malloc_trim not available on this platform.')
1986 error('malloc_trim not available with non-libc memory allocator')
1990 gnu_source_prefix = '''
1996 # Check whether the glibc provides STATX_BASIC_STATS
1998 has_statx = cc.has_header_symbol('sys/stat.h', 'STATX_BASIC_STATS', prefix: gnu_source_prefix)
2000 # Check whether statx() provides mount ID information
2002 has_statx_mnt_id = cc.has_header_symbol('sys/stat.h', 'STATX_MNT_ID', prefix: gnu_source_prefix)
2004 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
2005 .require(host_os == 'linux',
2006 error_message: 'vhost_user_blk_server requires linux') \
2007 .require(have_vhost_user,
2008 error_message: 'vhost_user_blk_server requires vhost-user support') \
2009 .disable_auto_if(not have_tools and not have_system) \
2012 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
2013 error('Cannot enable fuse-lseek while fuse is disabled')
2016 fuse = dependency('fuse3', required: get_option('fuse'),
2017 version: '>=3.1', method: 'pkg-config')
2019 fuse_lseek = not_found
2020 if get_option('fuse_lseek').allowed()
2021 if fuse.version().version_compare('>=3.8')
2023 fuse_lseek = declare_dependency()
2024 elif get_option('fuse_lseek').enabled()
2026 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
2028 error('fuse-lseek requires libfuse, which was not found')
2033 have_libvduse = (host_os == 'linux')
2034 if get_option('libvduse').enabled()
2035 if host_os != 'linux'
2036 error('libvduse requires linux')
2038 elif get_option('libvduse').disabled()
2039 have_libvduse = false
2042 have_vduse_blk_export = (have_libvduse and host_os == 'linux')
2043 if get_option('vduse_blk_export').enabled()
2044 if host_os != 'linux'
2045 error('vduse_blk_export requires linux')
2046 elif not have_libvduse
2047 error('vduse_blk_export requires libvduse support')
2049 elif get_option('vduse_blk_export').disabled()
2050 have_vduse_blk_export = false
2054 bpf_version = '1.1.0'
2055 libbpf = dependency('libbpf', version: '>=' + bpf_version, required: get_option('bpf'), method: 'pkg-config')
2056 if libbpf.found() and not cc.links('''
2057 #include <bpf/libbpf.h>
2058 #include <linux/bpf.h>
2061 // check flag availability
2062 int flag = BPF_F_MMAPABLE;
2063 bpf_object__destroy_skeleton(NULL);
2065 }''', dependencies: libbpf)
2067 if get_option('bpf').enabled()
2068 error('libbpf skeleton/mmaping test failed')
2070 warning('libbpf skeleton/mmaping test failed, disabling')
2076 if not get_option('af_xdp').auto() or have_system
2077 libxdp = dependency('libxdp', required: get_option('af_xdp'),
2078 version: '>=1.4.0', method: 'pkg-config')
2083 if not get_option('libdw').auto() or \
2084 (not get_option('prefer_static') and (have_system or have_user))
2085 libdw = dependency('libdw',
2086 method: 'pkg-config',
2087 required: get_option('libdw'))
2094 config_host_data = configuration_data()
2096 audio_drivers_selected = []
2098 audio_drivers_available = {
2099 'alsa': alsa.found(),
2100 'coreaudio': coreaudio.found(),
2101 'dsound': dsound.found(),
2102 'jack': jack.found(),
2104 'pa': pulse.found(),
2105 'pipewire': pipewire.found(),
2107 'sndio': sndio.found(),
2109 foreach k, v: audio_drivers_available
2110 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
2113 # Default to native drivers first, OSS second, SDL third
2114 audio_drivers_priority = \
2115 [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \
2116 (host_os == 'linux' ? [] : [ 'sdl' ])
2117 audio_drivers_default = []
2118 foreach k: audio_drivers_priority
2119 if audio_drivers_available[k]
2120 audio_drivers_default += k
2124 foreach k: get_option('audio_drv_list')
2126 audio_drivers_selected += audio_drivers_default
2127 elif not audio_drivers_available[k]
2128 error('Audio driver "@0@" not available.'.format(k))
2130 audio_drivers_selected += k
2134 config_host_data.set('CONFIG_AUDIO_DRIVERS',
2135 '"' + '", "'.join(audio_drivers_selected) + '", ')
2137 have_host_block_device = (host_os != 'darwin' or
2138 cc.has_header('IOKit/storage/IOMedia.h'))
2140 dbus_display = get_option('dbus_display') \
2141 .require(gio.version().version_compare('>=2.64'),
2142 error_message: '-display dbus requires glib>=2.64') \
2143 .require(gdbus_codegen.found(),
2144 error_message: gdbus_codegen_error.format('-display dbus')) \
2147 have_virtfs = get_option('virtfs') \
2148 .require(host_os == 'linux' or host_os == 'darwin',
2149 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
2150 .require(host_os == 'linux' or cc.has_function('pthread_fchdir_np'),
2151 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
2152 .require(host_os == 'darwin' or libattr.found(),
2153 error_message: 'virtio-9p (virtfs) on Linux requires libattr-devel') \
2154 .disable_auto_if(not have_tools and not have_system) \
2157 have_virtfs_proxy_helper = get_option('virtfs_proxy_helper') \
2158 .require(host_os != 'darwin', error_message: 'the virtfs proxy helper is incompatible with macOS') \
2159 .require(have_virtfs, error_message: 'the virtfs proxy helper requires that virtfs is enabled') \
2160 .disable_auto_if(not have_tools) \
2161 .require(libcap_ng.found(), error_message: 'the virtfs proxy helper requires libcap-ng') \
2164 if get_option('block_drv_ro_whitelist') == ''
2165 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
2167 config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
2168 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
2170 if get_option('block_drv_rw_whitelist') == ''
2171 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
2173 config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
2174 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
2177 foreach k : get_option('trace_backends')
2178 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
2180 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
2181 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
2183 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
2185 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
2186 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
2187 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
2188 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
2189 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
2191 qemu_firmwarepath = ''
2192 foreach k : get_option('qemu_firmwarepath')
2193 qemu_firmwarepath += '"' + get_option('prefix') / k + '", '
2195 config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath)
2197 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
2198 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
2199 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
2200 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
2201 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
2202 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
2205 config_host_data.set('CONFIG_STAMP', run_command(
2206 meson.current_source_dir() / 'scripts/qemu-stamp.py',
2207 meson.project_version(), get_option('pkgversion'), '--',
2208 meson.current_source_dir() / 'configure',
2209 capture: true, check: true).stdout().strip())
2212 have_slirp_smbd = get_option('slirp_smbd') \
2213 .require(host_os != 'windows', error_message: 'Host smbd not supported on this platform.') \
2216 smbd_path = get_option('smbd')
2218 smbd_path = (host_os == 'sunos' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
2220 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
2223 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
2225 kvm_targets_c = '""'
2226 if get_option('kvm').allowed() and host_os == 'linux'
2227 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
2229 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
2231 if get_option('module_upgrades') and not enable_modules
2232 error('Cannot enable module-upgrades as modules are not enabled')
2234 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
2236 config_host_data.set('CONFIG_ATTR', libattr.found())
2237 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
2238 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
2239 config_host_data.set('CONFIG_BSD', host_os in bsd_oses)
2240 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2241 config_host_data.set('CONFIG_COCOA', cocoa.found())
2242 config_host_data.set('CONFIG_DARWIN', host_os == 'darwin')
2243 config_host_data.set('CONFIG_FDT', fdt.found())
2244 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
2245 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
2246 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
2247 config_host_data.set('CONFIG_LINUX', host_os == 'linux')
2248 config_host_data.set('CONFIG_POSIX', host_os != 'windows')
2249 config_host_data.set('CONFIG_WIN32', host_os == 'windows')
2250 config_host_data.set('CONFIG_LZO', lzo.found())
2251 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
2252 config_host_data.set('CONFIG_BLKIO', blkio.found())
2254 config_host_data.set('CONFIG_BLKIO_VHOST_VDPA_FD',
2255 blkio.version().version_compare('>=1.3.0'))
2257 config_host_data.set('CONFIG_CURL', curl.found())
2258 config_host_data.set('CONFIG_CURSES', curses.found())
2259 config_host_data.set('CONFIG_GBM', gbm.found())
2260 config_host_data.set('CONFIG_GIO', gio.found())
2261 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
2262 if glusterfs.found()
2263 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
2264 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
2265 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
2266 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
2267 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
2268 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
2270 config_host_data.set('CONFIG_GTK', gtk.found())
2271 config_host_data.set('CONFIG_VTE', vte.found())
2272 config_host_data.set('CONFIG_GTK_CLIPBOARD', have_gtk_clipboard)
2273 config_host_data.set('CONFIG_HEXAGON_IDEF_PARSER', get_option('hexagon_idef_parser'))
2274 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
2275 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
2276 config_host_data.set('CONFIG_EBPF', libbpf.found())
2277 config_host_data.set('CONFIG_AF_XDP', libxdp.found())
2278 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
2279 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
2280 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
2281 config_host_data.set('CONFIG_LIBSSH', libssh.found())
2282 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
2283 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
2284 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
2285 config_host_data.set('CONFIG_MODULES', enable_modules)
2286 config_host_data.set('CONFIG_NUMA', numa.found())
2288 config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY',
2289 cc.has_function('numa_has_preferred_many',
2290 dependencies: numa))
2292 config_host_data.set('CONFIG_OPENGL', opengl.found())
2293 config_host_data.set('CONFIG_PLUGIN', get_option('plugins'))
2294 config_host_data.set('CONFIG_RBD', rbd.found())
2295 config_host_data.set('CONFIG_RDMA', rdma.found())
2296 config_host_data.set('CONFIG_RELOCATABLE', get_option('relocatable'))
2297 config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack'))
2298 config_host_data.set('CONFIG_SDL', sdl.found())
2299 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
2300 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
2302 config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc)
2304 config_host_data.set('CONFIG_PIXMAN', pixman.found())
2305 config_host_data.set('CONFIG_SLIRP', slirp.found())
2306 config_host_data.set('CONFIG_SNAPPY', snappy.found())
2307 config_host_data.set('CONFIG_SOLARIS', host_os == 'sunos')
2308 if get_option('tcg').allowed()
2309 config_host_data.set('CONFIG_TCG', 1)
2310 config_host_data.set('CONFIG_TCG_INTERPRETER', tcg_arch == 'tci')
2312 config_host_data.set('CONFIG_TPM', have_tpm)
2313 config_host_data.set('CONFIG_TSAN', get_option('tsan'))
2314 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
2315 config_host_data.set('CONFIG_VDE', vde.found())
2316 config_host_data.set('CONFIG_VHOST', have_vhost)
2317 config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
2318 config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
2319 config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)
2320 config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
2321 config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
2322 config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
2323 config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
2324 config_host_data.set('CONFIG_VMNET', vmnet.found())
2325 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
2326 config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export)
2327 config_host_data.set('CONFIG_PNG', png.found())
2328 config_host_data.set('CONFIG_VNC', vnc.found())
2329 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
2330 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
2332 config_host_data.set('HAVE_VIRGL_D3D_INFO_EXT',
2333 cc.has_member('struct virgl_renderer_resource_info_ext', 'd3d_tex2d',
2334 prefix: '#include <virglrenderer.h>',
2335 dependencies: virgl))
2337 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
2338 config_host_data.set('CONFIG_VTE', vte.found())
2339 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
2340 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
2341 config_host_data.set('CONFIG_GETTID', has_gettid)
2342 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
2343 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
2344 config_host_data.set('CONFIG_TASN1', tasn1.found())
2345 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
2346 config_host_data.set('CONFIG_NETTLE', nettle.found())
2347 config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found())
2348 config_host_data.set('CONFIG_HOGWEED', hogweed.found())
2349 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
2350 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
2351 config_host_data.set('CONFIG_STATX', has_statx)
2352 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
2353 config_host_data.set('CONFIG_ZSTD', zstd.found())
2354 config_host_data.set('CONFIG_QPL', qpl.found())
2355 config_host_data.set('CONFIG_UADK', uadk.found())
2356 config_host_data.set('CONFIG_FUSE', fuse.found())
2357 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
2358 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
2359 if spice_protocol.found()
2360 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
2361 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
2362 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
2364 config_host_data.set('CONFIG_SPICE', spice.found())
2365 config_host_data.set('CONFIG_X11', x11.found())
2366 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
2367 config_host_data.set('CONFIG_CFI', get_option('cfi'))
2368 config_host_data.set('CONFIG_SELINUX', selinux.found())
2369 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
2370 config_host_data.set('CONFIG_LIBDW', libdw.found())
2372 # protect from xen.version() having less than three components
2373 xen_version = xen.version().split('.') + ['0', '0']
2374 xen_ctrl_version = xen_version[0] + \
2375 ('0' + xen_version[1]).substring(-2) + \
2376 ('0' + xen_version[2]).substring(-2)
2377 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
2379 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
2380 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
2381 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
2382 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
2384 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
2385 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
2387 have_coroutine_pool = get_option('coroutine_pool')
2388 if get_option('debug_stack_usage') and have_coroutine_pool
2389 message('Disabling coroutine pool to measure stack usage')
2390 have_coroutine_pool = false
2392 config_host_data.set('CONFIG_COROUTINE_POOL', have_coroutine_pool)
2393 config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock'))
2394 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
2395 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
2396 config_host_data.set('CONFIG_DEBUG_TCG', get_option('debug_tcg'))
2397 config_host_data.set('CONFIG_DEBUG_REMAP', get_option('debug_remap'))
2398 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
2399 config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
2402 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
2403 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
2404 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
2405 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
2406 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
2407 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
2408 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
2409 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
2410 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
2411 if host_os == 'windows'
2412 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h'))
2416 config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range'))
2417 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
2418 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
2419 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
2420 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
2421 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
2422 config_host_data.set('CONFIG_GETCPU', cc.has_function('getcpu', prefix: gnu_source_prefix))
2423 config_host_data.set('CONFIG_SCHED_GETCPU', cc.has_function('sched_getcpu', prefix: '#include <sched.h>'))
2424 # Note that we need to specify prefix: here to avoid incorrectly
2425 # thinking that Windows has posix_memalign()
2426 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
2427 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
2428 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
2429 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
2430 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
2431 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
2432 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
2433 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
2434 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
2435 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
2436 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
2437 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
2438 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
2439 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
2440 config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice)
2441 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
2442 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
2443 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
2445 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
2446 cc.has_function('rbd_namespace_exists',
2448 prefix: '#include <rbd/librbd.h>'))
2451 config_host_data.set('HAVE_IBV_ADVISE_MR',
2452 cc.has_function('ibv_advise_mr',
2454 prefix: '#include <infiniband/verbs.h>'))
2457 have_asan_fiber = false
2458 if get_option('sanitizers') and \
2459 not cc.has_function('__sanitizer_start_switch_fiber',
2460 args: '-fsanitize=address',
2461 prefix: '#include <sanitizer/asan_interface.h>')
2462 warning('Missing ASAN due to missing fiber annotation interface')
2463 warning('Without code annotation, the report may be inferior.')
2465 have_asan_fiber = true
2467 config_host_data.set('CONFIG_ASAN_IFACE_FIBER', have_asan_fiber)
2469 have_inotify_init = cc.has_header_symbol('sys/inotify.h', 'inotify_init')
2470 have_inotify_init1 = cc.has_header_symbol('sys/inotify.h', 'inotify_init1')
2472 if (have_inotify_init or have_inotify_init1) and host_os == 'freebsd'
2474 inotify = cc.find_library('inotify')
2475 if have_inotify_init
2476 have_inotify_init = inotify.found()
2478 if have_inotify_init1
2479 have_inotify_init1 = inotify.found()
2482 config_host_data.set('CONFIG_INOTIFY', have_inotify_init)
2483 config_host_data.set('CONFIG_INOTIFY1', have_inotify_init1)
2486 config_host_data.set('CONFIG_BLKZONED',
2487 cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE'))
2488 config_host_data.set('CONFIG_EPOLL_CREATE1',
2489 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
2490 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
2491 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
2492 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
2493 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
2494 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
2495 config_host_data.set('CONFIG_FIEMAP',
2496 cc.has_header('linux/fiemap.h') and
2497 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
2498 config_host_data.set('CONFIG_GETRANDOM',
2499 cc.has_function('getrandom') and
2500 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
2501 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
2502 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
2503 config_host_data.set('CONFIG_RTNETLINK',
2504 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
2505 config_host_data.set('CONFIG_SYSMACROS',
2506 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
2507 config_host_data.set('HAVE_OPTRESET',
2508 cc.has_header_symbol('getopt.h', 'optreset'))
2509 config_host_data.set('HAVE_IPPROTO_MPTCP',
2510 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
2513 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
2514 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
2515 prefix: '#include <signal.h>'))
2516 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
2517 cc.has_member('struct stat', 'st_atim',
2518 prefix: '#include <sys/stat.h>'))
2519 config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY',
2520 cc.has_member('struct blk_zone', 'capacity',
2521 prefix: '#include <linux/blkzoned.h>'))
2524 config_host_data.set('CONFIG_IOVEC',
2525 cc.has_type('struct iovec',
2526 prefix: '#include <sys/uio.h>'))
2527 config_host_data.set('HAVE_UTMPX',
2528 cc.has_type('struct utmpx',
2529 prefix: '#include <utmpx.h>'))
2531 config_host_data.set('CONFIG_EVENTFD', cc.links('''
2532 #include <sys/eventfd.h>
2533 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
2534 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
2537 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
2538 return fdatasync(0);
2540 #error Not supported
2544 has_madvise = cc.links(gnu_source_prefix + '''
2545 #include <sys/types.h>
2546 #include <sys/mman.h>
2548 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
2549 missing_madvise_proto = false
2551 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
2552 # but forget to prototype it. In this case, has_madvise will be true (the
2553 # test program links despite a compile warning). To detect the
2554 # missing-prototype case, we try again with a definitely-bogus prototype.
2555 # This will only compile if the system headers don't provide the prototype;
2556 # otherwise the conflicting prototypes will cause a compiler error.
2557 missing_madvise_proto = cc.links(gnu_source_prefix + '''
2558 #include <sys/types.h>
2559 #include <sys/mman.h>
2561 extern int madvise(int);
2562 int main(void) { return madvise(0); }''')
2564 config_host_data.set('CONFIG_MADVISE', has_madvise)
2565 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
2567 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
2568 #include <sys/mman.h>
2569 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
2570 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
2572 #if !defined(AT_EMPTY_PATH)
2573 # error missing definition
2575 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
2578 # On Darwin posix_madvise() has the same return semantics as plain madvise(),
2579 # i.e. errno is set and -1 is returned. That's not really how POSIX defines the
2580 # function. On the flip side, it has madvise() which is preferred anyways.
2581 if host_os != 'darwin'
2582 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
2583 #include <sys/mman.h>
2585 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
2588 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
2589 #include <pthread.h>
2591 static void *f(void *p) { return NULL; }
2595 pthread_create(&thread, 0, f, 0);
2596 pthread_setname_np(thread, "QEMU");
2598 }''', dependencies: threads))
2599 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
2600 #include <pthread.h>
2602 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
2606 pthread_create(&thread, 0, f, 0);
2608 }''', dependencies: threads))
2609 config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(gnu_source_prefix + '''
2610 #include <pthread.h>
2611 #include <pthread_np.h>
2613 static void *f(void *p) { return NULL; }
2617 pthread_create(&thread, 0, f, 0);
2618 pthread_set_name_np(thread, "QEMU");
2620 }''', dependencies: threads))
2621 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
2622 #include <pthread.h>
2627 pthread_condattr_t attr
2628 pthread_condattr_init(&attr);
2629 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
2631 }''', dependencies: threads))
2632 config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(gnu_source_prefix + '''
2633 #include <pthread.h>
2635 static void *f(void *p) { return NULL; }
2638 int setsize = CPU_ALLOC_SIZE(64);
2641 pthread_create(&thread, 0, f, 0);
2642 cpuset = CPU_ALLOC(64);
2643 CPU_ZERO_S(setsize, cpuset);
2644 pthread_setaffinity_np(thread, setsize, cpuset);
2645 pthread_getaffinity_np(thread, setsize, cpuset);
2648 }''', dependencies: threads))
2649 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
2650 #include <sys/signalfd.h>
2652 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
2653 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
2661 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
2662 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
2666 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
2667 #include <sys/mman.h>
2669 return mlockall(MCL_FUTURE);
2673 if get_option('l2tpv3').allowed() and have_system
2674 have_l2tpv3 = cc.has_type('struct mmsghdr',
2675 prefix: gnu_source_prefix + '''
2676 #include <sys/socket.h>
2677 #include <linux/ip.h>''')
2679 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2682 if get_option('netmap').allowed() and have_system
2683 have_netmap = cc.compiles('''
2684 #include <inttypes.h>
2686 #include <net/netmap.h>
2687 #include <net/netmap_user.h>
2688 #if (NETMAP_API < 11) || (NETMAP_API > 15)
2691 int main(void) { return 0; }''')
2692 if not have_netmap and get_option('netmap').enabled()
2693 error('Netmap headers not available')
2696 config_host_data.set('CONFIG_NETMAP', have_netmap)
2698 # Work around a system header bug with some kernel/XFS header
2699 # versions where they both try to define 'struct fsxattr':
2700 # xfs headers will not try to redefine structs from linux headers
2701 # if this macro is set.
2702 config_host_data.set('HAVE_FSXATTR', cc.links('''
2703 #include <linux/fs.h>
2709 # Some versions of Mac OS X incorrectly define SIZE_MAX
2710 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2714 return printf("%zu", SIZE_MAX);
2715 }''', args: ['-Werror']))
2717 # See if 64-bit atomic operations are supported.
2718 # Note that without __atomic builtins, we can only
2719 # assume atomic loads/stores max at pointer size.
2720 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
2724 uint64_t x = 0, y = 0;
2725 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2726 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2727 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2728 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2729 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2733 has_int128_type = cc.compiles('''
2736 int main(void) { b = a; }''')
2737 config_host_data.set('CONFIG_INT128_TYPE', has_int128_type)
2739 has_int128 = has_int128_type and cc.links('''
2748 config_host_data.set('CONFIG_INT128', has_int128)
2751 # "do we have 128-bit atomics which are handled inline and specifically not
2752 # via libatomic". The reason we can't use libatomic is documented in the
2753 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2754 # We only care about these operations on 16-byte aligned pointers, so
2755 # force 16-byte alignment of the pointer, which may be greater than
2756 # __alignof(unsigned __int128) for the host.
2757 atomic_test_128 = '''
2758 int main(int ac, char **av) {
2759 __uint128_t *p = __builtin_assume_aligned(av[ac - 1], 16);
2760 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED);
2761 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED);
2762 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2765 has_atomic128 = cc.links(atomic_test_128)
2767 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2769 if not has_atomic128
2770 # Even with __builtin_assume_aligned, the above test may have failed
2771 # without optimization enabled. Try again with optimizations locally
2772 # enabled for the function. See
2773 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389
2774 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128)
2775 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt)
2777 if not has_atomic128_opt
2778 config_host_data.set('CONFIG_CMPXCHG128', cc.links('''
2781 __uint128_t x = 0, y = 0;
2782 __sync_val_compare_and_swap_16(&x, y, x);
2790 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2791 #include <sys/auxv.h>
2793 return getauxval(AT_HWCAP) == 0;
2796 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2797 #include <linux/usbdevice_fs.h>
2799 #ifndef USBDEVFS_GET_CAPABILITIES
2800 #error "USBDEVFS_GET_CAPABILITIES undefined"
2803 #ifndef USBDEVFS_DISCONNECT_CLAIM
2804 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2807 int main(void) { return 0; }'''))
2809 have_keyring = get_option('keyring') \
2810 .require(host_os == 'linux', error_message: 'keyring is only available on Linux') \
2811 .require(cc.compiles('''
2813 #include <asm/unistd.h>
2814 #include <linux/keyctl.h>
2815 #include <sys/syscall.h>
2818 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2819 }'''), error_message: 'keyctl syscall not available on this system').allowed()
2820 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2822 have_cpuid_h = cc.links('''
2825 unsigned a, b, c, d;
2826 unsigned max = __get_cpuid_max(0, 0);
2829 __cpuid(1, a, b, c, d);
2833 __cpuid_count(7, 0, a, b, c, d);
2838 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2840 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2841 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2842 .require(cc.links('''
2844 #include <immintrin.h>
2845 static int __attribute__((target("avx2"))) bar(void *a) {
2846 __m256i x = *(__m256i *)a;
2847 return _mm256_testz_si256(x, x);
2849 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2850 '''), error_message: 'AVX2 not available').allowed())
2852 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2853 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2854 .require(cc.links('''
2856 #include <immintrin.h>
2857 static int __attribute__((target("avx512f"))) bar(void *a) {
2858 __m512i x = *(__m512i *)a;
2859 return _mm512_test_epi64_mask(x, x);
2861 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2862 '''), error_message: 'AVX512F not available').allowed())
2864 config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \
2865 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \
2866 .require(cc.links('''
2868 #include <immintrin.h>
2869 static int __attribute__((target("avx512bw"))) bar(void *a) {
2871 __m512i res= _mm512_abs_epi8(*x);
2874 int main(int argc, char *argv[]) { return bar(argv[0]); }
2875 '''), error_message: 'AVX512BW not available').allowed())
2877 # For both AArch64 and AArch32, detect if builtins are available.
2878 config_host_data.set('CONFIG_ARM_AES_BUILTIN', cc.compiles('''
2879 #include <arm_neon.h>
2880 #ifndef __ARM_FEATURE_AES
2881 __attribute__((target("+crypto")))
2883 void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); }
2886 if get_option('membarrier').disabled()
2887 have_membarrier = false
2888 elif host_os == 'windows'
2889 have_membarrier = true
2890 elif host_os == 'linux'
2891 have_membarrier = cc.compiles('''
2892 #include <linux/membarrier.h>
2893 #include <sys/syscall.h>
2897 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2898 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2902 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2903 .require(have_membarrier, error_message: 'membarrier system call not available') \
2906 have_afalg = get_option('crypto_afalg') \
2907 .require(cc.compiles(gnu_source_prefix + '''
2909 #include <sys/types.h>
2910 #include <sys/socket.h>
2911 #include <linux/if_alg.h>
2914 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2917 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2918 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2920 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2921 'linux/vm_sockets.h', 'AF_VSOCK',
2922 prefix: '#include <sys/socket.h>',
2926 have_vss_sdk = false # old xp/2003 SDK
2927 if host_os == 'windows' and 'cpp' in all_languages
2928 have_vss = cxx.compiles('''
2929 #define __MIDL_user_allocate_free_DEFINED__
2931 int main(void) { return VSS_CTX_BACKUP; }''')
2932 have_vss_sdk = cxx.has_header('vscoordint.h')
2934 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2936 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2937 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2938 if host_os == 'windows'
2939 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2945 }''', name: '_lock_file and _unlock_file'))
2948 if host_os == 'windows'
2949 mingw_has_setjmp_longjmp = cc.links('''
2953 * These functions are not available in setjmp header, but may be
2954 * available at link time, from libmingwex.a.
2956 extern int __mingw_setjmp(jmp_buf);
2957 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
2959 __mingw_setjmp(env);
2960 __mingw_longjmp(env, 0);
2962 ''', name: 'mingw setjmp and longjmp')
2964 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp
2965 error('mingw must provide setjmp/longjmp for windows-arm64')
2969 ########################
2970 # Target configuration #
2971 ########################
2973 minikconf = find_program('scripts/minikconf.py')
2975 config_all_accel = {}
2976 config_all_devices = {}
2977 config_devices_mak_list = []
2978 config_devices_h = {}
2979 config_target_h = {}
2980 config_target_mak = {}
2983 'alpha' : ['CONFIG_ALPHA_DIS'],
2984 'avr' : ['CONFIG_AVR_DIS'],
2985 'cris' : ['CONFIG_CRIS_DIS'],
2986 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2987 'hppa' : ['CONFIG_HPPA_DIS'],
2988 'i386' : ['CONFIG_I386_DIS'],
2989 'x86_64' : ['CONFIG_I386_DIS'],
2990 'm68k' : ['CONFIG_M68K_DIS'],
2991 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2992 'mips' : ['CONFIG_MIPS_DIS'],
2993 'or1k' : ['CONFIG_OPENRISC_DIS'],
2994 'ppc' : ['CONFIG_PPC_DIS'],
2995 'riscv' : ['CONFIG_RISCV_DIS'],
2996 'rx' : ['CONFIG_RX_DIS'],
2997 's390' : ['CONFIG_S390_DIS'],
2998 'sh4' : ['CONFIG_SH4_DIS'],
2999 'sparc' : ['CONFIG_SPARC_DIS'],
3000 'xtensa' : ['CONFIG_XTENSA_DIS'],
3001 'loongarch' : ['CONFIG_LOONGARCH_DIS'],
3004 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
3006 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
3007 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
3008 (pixman.found() ? ['CONFIG_PIXMAN=y'] : []) + \
3009 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
3010 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
3011 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
3012 (x11.found() ? ['CONFIG_X11=y'] : []) + \
3013 (fdt.found() ? ['CONFIG_FDT=y'] : []) + \
3014 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
3015 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
3016 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
3017 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
3018 (host_os == 'linux' ? ['CONFIG_LINUX=y'] : []) + \
3019 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
3020 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \
3021 (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : [])
3023 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
3025 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
3026 actual_target_dirs = []
3028 foreach target : target_dirs
3029 config_target = { 'TARGET_NAME': target.split('-')[0] }
3030 if target.endswith('linux-user')
3031 if host_os != 'linux'
3035 error('Target @0@ is only available on a Linux host'.format(target))
3037 config_target += { 'CONFIG_LINUX_USER': 'y' }
3038 elif target.endswith('bsd-user')
3039 if host_os not in bsd_oses
3043 error('Target @0@ is only available on a BSD host'.format(target))
3045 config_target += { 'CONFIG_BSD_USER': 'y' }
3046 elif target.endswith('softmmu')
3047 config_target += { 'CONFIG_SYSTEM_ONLY': 'y' }
3048 config_target += { 'CONFIG_SOFTMMU': 'y' }
3050 if target.endswith('-user')
3052 'CONFIG_USER_ONLY': 'y',
3053 'CONFIG_QEMU_INTERP_PREFIX':
3054 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
3059 foreach sym: accelerators
3060 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
3061 config_target += { sym: 'y' }
3062 config_all_accel += { sym: 'y' }
3063 if target in modular_tcg
3064 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
3066 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
3068 target_kconfig += [ sym + '=y' ]
3071 if target_kconfig.length() == 0
3075 error('No accelerator available for target @0@'.format(target))
3078 config_target += keyval.load('configs/targets' / target + '.mak')
3079 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
3081 if 'TARGET_NEED_FDT' in config_target and not fdt.found()
3083 warning('Disabling ' + target + ' due to missing libfdt')
3085 fdt_required += target
3090 actual_target_dirs += target
3093 if 'TARGET_BASE_ARCH' not in config_target
3094 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
3096 if 'TARGET_ABI_DIR' not in config_target
3097 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
3099 if 'TARGET_BIG_ENDIAN' not in config_target
3100 config_target += {'TARGET_BIG_ENDIAN': 'n'}
3103 foreach k, v: disassemblers
3104 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
3106 config_target += { sym: 'y' }
3111 config_target_data = configuration_data()
3112 foreach k, v: config_target
3113 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
3115 elif ignored.contains(k)
3117 elif k == 'TARGET_BASE_ARCH'
3118 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
3119 # not used to select files from sourcesets.
3120 config_target_data.set('TARGET_' + v.to_upper(), 1)
3121 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
3122 config_target_data.set_quoted(k, v)
3124 config_target_data.set(k, 1)
3126 config_target_data.set(k, 0)
3128 config_target_data.set(k, v)
3131 config_target_data.set('QEMU_ARCH',
3132 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
3133 config_target_h += {target: configure_file(output: target + '-config-target.h',
3134 configuration: config_target_data)}
3136 if target.endswith('-softmmu')
3137 target_kconfig += 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'
3138 target_kconfig += 'CONFIG_TARGET_BIG_ENDIAN=' + config_target['TARGET_BIG_ENDIAN']
3140 config_input = meson.get_external_property(target, 'default')
3141 config_devices_mak = target + '-config-devices.mak'
3142 config_devices_mak = configure_file(
3143 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
3144 output: config_devices_mak,
3145 depfile: config_devices_mak + '.d',
3147 command: [minikconf,
3148 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
3149 config_devices_mak, '@DEPFILE@', '@INPUT@',
3150 host_kconfig, target_kconfig])
3152 config_devices_data = configuration_data()
3153 config_devices = keyval.load(config_devices_mak)
3154 foreach k, v: config_devices
3155 config_devices_data.set(k, 1)
3157 config_devices_mak_list += config_devices_mak
3158 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
3159 configuration: config_devices_data)}
3160 config_target += config_devices
3161 config_all_devices += config_devices
3163 config_target_mak += {target: config_target}
3165 target_dirs = actual_target_dirs
3167 target_configs_h = []
3168 foreach target: target_dirs
3169 target_configs_h += config_target_h[target]
3170 target_configs_h += config_devices_h.get(target, [])
3172 genh += custom_target('config-poison.h',
3173 input: [target_configs_h],
3174 output: 'config-poison.h',
3176 command: [find_program('scripts/make-config-poison.sh'),
3179 if fdt_required.length() > 0
3180 error('fdt disabled but required by targets ' + ', '.join(fdt_required))
3187 libvfio_user_dep = not_found
3188 if have_system and vfio_user_server_allowed
3189 libvfio_user_proj = subproject('libvfio-user', required: true)
3190 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep')
3193 vhost_user = not_found
3194 if host_os == 'linux' and have_vhost_user
3195 libvhost_user = subproject('libvhost-user')
3196 vhost_user = libvhost_user.get_variable('vhost_user_dep')
3199 libvduse = not_found
3201 libvduse_proj = subproject('libvduse')
3202 libvduse = libvduse_proj.get_variable('libvduse_dep')
3205 #####################
3206 # Generated sources #
3207 #####################
3209 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
3211 hxtool = find_program('scripts/hxtool')
3212 shaderinclude = find_program('scripts/shaderinclude.py')
3213 qapi_gen = find_program('scripts/qapi-gen.py')
3214 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
3215 meson.current_source_dir() / 'scripts/qapi/commands.py',
3216 meson.current_source_dir() / 'scripts/qapi/common.py',
3217 meson.current_source_dir() / 'scripts/qapi/error.py',
3218 meson.current_source_dir() / 'scripts/qapi/events.py',
3219 meson.current_source_dir() / 'scripts/qapi/expr.py',
3220 meson.current_source_dir() / 'scripts/qapi/gen.py',
3221 meson.current_source_dir() / 'scripts/qapi/introspect.py',
3222 meson.current_source_dir() / 'scripts/qapi/main.py',
3223 meson.current_source_dir() / 'scripts/qapi/parser.py',
3224 meson.current_source_dir() / 'scripts/qapi/schema.py',
3225 meson.current_source_dir() / 'scripts/qapi/source.py',
3226 meson.current_source_dir() / 'scripts/qapi/types.py',
3227 meson.current_source_dir() / 'scripts/qapi/visit.py',
3228 meson.current_source_dir() / 'scripts/qapi-gen.py'
3232 python, files('scripts/tracetool.py'),
3233 '--backend=' + ','.join(get_option('trace_backends'))
3235 tracetool_depends = files(
3236 'scripts/tracetool/backend/log.py',
3237 'scripts/tracetool/backend/__init__.py',
3238 'scripts/tracetool/backend/dtrace.py',
3239 'scripts/tracetool/backend/ftrace.py',
3240 'scripts/tracetool/backend/simple.py',
3241 'scripts/tracetool/backend/syslog.py',
3242 'scripts/tracetool/backend/ust.py',
3243 'scripts/tracetool/format/ust_events_c.py',
3244 'scripts/tracetool/format/ust_events_h.py',
3245 'scripts/tracetool/format/__init__.py',
3246 'scripts/tracetool/format/d.py',
3247 'scripts/tracetool/format/simpletrace_stap.py',
3248 'scripts/tracetool/format/c.py',
3249 'scripts/tracetool/format/h.py',
3250 'scripts/tracetool/format/log_stap.py',
3251 'scripts/tracetool/format/stap.py',
3252 'scripts/tracetool/__init__.py',
3255 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
3256 meson.current_source_dir(),
3257 get_option('pkgversion'), meson.project_version()]
3258 qemu_version = custom_target('qemu-version.h',
3259 output: 'qemu-version.h',
3260 command: qemu_version_cmd,
3262 build_by_default: true,
3263 build_always_stale: true)
3264 genh += qemu_version
3268 ['qemu-options.hx', 'qemu-options.def'],
3269 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
3273 ['hmp-commands.hx', 'hmp-commands.h'],
3274 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
3277 foreach d : hx_headers
3278 hxdep += custom_target(d[1],
3282 command: [hxtool, '-h', '@INPUT0@'])
3290 # TODO: add each directory to the subdirs from its own meson.build, once
3292 trace_events_subdirs = [
3301 trace_events_subdirs += [ 'linux-user' ]
3304 trace_events_subdirs += [ 'bsd-user' ]
3307 trace_events_subdirs += [
3316 trace_events_subdirs += [
3379 if have_system or have_user
3380 trace_events_subdirs += [
3402 authz_ss = ss.source_set()
3403 blockdev_ss = ss.source_set()
3404 block_ss = ss.source_set()
3405 chardev_ss = ss.source_set()
3406 common_ss = ss.source_set()
3407 crypto_ss = ss.source_set()
3408 hwcore_ss = ss.source_set()
3409 io_ss = ss.source_set()
3410 qmp_ss = ss.source_set()
3411 qom_ss = ss.source_set()
3412 system_ss = ss.source_set()
3413 specific_fuzz_ss = ss.source_set()
3414 specific_ss = ss.source_set()
3415 stub_ss = ss.source_set()
3416 trace_ss = ss.source_set()
3417 user_ss = ss.source_set()
3418 util_ss = ss.source_set()
3421 qtest_module_ss = ss.source_set()
3422 tcg_module_ss = ss.source_set()
3428 target_system_arch = {}
3429 target_user_arch = {}
3431 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3432 # that is filled in by qapi/.
3450 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3451 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3454 qom_ss = qom_ss.apply({})
3455 libqom = static_library('qom', qom_ss.sources() + genh,
3456 dependencies: [qom_ss.dependencies()],
3458 build_by_default: false)
3459 qom = declare_dependency(link_whole: libqom)
3461 event_loop_base = files('event-loop-base.c')
3462 event_loop_base = static_library('event-loop-base',
3463 sources: event_loop_base + genh,
3465 build_by_default: false)
3466 event_loop_base = declare_dependency(link_whole: event_loop_base,
3467 dependencies: [qom])
3469 stub_ss = stub_ss.apply({})
3471 util_ss.add_all(trace_ss)
3472 util_ss = util_ss.apply({})
3473 libqemuutil = static_library('qemuutil',
3474 build_by_default: false,
3475 sources: util_ss.sources() + stub_ss.sources() + genh,
3476 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc])
3477 qemuutil = declare_dependency(link_with: libqemuutil,
3478 sources: genh + version_res,
3479 dependencies: [event_loop_base])
3481 if have_system or have_user
3482 decodetree = generator(find_program('scripts/decodetree.py'),
3483 output: 'decode-@BASENAME@.c.inc',
3484 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3485 subdir('libdecnumber')
3502 if config_host_data.get('CONFIG_REPLICATION')
3503 block_ss.add(files('replication.c'))
3510 blockdev_ss.add(files(
3517 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3518 # os-win32.c does not
3519 if host_os == 'windows'
3520 system_ss.add(files('os-win32.c'))
3522 blockdev_ss.add(files('os-posix.c'))
3526 common_ss.add(files('cpu-common.c'))
3527 specific_ss.add(files('cpu-target.c'))
3531 # Work around a gcc bug/misfeature wherein constant propagation looks
3533 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3534 # to guess that a const variable is always zero. Without lto, this is
3535 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
3536 # without lto, not even the alias is required -- we simply use different
3537 # declarations in different compilation units.
3538 pagevary = files('page-vary-common.c')
3539 if get_option('b_lto')
3540 pagevary_flags = ['-fno-lto']
3541 if get_option('cfi')
3542 pagevary_flags += '-fno-sanitize=cfi-icall'
3544 pagevary = static_library('page-vary-common', sources: pagevary + genh,
3545 c_args: pagevary_flags)
3546 pagevary = declare_dependency(link_with: pagevary)
3548 common_ss.add(pagevary)
3549 specific_ss.add(files('page-target.c', 'page-vary-target.c'))
3557 subdir('semihosting')
3565 common_user_inc = []
3567 subdir('common-user')
3569 subdir('linux-user')
3571 # needed for fuzzing binaries
3572 subdir('tests/qtest/libqos')
3573 subdir('tests/qtest/fuzz')
3576 tcg_real_module_ss = ss.source_set()
3577 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3578 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3579 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3580 'tcg': tcg_real_module_ss }}
3582 ##############################################
3583 # Internal static_libraries and dependencies #
3584 ##############################################
3586 modinfo_collect = find_program('scripts/modinfo-collect.py')
3587 modinfo_generate = find_program('scripts/modinfo-generate.py')
3592 foreach d, list : modules
3593 if not (d == 'block' ? have_block : have_system)
3597 foreach m, module_ss : list
3599 module_ss = module_ss.apply(config_all_devices, strict: false)
3600 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3601 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3607 if module_ss.sources() != []
3608 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3609 # input. Sources can be used multiple times but objects are
3610 # unique when it comes to lookup in compile_commands.json.
3611 # Depnds on a mesion version with
3612 # https://github.com/mesonbuild/meson/pull/8900
3613 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3614 output: d + '-' + m + '.modinfo',
3615 input: module_ss.sources() + genh,
3617 command: [modinfo_collect, module_ss.sources()])
3621 block_ss.add_all(module_ss)
3623 system_ss.add_all(module_ss)
3629 foreach d, list : target_modules
3630 foreach m, module_ss : list
3632 foreach target : target_dirs
3633 if target.endswith('-softmmu')
3634 config_target = config_target_mak[target]
3635 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3636 c_args = ['-DCOMPILING_PER_TARGET',
3637 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3638 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3639 target_module_ss = module_ss.apply(config_target, strict: false)
3640 if target_module_ss.sources() != []
3641 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3642 sl = static_library(module_name,
3643 [genh, target_module_ss.sources()],
3644 dependencies: [modulecommon, target_module_ss.dependencies()],
3645 include_directories: target_inc,
3649 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3650 modinfo_files += custom_target(module_name + '.modinfo',
3651 output: module_name + '.modinfo',
3652 input: target_module_ss.sources() + genh,
3654 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3659 specific_ss.add_all(module_ss)
3665 foreach target : target_dirs
3666 if target.endswith('-softmmu')
3667 config_target = config_target_mak[target]
3668 config_devices_mak = target + '-config-devices.mak'
3669 modinfo_src = custom_target('modinfo-' + target + '.c',
3670 output: 'modinfo-' + target + '.c',
3671 input: modinfo_files,
3672 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'],
3675 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
3676 modinfo_dep = declare_dependency(link_with: modinfo_lib)
3678 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH']
3679 hw_arch[arch].add(modinfo_dep)
3684 nm = find_program('nm')
3685 undefsym = find_program('scripts/undefsym.py')
3686 block_syms = custom_target('block.syms', output: 'block.syms',
3687 input: [libqemuutil, block_mods],
3689 command: [undefsym, nm, '@INPUT@'])
3690 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3691 input: [libqemuutil, system_mods],
3693 command: [undefsym, nm, '@INPUT@'])
3695 authz_ss = authz_ss.apply({})
3696 libauthz = static_library('authz', authz_ss.sources() + genh,
3697 dependencies: [authz_ss.dependencies()],
3699 build_by_default: false)
3701 authz = declare_dependency(link_whole: libauthz,
3704 crypto_ss = crypto_ss.apply({})
3705 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3706 dependencies: [crypto_ss.dependencies()],
3708 build_by_default: false)
3710 crypto = declare_dependency(link_whole: libcrypto,
3711 dependencies: [authz, qom])
3713 io_ss = io_ss.apply({})
3714 libio = static_library('io', io_ss.sources() + genh,
3715 dependencies: [io_ss.dependencies()],
3716 link_with: libqemuutil,
3718 build_by_default: false)
3720 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3722 libmigration = static_library('migration', sources: migration_files + genh,
3724 build_by_default: false)
3725 migration = declare_dependency(link_with: libmigration,
3726 dependencies: [qom, io])
3727 system_ss.add(migration)
3729 block_ss = block_ss.apply({})
3730 libblock = static_library('block', block_ss.sources() + genh,
3731 dependencies: block_ss.dependencies(),
3732 link_depends: block_syms,
3734 build_by_default: false)
3736 block = declare_dependency(link_whole: [libblock],
3737 link_args: '@block.syms',
3738 dependencies: [crypto, io])
3740 blockdev_ss = blockdev_ss.apply({})
3741 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3742 dependencies: blockdev_ss.dependencies(),
3744 build_by_default: false)
3746 blockdev = declare_dependency(link_whole: [libblockdev],
3747 dependencies: [block, event_loop_base])
3749 qmp_ss = qmp_ss.apply({})
3750 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3751 dependencies: qmp_ss.dependencies(),
3753 build_by_default: false)
3755 qmp = declare_dependency(link_whole: [libqmp])
3757 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3759 dependencies: chardev_ss.dependencies(),
3760 build_by_default: false)
3762 chardev = declare_dependency(link_whole: libchardev)
3764 hwcore_ss = hwcore_ss.apply({})
3765 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3767 build_by_default: false)
3768 hwcore = declare_dependency(link_whole: libhwcore)
3769 common_ss.add(hwcore)
3775 emulator_modules = []
3776 foreach m : block_mods + system_mods
3777 emulator_modules += shared_module(m.name(),
3778 build_by_default: true,
3782 install_dir: qemu_moddir)
3784 if emulator_modules.length() > 0
3785 alias_target('modules', emulator_modules)
3788 system_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3789 common_ss.add(qom, qemuutil)
3791 common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss])
3792 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3794 # Note that this library is never used directly (only through extract_objects)
3795 # and is not built by default; therefore, source files not used by the build
3796 # configuration will be in build.ninja, but are never built by default.
3797 common_all = static_library('common',
3798 build_by_default: false,
3799 sources: common_ss.all_sources() + genh,
3800 include_directories: common_user_inc,
3801 implicit_include_directories: false,
3802 dependencies: common_ss.all_dependencies(),
3805 feature_to_c = find_program('scripts/feature_to_c.py')
3807 if host_os == 'darwin'
3808 entitlement = find_program('scripts/entitlement.sh')
3813 foreach target : target_dirs
3814 config_target = config_target_mak[target]
3815 target_name = config_target['TARGET_NAME']
3816 target_base_arch = config_target['TARGET_BASE_ARCH']
3817 arch_srcs = [config_target_h[target]]
3819 c_args = ['-DCOMPILING_PER_TARGET',
3820 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3821 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3822 link_args = emulator_link_args
3824 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3825 if host_os == 'linux'
3826 target_inc += include_directories('linux-headers', is_system: true)
3828 if target.endswith('-softmmu')
3829 target_type='system'
3830 t = target_system_arch[target_base_arch].apply(config_target, strict: false)
3831 arch_srcs += t.sources()
3832 arch_deps += t.dependencies()
3834 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3835 if hw_arch.has_key(hw_dir)
3836 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3837 arch_srcs += hw.sources()
3838 arch_deps += hw.dependencies()
3841 arch_srcs += config_devices_h[target]
3842 link_args += ['@block.syms', '@qemu.syms']
3844 abi = config_target['TARGET_ABI_DIR']
3846 target_inc += common_user_inc
3847 if target_base_arch in target_user_arch
3848 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3849 arch_srcs += t.sources()
3850 arch_deps += t.dependencies()
3852 if 'CONFIG_LINUX_USER' in config_target
3853 base_dir = 'linux-user'
3855 if 'CONFIG_BSD_USER' in config_target
3856 base_dir = 'bsd-user'
3857 target_inc += include_directories('bsd-user/' / host_os)
3858 target_inc += include_directories('bsd-user/host/' / host_arch)
3859 dir = base_dir / abi
3860 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3862 target_inc += include_directories(
3866 if 'CONFIG_LINUX_USER' in config_target
3867 dir = base_dir / abi
3868 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3869 if config_target.has_key('TARGET_SYSTBL_ABI')
3871 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3872 extra_args : config_target['TARGET_SYSTBL_ABI'])
3877 if 'TARGET_XML_FILES' in config_target
3878 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3879 output: target + '-gdbstub-xml.c',
3880 input: files(config_target['TARGET_XML_FILES'].split()),
3881 command: [feature_to_c, '@INPUT@'],
3883 arch_srcs += gdbstub_xml
3886 t = target_arch[target_base_arch].apply(config_target, strict: false)
3887 arch_srcs += t.sources()
3888 arch_deps += t.dependencies()
3890 target_common = common_ss.apply(config_target, strict: false)
3891 objects = common_all.extract_objects(target_common.sources())
3892 arch_deps += target_common.dependencies()
3894 target_specific = specific_ss.apply(config_target, strict: false)
3895 arch_srcs += target_specific.sources()
3896 arch_deps += target_specific.dependencies()
3898 # allow using headers from the dependencies but do not include the sources,
3899 # because this emulator only needs those in "objects". For external
3900 # dependencies, the full dependency is included below in the executable.
3902 foreach dep : arch_deps
3903 lib_deps += dep.partial_dependency(compile_args: true, includes: true)
3906 lib = static_library('qemu-' + target,
3907 sources: arch_srcs + genh,
3908 dependencies: lib_deps,
3910 include_directories: target_inc,
3912 build_by_default: false,
3915 if target.endswith('-softmmu')
3917 'name': 'qemu-system-' + target_name,
3918 'win_subsystem': 'console',
3919 'sources': files('system/main.c'),
3922 if host_os == 'windows' and (sdl.found() or gtk.found())
3924 'name': 'qemu-system-' + target_name + 'w',
3925 'win_subsystem': 'windows',
3926 'sources': files('system/main.c'),
3930 if get_option('fuzzing')
3931 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3933 'name': 'qemu-fuzz-' + target_name,
3934 'win_subsystem': 'console',
3935 'sources': specific_fuzz.sources(),
3936 'dependencies': specific_fuzz.dependencies(),
3941 'name': 'qemu-' + target_name,
3942 'win_subsystem': 'console',
3948 exe_name = exe['name']
3949 if host_os == 'darwin'
3950 exe_name += '-unsigned'
3953 emulator = executable(exe_name, exe['sources'],
3956 dependencies: arch_deps + exe['dependencies'],
3957 objects: lib.extract_all_objects(recursive: true),
3958 link_depends: [block_syms, qemu_syms],
3959 link_args: link_args,
3960 win_subsystem: exe['win_subsystem'])
3962 if host_os == 'darwin'
3963 icon = 'pc-bios/qemu.rsrc'
3964 build_input = [emulator, files(icon)]
3966 get_option('bindir') / exe_name,
3967 meson.current_source_dir() / icon
3969 if 'CONFIG_HVF' in config_target
3970 entitlements = 'accel/hvf/entitlements.plist'
3971 build_input += files(entitlements)
3972 install_input += meson.current_source_dir() / entitlements
3975 emulators += {exe['name'] : custom_target(exe['name'],
3977 output: exe['name'],
3978 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3981 meson.add_install_script(entitlement, '--install',
3982 get_option('bindir') / exe['name'],
3985 emulators += {exe['name']: emulator}
3990 'probe-prefix': 'qemu.' + target_type + '.' + target_name,
3996 # Other build targets
3998 if get_option('plugins')
3999 install_headers('include/qemu/qemu-plugin.h')
4000 if host_os == 'windows'
4001 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer,
4002 # so that plugin authors can compile against it.
4003 install_data(win32_qemu_plugin_api_lib, install_dir: 'lib')
4009 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
4010 # when we don't build tools or system
4011 if xkbcommon.found()
4012 # used for the update-keymaps target, so include rules even if !have_tools
4013 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
4014 dependencies: [qemuutil, xkbcommon], install: have_tools)
4018 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
4019 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
4020 qemu_io = executable('qemu-io', files('qemu-io.c'),
4021 dependencies: [block, qemuutil], install: true)
4022 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
4023 dependencies: [blockdev, qemuutil, gnutls, selinux],
4026 subdir('storage-daemon')
4028 foreach exe: [ 'qemu-img', 'qemu-io', 'qemu-nbd', 'qemu-storage-daemon']
4031 'probe-prefix': 'qemu.' + exe.substring(5).replace('-', '_')
4035 subdir('contrib/elf2dmp')
4037 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
4038 dependencies: qemuutil,
4042 subdir('contrib/vhost-user-blk')
4043 subdir('contrib/vhost-user-gpu')
4044 subdir('contrib/vhost-user-input')
4045 subdir('contrib/vhost-user-scsi')
4048 if host_os == 'linux'
4049 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
4050 dependencies: [qemuutil, libcap_ng],
4052 install_dir: get_option('libexecdir'))
4054 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
4055 dependencies: [authz, crypto, io, qom, qemuutil,
4056 libcap_ng, mpathpersist],
4061 subdir('contrib/ivshmem-client')
4062 subdir('contrib/ivshmem-server')
4067 foreach t: traceable
4069 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / t['exe'], 'install': false},
4070 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / t['exe'], 'install': true},
4071 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
4072 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
4075 tracetool, '--group=all', '--format=' + stp['fmt'],
4076 '--binary=' + stp['bin'],
4077 '--probe-prefix=' + t['probe-prefix'],
4078 '@INPUT@', '@OUTPUT@'
4081 custom_target(t['exe'] + stp['ext'],
4082 input: trace_events_all,
4083 output: t['exe'] + stp['ext'],
4084 install: stp['install'],
4085 install_dir: get_option('datadir') / 'systemtap/tapset',
4087 depend_files: tracetool_depends)
4101 if host_machine.system() == 'windows'
4103 find_program('scripts/nsis.py'),
4105 get_option('prefix'),
4106 meson.current_source_dir(),
4107 glib_pc.get_variable('bindir'),
4110 '-DDISPLAYVERSION=' + meson.project_version(),
4113 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
4116 nsis_cmd += '-DCONFIG_GTK=y'
4119 nsis = custom_target('nsis',
4120 output: 'qemu-setup-' + meson.project_version() + '.exe',
4121 input: files('qemu.nsi'),
4122 build_always_stale: true,
4123 command: nsis_cmd + ['@INPUT@'])
4124 alias_target('installer', nsis)
4127 #########################
4128 # Configuration summary #
4129 #########################
4133 summary_info += {'Build directory': meson.current_build_dir()}
4134 summary_info += {'Source path': meson.current_source_dir()}
4135 summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'}
4136 summary(summary_info, bool_yn: true, section: 'Build environment')
4139 summary_info += {'Install prefix': get_option('prefix')}
4140 summary_info += {'BIOS directory': qemu_datadir}
4141 pathsep = host_os == 'windows' ? ';' : ':'
4142 summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))}
4143 summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
4144 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
4145 summary_info += {'module directory': qemu_moddir}
4146 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
4147 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
4148 summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')}
4149 if host_os != 'windows'
4150 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
4151 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')}
4153 summary_info += {'local state directory': 'queried at runtime'}
4155 summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
4156 summary(summary_info, bool_yn: true, section: 'Directories')
4160 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
4161 summary_info += {'sphinx-build': sphinx_build}
4163 # FIXME: the [binaries] section of machine files, which can be probed
4164 # with find_program(), would be great for passing gdb and genisoimage
4165 # paths from configure to Meson. However, there seems to be no way to
4166 # hide a program (for example if gdb is too old).
4167 if config_host.has_key('GDB')
4168 summary_info += {'gdb': config_host['GDB']}
4170 summary_info += {'iasl': iasl}
4171 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
4172 if host_os == 'windows' and have_ga
4173 summary_info += {'wixl': wixl}
4175 if slirp.found() and have_system
4176 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
4178 summary(summary_info, bool_yn: true, section: 'Host binaries')
4180 # Configurable features
4182 summary_info += {'Documentation': build_docs}
4183 summary_info += {'system-mode emulation': have_system}
4184 summary_info += {'user-mode emulation': have_user}
4185 summary_info += {'block layer': have_block}
4186 summary_info += {'Install blobs': get_option('install_blobs')}
4187 summary_info += {'module support': enable_modules}
4189 summary_info += {'alternative module path': get_option('module_upgrades')}
4191 summary_info += {'fuzzing support': get_option('fuzzing')}
4193 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
4195 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
4196 if 'simple' in get_option('trace_backends')
4197 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
4199 summary_info += {'D-Bus display': dbus_display}
4200 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
4201 summary_info += {'Relocatable install': get_option('relocatable')}
4202 summary_info += {'vhost-kernel support': have_vhost_kernel}
4203 summary_info += {'vhost-net support': have_vhost_net}
4204 summary_info += {'vhost-user support': have_vhost_user}
4205 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
4206 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
4207 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
4208 summary_info += {'build guest agent': have_ga}
4209 summary(summary_info, bool_yn: true, section: 'Configurable features')
4211 # Compilation information
4213 summary_info += {'host CPU': cpu}
4214 summary_info += {'host endianness': build_machine.endian()}
4215 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
4216 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
4217 if 'cpp' in all_languages
4218 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
4220 summary_info += {'C++ compiler': false}
4222 if 'objc' in all_languages
4223 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
4225 summary_info += {'Objective-C compiler': false}
4227 option_cflags = (get_option('debug') ? ['-g'] : [])
4228 if get_option('optimization') != 'plain'
4229 option_cflags += ['-O' + get_option('optimization')]
4231 summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)}
4232 if 'cpp' in all_languages
4233 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)}
4235 if 'objc' in all_languages
4236 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)}
4238 link_args = get_option('c_link_args')
4239 if link_args.length() > 0
4240 summary_info += {'LDFLAGS': ' '.join(link_args)}
4242 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)}
4243 if 'cpp' in all_languages
4244 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)}
4246 if 'objc' in all_languages
4247 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)}
4249 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
4250 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
4251 summary_info += {'PIE': get_option('b_pie')}
4252 summary_info += {'static build': get_option('prefer_static')}
4253 summary_info += {'malloc trim support': has_malloc_trim}
4254 summary_info += {'membarrier': have_membarrier}
4255 summary_info += {'debug graph lock': get_option('debug_graph_lock')}
4256 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
4257 summary_info += {'mutex debugging': get_option('debug_mutex')}
4258 summary_info += {'memory allocator': get_option('malloc')}
4259 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
4260 summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')}
4261 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
4262 summary_info += {'gcov': get_option('b_coverage')}
4263 summary_info += {'thread sanitizer': get_option('tsan')}
4264 summary_info += {'CFI support': get_option('cfi')}
4265 if get_option('cfi')
4266 summary_info += {'CFI debug support': get_option('cfi_debug')}
4268 summary_info += {'strip binaries': get_option('strip')}
4269 summary_info += {'sparse': sparse}
4270 summary_info += {'mingw32 support': host_os == 'windows'}
4271 summary(summary_info, bool_yn: true, section: 'Compilation')
4273 # snarf the cross-compilation information for tests
4276 foreach target: target_dirs
4277 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak'
4278 if fs.exists(tcg_mak)
4279 config_cross_tcg = keyval.load(tcg_mak)
4280 if 'CC' in config_cross_tcg
4281 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']}
4287 summary(summary_info, bool_yn: true, section: 'Cross compilers')
4290 # Targets and accelerators
4293 summary_info += {'KVM support': config_all_accel.has_key('CONFIG_KVM')}
4294 summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')}
4295 summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')}
4296 summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')}
4297 summary_info += {'Xen support': xen.found()}
4299 summary_info += {'xen ctrl version': xen.version()}
4301 summary_info += {'Xen emulation': config_all_devices.has_key('CONFIG_XEN_EMU')}
4303 summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')}
4304 if config_all_accel.has_key('CONFIG_TCG')
4305 if get_option('tcg_interpreter')
4306 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
4308 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
4310 summary_info += {'TCG plugins': get_option('plugins')}
4311 summary_info += {'TCG debug enabled': get_option('debug_tcg')}
4312 if have_linux_user or have_bsd_user
4313 summary_info += {'syscall buffer debugging support': get_option('debug_remap')}
4316 summary_info += {'target list': ' '.join(target_dirs)}
4318 summary_info += {'default devices': get_option('default_devices')}
4319 summary_info += {'out of process emulation': multiprocess_allowed}
4320 summary_info += {'vfio-user server': vfio_user_server_allowed}
4322 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
4326 summary_info += {'coroutine backend': coroutine_backend}
4327 summary_info += {'coroutine pool': have_coroutine_pool}
4329 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
4330 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
4331 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
4332 summary_info += {'VirtFS (9P) support': have_virtfs}
4333 summary_info += {'VirtFS (9P) Proxy Helper support (deprecated)': have_virtfs_proxy_helper}
4334 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
4335 summary_info += {'bochs support': get_option('bochs').allowed()}
4336 summary_info += {'cloop support': get_option('cloop').allowed()}
4337 summary_info += {'dmg support': get_option('dmg').allowed()}
4338 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
4339 summary_info += {'vdi support': get_option('vdi').allowed()}
4340 summary_info += {'vhdx support': get_option('vhdx').allowed()}
4341 summary_info += {'vmdk support': get_option('vmdk').allowed()}
4342 summary_info += {'vpc support': get_option('vpc').allowed()}
4343 summary_info += {'vvfat support': get_option('vvfat').allowed()}
4344 summary_info += {'qed support': get_option('qed').allowed()}
4345 summary_info += {'parallels support': get_option('parallels').allowed()}
4346 summary_info += {'FUSE exports': fuse}
4347 summary_info += {'VDUSE block exports': have_vduse_blk_export}
4349 summary(summary_info, bool_yn: true, section: 'Block layer support')
4353 summary_info += {'TLS priority': get_option('tls_priority')}
4354 summary_info += {'GNUTLS support': gnutls}
4356 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
4358 summary_info += {'libgcrypt': gcrypt}
4359 summary_info += {'nettle': nettle}
4361 summary_info += {' XTS': xts != 'private'}
4363 summary_info += {'SM4 ALG support': crypto_sm4}
4364 summary_info += {'AF_ALG support': have_afalg}
4365 summary_info += {'rng-none': get_option('rng_none')}
4366 summary_info += {'Linux keyring': have_keyring}
4367 summary_info += {'Linux keyutils': keyutils}
4368 summary(summary_info, bool_yn: true, section: 'Crypto')
4372 if host_os == 'darwin'
4373 summary_info += {'Cocoa support': cocoa}
4375 summary_info += {'SDL support': sdl}
4376 summary_info += {'SDL image support': sdl_image}
4377 summary_info += {'GTK support': gtk}
4378 summary_info += {'pixman': pixman}
4379 summary_info += {'VTE support': vte}
4380 summary_info += {'PNG support': png}
4381 summary_info += {'VNC support': vnc}
4383 summary_info += {'VNC SASL support': sasl}
4384 summary_info += {'VNC JPEG support': jpeg}
4386 summary_info += {'spice protocol support': spice_protocol}
4387 if spice_protocol.found()
4388 summary_info += {' spice server support': spice}
4390 summary_info += {'curses support': curses}
4391 summary_info += {'brlapi support': brlapi}
4392 summary(summary_info, bool_yn: true, section: 'User interface')
4396 summary_info += {'VirGL support': virgl}
4397 summary_info += {'Rutabaga support': rutabaga}
4398 summary(summary_info, bool_yn: true, section: 'Graphics backends')
4402 if host_os not in ['darwin', 'haiku', 'windows']
4403 summary_info += {'OSS support': oss}
4404 summary_info += {'sndio support': sndio}
4405 elif host_os == 'darwin'
4406 summary_info += {'CoreAudio support': coreaudio}
4407 elif host_os == 'windows'
4408 summary_info += {'DirectSound support': dsound}
4410 if host_os == 'linux'
4411 summary_info += {'ALSA support': alsa}
4412 summary_info += {'PulseAudio support': pulse}
4414 summary_info += {'PipeWire support': pipewire}
4415 summary_info += {'JACK support': jack}
4416 summary(summary_info, bool_yn: true, section: 'Audio backends')
4420 if host_os == 'darwin'
4421 summary_info += {'vmnet.framework support': vmnet}
4423 summary_info += {'AF_XDP support': libxdp}
4424 summary_info += {'slirp support': slirp}
4425 summary_info += {'vde support': vde}
4426 summary_info += {'netmap support': have_netmap}
4427 summary_info += {'l2tpv3 support': have_l2tpv3}
4428 summary(summary_info, bool_yn: true, section: 'Network backends')
4432 summary_info += {'libtasn1': tasn1}
4433 summary_info += {'PAM': pam}
4434 summary_info += {'iconv support': iconv}
4435 summary_info += {'blkio support': blkio}
4436 summary_info += {'curl support': curl}
4437 summary_info += {'Multipath support': mpathpersist}
4438 summary_info += {'Linux AIO support': libaio}
4439 summary_info += {'Linux io_uring support': linux_io_uring}
4440 summary_info += {'ATTR/XATTR support': libattr}
4441 summary_info += {'RDMA support': rdma}
4442 summary_info += {'fdt support': fdt_opt == 'internal' ? 'internal' : fdt}
4443 summary_info += {'libcap-ng support': libcap_ng}
4444 summary_info += {'bpf support': libbpf}
4445 summary_info += {'rbd support': rbd}
4446 summary_info += {'smartcard support': cacard}
4447 summary_info += {'U2F support': u2f}
4448 summary_info += {'libusb': libusb}
4449 summary_info += {'usb net redir': usbredir}
4450 summary_info += {'OpenGL support (epoxy)': opengl}
4451 summary_info += {'GBM': gbm}
4452 summary_info += {'libiscsi support': libiscsi}
4453 summary_info += {'libnfs support': libnfs}
4454 if host_os == 'windows'
4456 summary_info += {'QGA VSS support': have_qga_vss}
4459 summary_info += {'seccomp support': seccomp}
4460 summary_info += {'GlusterFS support': glusterfs}
4461 summary_info += {'hv-balloon support': hv_balloon}
4462 summary_info += {'TPM support': have_tpm}
4463 summary_info += {'libssh support': libssh}
4464 summary_info += {'lzo support': lzo}
4465 summary_info += {'snappy support': snappy}
4466 summary_info += {'bzip2 support': libbzip2}
4467 summary_info += {'lzfse support': liblzfse}
4468 summary_info += {'zstd support': zstd}
4469 summary_info += {'Query Processing Library support': qpl}
4470 summary_info += {'UADK Library support': uadk}
4471 summary_info += {'NUMA host support': numa}
4472 summary_info += {'capstone': capstone}
4473 summary_info += {'libpmem support': libpmem}
4474 summary_info += {'libdaxctl support': libdaxctl}
4475 summary_info += {'libudev': libudev}
4476 # Dummy dependency, keep .found()
4477 summary_info += {'FUSE lseek': fuse_lseek.found()}
4478 summary_info += {'selinux': selinux}
4479 summary_info += {'libdw': libdw}
4480 if host_os == 'freebsd'
4481 summary_info += {'libinotify-kqueue': inotify}
4483 summary(summary_info, bool_yn: true, section: 'Dependencies')
4485 if host_arch == 'unknown'
4487 warning('UNSUPPORTED HOST CPU')
4489 message('Support for CPU host architecture ' + cpu + ' is not currently')
4490 message('maintained. The QEMU project does not guarantee that QEMU will')
4491 message('compile or work on this host CPU. You can help by volunteering')
4492 message('to maintain it and providing a build host for our continuous')
4493 message('integration setup.')
4494 if get_option('tcg').allowed() and target_dirs.length() > 0
4496 message('configure has succeeded and you can continue to build, but')
4497 message('QEMU will use a slow interpreter to emulate the target CPU.')
4501 if not supported_oses.contains(host_os)
4503 warning('UNSUPPORTED HOST OS')
4505 message('Support for host OS ' + host_os + 'is not currently maintained.')
4506 message('configure has succeeded and you can continue to build, but')
4507 message('the QEMU project does not guarantee that QEMU will compile or')
4508 message('work on this operating system. You can help by volunteering')
4509 message('to maintain it and providing a build host for our continuous')
4510 message('integration setup. This will ensure that future versions of QEMU')
4511 message('will keep working on ' + host_os + '.')
4514 if host_arch == 'unknown' or not supported_oses.contains(host_os)
4516 message('If you want to help supporting QEMU on this platform, please')
4517 message('contact the developers at qemu-devel@nongnu.org.')
4520 actually_reloc = get_option('relocatable')
4521 # check if get_relocated_path() is actually able to relocate paths
4522 if get_option('relocatable') and \
4523 not (get_option('prefix') / get_option('bindir')).startswith(get_option('prefix') / '')
4525 warning('bindir not included within prefix, the installation will not be relocatable.')
4526 actually_reloc = false
4528 if not actually_reloc and (host_os == 'windows' or get_option('relocatable'))
4529 if host_os == 'windows'
4531 warning('Windows installs should usually be relocatable.')
4534 message('QEMU will have to be installed under ' + get_option('prefix') + '.')
4535 message('Use --disable-relocatable to remove this warning.')