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')
1206 have_vhost_user_gpu = have_tools and host_os == 'linux' and pixman.found()
1207 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
1208 virgl = dependency('virglrenderer',
1209 method: 'pkg-config',
1210 required: get_option('virglrenderer'))
1212 rutabaga = not_found
1213 if not get_option('rutabaga_gfx').auto() or have_system or have_vhost_user_gpu
1214 rutabaga = dependency('rutabaga_gfx_ffi',
1215 method: 'pkg-config',
1216 required: get_option('rutabaga_gfx'))
1219 if not get_option('blkio').auto() or have_block
1220 blkio = dependency('blkio',
1221 method: 'pkg-config',
1222 required: get_option('blkio'))
1225 if not get_option('curl').auto() or have_block
1226 curl = dependency('libcurl', version: '>=7.29.0',
1227 method: 'pkg-config',
1228 required: get_option('curl'))
1231 if host_os == 'linux' and (have_system or have_tools)
1232 libudev = dependency('libudev',
1233 method: 'pkg-config',
1234 required: get_option('libudev'))
1237 mpathlibs = [libudev]
1238 mpathpersist = not_found
1239 if host_os == 'linux' and have_tools and get_option('mpath').allowed()
1240 mpath_test_source = '''
1241 #include <libudev.h>
1242 #include <mpath_persist.h>
1243 unsigned mpath_mx_alloc_len = 1024;
1245 static struct config *multipath_conf;
1246 extern struct udev *udev;
1247 extern struct config *get_multipath_config(void);
1248 extern void put_multipath_config(struct config *conf);
1250 struct config *get_multipath_config(void) { return multipath_conf; }
1251 void put_multipath_config(struct config *conf) { }
1254 multipath_conf = mpath_lib_init();
1257 libmpathpersist = cc.find_library('mpathpersist',
1258 required: get_option('mpath'))
1259 if libmpathpersist.found()
1260 mpathlibs += libmpathpersist
1261 if get_option('prefer_static')
1262 mpathlibs += cc.find_library('devmapper',
1263 required: get_option('mpath'))
1265 mpathlibs += cc.find_library('multipath',
1266 required: get_option('mpath'))
1267 foreach lib: mpathlibs
1273 if mpathlibs.length() == 0
1274 msg = 'Dependencies missing for libmpathpersist'
1275 elif cc.links(mpath_test_source, dependencies: mpathlibs)
1276 mpathpersist = declare_dependency(dependencies: mpathlibs)
1278 msg = 'Cannot detect libmpathpersist API'
1280 if not mpathpersist.found()
1281 if get_option('mpath').enabled()
1284 warning(msg + ', disabling')
1292 if have_system and get_option('curses').allowed()
1294 #if defined(__APPLE__) || defined(__OpenBSD__)
1295 #define _XOPEN_SOURCE_EXTENDED 1
1302 setlocale(LC_ALL, "");
1304 addwstr(L"wide chars\n");
1306 add_wch(WACS_DEGREE);
1310 curses_dep_list = host_os == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
1311 curses = dependency(curses_dep_list,
1313 method: 'pkg-config')
1314 msg = get_option('curses').enabled() ? 'curses library not found' : ''
1315 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
1317 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
1318 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses],
1319 version: curses.version())
1321 msg = 'curses package not usable'
1325 if not curses.found()
1326 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1327 if host_os != 'windows' and not has_curses_h
1328 message('Trying with /usr/include/ncursesw')
1329 curses_compile_args += ['-I/usr/include/ncursesw']
1330 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1333 curses_libname_list = (host_os == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
1334 foreach curses_libname : curses_libname_list
1335 libcurses = cc.find_library(curses_libname,
1337 if libcurses.found()
1338 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
1339 curses = declare_dependency(compile_args: curses_compile_args,
1340 dependencies: [libcurses])
1343 msg = 'curses library not usable'
1349 if get_option('iconv').allowed()
1350 foreach link_args : [ ['-liconv'], [] ]
1351 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
1352 # We need to use libiconv if available because mixing libiconv's headers with
1353 # the system libc does not work.
1354 # However, without adding glib to the dependencies -L/usr/local/lib will not be
1355 # included in the command line and libiconv will not be found.
1359 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
1360 return conv != (iconv_t) -1;
1361 }''', args: link_args, dependencies: glib)
1362 iconv = declare_dependency(link_args: link_args, dependencies: glib)
1367 if curses.found() and not iconv.found()
1368 if get_option('iconv').enabled()
1369 error('iconv not available')
1371 msg = 'iconv required for curses UI but not available'
1374 if not curses.found() and msg != ''
1375 if get_option('curses').enabled()
1378 warning(msg + ', disabling')
1384 if not get_option('brlapi').auto() or have_system
1385 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
1386 required: get_option('brlapi'))
1387 if brlapi.found() and not cc.links('''
1390 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
1392 if get_option('brlapi').enabled()
1393 error('could not link brlapi')
1395 warning('could not link brlapi, disabling')
1401 if not get_option('sdl').auto() or have_system
1402 sdl = dependency('sdl2', required: get_option('sdl'))
1403 sdl_image = not_found
1406 # Some versions of SDL have problems with -Wundef
1407 if not cc.compiles('''
1409 #include <SDL_syswm.h>
1410 int main(int argc, char *argv[]) { return 0; }
1411 ''', dependencies: sdl, args: '-Werror=undef')
1412 sdl = declare_dependency(compile_args: '-Wno-undef',
1414 version: sdl.version())
1416 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
1417 method: 'pkg-config')
1419 if get_option('sdl_image').enabled()
1420 error('sdl-image required, but SDL was @0@'.format(
1421 get_option('sdl').disabled() ? 'disabled' : 'not found'))
1423 sdl_image = not_found
1427 if not get_option('rbd').auto() or have_block
1428 librados = cc.find_library('rados', required: get_option('rbd'))
1429 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
1430 required: get_option('rbd'))
1431 if librados.found() and librbd.found()
1434 #include <rbd/librbd.h>
1437 rados_create(&cluster, NULL);
1438 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
1442 }''', dependencies: [librbd, librados])
1443 rbd = declare_dependency(dependencies: [librbd, librados])
1444 elif get_option('rbd').enabled()
1445 error('librbd >= 1.12.0 required')
1447 warning('librbd >= 1.12.0 not found, disabling')
1452 glusterfs = not_found
1453 glusterfs_ftruncate_has_stat = false
1454 glusterfs_iocb_has_stat = false
1455 if not get_option('glusterfs').auto() or have_block
1456 glusterfs = dependency('glusterfs-api', version: '>=3',
1457 required: get_option('glusterfs'),
1458 method: 'pkg-config')
1459 if glusterfs.found()
1460 glusterfs_ftruncate_has_stat = cc.links('''
1461 #include <glusterfs/api/glfs.h>
1466 /* new glfs_ftruncate() passes two additional args */
1467 return glfs_ftruncate(NULL, 0, NULL, NULL);
1469 ''', dependencies: glusterfs)
1470 glusterfs_iocb_has_stat = cc.links('''
1471 #include <glusterfs/api/glfs.h>
1473 /* new glfs_io_cbk() passes two additional glfs_stat structs */
1475 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
1481 glfs_io_cbk iocb = &glusterfs_iocb;
1482 iocb(NULL, 0 , NULL, NULL, NULL);
1485 ''', dependencies: glusterfs)
1490 if get_option('hv_balloon').allowed() and have_system
1493 #include <gmodule.h>
1497 tree = g_tree_new((GCompareFunc)strcmp);
1498 (void)g_tree_node_first(tree);
1499 g_tree_destroy(tree);
1502 ''', dependencies: glib)
1505 if get_option('hv_balloon').enabled()
1506 error('could not enable hv-balloon, update your glib')
1508 warning('could not find glib support for hv-balloon, disabling')
1514 if not get_option('libssh').auto() or have_block
1515 libssh = dependency('libssh', version: '>=0.8.7',
1516 method: 'pkg-config',
1517 required: get_option('libssh'))
1520 libbzip2 = not_found
1521 if not get_option('bzip2').auto() or have_block
1522 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
1523 required: get_option('bzip2'))
1524 if libbzip2.found() and not cc.links('''
1526 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
1527 libbzip2 = not_found
1528 if get_option('bzip2').enabled()
1529 error('could not link libbzip2')
1531 warning('could not link libbzip2, disabling')
1536 liblzfse = not_found
1537 if not get_option('lzfse').auto() or have_block
1538 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
1539 required: get_option('lzfse'))
1541 if liblzfse.found() and not cc.links('''
1543 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
1544 liblzfse = not_found
1545 if get_option('lzfse').enabled()
1546 error('could not link liblzfse')
1548 warning('could not link liblzfse, disabling')
1553 if get_option('oss').allowed() and have_system
1554 if not cc.has_header('sys/soundcard.h')
1556 elif host_os == 'netbsd'
1557 oss = cc.find_library('ossaudio', required: get_option('oss'))
1559 oss = declare_dependency()
1563 if get_option('oss').enabled()
1564 error('OSS not found')
1569 if not get_option('dsound').auto() or (host_os == 'windows' and have_system)
1570 if cc.has_header('dsound.h')
1571 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
1574 if not dsound.found()
1575 if get_option('dsound').enabled()
1576 error('DirectSound not found')
1581 coreaudio = not_found
1582 if not get_option('coreaudio').auto() or (host_os == 'darwin' and have_system)
1583 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
1584 required: get_option('coreaudio'))
1588 if not get_option('opengl').auto() or have_system or have_vhost_user_gpu
1589 epoxy = dependency('epoxy', method: 'pkg-config',
1590 required: get_option('opengl'))
1591 if cc.has_header('epoxy/egl.h', dependencies: epoxy)
1593 elif get_option('opengl').enabled()
1594 error('epoxy/egl.h not found')
1598 if (have_system or have_tools) and (virgl.found() or opengl.found())
1599 gbm = dependency('gbm', method: 'pkg-config', required: false)
1601 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and opengl.found() and gbm.found()
1604 gnutls_crypto = not_found
1605 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1606 # For general TLS support our min gnutls matches
1607 # that implied by our platform support matrix
1609 # For the crypto backends, we look for a newer
1612 # Version 3.6.8 is needed to get XTS
1613 # Version 3.6.13 is needed to get PBKDF
1614 # Version 3.6.14 is needed to get HW accelerated XTS
1616 # If newer enough gnutls isn't available, we can
1617 # still use a different crypto backend to satisfy
1618 # the platform support requirements
1619 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1620 method: 'pkg-config',
1622 if gnutls_crypto.found()
1623 gnutls = gnutls_crypto
1625 # Our min version if all we need is TLS
1626 gnutls = dependency('gnutls', version: '>=3.5.18',
1627 method: 'pkg-config',
1628 required: get_option('gnutls'))
1632 # We prefer use of gnutls for crypto, unless the options
1633 # explicitly asked for nettle or gcrypt.
1635 # If gnutls isn't available for crypto, then we'll prefer
1636 # gcrypt over nettle for performance reasons.
1640 crypto_sm4 = not_found
1643 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1644 error('Only one of gcrypt & nettle can be enabled')
1647 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1648 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1649 gnutls_crypto = not_found
1652 if not gnutls_crypto.found()
1653 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1654 gcrypt = dependency('libgcrypt', version: '>=1.8',
1655 method: 'config-tool',
1656 required: get_option('gcrypt'))
1657 # Debian has removed -lgpg-error from libgcrypt-config
1658 # as it "spreads unnecessary dependencies" which in
1659 # turn breaks static builds...
1660 if gcrypt.found() and get_option('prefer_static')
1661 gcrypt = declare_dependency(dependencies:
1663 cc.find_library('gpg-error', required: true)],
1664 version: gcrypt.version())
1667 # SM4 ALG is available in libgcrypt >= 1.9
1668 if gcrypt.found() and not cc.links('''
1671 gcry_cipher_hd_t handler;
1672 gcry_cipher_open(&handler, GCRY_CIPHER_SM4, GCRY_CIPHER_MODE_ECB, 0);
1674 }''', dependencies: gcrypt)
1675 crypto_sm4 = not_found
1678 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1679 nettle = dependency('nettle', version: '>=3.4',
1680 method: 'pkg-config',
1681 required: get_option('nettle'))
1682 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1686 # SM4 ALG is available in nettle >= 3.9
1687 if nettle.found() and not cc.links('''
1688 #include <nettle/sm4.h>
1691 unsigned char key[16] = {0};
1692 sm4_set_encrypt_key(&ctx, key);
1694 }''', dependencies: nettle)
1695 crypto_sm4 = not_found
1700 capstone = not_found
1701 if not get_option('capstone').auto() or have_system or have_user
1702 capstone = dependency('capstone', version: '>=3.0.5',
1703 method: 'pkg-config',
1704 required: get_option('capstone'))
1706 # Some versions of capstone have broken pkg-config file
1707 # that reports a wrong -I path, causing the #include to
1708 # fail later. If the system has such a broken version
1710 if capstone.found() and not cc.compiles('#include <capstone.h>',
1711 dependencies: [capstone])
1712 capstone = not_found
1713 if get_option('capstone').enabled()
1714 error('capstone requested, but it does not appear to work')
1719 gmp = dependency('gmp', required: false, method: 'pkg-config')
1720 if nettle.found() and gmp.found()
1721 hogweed = dependency('hogweed', version: '>=3.4',
1722 method: 'pkg-config',
1723 required: get_option('nettle'))
1730 have_gtk_clipboard = get_option('gtk_clipboard').enabled()
1732 if get_option('gtk') \
1733 .disable_auto_if(not have_system) \
1734 .require(pixman.found(),
1735 error_message: 'cannot enable GTK if pixman is not available') \
1737 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1738 method: 'pkg-config',
1739 required: get_option('gtk'))
1741 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1742 method: 'pkg-config',
1744 gtk = declare_dependency(dependencies: [gtk, gtkx11],
1745 version: gtk.version())
1747 if not get_option('vte').auto() or have_system
1748 vte = dependency('vte-2.91',
1749 method: 'pkg-config',
1750 required: get_option('vte'))
1752 elif have_gtk_clipboard
1753 error('GTK clipboard requested, but GTK not found')
1759 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found())
1762 if get_option('png').allowed() and have_system
1763 png = dependency('libpng', version: '>=1.6.34', required: get_option('png'),
1764 method: 'pkg-config')
1769 if get_option('vnc') \
1770 .disable_auto_if(not have_system) \
1771 .require(pixman.found(),
1772 error_message: 'cannot enable VNC if pixman is not available') \
1774 vnc = declare_dependency() # dummy dependency
1775 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1776 method: 'pkg-config')
1777 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1778 required: get_option('vnc_sasl'))
1780 sasl = declare_dependency(dependencies: sasl,
1781 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1786 if not get_option('auth_pam').auto() or have_system
1787 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1788 required: get_option('auth_pam'))
1790 if pam.found() and not cc.links('''
1792 #include <security/pam_appl.h>
1794 const char *service_name = "qemu";
1795 const char *user = "frank";
1796 const struct pam_conv pam_conv = { 0 };
1797 pam_handle_t *pamh = NULL;
1798 pam_start(service_name, user, &pam_conv, &pamh);
1800 }''', dependencies: pam)
1802 if get_option('auth_pam').enabled()
1803 error('could not link libpam')
1805 warning('could not link libpam, disabling')
1810 if not get_option('snappy').auto() or have_system
1811 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1812 required: get_option('snappy'))
1814 if snappy.found() and not cc.links('''
1815 #include <snappy-c.h>
1816 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1818 if get_option('snappy').enabled()
1819 error('could not link libsnappy')
1821 warning('could not link libsnappy, disabling')
1826 if not get_option('lzo').auto() or have_system
1827 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1828 required: get_option('lzo'))
1830 if lzo.found() and not cc.links('''
1831 #include <lzo/lzo1x.h>
1832 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1834 if get_option('lzo').enabled()
1835 error('could not link liblzo2')
1837 warning('could not link liblzo2, disabling')
1842 if not get_option('numa').auto() or have_system or have_tools
1843 numa = cc.find_library('numa', has_headers: ['numa.h'],
1844 required: get_option('numa'))
1846 if numa.found() and not cc.links('''
1848 int main(void) { return numa_available(); }
1849 ''', dependencies: numa)
1851 if get_option('numa').enabled()
1852 error('could not link numa')
1854 warning('could not link numa, disabling')
1859 fdt_opt = get_option('fdt')
1860 if fdt_opt == 'enabled' and get_option('wrap_mode') == 'nodownload'
1863 if fdt_opt in ['enabled', 'system'] or (fdt_opt == 'auto' and have_system)
1864 fdt = cc.find_library('fdt', required: fdt_opt == 'system')
1865 if fdt.found() and cc.links('''
1867 #include <libfdt_env.h>
1868 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
1871 elif fdt_opt != 'system'
1872 fdt_opt = get_option('wrap_mode') == 'nodownload' ? 'disabled' : 'internal'
1875 error('system libfdt is too old (1.5.1 or newer required)')
1878 if fdt_opt == 'internal'
1879 assert(not fdt.found())
1880 libfdt_proj = subproject('dtc', required: true,
1881 default_options: ['tools=false', 'yaml=disabled',
1882 'python=disabled', 'default_library=static'])
1883 fdt = libfdt_proj.get_variable('libfdt_dep')
1887 if not get_option('rdma').auto() or have_system
1888 libumad = cc.find_library('ibumad', required: get_option('rdma'))
1889 rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'],
1890 required: get_option('rdma')),
1891 cc.find_library('ibverbs', required: get_option('rdma')),
1893 rdma = declare_dependency(dependencies: rdma_libs)
1894 foreach lib: rdma_libs
1902 if not get_option('smartcard').auto() or have_system
1903 cacard = dependency('libcacard', required: get_option('smartcard'),
1904 version: '>=2.5.1', method: 'pkg-config')
1907 if not get_option('u2f').auto() or have_system
1908 u2f = dependency('u2f-emu', required: get_option('u2f'),
1909 method: 'pkg-config')
1912 if not get_option('canokey').auto() or have_system
1913 canokey = dependency('canokey-qemu', required: get_option('canokey'),
1914 method: 'pkg-config')
1916 usbredir = not_found
1917 if not get_option('usb_redir').auto() or have_system
1918 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1919 version: '>=0.6', method: 'pkg-config')
1922 if not get_option('libusb').auto() or have_system
1923 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1924 version: '>=1.0.13', method: 'pkg-config')
1928 if not get_option('libpmem').auto() or have_system
1929 libpmem = dependency('libpmem', required: get_option('libpmem'),
1930 method: 'pkg-config')
1932 libdaxctl = not_found
1933 if not get_option('libdaxctl').auto() or have_system
1934 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1935 version: '>=57', method: 'pkg-config')
1939 tasn1 = dependency('libtasn1',
1940 method: 'pkg-config')
1942 keyutils = not_found
1943 if not get_option('libkeyutils').auto() or have_block
1944 keyutils = dependency('libkeyutils', required: get_option('libkeyutils'),
1945 method: 'pkg-config')
1948 has_gettid = cc.has_function('gettid')
1951 selinux = dependency('libselinux',
1952 required: get_option('selinux'),
1953 method: 'pkg-config')
1958 if get_option('malloc') == 'system'
1960 get_option('malloc_trim').allowed() and \
1961 cc.has_function('malloc_trim', prefix: '#include <malloc.h>')
1963 has_malloc_trim = false
1964 malloc = cc.find_library(get_option('malloc'), required: true)
1966 if not has_malloc_trim and get_option('malloc_trim').enabled()
1967 if get_option('malloc') == 'system'
1968 error('malloc_trim not available on this platform.')
1970 error('malloc_trim not available with non-libc memory allocator')
1974 gnu_source_prefix = '''
1980 # Check whether the glibc provides STATX_BASIC_STATS
1982 has_statx = cc.has_header_symbol('sys/stat.h', 'STATX_BASIC_STATS', prefix: gnu_source_prefix)
1984 # Check whether statx() provides mount ID information
1986 has_statx_mnt_id = cc.has_header_symbol('sys/stat.h', 'STATX_MNT_ID', prefix: gnu_source_prefix)
1988 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
1989 .require(host_os == 'linux',
1990 error_message: 'vhost_user_blk_server requires linux') \
1991 .require(have_vhost_user,
1992 error_message: 'vhost_user_blk_server requires vhost-user support') \
1993 .disable_auto_if(not have_tools and not have_system) \
1996 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1997 error('Cannot enable fuse-lseek while fuse is disabled')
2000 fuse = dependency('fuse3', required: get_option('fuse'),
2001 version: '>=3.1', method: 'pkg-config')
2003 fuse_lseek = not_found
2004 if get_option('fuse_lseek').allowed()
2005 if fuse.version().version_compare('>=3.8')
2007 fuse_lseek = declare_dependency()
2008 elif get_option('fuse_lseek').enabled()
2010 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
2012 error('fuse-lseek requires libfuse, which was not found')
2017 have_libvduse = (host_os == 'linux')
2018 if get_option('libvduse').enabled()
2019 if host_os != 'linux'
2020 error('libvduse requires linux')
2022 elif get_option('libvduse').disabled()
2023 have_libvduse = false
2026 have_vduse_blk_export = (have_libvduse and host_os == 'linux')
2027 if get_option('vduse_blk_export').enabled()
2028 if host_os != 'linux'
2029 error('vduse_blk_export requires linux')
2030 elif not have_libvduse
2031 error('vduse_blk_export requires libvduse support')
2033 elif get_option('vduse_blk_export').disabled()
2034 have_vduse_blk_export = false
2038 bpf_version = '1.1.0'
2039 libbpf = dependency('libbpf', version: '>=' + bpf_version, required: get_option('bpf'), method: 'pkg-config')
2040 if libbpf.found() and not cc.links('''
2041 #include <bpf/libbpf.h>
2042 #include <linux/bpf.h>
2045 // check flag availability
2046 int flag = BPF_F_MMAPABLE;
2047 bpf_object__destroy_skeleton(NULL);
2049 }''', dependencies: libbpf)
2051 if get_option('bpf').enabled()
2052 error('libbpf skeleton/mmaping test failed')
2054 warning('libbpf skeleton/mmaping test failed, disabling')
2060 if not get_option('af_xdp').auto() or have_system
2061 libxdp = dependency('libxdp', required: get_option('af_xdp'),
2062 version: '>=1.4.0', method: 'pkg-config')
2067 if not get_option('libdw').auto() or \
2068 (not get_option('prefer_static') and (have_system or have_user))
2069 libdw = dependency('libdw',
2070 method: 'pkg-config',
2071 required: get_option('libdw'))
2078 config_host_data = configuration_data()
2080 audio_drivers_selected = []
2082 audio_drivers_available = {
2083 'alsa': alsa.found(),
2084 'coreaudio': coreaudio.found(),
2085 'dsound': dsound.found(),
2086 'jack': jack.found(),
2088 'pa': pulse.found(),
2089 'pipewire': pipewire.found(),
2091 'sndio': sndio.found(),
2093 foreach k, v: audio_drivers_available
2094 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
2097 # Default to native drivers first, OSS second, SDL third
2098 audio_drivers_priority = \
2099 [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \
2100 (host_os == 'linux' ? [] : [ 'sdl' ])
2101 audio_drivers_default = []
2102 foreach k: audio_drivers_priority
2103 if audio_drivers_available[k]
2104 audio_drivers_default += k
2108 foreach k: get_option('audio_drv_list')
2110 audio_drivers_selected += audio_drivers_default
2111 elif not audio_drivers_available[k]
2112 error('Audio driver "@0@" not available.'.format(k))
2114 audio_drivers_selected += k
2118 config_host_data.set('CONFIG_AUDIO_DRIVERS',
2119 '"' + '", "'.join(audio_drivers_selected) + '", ')
2121 have_host_block_device = (host_os != 'darwin' or
2122 cc.has_header('IOKit/storage/IOMedia.h'))
2124 dbus_display = get_option('dbus_display') \
2125 .require(gio.version().version_compare('>=2.64'),
2126 error_message: '-display dbus requires glib>=2.64') \
2127 .require(gdbus_codegen.found(),
2128 error_message: gdbus_codegen_error.format('-display dbus')) \
2131 have_virtfs = get_option('virtfs') \
2132 .require(host_os == 'linux' or host_os == 'darwin',
2133 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
2134 .require(host_os == 'linux' or cc.has_function('pthread_fchdir_np'),
2135 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
2136 .require(host_os == 'darwin' or libattr.found(),
2137 error_message: 'virtio-9p (virtfs) on Linux requires libattr-devel') \
2138 .disable_auto_if(not have_tools and not have_system) \
2141 have_virtfs_proxy_helper = get_option('virtfs_proxy_helper') \
2142 .require(host_os != 'darwin', error_message: 'the virtfs proxy helper is incompatible with macOS') \
2143 .require(have_virtfs, error_message: 'the virtfs proxy helper requires that virtfs is enabled') \
2144 .disable_auto_if(not have_tools) \
2145 .require(libcap_ng.found(), error_message: 'the virtfs proxy helper requires libcap-ng') \
2148 if get_option('block_drv_ro_whitelist') == ''
2149 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
2151 config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
2152 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
2154 if get_option('block_drv_rw_whitelist') == ''
2155 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
2157 config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
2158 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
2161 foreach k : get_option('trace_backends')
2162 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
2164 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
2165 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
2167 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
2169 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
2170 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
2171 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
2172 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
2173 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
2175 qemu_firmwarepath = ''
2176 foreach k : get_option('qemu_firmwarepath')
2177 qemu_firmwarepath += '"' + get_option('prefix') / k + '", '
2179 config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath)
2181 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
2182 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
2183 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
2184 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
2185 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
2186 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
2189 config_host_data.set('CONFIG_STAMP', run_command(
2190 meson.current_source_dir() / 'scripts/qemu-stamp.py',
2191 meson.project_version(), get_option('pkgversion'), '--',
2192 meson.current_source_dir() / 'configure',
2193 capture: true, check: true).stdout().strip())
2196 have_slirp_smbd = get_option('slirp_smbd') \
2197 .require(host_os != 'windows', error_message: 'Host smbd not supported on this platform.') \
2200 smbd_path = get_option('smbd')
2202 smbd_path = (host_os == 'sunos' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
2204 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
2207 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
2209 kvm_targets_c = '""'
2210 if get_option('kvm').allowed() and host_os == 'linux'
2211 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
2213 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
2215 if get_option('module_upgrades') and not enable_modules
2216 error('Cannot enable module-upgrades as modules are not enabled')
2218 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
2220 config_host_data.set('CONFIG_ATTR', libattr.found())
2221 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
2222 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
2223 config_host_data.set('CONFIG_BSD', host_os in bsd_oses)
2224 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2225 config_host_data.set('CONFIG_COCOA', cocoa.found())
2226 config_host_data.set('CONFIG_DARWIN', host_os == 'darwin')
2227 config_host_data.set('CONFIG_FDT', fdt.found())
2228 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
2229 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
2230 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
2231 config_host_data.set('CONFIG_LINUX', host_os == 'linux')
2232 config_host_data.set('CONFIG_POSIX', host_os != 'windows')
2233 config_host_data.set('CONFIG_WIN32', host_os == 'windows')
2234 config_host_data.set('CONFIG_LZO', lzo.found())
2235 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
2236 config_host_data.set('CONFIG_BLKIO', blkio.found())
2238 config_host_data.set('CONFIG_BLKIO_VHOST_VDPA_FD',
2239 blkio.version().version_compare('>=1.3.0'))
2241 config_host_data.set('CONFIG_CURL', curl.found())
2242 config_host_data.set('CONFIG_CURSES', curses.found())
2243 config_host_data.set('CONFIG_GBM', gbm.found())
2244 config_host_data.set('CONFIG_GIO', gio.found())
2245 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
2246 if glusterfs.found()
2247 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
2248 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
2249 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
2250 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
2251 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
2252 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
2254 config_host_data.set('CONFIG_GTK', gtk.found())
2255 config_host_data.set('CONFIG_VTE', vte.found())
2256 config_host_data.set('CONFIG_GTK_CLIPBOARD', have_gtk_clipboard)
2257 config_host_data.set('CONFIG_HEXAGON_IDEF_PARSER', get_option('hexagon_idef_parser'))
2258 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
2259 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
2260 config_host_data.set('CONFIG_EBPF', libbpf.found())
2261 config_host_data.set('CONFIG_AF_XDP', libxdp.found())
2262 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
2263 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
2264 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
2265 config_host_data.set('CONFIG_LIBSSH', libssh.found())
2266 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
2267 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
2268 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
2269 config_host_data.set('CONFIG_MODULES', enable_modules)
2270 config_host_data.set('CONFIG_NUMA', numa.found())
2272 config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY',
2273 cc.has_function('numa_has_preferred_many',
2274 dependencies: numa))
2276 config_host_data.set('CONFIG_OPENGL', opengl.found())
2277 config_host_data.set('CONFIG_PLUGIN', get_option('plugins'))
2278 config_host_data.set('CONFIG_RBD', rbd.found())
2279 config_host_data.set('CONFIG_RDMA', rdma.found())
2280 config_host_data.set('CONFIG_RELOCATABLE', get_option('relocatable'))
2281 config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack'))
2282 config_host_data.set('CONFIG_SDL', sdl.found())
2283 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
2284 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
2286 config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc)
2288 config_host_data.set('CONFIG_PIXMAN', pixman.found())
2289 config_host_data.set('CONFIG_SLIRP', slirp.found())
2290 config_host_data.set('CONFIG_SNAPPY', snappy.found())
2291 config_host_data.set('CONFIG_SOLARIS', host_os == 'sunos')
2292 if get_option('tcg').allowed()
2293 config_host_data.set('CONFIG_TCG', 1)
2294 config_host_data.set('CONFIG_TCG_INTERPRETER', tcg_arch == 'tci')
2296 config_host_data.set('CONFIG_TPM', have_tpm)
2297 config_host_data.set('CONFIG_TSAN', get_option('tsan'))
2298 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
2299 config_host_data.set('CONFIG_VDE', vde.found())
2300 config_host_data.set('CONFIG_VHOST', have_vhost)
2301 config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
2302 config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
2303 config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)
2304 config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
2305 config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
2306 config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
2307 config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
2308 config_host_data.set('CONFIG_VMNET', vmnet.found())
2309 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
2310 config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export)
2311 config_host_data.set('CONFIG_PNG', png.found())
2312 config_host_data.set('CONFIG_VNC', vnc.found())
2313 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
2314 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
2316 config_host_data.set('HAVE_VIRGL_D3D_INFO_EXT',
2317 cc.has_member('struct virgl_renderer_resource_info_ext', 'd3d_tex2d',
2318 prefix: '#include <virglrenderer.h>',
2319 dependencies: virgl))
2321 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
2322 config_host_data.set('CONFIG_VTE', vte.found())
2323 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
2324 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
2325 config_host_data.set('CONFIG_GETTID', has_gettid)
2326 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
2327 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
2328 config_host_data.set('CONFIG_TASN1', tasn1.found())
2329 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
2330 config_host_data.set('CONFIG_NETTLE', nettle.found())
2331 config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found())
2332 config_host_data.set('CONFIG_HOGWEED', hogweed.found())
2333 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
2334 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
2335 config_host_data.set('CONFIG_STATX', has_statx)
2336 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
2337 config_host_data.set('CONFIG_ZSTD', zstd.found())
2338 config_host_data.set('CONFIG_FUSE', fuse.found())
2339 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
2340 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
2341 if spice_protocol.found()
2342 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
2343 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
2344 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
2346 config_host_data.set('CONFIG_SPICE', spice.found())
2347 config_host_data.set('CONFIG_X11', x11.found())
2348 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
2349 config_host_data.set('CONFIG_CFI', get_option('cfi'))
2350 config_host_data.set('CONFIG_SELINUX', selinux.found())
2351 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
2352 config_host_data.set('CONFIG_LIBDW', libdw.found())
2354 # protect from xen.version() having less than three components
2355 xen_version = xen.version().split('.') + ['0', '0']
2356 xen_ctrl_version = xen_version[0] + \
2357 ('0' + xen_version[1]).substring(-2) + \
2358 ('0' + xen_version[2]).substring(-2)
2359 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
2361 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
2362 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
2363 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
2364 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
2366 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
2367 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
2369 have_coroutine_pool = get_option('coroutine_pool')
2370 if get_option('debug_stack_usage') and have_coroutine_pool
2371 message('Disabling coroutine pool to measure stack usage')
2372 have_coroutine_pool = false
2374 config_host_data.set('CONFIG_COROUTINE_POOL', have_coroutine_pool)
2375 config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock'))
2376 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
2377 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
2378 config_host_data.set('CONFIG_DEBUG_TCG', get_option('debug_tcg'))
2379 config_host_data.set('CONFIG_DEBUG_REMAP', get_option('debug_remap'))
2380 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
2381 config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
2384 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
2385 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
2386 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
2387 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
2388 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
2389 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
2390 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
2391 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
2392 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
2393 if host_os == 'windows'
2394 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h'))
2398 config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range'))
2399 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
2400 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
2401 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
2402 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
2403 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
2404 config_host_data.set('CONFIG_GETCPU', cc.has_function('getcpu', prefix: gnu_source_prefix))
2405 config_host_data.set('CONFIG_SCHED_GETCPU', cc.has_function('sched_getcpu', prefix: '#include <sched.h>'))
2406 # Note that we need to specify prefix: here to avoid incorrectly
2407 # thinking that Windows has posix_memalign()
2408 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
2409 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
2410 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
2411 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
2412 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
2413 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
2414 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
2415 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
2416 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
2417 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
2418 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
2419 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
2420 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
2421 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
2422 config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice)
2423 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
2424 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
2425 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
2427 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
2428 cc.has_function('rbd_namespace_exists',
2430 prefix: '#include <rbd/librbd.h>'))
2433 config_host_data.set('HAVE_IBV_ADVISE_MR',
2434 cc.has_function('ibv_advise_mr',
2436 prefix: '#include <infiniband/verbs.h>'))
2439 have_asan_fiber = false
2440 if get_option('sanitizers') and \
2441 not cc.has_function('__sanitizer_start_switch_fiber',
2442 args: '-fsanitize=address',
2443 prefix: '#include <sanitizer/asan_interface.h>')
2444 warning('Missing ASAN due to missing fiber annotation interface')
2445 warning('Without code annotation, the report may be inferior.')
2447 have_asan_fiber = true
2449 config_host_data.set('CONFIG_ASAN_IFACE_FIBER', have_asan_fiber)
2451 have_inotify_init = cc.has_header_symbol('sys/inotify.h', 'inotify_init')
2452 have_inotify_init1 = cc.has_header_symbol('sys/inotify.h', 'inotify_init1')
2454 if (have_inotify_init or have_inotify_init1) and host_os == 'freebsd'
2456 inotify = cc.find_library('inotify')
2457 if have_inotify_init
2458 have_inotify_init = inotify.found()
2460 if have_inotify_init1
2461 have_inotify_init1 = inotify.found()
2464 config_host_data.set('CONFIG_INOTIFY', have_inotify_init)
2465 config_host_data.set('CONFIG_INOTIFY1', have_inotify_init1)
2468 config_host_data.set('CONFIG_BLKZONED',
2469 cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE'))
2470 config_host_data.set('CONFIG_EPOLL_CREATE1',
2471 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
2472 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
2473 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
2474 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
2475 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
2476 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
2477 config_host_data.set('CONFIG_FIEMAP',
2478 cc.has_header('linux/fiemap.h') and
2479 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
2480 config_host_data.set('CONFIG_GETRANDOM',
2481 cc.has_function('getrandom') and
2482 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
2483 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
2484 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
2485 config_host_data.set('CONFIG_RTNETLINK',
2486 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
2487 config_host_data.set('CONFIG_SYSMACROS',
2488 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
2489 config_host_data.set('HAVE_OPTRESET',
2490 cc.has_header_symbol('getopt.h', 'optreset'))
2491 config_host_data.set('HAVE_IPPROTO_MPTCP',
2492 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
2495 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
2496 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
2497 prefix: '#include <signal.h>'))
2498 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
2499 cc.has_member('struct stat', 'st_atim',
2500 prefix: '#include <sys/stat.h>'))
2501 config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY',
2502 cc.has_member('struct blk_zone', 'capacity',
2503 prefix: '#include <linux/blkzoned.h>'))
2506 config_host_data.set('CONFIG_IOVEC',
2507 cc.has_type('struct iovec',
2508 prefix: '#include <sys/uio.h>'))
2509 config_host_data.set('HAVE_UTMPX',
2510 cc.has_type('struct utmpx',
2511 prefix: '#include <utmpx.h>'))
2513 config_host_data.set('CONFIG_EVENTFD', cc.links('''
2514 #include <sys/eventfd.h>
2515 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
2516 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
2519 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
2520 return fdatasync(0);
2522 #error Not supported
2526 has_madvise = cc.links(gnu_source_prefix + '''
2527 #include <sys/types.h>
2528 #include <sys/mman.h>
2530 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
2531 missing_madvise_proto = false
2533 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
2534 # but forget to prototype it. In this case, has_madvise will be true (the
2535 # test program links despite a compile warning). To detect the
2536 # missing-prototype case, we try again with a definitely-bogus prototype.
2537 # This will only compile if the system headers don't provide the prototype;
2538 # otherwise the conflicting prototypes will cause a compiler error.
2539 missing_madvise_proto = cc.links(gnu_source_prefix + '''
2540 #include <sys/types.h>
2541 #include <sys/mman.h>
2543 extern int madvise(int);
2544 int main(void) { return madvise(0); }''')
2546 config_host_data.set('CONFIG_MADVISE', has_madvise)
2547 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
2549 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
2550 #include <sys/mman.h>
2551 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
2552 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
2554 #if !defined(AT_EMPTY_PATH)
2555 # error missing definition
2557 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
2560 # On Darwin posix_madvise() has the same return semantics as plain madvise(),
2561 # i.e. errno is set and -1 is returned. That's not really how POSIX defines the
2562 # function. On the flip side, it has madvise() which is preferred anyways.
2563 if host_os != 'darwin'
2564 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
2565 #include <sys/mman.h>
2567 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
2570 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
2571 #include <pthread.h>
2573 static void *f(void *p) { return NULL; }
2577 pthread_create(&thread, 0, f, 0);
2578 pthread_setname_np(thread, "QEMU");
2580 }''', dependencies: threads))
2581 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
2582 #include <pthread.h>
2584 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
2588 pthread_create(&thread, 0, f, 0);
2590 }''', dependencies: threads))
2591 config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(gnu_source_prefix + '''
2592 #include <pthread.h>
2593 #include <pthread_np.h>
2595 static void *f(void *p) { return NULL; }
2599 pthread_create(&thread, 0, f, 0);
2600 pthread_set_name_np(thread, "QEMU");
2602 }''', dependencies: threads))
2603 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
2604 #include <pthread.h>
2609 pthread_condattr_t attr
2610 pthread_condattr_init(&attr);
2611 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
2613 }''', dependencies: threads))
2614 config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(gnu_source_prefix + '''
2615 #include <pthread.h>
2617 static void *f(void *p) { return NULL; }
2620 int setsize = CPU_ALLOC_SIZE(64);
2623 pthread_create(&thread, 0, f, 0);
2624 cpuset = CPU_ALLOC(64);
2625 CPU_ZERO_S(setsize, cpuset);
2626 pthread_setaffinity_np(thread, setsize, cpuset);
2627 pthread_getaffinity_np(thread, setsize, cpuset);
2630 }''', dependencies: threads))
2631 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
2632 #include <sys/signalfd.h>
2634 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
2635 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
2643 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
2644 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
2648 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
2649 #include <sys/mman.h>
2651 return mlockall(MCL_FUTURE);
2655 if get_option('l2tpv3').allowed() and have_system
2656 have_l2tpv3 = cc.has_type('struct mmsghdr',
2657 prefix: gnu_source_prefix + '''
2658 #include <sys/socket.h>
2659 #include <linux/ip.h>''')
2661 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2664 if get_option('netmap').allowed() and have_system
2665 have_netmap = cc.compiles('''
2666 #include <inttypes.h>
2668 #include <net/netmap.h>
2669 #include <net/netmap_user.h>
2670 #if (NETMAP_API < 11) || (NETMAP_API > 15)
2673 int main(void) { return 0; }''')
2674 if not have_netmap and get_option('netmap').enabled()
2675 error('Netmap headers not available')
2678 config_host_data.set('CONFIG_NETMAP', have_netmap)
2680 # Work around a system header bug with some kernel/XFS header
2681 # versions where they both try to define 'struct fsxattr':
2682 # xfs headers will not try to redefine structs from linux headers
2683 # if this macro is set.
2684 config_host_data.set('HAVE_FSXATTR', cc.links('''
2685 #include <linux/fs.h>
2691 # Some versions of Mac OS X incorrectly define SIZE_MAX
2692 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2696 return printf("%zu", SIZE_MAX);
2697 }''', args: ['-Werror']))
2699 # See if 64-bit atomic operations are supported.
2700 # Note that without __atomic builtins, we can only
2701 # assume atomic loads/stores max at pointer size.
2702 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
2706 uint64_t x = 0, y = 0;
2707 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2708 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2709 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2710 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2711 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2715 has_int128_type = cc.compiles('''
2718 int main(void) { b = a; }''')
2719 config_host_data.set('CONFIG_INT128_TYPE', has_int128_type)
2721 has_int128 = has_int128_type and cc.links('''
2730 config_host_data.set('CONFIG_INT128', has_int128)
2733 # "do we have 128-bit atomics which are handled inline and specifically not
2734 # via libatomic". The reason we can't use libatomic is documented in the
2735 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2736 # We only care about these operations on 16-byte aligned pointers, so
2737 # force 16-byte alignment of the pointer, which may be greater than
2738 # __alignof(unsigned __int128) for the host.
2739 atomic_test_128 = '''
2740 int main(int ac, char **av) {
2741 __uint128_t *p = __builtin_assume_aligned(av[ac - 1], 16);
2742 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED);
2743 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED);
2744 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2747 has_atomic128 = cc.links(atomic_test_128)
2749 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2751 if not has_atomic128
2752 # Even with __builtin_assume_aligned, the above test may have failed
2753 # without optimization enabled. Try again with optimizations locally
2754 # enabled for the function. See
2755 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389
2756 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128)
2757 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt)
2759 if not has_atomic128_opt
2760 config_host_data.set('CONFIG_CMPXCHG128', cc.links('''
2763 __uint128_t x = 0, y = 0;
2764 __sync_val_compare_and_swap_16(&x, y, x);
2772 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2773 #include <sys/auxv.h>
2775 return getauxval(AT_HWCAP) == 0;
2778 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2779 #include <linux/usbdevice_fs.h>
2781 #ifndef USBDEVFS_GET_CAPABILITIES
2782 #error "USBDEVFS_GET_CAPABILITIES undefined"
2785 #ifndef USBDEVFS_DISCONNECT_CLAIM
2786 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2789 int main(void) { return 0; }'''))
2791 have_keyring = get_option('keyring') \
2792 .require(host_os == 'linux', error_message: 'keyring is only available on Linux') \
2793 .require(cc.compiles('''
2795 #include <asm/unistd.h>
2796 #include <linux/keyctl.h>
2797 #include <sys/syscall.h>
2800 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2801 }'''), error_message: 'keyctl syscall not available on this system').allowed()
2802 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2804 have_cpuid_h = cc.links('''
2807 unsigned a, b, c, d;
2808 unsigned max = __get_cpuid_max(0, 0);
2811 __cpuid(1, a, b, c, d);
2815 __cpuid_count(7, 0, a, b, c, d);
2820 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2822 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2823 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2824 .require(cc.links('''
2826 #include <immintrin.h>
2827 static int __attribute__((target("avx2"))) bar(void *a) {
2828 __m256i x = *(__m256i *)a;
2829 return _mm256_testz_si256(x, x);
2831 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2832 '''), error_message: 'AVX2 not available').allowed())
2834 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2835 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2836 .require(cc.links('''
2838 #include <immintrin.h>
2839 static int __attribute__((target("avx512f"))) bar(void *a) {
2840 __m512i x = *(__m512i *)a;
2841 return _mm512_test_epi64_mask(x, x);
2843 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2844 '''), error_message: 'AVX512F not available').allowed())
2846 config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \
2847 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \
2848 .require(cc.links('''
2850 #include <immintrin.h>
2851 static int __attribute__((target("avx512bw"))) bar(void *a) {
2853 __m512i res= _mm512_abs_epi8(*x);
2856 int main(int argc, char *argv[]) { return bar(argv[0]); }
2857 '''), error_message: 'AVX512BW not available').allowed())
2859 # For both AArch64 and AArch32, detect if builtins are available.
2860 config_host_data.set('CONFIG_ARM_AES_BUILTIN', cc.compiles('''
2861 #include <arm_neon.h>
2862 #ifndef __ARM_FEATURE_AES
2863 __attribute__((target("+crypto")))
2865 void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); }
2868 if get_option('membarrier').disabled()
2869 have_membarrier = false
2870 elif host_os == 'windows'
2871 have_membarrier = true
2872 elif host_os == 'linux'
2873 have_membarrier = cc.compiles('''
2874 #include <linux/membarrier.h>
2875 #include <sys/syscall.h>
2879 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2880 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2884 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2885 .require(have_membarrier, error_message: 'membarrier system call not available') \
2888 have_afalg = get_option('crypto_afalg') \
2889 .require(cc.compiles(gnu_source_prefix + '''
2891 #include <sys/types.h>
2892 #include <sys/socket.h>
2893 #include <linux/if_alg.h>
2896 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2899 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2900 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2902 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2903 'linux/vm_sockets.h', 'AF_VSOCK',
2904 prefix: '#include <sys/socket.h>',
2908 have_vss_sdk = false # old xp/2003 SDK
2909 if host_os == 'windows' and 'cpp' in all_languages
2910 have_vss = cxx.compiles('''
2911 #define __MIDL_user_allocate_free_DEFINED__
2913 int main(void) { return VSS_CTX_BACKUP; }''')
2914 have_vss_sdk = cxx.has_header('vscoordint.h')
2916 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2918 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2919 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2920 if host_os == 'windows'
2921 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2927 }''', name: '_lock_file and _unlock_file'))
2930 if host_os == 'windows'
2931 mingw_has_setjmp_longjmp = cc.links('''
2935 * These functions are not available in setjmp header, but may be
2936 * available at link time, from libmingwex.a.
2938 extern int __mingw_setjmp(jmp_buf);
2939 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
2941 __mingw_setjmp(env);
2942 __mingw_longjmp(env, 0);
2944 ''', name: 'mingw setjmp and longjmp')
2946 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp
2947 error('mingw must provide setjmp/longjmp for windows-arm64')
2951 ########################
2952 # Target configuration #
2953 ########################
2955 minikconf = find_program('scripts/minikconf.py')
2957 config_all_accel = {}
2958 config_all_devices = {}
2959 config_devices_mak_list = []
2960 config_devices_h = {}
2961 config_target_h = {}
2962 config_target_mak = {}
2965 'alpha' : ['CONFIG_ALPHA_DIS'],
2966 'avr' : ['CONFIG_AVR_DIS'],
2967 'cris' : ['CONFIG_CRIS_DIS'],
2968 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2969 'hppa' : ['CONFIG_HPPA_DIS'],
2970 'i386' : ['CONFIG_I386_DIS'],
2971 'x86_64' : ['CONFIG_I386_DIS'],
2972 'm68k' : ['CONFIG_M68K_DIS'],
2973 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2974 'mips' : ['CONFIG_MIPS_DIS'],
2975 'or1k' : ['CONFIG_OPENRISC_DIS'],
2976 'ppc' : ['CONFIG_PPC_DIS'],
2977 'riscv' : ['CONFIG_RISCV_DIS'],
2978 'rx' : ['CONFIG_RX_DIS'],
2979 's390' : ['CONFIG_S390_DIS'],
2980 'sh4' : ['CONFIG_SH4_DIS'],
2981 'sparc' : ['CONFIG_SPARC_DIS'],
2982 'xtensa' : ['CONFIG_XTENSA_DIS'],
2983 'loongarch' : ['CONFIG_LOONGARCH_DIS'],
2986 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2988 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2989 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2990 (pixman.found() ? ['CONFIG_PIXMAN=y'] : []) + \
2991 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2992 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2993 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2994 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2995 (fdt.found() ? ['CONFIG_FDT=y'] : []) + \
2996 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
2997 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2998 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2999 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
3000 (host_os == 'linux' ? ['CONFIG_LINUX=y'] : []) + \
3001 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
3002 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \
3003 (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : [])
3005 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
3007 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
3008 actual_target_dirs = []
3010 foreach target : target_dirs
3011 config_target = { 'TARGET_NAME': target.split('-')[0] }
3012 if target.endswith('linux-user')
3013 if host_os != 'linux'
3017 error('Target @0@ is only available on a Linux host'.format(target))
3019 config_target += { 'CONFIG_LINUX_USER': 'y' }
3020 elif target.endswith('bsd-user')
3021 if host_os not in bsd_oses
3025 error('Target @0@ is only available on a BSD host'.format(target))
3027 config_target += { 'CONFIG_BSD_USER': 'y' }
3028 elif target.endswith('softmmu')
3029 config_target += { 'CONFIG_SYSTEM_ONLY': 'y' }
3030 config_target += { 'CONFIG_SOFTMMU': 'y' }
3032 if target.endswith('-user')
3034 'CONFIG_USER_ONLY': 'y',
3035 'CONFIG_QEMU_INTERP_PREFIX':
3036 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
3041 foreach sym: accelerators
3042 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
3043 config_target += { sym: 'y' }
3044 config_all_accel += { sym: 'y' }
3045 if target in modular_tcg
3046 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
3048 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
3050 target_kconfig += [ sym + '=y' ]
3053 if target_kconfig.length() == 0
3057 error('No accelerator available for target @0@'.format(target))
3060 config_target += keyval.load('configs/targets' / target + '.mak')
3061 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
3063 if 'TARGET_NEED_FDT' in config_target and not fdt.found()
3065 warning('Disabling ' + target + ' due to missing libfdt')
3067 fdt_required += target
3072 actual_target_dirs += target
3075 if 'TARGET_BASE_ARCH' not in config_target
3076 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
3078 if 'TARGET_ABI_DIR' not in config_target
3079 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
3081 if 'TARGET_BIG_ENDIAN' not in config_target
3082 config_target += {'TARGET_BIG_ENDIAN': 'n'}
3085 foreach k, v: disassemblers
3086 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
3088 config_target += { sym: 'y' }
3093 config_target_data = configuration_data()
3094 foreach k, v: config_target
3095 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
3097 elif ignored.contains(k)
3099 elif k == 'TARGET_BASE_ARCH'
3100 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
3101 # not used to select files from sourcesets.
3102 config_target_data.set('TARGET_' + v.to_upper(), 1)
3103 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
3104 config_target_data.set_quoted(k, v)
3106 config_target_data.set(k, 1)
3108 config_target_data.set(k, 0)
3110 config_target_data.set(k, v)
3113 config_target_data.set('QEMU_ARCH',
3114 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
3115 config_target_h += {target: configure_file(output: target + '-config-target.h',
3116 configuration: config_target_data)}
3118 if target.endswith('-softmmu')
3119 target_kconfig += 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'
3120 target_kconfig += 'CONFIG_TARGET_BIG_ENDIAN=' + config_target['TARGET_BIG_ENDIAN']
3122 config_input = meson.get_external_property(target, 'default')
3123 config_devices_mak = target + '-config-devices.mak'
3124 config_devices_mak = configure_file(
3125 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
3126 output: config_devices_mak,
3127 depfile: config_devices_mak + '.d',
3129 command: [minikconf,
3130 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
3131 config_devices_mak, '@DEPFILE@', '@INPUT@',
3132 host_kconfig, target_kconfig])
3134 config_devices_data = configuration_data()
3135 config_devices = keyval.load(config_devices_mak)
3136 foreach k, v: config_devices
3137 config_devices_data.set(k, 1)
3139 config_devices_mak_list += config_devices_mak
3140 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
3141 configuration: config_devices_data)}
3142 config_target += config_devices
3143 config_all_devices += config_devices
3145 config_target_mak += {target: config_target}
3147 target_dirs = actual_target_dirs
3149 target_configs_h = []
3150 foreach target: target_dirs
3151 target_configs_h += config_target_h[target]
3152 target_configs_h += config_devices_h.get(target, [])
3154 genh += custom_target('config-poison.h',
3155 input: [target_configs_h],
3156 output: 'config-poison.h',
3158 command: [find_program('scripts/make-config-poison.sh'),
3161 if fdt_required.length() > 0
3162 error('fdt disabled but required by targets ' + ', '.join(fdt_required))
3169 libvfio_user_dep = not_found
3170 if have_system and vfio_user_server_allowed
3171 libvfio_user_proj = subproject('libvfio-user', required: true)
3172 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep')
3175 vhost_user = not_found
3176 if host_os == 'linux' and have_vhost_user
3177 libvhost_user = subproject('libvhost-user')
3178 vhost_user = libvhost_user.get_variable('vhost_user_dep')
3181 libvduse = not_found
3183 libvduse_proj = subproject('libvduse')
3184 libvduse = libvduse_proj.get_variable('libvduse_dep')
3187 #####################
3188 # Generated sources #
3189 #####################
3191 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
3193 hxtool = find_program('scripts/hxtool')
3194 shaderinclude = find_program('scripts/shaderinclude.py')
3195 qapi_gen = find_program('scripts/qapi-gen.py')
3196 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
3197 meson.current_source_dir() / 'scripts/qapi/commands.py',
3198 meson.current_source_dir() / 'scripts/qapi/common.py',
3199 meson.current_source_dir() / 'scripts/qapi/error.py',
3200 meson.current_source_dir() / 'scripts/qapi/events.py',
3201 meson.current_source_dir() / 'scripts/qapi/expr.py',
3202 meson.current_source_dir() / 'scripts/qapi/gen.py',
3203 meson.current_source_dir() / 'scripts/qapi/introspect.py',
3204 meson.current_source_dir() / 'scripts/qapi/main.py',
3205 meson.current_source_dir() / 'scripts/qapi/parser.py',
3206 meson.current_source_dir() / 'scripts/qapi/schema.py',
3207 meson.current_source_dir() / 'scripts/qapi/source.py',
3208 meson.current_source_dir() / 'scripts/qapi/types.py',
3209 meson.current_source_dir() / 'scripts/qapi/visit.py',
3210 meson.current_source_dir() / 'scripts/qapi-gen.py'
3214 python, files('scripts/tracetool.py'),
3215 '--backend=' + ','.join(get_option('trace_backends'))
3217 tracetool_depends = files(
3218 'scripts/tracetool/backend/log.py',
3219 'scripts/tracetool/backend/__init__.py',
3220 'scripts/tracetool/backend/dtrace.py',
3221 'scripts/tracetool/backend/ftrace.py',
3222 'scripts/tracetool/backend/simple.py',
3223 'scripts/tracetool/backend/syslog.py',
3224 'scripts/tracetool/backend/ust.py',
3225 'scripts/tracetool/format/ust_events_c.py',
3226 'scripts/tracetool/format/ust_events_h.py',
3227 'scripts/tracetool/format/__init__.py',
3228 'scripts/tracetool/format/d.py',
3229 'scripts/tracetool/format/simpletrace_stap.py',
3230 'scripts/tracetool/format/c.py',
3231 'scripts/tracetool/format/h.py',
3232 'scripts/tracetool/format/log_stap.py',
3233 'scripts/tracetool/format/stap.py',
3234 'scripts/tracetool/__init__.py',
3235 'scripts/tracetool/vcpu.py'
3238 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
3239 meson.current_source_dir(),
3240 get_option('pkgversion'), meson.project_version()]
3241 qemu_version = custom_target('qemu-version.h',
3242 output: 'qemu-version.h',
3243 command: qemu_version_cmd,
3245 build_by_default: true,
3246 build_always_stale: true)
3247 genh += qemu_version
3251 ['qemu-options.hx', 'qemu-options.def'],
3252 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
3256 ['hmp-commands.hx', 'hmp-commands.h'],
3257 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
3260 foreach d : hx_headers
3261 hxdep += custom_target(d[1],
3265 command: [hxtool, '-h', '@INPUT0@'])
3273 # TODO: add each directory to the subdirs from its own meson.build, once
3275 trace_events_subdirs = [
3284 trace_events_subdirs += [ 'linux-user' ]
3287 trace_events_subdirs += [ 'bsd-user' ]
3290 trace_events_subdirs += [
3299 trace_events_subdirs += [
3362 if have_system or have_user
3363 trace_events_subdirs += [
3385 authz_ss = ss.source_set()
3386 blockdev_ss = ss.source_set()
3387 block_ss = ss.source_set()
3388 chardev_ss = ss.source_set()
3389 common_ss = ss.source_set()
3390 crypto_ss = ss.source_set()
3391 hwcore_ss = ss.source_set()
3392 io_ss = ss.source_set()
3393 qmp_ss = ss.source_set()
3394 qom_ss = ss.source_set()
3395 system_ss = ss.source_set()
3396 specific_fuzz_ss = ss.source_set()
3397 specific_ss = ss.source_set()
3398 stub_ss = ss.source_set()
3399 trace_ss = ss.source_set()
3400 user_ss = ss.source_set()
3401 util_ss = ss.source_set()
3404 qtest_module_ss = ss.source_set()
3405 tcg_module_ss = ss.source_set()
3411 target_system_arch = {}
3412 target_user_arch = {}
3414 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3415 # that is filled in by qapi/.
3433 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3434 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3437 qom_ss = qom_ss.apply({})
3438 libqom = static_library('qom', qom_ss.sources() + genh,
3439 dependencies: [qom_ss.dependencies()],
3441 build_by_default: false)
3442 qom = declare_dependency(link_whole: libqom)
3444 event_loop_base = files('event-loop-base.c')
3445 event_loop_base = static_library('event-loop-base',
3446 sources: event_loop_base + genh,
3448 build_by_default: false)
3449 event_loop_base = declare_dependency(link_whole: event_loop_base,
3450 dependencies: [qom])
3452 stub_ss = stub_ss.apply({})
3454 util_ss.add_all(trace_ss)
3455 util_ss = util_ss.apply({})
3456 libqemuutil = static_library('qemuutil',
3457 build_by_default: false,
3458 sources: util_ss.sources() + stub_ss.sources() + genh,
3459 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc])
3460 qemuutil = declare_dependency(link_with: libqemuutil,
3461 sources: genh + version_res,
3462 dependencies: [event_loop_base])
3464 if have_system or have_user
3465 decodetree = generator(find_program('scripts/decodetree.py'),
3466 output: 'decode-@BASENAME@.c.inc',
3467 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3468 subdir('libdecnumber')
3485 if config_host_data.get('CONFIG_REPLICATION')
3486 block_ss.add(files('replication.c'))
3493 blockdev_ss.add(files(
3500 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3501 # os-win32.c does not
3502 if host_os == 'windows'
3503 system_ss.add(files('os-win32.c'))
3505 blockdev_ss.add(files('os-posix.c'))
3509 common_ss.add(files('cpu-common.c'))
3510 specific_ss.add(files('cpu-target.c'))
3514 # Work around a gcc bug/misfeature wherein constant propagation looks
3516 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3517 # to guess that a const variable is always zero. Without lto, this is
3518 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
3519 # without lto, not even the alias is required -- we simply use different
3520 # declarations in different compilation units.
3521 pagevary = files('page-vary-common.c')
3522 if get_option('b_lto')
3523 pagevary_flags = ['-fno-lto']
3524 if get_option('cfi')
3525 pagevary_flags += '-fno-sanitize=cfi-icall'
3527 pagevary = static_library('page-vary-common', sources: pagevary + genh,
3528 c_args: pagevary_flags)
3529 pagevary = declare_dependency(link_with: pagevary)
3531 common_ss.add(pagevary)
3532 specific_ss.add(files('page-target.c', 'page-vary-target.c'))
3540 subdir('semihosting')
3548 common_user_inc = []
3550 subdir('common-user')
3552 subdir('linux-user')
3554 # needed for fuzzing binaries
3555 subdir('tests/qtest/libqos')
3556 subdir('tests/qtest/fuzz')
3559 tcg_real_module_ss = ss.source_set()
3560 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3561 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3562 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3563 'tcg': tcg_real_module_ss }}
3565 ##############################################
3566 # Internal static_libraries and dependencies #
3567 ##############################################
3569 modinfo_collect = find_program('scripts/modinfo-collect.py')
3570 modinfo_generate = find_program('scripts/modinfo-generate.py')
3575 foreach d, list : modules
3576 if not (d == 'block' ? have_block : have_system)
3580 foreach m, module_ss : list
3582 module_ss = module_ss.apply(config_all_devices, strict: false)
3583 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3584 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3590 if module_ss.sources() != []
3591 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3592 # input. Sources can be used multiple times but objects are
3593 # unique when it comes to lookup in compile_commands.json.
3594 # Depnds on a mesion version with
3595 # https://github.com/mesonbuild/meson/pull/8900
3596 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3597 output: d + '-' + m + '.modinfo',
3598 input: module_ss.sources() + genh,
3600 command: [modinfo_collect, module_ss.sources()])
3604 block_ss.add_all(module_ss)
3606 system_ss.add_all(module_ss)
3612 foreach d, list : target_modules
3613 foreach m, module_ss : list
3615 foreach target : target_dirs
3616 if target.endswith('-softmmu')
3617 config_target = config_target_mak[target]
3618 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3619 c_args = ['-DCOMPILING_PER_TARGET',
3620 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3621 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3622 target_module_ss = module_ss.apply(config_target, strict: false)
3623 if target_module_ss.sources() != []
3624 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3625 sl = static_library(module_name,
3626 [genh, target_module_ss.sources()],
3627 dependencies: [modulecommon, target_module_ss.dependencies()],
3628 include_directories: target_inc,
3632 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3633 modinfo_files += custom_target(module_name + '.modinfo',
3634 output: module_name + '.modinfo',
3635 input: target_module_ss.sources() + genh,
3637 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3642 specific_ss.add_all(module_ss)
3648 foreach target : target_dirs
3649 if target.endswith('-softmmu')
3650 config_target = config_target_mak[target]
3651 config_devices_mak = target + '-config-devices.mak'
3652 modinfo_src = custom_target('modinfo-' + target + '.c',
3653 output: 'modinfo-' + target + '.c',
3654 input: modinfo_files,
3655 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'],
3658 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
3659 modinfo_dep = declare_dependency(link_with: modinfo_lib)
3661 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH']
3662 hw_arch[arch].add(modinfo_dep)
3667 nm = find_program('nm')
3668 undefsym = find_program('scripts/undefsym.py')
3669 block_syms = custom_target('block.syms', output: 'block.syms',
3670 input: [libqemuutil, block_mods],
3672 command: [undefsym, nm, '@INPUT@'])
3673 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3674 input: [libqemuutil, system_mods],
3676 command: [undefsym, nm, '@INPUT@'])
3678 authz_ss = authz_ss.apply({})
3679 libauthz = static_library('authz', authz_ss.sources() + genh,
3680 dependencies: [authz_ss.dependencies()],
3682 build_by_default: false)
3684 authz = declare_dependency(link_whole: libauthz,
3687 crypto_ss = crypto_ss.apply({})
3688 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3689 dependencies: [crypto_ss.dependencies()],
3691 build_by_default: false)
3693 crypto = declare_dependency(link_whole: libcrypto,
3694 dependencies: [authz, qom])
3696 io_ss = io_ss.apply({})
3697 libio = static_library('io', io_ss.sources() + genh,
3698 dependencies: [io_ss.dependencies()],
3699 link_with: libqemuutil,
3701 build_by_default: false)
3703 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3705 libmigration = static_library('migration', sources: migration_files + genh,
3707 build_by_default: false)
3708 migration = declare_dependency(link_with: libmigration,
3709 dependencies: [qom, io])
3710 system_ss.add(migration)
3712 block_ss = block_ss.apply({})
3713 libblock = static_library('block', block_ss.sources() + genh,
3714 dependencies: block_ss.dependencies(),
3715 link_depends: block_syms,
3717 build_by_default: false)
3719 block = declare_dependency(link_whole: [libblock],
3720 link_args: '@block.syms',
3721 dependencies: [crypto, io])
3723 blockdev_ss = blockdev_ss.apply({})
3724 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3725 dependencies: blockdev_ss.dependencies(),
3727 build_by_default: false)
3729 blockdev = declare_dependency(link_whole: [libblockdev],
3730 dependencies: [block, event_loop_base])
3732 qmp_ss = qmp_ss.apply({})
3733 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3734 dependencies: qmp_ss.dependencies(),
3736 build_by_default: false)
3738 qmp = declare_dependency(link_whole: [libqmp])
3740 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3742 dependencies: chardev_ss.dependencies(),
3743 build_by_default: false)
3745 chardev = declare_dependency(link_whole: libchardev)
3747 hwcore_ss = hwcore_ss.apply({})
3748 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3750 build_by_default: false)
3751 hwcore = declare_dependency(link_whole: libhwcore)
3752 common_ss.add(hwcore)
3758 emulator_modules = []
3759 foreach m : block_mods + system_mods
3760 emulator_modules += shared_module(m.name(),
3761 build_by_default: true,
3765 install_dir: qemu_moddir)
3767 if emulator_modules.length() > 0
3768 alias_target('modules', emulator_modules)
3771 system_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3772 common_ss.add(qom, qemuutil)
3774 common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss])
3775 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3777 # Note that this library is never used directly (only through extract_objects)
3778 # and is not built by default; therefore, source files not used by the build
3779 # configuration will be in build.ninja, but are never built by default.
3780 common_all = static_library('common',
3781 build_by_default: false,
3782 sources: common_ss.all_sources() + genh,
3783 include_directories: common_user_inc,
3784 implicit_include_directories: false,
3785 dependencies: common_ss.all_dependencies(),
3788 feature_to_c = find_program('scripts/feature_to_c.py')
3790 if host_os == 'darwin'
3791 entitlement = find_program('scripts/entitlement.sh')
3796 foreach target : target_dirs
3797 config_target = config_target_mak[target]
3798 target_name = config_target['TARGET_NAME']
3799 target_base_arch = config_target['TARGET_BASE_ARCH']
3800 arch_srcs = [config_target_h[target]]
3802 c_args = ['-DCOMPILING_PER_TARGET',
3803 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3804 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3805 link_args = emulator_link_args
3807 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3808 if host_os == 'linux'
3809 target_inc += include_directories('linux-headers', is_system: true)
3811 if target.endswith('-softmmu')
3812 target_type='system'
3813 t = target_system_arch[target_base_arch].apply(config_target, strict: false)
3814 arch_srcs += t.sources()
3815 arch_deps += t.dependencies()
3817 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3818 if hw_arch.has_key(hw_dir)
3819 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3820 arch_srcs += hw.sources()
3821 arch_deps += hw.dependencies()
3824 arch_srcs += config_devices_h[target]
3825 link_args += ['@block.syms', '@qemu.syms']
3827 abi = config_target['TARGET_ABI_DIR']
3829 target_inc += common_user_inc
3830 if target_base_arch in target_user_arch
3831 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3832 arch_srcs += t.sources()
3833 arch_deps += t.dependencies()
3835 if 'CONFIG_LINUX_USER' in config_target
3836 base_dir = 'linux-user'
3838 if 'CONFIG_BSD_USER' in config_target
3839 base_dir = 'bsd-user'
3840 target_inc += include_directories('bsd-user/' / host_os)
3841 target_inc += include_directories('bsd-user/host/' / host_arch)
3842 dir = base_dir / abi
3843 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3845 target_inc += include_directories(
3849 if 'CONFIG_LINUX_USER' in config_target
3850 dir = base_dir / abi
3851 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3852 if config_target.has_key('TARGET_SYSTBL_ABI')
3854 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3855 extra_args : config_target['TARGET_SYSTBL_ABI'])
3860 if 'TARGET_XML_FILES' in config_target
3861 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3862 output: target + '-gdbstub-xml.c',
3863 input: files(config_target['TARGET_XML_FILES'].split()),
3864 command: [feature_to_c, '@INPUT@'],
3866 arch_srcs += gdbstub_xml
3869 t = target_arch[target_base_arch].apply(config_target, strict: false)
3870 arch_srcs += t.sources()
3871 arch_deps += t.dependencies()
3873 target_common = common_ss.apply(config_target, strict: false)
3874 objects = common_all.extract_objects(target_common.sources())
3875 arch_deps += target_common.dependencies()
3877 target_specific = specific_ss.apply(config_target, strict: false)
3878 arch_srcs += target_specific.sources()
3879 arch_deps += target_specific.dependencies()
3881 # allow using headers from the dependencies but do not include the sources,
3882 # because this emulator only needs those in "objects". For external
3883 # dependencies, the full dependency is included below in the executable.
3885 foreach dep : arch_deps
3886 lib_deps += dep.partial_dependency(compile_args: true, includes: true)
3889 lib = static_library('qemu-' + target,
3890 sources: arch_srcs + genh,
3891 dependencies: lib_deps,
3893 include_directories: target_inc,
3895 build_by_default: false,
3898 if target.endswith('-softmmu')
3900 'name': 'qemu-system-' + target_name,
3901 'win_subsystem': 'console',
3902 'sources': files('system/main.c'),
3905 if host_os == 'windows' and (sdl.found() or gtk.found())
3907 'name': 'qemu-system-' + target_name + 'w',
3908 'win_subsystem': 'windows',
3909 'sources': files('system/main.c'),
3913 if get_option('fuzzing')
3914 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3916 'name': 'qemu-fuzz-' + target_name,
3917 'win_subsystem': 'console',
3918 'sources': specific_fuzz.sources(),
3919 'dependencies': specific_fuzz.dependencies(),
3924 'name': 'qemu-' + target_name,
3925 'win_subsystem': 'console',
3931 exe_name = exe['name']
3932 if host_os == 'darwin'
3933 exe_name += '-unsigned'
3936 emulator = executable(exe_name, exe['sources'],
3939 dependencies: arch_deps + exe['dependencies'],
3940 objects: lib.extract_all_objects(recursive: true),
3941 link_depends: [block_syms, qemu_syms],
3942 link_args: link_args,
3943 win_subsystem: exe['win_subsystem'])
3945 if host_os == 'darwin'
3946 icon = 'pc-bios/qemu.rsrc'
3947 build_input = [emulator, files(icon)]
3949 get_option('bindir') / exe_name,
3950 meson.current_source_dir() / icon
3952 if 'CONFIG_HVF' in config_target
3953 entitlements = 'accel/hvf/entitlements.plist'
3954 build_input += files(entitlements)
3955 install_input += meson.current_source_dir() / entitlements
3958 emulators += {exe['name'] : custom_target(exe['name'],
3960 output: exe['name'],
3961 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3964 meson.add_install_script(entitlement, '--install',
3965 get_option('bindir') / exe['name'],
3968 emulators += {exe['name']: emulator}
3973 'probe-prefix': 'qemu.' + target_type + '.' + target_name,
3979 # Other build targets
3981 if get_option('plugins')
3982 install_headers('include/qemu/qemu-plugin.h')
3983 if host_os == 'windows'
3984 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer,
3985 # so that plugin authors can compile against it.
3986 install_data(win32_qemu_plugin_api_lib, install_dir: 'lib')
3992 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3993 # when we don't build tools or system
3994 if xkbcommon.found()
3995 # used for the update-keymaps target, so include rules even if !have_tools
3996 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3997 dependencies: [qemuutil, xkbcommon], install: have_tools)
4001 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
4002 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
4003 qemu_io = executable('qemu-io', files('qemu-io.c'),
4004 dependencies: [block, qemuutil], install: true)
4005 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
4006 dependencies: [blockdev, qemuutil, gnutls, selinux],
4009 subdir('storage-daemon')
4011 foreach exe: [ 'qemu-img', 'qemu-io', 'qemu-nbd', 'qemu-storage-daemon']
4014 'probe-prefix': 'qemu.' + exe.substring(5).replace('-', '_')
4018 subdir('contrib/elf2dmp')
4020 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
4021 dependencies: qemuutil,
4025 subdir('contrib/vhost-user-blk')
4026 subdir('contrib/vhost-user-gpu')
4027 subdir('contrib/vhost-user-input')
4028 subdir('contrib/vhost-user-scsi')
4031 if host_os == 'linux'
4032 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
4033 dependencies: [qemuutil, libcap_ng],
4035 install_dir: get_option('libexecdir'))
4037 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
4038 dependencies: [authz, crypto, io, qom, qemuutil,
4039 libcap_ng, mpathpersist],
4044 subdir('contrib/ivshmem-client')
4045 subdir('contrib/ivshmem-server')
4050 foreach t: traceable
4052 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / t['exe'], 'install': false},
4053 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / t['exe'], 'install': true},
4054 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
4055 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
4058 tracetool, '--group=all', '--format=' + stp['fmt'],
4059 '--binary=' + stp['bin'],
4060 '--probe-prefix=' + t['probe-prefix'],
4061 '@INPUT@', '@OUTPUT@'
4064 custom_target(t['exe'] + stp['ext'],
4065 input: trace_events_all,
4066 output: t['exe'] + stp['ext'],
4067 install: stp['install'],
4068 install_dir: get_option('datadir') / 'systemtap/tapset',
4070 depend_files: tracetool_depends)
4084 if host_machine.system() == 'windows'
4086 find_program('scripts/nsis.py'),
4088 get_option('prefix'),
4089 meson.current_source_dir(),
4090 glib_pc.get_variable('bindir'),
4093 '-DDISPLAYVERSION=' + meson.project_version(),
4096 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
4099 nsis_cmd += '-DCONFIG_GTK=y'
4102 nsis = custom_target('nsis',
4103 output: 'qemu-setup-' + meson.project_version() + '.exe',
4104 input: files('qemu.nsi'),
4105 build_always_stale: true,
4106 command: nsis_cmd + ['@INPUT@'])
4107 alias_target('installer', nsis)
4110 #########################
4111 # Configuration summary #
4112 #########################
4116 summary_info += {'Build directory': meson.current_build_dir()}
4117 summary_info += {'Source path': meson.current_source_dir()}
4118 summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'}
4119 summary(summary_info, bool_yn: true, section: 'Build environment')
4122 summary_info += {'Install prefix': get_option('prefix')}
4123 summary_info += {'BIOS directory': qemu_datadir}
4124 pathsep = host_os == 'windows' ? ';' : ':'
4125 summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))}
4126 summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
4127 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
4128 summary_info += {'module directory': qemu_moddir}
4129 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
4130 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
4131 summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')}
4132 if host_os != 'windows'
4133 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
4134 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')}
4136 summary_info += {'local state directory': 'queried at runtime'}
4138 summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
4139 summary(summary_info, bool_yn: true, section: 'Directories')
4143 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
4144 summary_info += {'sphinx-build': sphinx_build}
4146 # FIXME: the [binaries] section of machine files, which can be probed
4147 # with find_program(), would be great for passing gdb and genisoimage
4148 # paths from configure to Meson. However, there seems to be no way to
4149 # hide a program (for example if gdb is too old).
4150 if config_host.has_key('GDB')
4151 summary_info += {'gdb': config_host['GDB']}
4153 summary_info += {'iasl': iasl}
4154 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
4155 if host_os == 'windows' and have_ga
4156 summary_info += {'wixl': wixl}
4158 if slirp.found() and have_system
4159 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
4161 summary(summary_info, bool_yn: true, section: 'Host binaries')
4163 # Configurable features
4165 summary_info += {'Documentation': build_docs}
4166 summary_info += {'system-mode emulation': have_system}
4167 summary_info += {'user-mode emulation': have_user}
4168 summary_info += {'block layer': have_block}
4169 summary_info += {'Install blobs': get_option('install_blobs')}
4170 summary_info += {'module support': enable_modules}
4172 summary_info += {'alternative module path': get_option('module_upgrades')}
4174 summary_info += {'fuzzing support': get_option('fuzzing')}
4176 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
4178 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
4179 if 'simple' in get_option('trace_backends')
4180 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
4182 summary_info += {'D-Bus display': dbus_display}
4183 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
4184 summary_info += {'Relocatable install': get_option('relocatable')}
4185 summary_info += {'vhost-kernel support': have_vhost_kernel}
4186 summary_info += {'vhost-net support': have_vhost_net}
4187 summary_info += {'vhost-user support': have_vhost_user}
4188 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
4189 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
4190 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
4191 summary_info += {'build guest agent': have_ga}
4192 summary(summary_info, bool_yn: true, section: 'Configurable features')
4194 # Compilation information
4196 summary_info += {'host CPU': cpu}
4197 summary_info += {'host endianness': build_machine.endian()}
4198 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
4199 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
4200 if 'cpp' in all_languages
4201 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
4203 summary_info += {'C++ compiler': false}
4205 if 'objc' in all_languages
4206 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
4208 summary_info += {'Objective-C compiler': false}
4210 option_cflags = (get_option('debug') ? ['-g'] : [])
4211 if get_option('optimization') != 'plain'
4212 option_cflags += ['-O' + get_option('optimization')]
4214 summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)}
4215 if 'cpp' in all_languages
4216 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)}
4218 if 'objc' in all_languages
4219 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)}
4221 link_args = get_option('c_link_args')
4222 if link_args.length() > 0
4223 summary_info += {'LDFLAGS': ' '.join(link_args)}
4225 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)}
4226 if 'cpp' in all_languages
4227 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)}
4229 if 'objc' in all_languages
4230 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)}
4232 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
4233 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
4234 summary_info += {'PIE': get_option('b_pie')}
4235 summary_info += {'static build': get_option('prefer_static')}
4236 summary_info += {'malloc trim support': has_malloc_trim}
4237 summary_info += {'membarrier': have_membarrier}
4238 summary_info += {'debug graph lock': get_option('debug_graph_lock')}
4239 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
4240 summary_info += {'mutex debugging': get_option('debug_mutex')}
4241 summary_info += {'memory allocator': get_option('malloc')}
4242 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
4243 summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')}
4244 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
4245 summary_info += {'gcov': get_option('b_coverage')}
4246 summary_info += {'thread sanitizer': get_option('tsan')}
4247 summary_info += {'CFI support': get_option('cfi')}
4248 if get_option('cfi')
4249 summary_info += {'CFI debug support': get_option('cfi_debug')}
4251 summary_info += {'strip binaries': get_option('strip')}
4252 summary_info += {'sparse': sparse}
4253 summary_info += {'mingw32 support': host_os == 'windows'}
4254 summary(summary_info, bool_yn: true, section: 'Compilation')
4256 # snarf the cross-compilation information for tests
4259 foreach target: target_dirs
4260 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak'
4261 if fs.exists(tcg_mak)
4262 config_cross_tcg = keyval.load(tcg_mak)
4263 if 'CC' in config_cross_tcg
4264 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']}
4270 summary(summary_info, bool_yn: true, section: 'Cross compilers')
4273 # Targets and accelerators
4276 summary_info += {'KVM support': config_all_accel.has_key('CONFIG_KVM')}
4277 summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')}
4278 summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')}
4279 summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')}
4280 summary_info += {'Xen support': xen.found()}
4282 summary_info += {'xen ctrl version': xen.version()}
4284 summary_info += {'Xen emulation': config_all_devices.has_key('CONFIG_XEN_EMU')}
4286 summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')}
4287 if config_all_accel.has_key('CONFIG_TCG')
4288 if get_option('tcg_interpreter')
4289 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
4291 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
4293 summary_info += {'TCG plugins': get_option('plugins')}
4294 summary_info += {'TCG debug enabled': get_option('debug_tcg')}
4295 if have_linux_user or have_bsd_user
4296 summary_info += {'syscall buffer debugging support': get_option('debug_remap')}
4299 summary_info += {'target list': ' '.join(target_dirs)}
4301 summary_info += {'default devices': get_option('default_devices')}
4302 summary_info += {'out of process emulation': multiprocess_allowed}
4303 summary_info += {'vfio-user server': vfio_user_server_allowed}
4305 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
4309 summary_info += {'coroutine backend': coroutine_backend}
4310 summary_info += {'coroutine pool': have_coroutine_pool}
4312 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
4313 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
4314 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
4315 summary_info += {'VirtFS (9P) support': have_virtfs}
4316 summary_info += {'VirtFS (9P) Proxy Helper support (deprecated)': have_virtfs_proxy_helper}
4317 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
4318 summary_info += {'bochs support': get_option('bochs').allowed()}
4319 summary_info += {'cloop support': get_option('cloop').allowed()}
4320 summary_info += {'dmg support': get_option('dmg').allowed()}
4321 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
4322 summary_info += {'vdi support': get_option('vdi').allowed()}
4323 summary_info += {'vhdx support': get_option('vhdx').allowed()}
4324 summary_info += {'vmdk support': get_option('vmdk').allowed()}
4325 summary_info += {'vpc support': get_option('vpc').allowed()}
4326 summary_info += {'vvfat support': get_option('vvfat').allowed()}
4327 summary_info += {'qed support': get_option('qed').allowed()}
4328 summary_info += {'parallels support': get_option('parallels').allowed()}
4329 summary_info += {'FUSE exports': fuse}
4330 summary_info += {'VDUSE block exports': have_vduse_blk_export}
4332 summary(summary_info, bool_yn: true, section: 'Block layer support')
4336 summary_info += {'TLS priority': get_option('tls_priority')}
4337 summary_info += {'GNUTLS support': gnutls}
4339 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
4341 summary_info += {'libgcrypt': gcrypt}
4342 summary_info += {'nettle': nettle}
4344 summary_info += {' XTS': xts != 'private'}
4346 summary_info += {'SM4 ALG support': crypto_sm4}
4347 summary_info += {'AF_ALG support': have_afalg}
4348 summary_info += {'rng-none': get_option('rng_none')}
4349 summary_info += {'Linux keyring': have_keyring}
4350 summary_info += {'Linux keyutils': keyutils}
4351 summary(summary_info, bool_yn: true, section: 'Crypto')
4355 if host_os == 'darwin'
4356 summary_info += {'Cocoa support': cocoa}
4358 summary_info += {'SDL support': sdl}
4359 summary_info += {'SDL image support': sdl_image}
4360 summary_info += {'GTK support': gtk}
4361 summary_info += {'pixman': pixman}
4362 summary_info += {'VTE support': vte}
4363 summary_info += {'PNG support': png}
4364 summary_info += {'VNC support': vnc}
4366 summary_info += {'VNC SASL support': sasl}
4367 summary_info += {'VNC JPEG support': jpeg}
4369 summary_info += {'spice protocol support': spice_protocol}
4370 if spice_protocol.found()
4371 summary_info += {' spice server support': spice}
4373 summary_info += {'curses support': curses}
4374 summary_info += {'brlapi support': brlapi}
4375 summary(summary_info, bool_yn: true, section: 'User interface')
4379 summary_info += {'VirGL support': virgl}
4380 summary_info += {'Rutabaga support': rutabaga}
4381 summary(summary_info, bool_yn: true, section: 'Graphics backends')
4385 if host_os not in ['darwin', 'haiku', 'windows']
4386 summary_info += {'OSS support': oss}
4387 summary_info += {'sndio support': sndio}
4388 elif host_os == 'darwin'
4389 summary_info += {'CoreAudio support': coreaudio}
4390 elif host_os == 'windows'
4391 summary_info += {'DirectSound support': dsound}
4393 if host_os == 'linux'
4394 summary_info += {'ALSA support': alsa}
4395 summary_info += {'PulseAudio support': pulse}
4397 summary_info += {'PipeWire support': pipewire}
4398 summary_info += {'JACK support': jack}
4399 summary(summary_info, bool_yn: true, section: 'Audio backends')
4403 if host_os == 'darwin'
4404 summary_info += {'vmnet.framework support': vmnet}
4406 summary_info += {'AF_XDP support': libxdp}
4407 summary_info += {'slirp support': slirp}
4408 summary_info += {'vde support': vde}
4409 summary_info += {'netmap support': have_netmap}
4410 summary_info += {'l2tpv3 support': have_l2tpv3}
4411 summary(summary_info, bool_yn: true, section: 'Network backends')
4415 summary_info += {'libtasn1': tasn1}
4416 summary_info += {'PAM': pam}
4417 summary_info += {'iconv support': iconv}
4418 summary_info += {'blkio support': blkio}
4419 summary_info += {'curl support': curl}
4420 summary_info += {'Multipath support': mpathpersist}
4421 summary_info += {'Linux AIO support': libaio}
4422 summary_info += {'Linux io_uring support': linux_io_uring}
4423 summary_info += {'ATTR/XATTR support': libattr}
4424 summary_info += {'RDMA support': rdma}
4425 summary_info += {'fdt support': fdt_opt == 'internal' ? 'internal' : fdt}
4426 summary_info += {'libcap-ng support': libcap_ng}
4427 summary_info += {'bpf support': libbpf}
4428 summary_info += {'rbd support': rbd}
4429 summary_info += {'smartcard support': cacard}
4430 summary_info += {'U2F support': u2f}
4431 summary_info += {'libusb': libusb}
4432 summary_info += {'usb net redir': usbredir}
4433 summary_info += {'OpenGL support (epoxy)': opengl}
4434 summary_info += {'GBM': gbm}
4435 summary_info += {'libiscsi support': libiscsi}
4436 summary_info += {'libnfs support': libnfs}
4437 if host_os == 'windows'
4439 summary_info += {'QGA VSS support': have_qga_vss}
4442 summary_info += {'seccomp support': seccomp}
4443 summary_info += {'GlusterFS support': glusterfs}
4444 summary_info += {'hv-balloon support': hv_balloon}
4445 summary_info += {'TPM support': have_tpm}
4446 summary_info += {'libssh support': libssh}
4447 summary_info += {'lzo support': lzo}
4448 summary_info += {'snappy support': snappy}
4449 summary_info += {'bzip2 support': libbzip2}
4450 summary_info += {'lzfse support': liblzfse}
4451 summary_info += {'zstd support': zstd}
4452 summary_info += {'NUMA host support': numa}
4453 summary_info += {'capstone': capstone}
4454 summary_info += {'libpmem support': libpmem}
4455 summary_info += {'libdaxctl support': libdaxctl}
4456 summary_info += {'libudev': libudev}
4457 # Dummy dependency, keep .found()
4458 summary_info += {'FUSE lseek': fuse_lseek.found()}
4459 summary_info += {'selinux': selinux}
4460 summary_info += {'libdw': libdw}
4461 if host_os == 'freebsd'
4462 summary_info += {'libinotify-kqueue': inotify}
4464 summary(summary_info, bool_yn: true, section: 'Dependencies')
4466 if host_arch == 'unknown'
4468 warning('UNSUPPORTED HOST CPU')
4470 message('Support for CPU host architecture ' + cpu + ' is not currently')
4471 message('maintained. The QEMU project does not guarantee that QEMU will')
4472 message('compile or work on this host CPU. You can help by volunteering')
4473 message('to maintain it and providing a build host for our continuous')
4474 message('integration setup.')
4475 if get_option('tcg').allowed() and target_dirs.length() > 0
4477 message('configure has succeeded and you can continue to build, but')
4478 message('QEMU will use a slow interpreter to emulate the target CPU.')
4482 if not supported_oses.contains(host_os)
4484 warning('UNSUPPORTED HOST OS')
4486 message('Support for host OS ' + host_os + 'is not currently maintained.')
4487 message('configure has succeeded and you can continue to build, but')
4488 message('the QEMU project does not guarantee that QEMU will compile or')
4489 message('work on this operating system. You can help by volunteering')
4490 message('to maintain it and providing a build host for our continuous')
4491 message('integration setup. This will ensure that future versions of QEMU')
4492 message('will keep working on ' + host_os + '.')
4495 if host_arch == 'unknown' or not supported_oses.contains(host_os)
4497 message('If you want to help supporting QEMU on this platform, please')
4498 message('contact the developers at qemu-devel@nongnu.org.')
4501 actually_reloc = get_option('relocatable')
4502 # check if get_relocated_path() is actually able to relocate paths
4503 if get_option('relocatable') and \
4504 not (get_option('prefix') / get_option('bindir')).startswith(get_option('prefix') / '')
4506 warning('bindir not included within prefix, the installation will not be relocatable.')
4507 actually_reloc = false
4509 if not actually_reloc and (host_os == 'windows' or get_option('relocatable'))
4510 if host_os == 'windows'
4512 warning('Windows installs should usually be relocatable.')
4515 message('QEMU will have to be installed under ' + get_option('prefix') + '.')
4516 message('Use --disable-relocatable to remove this warning.')