1 project('qemu', ['c'], meson_version: '>=0.63.0',
2 default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
3 'b_staticpic=false', 'stdsplit=false', 'optimization=2', 'b_pie=true'],
4 version: files('VERSION'))
6 add_test_setup('quick', exclude_suites: ['slow', 'thorough'], is_default: true)
7 add_test_setup('slow', exclude_suites: ['thorough'], env: ['G_TEST_SLOW=1', 'SPEED=slow'])
8 add_test_setup('thorough', env: ['G_TEST_SLOW=1', 'SPEED=thorough'])
10 meson.add_postconf_script(find_program('scripts/symlink-install-tree.py'))
16 not_found = dependency('', required: false)
17 keyval = import('keyval')
18 ss = import('sourceset')
21 host_os = host_machine.system()
22 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
24 # Temporary directory used for files created while
25 # configure runs. Since it is in the build directory
26 # we can safely blow away any previous version of it
27 # (and we need not jump through hoops to try to delete
28 # it when configure exits.)
29 tmpdir = meson.current_build_dir() / 'meson-private/temp'
31 if get_option('qemu_suffix').startswith('/')
32 error('qemu_suffix cannot start with a /')
35 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
36 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
37 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
38 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
40 qemu_desktopdir = get_option('datadir') / 'applications'
41 qemu_icondir = get_option('datadir') / 'icons'
44 qapi_trace_events = []
46 bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
47 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
48 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
49 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64']
51 cpu = host_machine.cpu_family()
53 target_dirs = config_host['TARGET_DIRS'].split()
59 sh = find_program('sh')
60 python = import('python').find_installation()
62 cc = meson.get_compiler('c')
64 if host_os == 'windows' and add_languages('cpp', required: false, native: false)
65 all_languages += ['cpp']
66 cxx = meson.get_compiler('cpp')
68 if host_os == 'darwin' and \
69 add_languages('objc', required: get_option('cocoa'), native: false)
70 all_languages += ['objc']
71 objc = meson.get_compiler('objc')
76 if 'dtrace' in get_option('trace_backends')
77 dtrace = find_program('dtrace', required: true)
78 stap = find_program('stap', required: false)
80 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
81 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
82 # instead. QEMU --enable-modules depends on this because the SystemTap
83 # semaphores are linked into the main binary and not the module's shared
85 add_global_arguments('-DSTAP_SDT_V2',
86 native: false, language: all_languages)
90 if get_option('iasl') == ''
91 iasl = find_program('iasl', required: false)
93 iasl = find_program(get_option('iasl'), required: true)
96 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
97 unpack_edk2_blobs = false
98 foreach target : edk2_targets
99 if target in target_dirs
100 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
101 unpack_edk2_blobs = bzip2.found()
106 #####################
107 # Option validation #
108 #####################
111 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
114 #include <sys/types.h>
115 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
116 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
118 args: ['-Werror', '-fsanitize=fuzzer'])
119 error('Your compiler does not support -fsanitize=fuzzer')
123 if 'ftrace' in get_option('trace_backends') and host_os != 'linux'
124 error('ftrace is supported only on Linux')
126 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
129 openlog("qemu", LOG_PID, LOG_DAEMON);
130 syslog(LOG_INFO, "configure");
133 error('syslog is not supported on this system')
136 # Miscellaneous Linux-only features
137 get_option('mpath') \
138 .require(host_os == 'linux', error_message: 'Multipath is supported only on Linux')
140 multiprocess_allowed = get_option('multiprocess') \
141 .require(host_os == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
144 vfio_user_server_allowed = get_option('vfio_user_server') \
145 .require(host_os == 'linux', error_message: 'vfio-user server is supported only on Linux') \
148 have_tpm = get_option('tpm') \
149 .require(host_os != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
153 have_vhost_user = get_option('vhost_user') \
154 .disable_auto_if(host_os != 'linux') \
155 .require(host_os != 'windows',
156 error_message: 'vhost-user is not available on Windows').allowed()
157 have_vhost_vdpa = get_option('vhost_vdpa') \
158 .require(host_os == 'linux',
159 error_message: 'vhost-vdpa is only available on Linux').allowed()
160 have_vhost_kernel = get_option('vhost_kernel') \
161 .require(host_os == 'linux',
162 error_message: 'vhost-kernel is only available on Linux').allowed()
163 have_vhost_user_crypto = get_option('vhost_crypto') \
164 .require(have_vhost_user,
165 error_message: 'vhost-crypto requires vhost-user to be enabled').allowed()
167 have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel
169 have_vhost_net_user = have_vhost_user and get_option('vhost_net').allowed()
170 have_vhost_net_vdpa = have_vhost_vdpa and get_option('vhost_net').allowed()
171 have_vhost_net_kernel = have_vhost_kernel and get_option('vhost_net').allowed()
172 have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_vdpa
174 # type of binaries to build
175 have_linux_user = false
176 have_bsd_user = false
178 foreach target : target_dirs
179 have_linux_user = have_linux_user or target.endswith('linux-user')
180 have_bsd_user = have_bsd_user or target.endswith('bsd-user')
181 have_system = have_system or target.endswith('-softmmu')
183 have_user = have_linux_user or have_bsd_user
185 have_tools = get_option('tools') \
186 .disable_auto_if(not have_system) \
188 have_ga = get_option('guest_agent') \
189 .disable_auto_if(not have_system and not have_tools) \
190 .require(host_os in ['sunos', 'linux', 'windows', 'freebsd', 'netbsd', 'openbsd'],
191 error_message: 'unsupported OS for QEMU guest agent') \
193 have_block = have_system or have_tools
195 enable_modules = get_option('modules') \
196 .require(host_os != 'windows',
197 error_message: 'Modules are not available for Windows') \
198 .require(not get_option('prefer_static'),
199 error_message: 'Modules are incompatible with static linking') \
202 #######################################
203 # Variables for host and accelerators #
204 #######################################
206 if cpu not in supported_cpus
207 host_arch = 'unknown'
212 elif cpu in ['riscv32', 'riscv64']
218 if cpu in ['x86', 'x86_64']
219 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
220 elif cpu == 'aarch64'
221 kvm_targets = ['aarch64-softmmu']
223 kvm_targets = ['s390x-softmmu']
224 elif cpu in ['ppc', 'ppc64']
225 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
226 elif cpu in ['mips', 'mips64']
227 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
228 elif cpu in ['riscv32']
229 kvm_targets = ['riscv32-softmmu']
230 elif cpu in ['riscv64']
231 kvm_targets = ['riscv64-softmmu']
232 elif cpu in ['loongarch64']
233 kvm_targets = ['loongarch64-softmmu']
237 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
239 if cpu in ['x86', 'x86_64']
240 xen_targets = ['i386-softmmu', 'x86_64-softmmu']
241 elif cpu in ['arm', 'aarch64']
242 # i386 emulator provides xenpv machine type for multiple architectures
243 xen_targets = ['i386-softmmu', 'x86_64-softmmu', 'aarch64-softmmu']
247 accelerator_targets += { 'CONFIG_XEN': xen_targets }
249 if cpu in ['aarch64']
250 accelerator_targets += {
251 'CONFIG_HVF': ['aarch64-softmmu']
255 if cpu in ['x86', 'x86_64']
256 accelerator_targets += {
257 'CONFIG_HVF': ['x86_64-softmmu'],
258 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
259 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
264 # Darwin does not support references to thread-local variables in modules
265 if host_os != 'darwin'
266 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
273 foreach lang : all_languages
274 compiler = meson.get_compiler(lang)
275 if compiler.get_id() == 'gcc' and compiler.version().version_compare('>=7.4')
277 elif compiler.get_id() == 'clang' and compiler.compiles('''
278 #ifdef __apple_build_version__
279 # if __clang_major__ < 12 || (__clang_major__ == 12 && __clang_minor__ < 0)
280 # error You need at least XCode Clang v12.0 to compile QEMU
283 # if __clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 0)
284 # error You need at least Clang v10.0 to compile QEMU
289 error('You either need GCC v7.4 or Clang v10.0 (or XCode Clang v12.0) to compile QEMU')
293 # default flags for all hosts
294 # We use -fwrapv to tell the compiler that we require a C dialect where
295 # left shift of signed integers is well defined and has the expected
296 # 2s-complement style results. (Both clang and gcc agree that it
297 # provides these semantics.)
299 qemu_common_flags = [
300 '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE',
301 '-fno-strict-aliasing', '-fno-common', '-fwrapv' ]
305 if host_os == 'darwin'
306 # Disable attempts to use ObjectiveC features in os/object.h since they
307 # won't work when we're compiling with gcc as a C compiler.
308 if compiler.get_id() == 'gcc'
309 qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
311 elif host_os == 'sunos'
312 # needed for CMSG_ macros in sys/socket.h
313 qemu_common_flags += '-D_XOPEN_SOURCE=600'
314 # needed for TIOCWIN* defines in termios.h
315 qemu_common_flags += '-D__EXTENSIONS__'
316 elif host_os == 'haiku'
317 qemu_common_flags += ['-DB_USE_POSITIVE_POSIX_ERRORS', '-D_BSD_SOURCE', '-fPIC']
320 # __sync_fetch_and_and requires at least -march=i486. Many toolchains
321 # use i686 as default anyway, but for those that don't, an explicit
322 # specification is necessary
323 if host_arch == 'i386' and not cc.links('''
324 static int sfaa(int *ptr)
326 return __sync_fetch_and_and(ptr, 0);
332 val = __sync_val_compare_and_swap(&val, 0, 1);
336 qemu_common_flags = ['-march=i486'] + qemu_common_flags
339 if get_option('prefer_static')
340 qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
343 # Meson currently only handles pie as a boolean for now, so if the user
344 # has explicitly disabled PIE we need to extend our cflags.
346 # -no-pie is supposedly a linker flag that has no effect on the compiler
347 # command line, but some distros, that didn't quite know what they were
348 # doing, made local changes to gcc's specs file that turned it into
349 # a compiler command-line flag.
351 # What about linker flags? For a static build, no PIE is implied by -static
352 # which we added above (and if it's not because of the same specs patching,
353 # there's nothing we can do: compilation will fail, report a bug to your
354 # distro and do not use --disable-pie in the meanwhile). For dynamic linking,
355 # instead, we can't add -no-pie because it overrides -shared: the linker then
356 # tries to build an executable instead of a shared library and fails. So
357 # don't add -no-pie anywhere and cross fingers. :(
358 if not get_option('b_pie')
359 qemu_common_flags += cc.get_supported_arguments('-fno-pie', '-no-pie')
362 if not get_option('stack_protector').disabled()
363 stack_protector_probe = '''
364 int main(int argc, char *argv[])
366 char arr[64], *p = arr, *c = argv[argc - 1];
372 have_stack_protector = false
373 foreach arg : ['-fstack-protector-strong', '-fstack-protector-all']
374 # We need to check both a compile and a link, since some compiler
375 # setups fail only on a .c->.o compile and some only at link time
376 if cc.compiles(stack_protector_probe, args: ['-Werror', arg]) and \
377 cc.links(stack_protector_probe, args: ['-Werror', arg])
378 have_stack_protector = true
384 get_option('stack_protector') \
385 .require(have_stack_protector, error_message: 'Stack protector not supported')
388 coroutine_backend = get_option('coroutine_backend')
390 #include <ucontext.h>
391 #ifdef __stub_makecontext
392 #error Ignoring glibc stub makecontext which will always fail
394 int main(void) { makecontext(0, 0, 0); return 0; }'''
396 # On Windows the only valid backend is the Windows specific one.
397 # For POSIX prefer ucontext, but it's not always possible. The fallback
399 supported_backends = []
400 if host_os == 'windows'
401 supported_backends += ['windows']
403 if host_os != 'darwin' and cc.links(ucontext_probe)
404 supported_backends += ['ucontext']
406 supported_backends += ['sigaltstack']
409 if coroutine_backend == 'auto'
410 coroutine_backend = supported_backends[0]
411 elif coroutine_backend not in supported_backends
412 error('"@0@" backend requested but not available. Available backends: @1@' \
413 .format(coroutine_backend, ', '.join(supported_backends)))
416 # Compiles if SafeStack *not* enabled
417 safe_stack_probe = '''
420 #if defined(__has_feature)
421 #if __has_feature(safe_stack)
422 #error SafeStack Enabled
427 if get_option('safe_stack') != not cc.compiles(safe_stack_probe)
428 safe_stack_arg = get_option('safe_stack') ? '-fsanitize=safe-stack' : '-fno-sanitize=safe-stack'
429 if get_option('safe_stack') != not cc.compiles(safe_stack_probe, args: safe_stack_arg)
430 error(get_option('safe_stack') \
431 ? 'SafeStack not supported by your compiler' \
432 : 'Cannot disable SafeStack')
434 qemu_cflags += safe_stack_arg
435 qemu_ldflags += safe_stack_arg
437 if get_option('safe_stack') and coroutine_backend != 'ucontext'
438 error('SafeStack is only supported with the ucontext coroutine backend')
441 if get_option('sanitizers')
442 if cc.has_argument('-fsanitize=address')
443 qemu_cflags = ['-fsanitize=address'] + qemu_cflags
444 qemu_ldflags = ['-fsanitize=address'] + qemu_ldflags
447 # Detect static linking issue with ubsan - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84285
448 if cc.links('int main(int argc, char **argv) { return argc + 1; }',
449 args: [qemu_ldflags, '-fsanitize=undefined'])
450 qemu_cflags = ['-fsanitize=undefined'] + qemu_cflags
451 qemu_ldflags = ['-fsanitize=undefined'] + qemu_ldflags
455 # Thread sanitizer is, for now, much noisier than the other sanitizers;
456 # keep it separate until that is not the case.
457 if get_option('tsan')
458 if get_option('sanitizers')
459 error('TSAN is not supported with other sanitizers')
461 if not cc.has_function('__tsan_create_fiber',
462 args: '-fsanitize=thread',
463 prefix: '#include <sanitizer/tsan_interface.h>')
464 error('Cannot enable TSAN due to missing fiber annotation interface')
466 qemu_cflags = ['-fsanitize=thread'] + qemu_cflags
467 qemu_ldflags = ['-fsanitize=thread'] + qemu_ldflags
470 # Detect support for PT_GNU_RELRO + DT_BIND_NOW.
471 # The combination is known as "full relro", because .got.plt is read-only too.
472 qemu_ldflags += cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now')
474 if host_os == 'windows'
475 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat')
476 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase', '-Wl,--high-entropy-va')
479 if get_option('fuzzing')
480 # Specify a filter to only instrument code that is directly related to
482 configure_file(output: 'instrumentation-filter',
483 input: 'scripts/oss-fuzz/instrumentation-filter-template',
486 if cc.compiles('int main () { return 0; }',
487 name: '-fsanitize-coverage-allowlist=/dev/null',
488 args: ['-fsanitize-coverage-allowlist=/dev/null',
489 '-fsanitize-coverage=trace-pc'] )
490 qemu_common_flags += ['-fsanitize-coverage-allowlist=instrumentation-filter']
493 if get_option('fuzzing_engine') == ''
494 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
495 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
496 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
497 # unable to bind the fuzzer-related callbacks added by instrumentation.
498 qemu_common_flags += ['-fsanitize=fuzzer-no-link']
499 qemu_ldflags += ['-fsanitize=fuzzer-no-link']
500 # For the actual fuzzer binaries, we need to link against the libfuzzer
501 # library. They need to be configurable, to support OSS-Fuzz
502 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
504 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
505 # the needed CFLAGS have already been provided
506 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
512 # Check for dependency on LTO
513 if not get_option('b_lto')
514 error('Selected Control-Flow Integrity but LTO is disabled')
517 error('Selected Control-Flow Integrity is not compatible with modules')
519 # Check for cfi flags. CFI requires LTO so we can't use
520 # get_supported_arguments, but need a more complex "compiles" which allows
522 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
523 args: ['-flto', '-fsanitize=cfi-icall'] )
524 cfi_flags += '-fsanitize=cfi-icall'
526 error('-fsanitize=cfi-icall is not supported by the compiler')
528 if cc.compiles('int main () { return 0; }',
529 name: '-fsanitize-cfi-icall-generalize-pointers',
530 args: ['-flto', '-fsanitize=cfi-icall',
531 '-fsanitize-cfi-icall-generalize-pointers'] )
532 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
534 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
536 if get_option('cfi_debug')
537 if cc.compiles('int main () { return 0; }',
538 name: '-fno-sanitize-trap=cfi-icall',
539 args: ['-flto', '-fsanitize=cfi-icall',
540 '-fno-sanitize-trap=cfi-icall'] )
541 cfi_flags += '-fno-sanitize-trap=cfi-icall'
543 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
546 add_global_arguments(cfi_flags, native: false, language: all_languages)
547 add_global_link_arguments(cfi_flags, native: false, language: all_languages)
550 # Check further flags that make QEMU more robust against malicious parties
553 # Initialize all stack variables to zero. This makes
554 # it harder to take advantage of uninitialized stack
555 # data to drive exploits
556 '-ftrivial-auto-var-init=zero',
559 # Zero out registers used during a function call
560 # upon its return. This makes it harder to assemble
561 # ROP gadgets into something usable
563 # NB: Clang 17 is broken and SEGVs
564 # https://github.com/llvm/llvm-project/issues/75168
565 if cc.compiles('extern struct { void (*cb)(void); } s; void f(void) { s.cb(); }',
566 name: '-fzero-call-used-regs=used-gpr',
567 args: ['-O2', '-fzero-call-used-regs=used-gpr'])
568 hardening_flags += '-fzero-call-used-regs=used-gpr'
571 qemu_common_flags += cc.get_supported_arguments(hardening_flags)
573 add_global_arguments(qemu_common_flags, native: false, language: all_languages)
574 add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
576 # Collect warning flags we want to set, sorted alphabetically
578 # First enable interesting warnings
581 '-Wexpansion-to-defined',
584 '-Wignored-qualifiers',
585 '-Wimplicit-fallthrough=2',
587 '-Wmissing-format-attribute',
588 '-Wmissing-prototypes',
590 '-Wold-style-declaration',
591 '-Wold-style-definition',
594 '-Wstrict-prototypes',
600 # Then disable some undesirable warnings
601 '-Wno-gnu-variable-sized-type-not-at-end',
602 '-Wno-initializer-overrides',
603 '-Wno-missing-include-dirs',
605 '-Wno-shift-negative-value',
606 '-Wno-string-plus-int',
607 '-Wno-tautological-type-limit-compare',
608 '-Wno-typedef-redefinition',
611 if host_os != 'darwin'
612 warn_flags += ['-Wthread-safety']
615 # Set up C++ compiler flags
617 if 'cpp' in all_languages
618 qemu_cxxflags = ['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'] + qemu_cflags
621 add_project_arguments(qemu_cflags, native: false, language: 'c')
622 add_project_arguments(cc.get_supported_arguments(warn_flags), native: false, language: 'c')
623 if 'cpp' in all_languages
624 add_project_arguments(qemu_cxxflags, native: false, language: 'cpp')
625 add_project_arguments(cxx.get_supported_arguments(warn_flags), native: false, language: 'cpp')
627 if 'objc' in all_languages
628 # Note sanitizer flags are not applied to Objective-C sources!
629 add_project_arguments(objc.get_supported_arguments(warn_flags), native: false, language: 'objc')
631 if host_os == 'linux'
632 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
633 '-isystem', 'linux-headers',
634 language: all_languages)
637 add_project_arguments('-iquote', '.',
638 '-iquote', meson.current_source_dir(),
639 '-iquote', meson.current_source_dir() / 'include',
640 language: all_languages)
642 # If a host-specific include directory exists, list that first...
643 host_include = meson.current_source_dir() / 'host/include/'
644 if fs.is_dir(host_include / host_arch)
645 add_project_arguments('-iquote', host_include / host_arch,
646 language: all_languages)
648 # ... followed by the generic fallback.
649 add_project_arguments('-iquote', host_include / 'generic',
650 language: all_languages)
652 sparse = find_program('cgcc', required: get_option('sparse'))
655 command: [find_program('scripts/check_sparse.py'),
656 'compile_commands.json', sparse.full_path(), '-Wbitwise',
657 '-Wno-transparent-union', '-Wno-old-initializer',
658 '-Wno-non-pointer-null'])
661 #####################################
662 # Host-specific libraries and flags #
663 #####################################
665 libm = cc.find_library('m', required: false)
666 threads = dependency('threads')
667 util = cc.find_library('util', required: false)
673 emulator_link_args = []
678 if host_os == 'windows'
679 midl = find_program('midl', required: false)
680 widl = find_program('widl', required: false)
681 pathcch = cc.find_library('pathcch')
682 socket = cc.find_library('ws2_32')
683 winmm = cc.find_library('winmm')
685 win = import('windows')
686 version_res = win.compile_resources('version.rc',
687 depend_files: files('pc-bios/qemu-nsis.ico'),
688 include_directories: include_directories('.'))
690 elif host_os == 'darwin'
691 coref = dependency('appleframeworks', modules: 'CoreFoundation')
692 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
693 host_dsosuf = '.dylib'
694 elif host_os == 'sunos'
695 socket = [cc.find_library('socket'),
696 cc.find_library('nsl'),
697 cc.find_library('resolv')]
698 elif host_os == 'haiku'
699 socket = [cc.find_library('posix_error_mapper'),
700 cc.find_library('network'),
701 cc.find_library('bsd')]
702 elif host_os == 'openbsd'
703 if get_option('tcg').allowed() and target_dirs.length() > 0
704 # Disable OpenBSD W^X if available
705 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
709 ###############################################
710 # Host-specific configuration of accelerators #
711 ###############################################
714 if get_option('kvm').allowed() and host_os == 'linux'
715 accelerators += 'CONFIG_KVM'
717 if get_option('whpx').allowed() and host_os == 'windows'
718 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
719 error('WHPX requires 64-bit host')
720 elif cc.has_header('winhvplatform.h', required: get_option('whpx')) and \
721 cc.has_header('winhvemulation.h', required: get_option('whpx'))
722 accelerators += 'CONFIG_WHPX'
727 if get_option('hvf').allowed()
728 hvf = dependency('appleframeworks', modules: 'Hypervisor',
729 required: get_option('hvf'))
731 accelerators += 'CONFIG_HVF'
736 if host_os == 'netbsd'
737 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
739 accelerators += 'CONFIG_NVMM'
744 if get_option('tcg').allowed()
745 if host_arch == 'unknown'
746 if not get_option('tcg_interpreter')
747 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
749 elif get_option('tcg_interpreter')
750 warning('Use of the TCG interpreter is not recommended on this host')
751 warning('architecture. There is a native TCG execution backend available')
752 warning('which provides substantially better performance and reliability.')
753 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
754 warning('configuration option on this architecture to use the native')
757 if get_option('tcg_interpreter')
759 elif host_arch == 'x86_64'
761 elif host_arch == 'ppc64'
764 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
765 language: all_languages)
767 accelerators += 'CONFIG_TCG'
770 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
771 error('KVM not available on this platform')
773 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
774 error('HVF not available on this platform')
776 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
777 error('NVMM not available on this platform')
779 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
780 error('WHPX not available on this platform')
784 if get_option('xen').enabled() or (get_option('xen').auto() and have_system)
785 xencontrol = dependency('xencontrol', required: false,
786 method: 'pkg-config')
787 if xencontrol.found()
788 xen_pc = declare_dependency(version: xencontrol.version(),
791 # disabler: true makes xen_pc.found() return false if any is not found
792 dependency('xenstore', required: false,
793 method: 'pkg-config',
795 dependency('xenforeignmemory', required: false,
796 method: 'pkg-config',
798 dependency('xengnttab', required: false,
799 method: 'pkg-config',
801 dependency('xenevtchn', required: false,
802 method: 'pkg-config',
804 dependency('xendevicemodel', required: false,
805 method: 'pkg-config',
807 # optional, no "disabler: true"
808 dependency('xentoolcore', required: false,
809 method: 'pkg-config')])
815 xen_tests = [ '4.11.0', '4.10.0', '4.9.0', '4.8.0', '4.7.1' ]
817 '4.11.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
818 '4.10.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
819 '4.9.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
820 '4.8.0': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
821 '4.7.1': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
824 foreach ver: xen_tests
825 # cache the various library tests to avoid polluting the logs
827 foreach l: xen_libs[ver]
829 xen_deps += { l: cc.find_library(l, required: false) }
831 xen_test_deps += xen_deps[l]
834 # Use -D to pick just one of the test programs in scripts/xen-detect.c
835 xen_version = ver.split('.')
836 xen_ctrl_version = xen_version[0] + \
837 ('0' + xen_version[1]).substring(-2) + \
838 ('0' + xen_version[2]).substring(-2)
839 if cc.links(files('scripts/xen-detect.c'),
840 args: '-DCONFIG_XEN_CTRL_INTERFACE_VERSION=' + xen_ctrl_version,
841 dependencies: xen_test_deps)
842 xen = declare_dependency(version: ver, dependencies: xen_test_deps)
848 accelerators += 'CONFIG_XEN'
849 elif get_option('xen').enabled()
850 error('could not compile and link Xen test program')
853 have_xen_pci_passthrough = get_option('xen_pci_passthrough') \
854 .require(xen.found(),
855 error_message: 'Xen PCI passthrough requested but Xen not enabled') \
856 .require(host_os == 'linux',
857 error_message: 'Xen PCI passthrough not available on this platform') \
858 .require(cpu == 'x86' or cpu == 'x86_64',
859 error_message: 'Xen PCI passthrough not available on this platform') \
866 # When bumping glib minimum version, please check also whether to increase
867 # the _WIN32_WINNT setting in osdep.h according to the value from glib
868 glib_req_ver = '>=2.56.0'
869 glib_pc = dependency('glib-2.0', version: glib_req_ver, required: true,
870 method: 'pkg-config')
873 gmodule = dependency('gmodule-export-2.0', version: glib_req_ver, required: true,
874 method: 'pkg-config')
875 elif get_option('plugins')
876 gmodule = dependency('gmodule-no-export-2.0', version: glib_req_ver, required: true,
877 method: 'pkg-config')
882 # This workaround is required due to a bug in pkg-config file for glib as it
883 # doesn't define GLIB_STATIC_COMPILATION for pkg-config --static
884 if host_os == 'windows' and get_option('prefer_static')
885 glib_cflags += ['-DGLIB_STATIC_COMPILATION']
888 # Sanity check that the current size_t matches the
889 # size that glib thinks it should be. This catches
890 # problems on multi-arch where people try to build
891 # 32-bit QEMU while pointing at 64-bit glib headers
893 if not cc.compiles('''
897 #define QEMU_BUILD_BUG_ON(x) \
898 typedef char qemu_build_bug_on[(x)?-1:1] __attribute__((unused));
901 QEMU_BUILD_BUG_ON(sizeof(size_t) != GLIB_SIZEOF_SIZE_T);
903 }''', dependencies: glib_pc, args: glib_cflags)
904 error('''sizeof(size_t) doesn't match GLIB_SIZEOF_SIZE_T.
905 You probably need to set PKG_CONFIG_LIBDIR" to point
906 to the right pkg-config files for your build target.''')
909 # Silence clang warnings triggered by glib < 2.57.2
910 if not cc.compiles('''
915 static void foo_free(Foo *f)
919 G_DEFINE_AUTOPTR_CLEANUP_FUNC(Foo, foo_free)
920 int main(void) { return 0; }''', dependencies: glib_pc, args: ['-Wunused-function', '-Werror'])
921 glib_cflags += cc.get_supported_arguments('-Wno-unused-function')
923 glib = declare_dependency(dependencies: [glib_pc, gmodule],
924 compile_args: glib_cflags,
925 version: glib_pc.version())
927 # Check whether glib has gslice, which we have to avoid for correctness.
928 # TODO: remove this check and the corresponding workaround (qtree) when
929 # the minimum supported glib is >= 2.75.3
930 glib_has_gslice = glib.version().version_compare('<2.75.3')
932 # override glib dep to include the above refinements
933 meson.override_dependency('glib-2.0', glib)
935 # The path to glib.h is added to all compilation commands.
936 add_project_dependencies(glib.partial_dependency(compile_args: true, includes: true),
937 native: false, language: all_languages)
940 gdbus_codegen = not_found
941 gdbus_codegen_error = '@0@ requires gdbus-codegen, please install libgio'
942 if not get_option('gio').auto() or have_system
943 gio = dependency('gio-2.0', required: get_option('gio'),
944 method: 'pkg-config')
945 if gio.found() and not cc.links('''
949 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
951 }''', dependencies: [glib, gio])
952 if get_option('gio').enabled()
953 error('The installed libgio is broken for static linking')
958 gdbus_codegen = find_program(gio.get_variable('gdbus_codegen'),
959 required: get_option('gio'))
960 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
961 method: 'pkg-config')
962 gio = declare_dependency(dependencies: [gio, gio_unix],
963 version: gio.version())
966 if gdbus_codegen.found() and get_option('cfi')
967 gdbus_codegen = not_found
968 gdbus_codegen_error = '@0@ uses gdbus-codegen, which does not support control flow integrity'
971 xml_pp = find_program('scripts/xml-preprocess.py')
974 if 'ust' in get_option('trace_backends')
975 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
976 method: 'pkg-config')
979 if not get_option('pixman').auto() or have_system or have_tools
980 pixman = dependency('pixman-1', required: get_option('pixman'), version:'>=0.21.8',
981 method: 'pkg-config')
984 zlib = dependency('zlib', required: true)
987 if not get_option('linux_aio').auto() or have_block
988 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
989 required: get_option('linux_aio'))
992 linux_io_uring_test = '''
993 #include <liburing.h>
994 #include <linux/errqueue.h>
996 int main(void) { return 0; }'''
998 linux_io_uring = not_found
999 if not get_option('linux_io_uring').auto() or have_block
1000 linux_io_uring = dependency('liburing', version: '>=0.3',
1001 required: get_option('linux_io_uring'),
1002 method: 'pkg-config')
1003 if not cc.links(linux_io_uring_test)
1004 linux_io_uring = not_found
1009 if not get_option('libnfs').auto() or have_block
1010 libnfs = dependency('libnfs', version: '>=1.9.3',
1011 required: get_option('libnfs'),
1012 method: 'pkg-config')
1017 #include <sys/types.h>
1018 #ifdef CONFIG_LIBATTR
1019 #include <attr/xattr.h>
1021 #include <sys/xattr.h>
1023 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
1026 have_old_libattr = false
1027 if get_option('attr').allowed()
1028 if cc.links(libattr_test)
1029 libattr = declare_dependency()
1031 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
1032 required: get_option('attr'))
1033 if libattr.found() and not \
1034 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
1036 if get_option('attr').enabled()
1037 error('could not link libattr')
1039 warning('could not link libattr, disabling')
1042 have_old_libattr = libattr.found()
1047 cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
1048 required: get_option('cocoa'))
1050 vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
1051 if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
1052 'VMNET_BRIDGED_MODE',
1053 dependencies: vmnet)
1055 if get_option('vmnet').enabled()
1056 error('vmnet.framework API is outdated')
1058 warning('vmnet.framework API is outdated, disabling')
1063 seccomp_has_sysrawrc = false
1064 if not get_option('seccomp').auto() or have_system or have_tools
1065 seccomp = dependency('libseccomp', version: '>=2.3.0',
1066 required: get_option('seccomp'),
1067 method: 'pkg-config')
1069 seccomp_has_sysrawrc = cc.has_header_symbol('seccomp.h',
1070 'SCMP_FLTATR_API_SYSRAWRC',
1071 dependencies: seccomp)
1075 libcap_ng = not_found
1076 if not get_option('cap_ng').auto() or have_system or have_tools
1077 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
1078 required: get_option('cap_ng'))
1080 if libcap_ng.found() and not cc.links('''
1084 capng_capability_to_name(CAPNG_EFFECTIVE);
1086 }''', dependencies: libcap_ng)
1087 libcap_ng = not_found
1088 if get_option('cap_ng').enabled()
1089 error('could not link libcap-ng')
1091 warning('could not link libcap-ng, disabling')
1095 if get_option('xkbcommon').auto() and not have_system and not have_tools
1096 xkbcommon = not_found
1098 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
1099 method: 'pkg-config')
1103 if not get_option('slirp').auto() or have_system
1104 slirp = dependency('slirp', required: get_option('slirp'),
1105 method: 'pkg-config')
1106 # slirp < 4.7 is incompatible with CFI support in QEMU. This is because
1107 # it passes function pointers within libslirp as callbacks for timers.
1108 # When using a system-wide shared libslirp, the type information for the
1109 # callback is missing and the timer call produces a false positive with CFI.
1110 # Do not use the "version" keyword argument to produce a better error.
1111 # with control-flow integrity.
1112 if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
1113 if get_option('slirp').enabled()
1114 error('Control-Flow Integrity requires libslirp 4.7.')
1116 warning('Cannot use libslirp since Control-Flow Integrity requires libslirp >= 4.7.')
1123 if not get_option('vde').auto() or have_system or have_tools
1124 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
1125 required: get_option('vde'))
1127 if vde.found() and not cc.links('''
1128 #include <libvdeplug.h>
1131 struct vde_open_args a = {0, 0, 0};
1135 }''', dependencies: vde)
1137 if get_option('cap_ng').enabled()
1138 error('could not link libvdeplug')
1140 warning('could not link libvdeplug, disabling')
1145 if not get_option('pa').auto() or (host_os == 'linux' and have_system)
1146 pulse = dependency('libpulse', required: get_option('pa'),
1147 method: 'pkg-config')
1150 if not get_option('alsa').auto() or (host_os == 'linux' and have_system)
1151 alsa = dependency('alsa', required: get_option('alsa'),
1152 method: 'pkg-config')
1155 if not get_option('jack').auto() or have_system
1156 jack = dependency('jack', required: get_option('jack'),
1157 method: 'pkg-config')
1159 pipewire = not_found
1160 if not get_option('pipewire').auto() or (host_os == 'linux' and have_system)
1161 pipewire = dependency('libpipewire-0.3', version: '>=0.3.60',
1162 required: get_option('pipewire'),
1163 method: 'pkg-config')
1166 if not get_option('sndio').auto() or have_system
1167 sndio = dependency('sndio', required: get_option('sndio'),
1168 method: 'pkg-config')
1171 spice_protocol = not_found
1172 if not get_option('spice_protocol').auto() or have_system
1173 spice_protocol = dependency('spice-protocol', version: '>=0.14.0',
1174 required: get_option('spice_protocol'),
1175 method: 'pkg-config')
1178 if get_option('spice') \
1179 .disable_auto_if(not have_system) \
1180 .require(pixman.found(),
1181 error_message: 'cannot enable SPICE if pixman is not available') \
1183 spice = dependency('spice-server', version: '>=0.14.0',
1184 required: get_option('spice'),
1185 method: 'pkg-config')
1187 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
1189 rt = cc.find_library('rt', required: false)
1191 libiscsi = not_found
1192 if not get_option('libiscsi').auto() or have_block
1193 libiscsi = dependency('libiscsi', version: '>=1.9.0',
1194 required: get_option('libiscsi'),
1195 method: 'pkg-config')
1198 if not get_option('zstd').auto() or have_block
1199 zstd = dependency('libzstd', version: '>=1.4.0',
1200 required: get_option('zstd'),
1201 method: 'pkg-config')
1205 have_vhost_user_gpu = have_tools and host_os == 'linux' and pixman.found()
1206 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
1207 virgl = dependency('virglrenderer',
1208 method: 'pkg-config',
1209 required: get_option('virglrenderer'))
1211 rutabaga = not_found
1212 if not get_option('rutabaga_gfx').auto() or have_system or have_vhost_user_gpu
1213 rutabaga = dependency('rutabaga_gfx_ffi',
1214 method: 'pkg-config',
1215 required: get_option('rutabaga_gfx'))
1218 if not get_option('blkio').auto() or have_block
1219 blkio = dependency('blkio',
1220 method: 'pkg-config',
1221 required: get_option('blkio'))
1224 if not get_option('curl').auto() or have_block
1225 curl = dependency('libcurl', version: '>=7.29.0',
1226 method: 'pkg-config',
1227 required: get_option('curl'))
1230 if host_os == 'linux' and (have_system or have_tools)
1231 libudev = dependency('libudev',
1232 method: 'pkg-config',
1233 required: get_option('libudev'))
1236 mpathlibs = [libudev]
1237 mpathpersist = not_found
1238 if host_os == 'linux' and have_tools and get_option('mpath').allowed()
1239 mpath_test_source = '''
1240 #include <libudev.h>
1241 #include <mpath_persist.h>
1242 unsigned mpath_mx_alloc_len = 1024;
1244 static struct config *multipath_conf;
1245 extern struct udev *udev;
1246 extern struct config *get_multipath_config(void);
1247 extern void put_multipath_config(struct config *conf);
1249 struct config *get_multipath_config(void) { return multipath_conf; }
1250 void put_multipath_config(struct config *conf) { }
1253 multipath_conf = mpath_lib_init();
1256 libmpathpersist = cc.find_library('mpathpersist',
1257 required: get_option('mpath'))
1258 if libmpathpersist.found()
1259 mpathlibs += libmpathpersist
1260 if get_option('prefer_static')
1261 mpathlibs += cc.find_library('devmapper',
1262 required: get_option('mpath'))
1264 mpathlibs += cc.find_library('multipath',
1265 required: get_option('mpath'))
1266 foreach lib: mpathlibs
1272 if mpathlibs.length() == 0
1273 msg = 'Dependencies missing for libmpathpersist'
1274 elif cc.links(mpath_test_source, dependencies: mpathlibs)
1275 mpathpersist = declare_dependency(dependencies: mpathlibs)
1277 msg = 'Cannot detect libmpathpersist API'
1279 if not mpathpersist.found()
1280 if get_option('mpath').enabled()
1283 warning(msg + ', disabling')
1291 if have_system and get_option('curses').allowed()
1293 #if defined(__APPLE__) || defined(__OpenBSD__)
1294 #define _XOPEN_SOURCE_EXTENDED 1
1301 setlocale(LC_ALL, "");
1303 addwstr(L"wide chars\n");
1305 add_wch(WACS_DEGREE);
1309 curses_dep_list = host_os == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
1310 curses = dependency(curses_dep_list,
1312 method: 'pkg-config')
1313 msg = get_option('curses').enabled() ? 'curses library not found' : ''
1314 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
1316 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
1317 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses],
1318 version: curses.version())
1320 msg = 'curses package not usable'
1324 if not curses.found()
1325 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1326 if host_os != 'windows' and not has_curses_h
1327 message('Trying with /usr/include/ncursesw')
1328 curses_compile_args += ['-I/usr/include/ncursesw']
1329 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1332 curses_libname_list = (host_os == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
1333 foreach curses_libname : curses_libname_list
1334 libcurses = cc.find_library(curses_libname,
1336 if libcurses.found()
1337 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
1338 curses = declare_dependency(compile_args: curses_compile_args,
1339 dependencies: [libcurses])
1342 msg = 'curses library not usable'
1348 if get_option('iconv').allowed()
1349 foreach link_args : [ ['-liconv'], [] ]
1350 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
1351 # We need to use libiconv if available because mixing libiconv's headers with
1352 # the system libc does not work.
1353 # However, without adding glib to the dependencies -L/usr/local/lib will not be
1354 # included in the command line and libiconv will not be found.
1358 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
1359 return conv != (iconv_t) -1;
1360 }''', args: link_args, dependencies: glib)
1361 iconv = declare_dependency(link_args: link_args, dependencies: glib)
1366 if curses.found() and not iconv.found()
1367 if get_option('iconv').enabled()
1368 error('iconv not available')
1370 msg = 'iconv required for curses UI but not available'
1373 if not curses.found() and msg != ''
1374 if get_option('curses').enabled()
1377 warning(msg + ', disabling')
1383 if not get_option('brlapi').auto() or have_system
1384 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
1385 required: get_option('brlapi'))
1386 if brlapi.found() and not cc.links('''
1389 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
1391 if get_option('brlapi').enabled()
1392 error('could not link brlapi')
1394 warning('could not link brlapi, disabling')
1400 if not get_option('sdl').auto() or have_system
1401 sdl = dependency('sdl2', required: get_option('sdl'))
1402 sdl_image = not_found
1405 # Some versions of SDL have problems with -Wundef
1406 if not cc.compiles('''
1408 #include <SDL_syswm.h>
1409 int main(int argc, char *argv[]) { return 0; }
1410 ''', dependencies: sdl, args: '-Werror=undef')
1411 sdl = declare_dependency(compile_args: '-Wno-undef',
1413 version: sdl.version())
1415 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
1416 method: 'pkg-config')
1418 if get_option('sdl_image').enabled()
1419 error('sdl-image required, but SDL was @0@'.format(
1420 get_option('sdl').disabled() ? 'disabled' : 'not found'))
1422 sdl_image = not_found
1426 if not get_option('rbd').auto() or have_block
1427 librados = cc.find_library('rados', required: get_option('rbd'))
1428 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
1429 required: get_option('rbd'))
1430 if librados.found() and librbd.found()
1433 #include <rbd/librbd.h>
1436 rados_create(&cluster, NULL);
1437 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
1441 }''', dependencies: [librbd, librados])
1442 rbd = declare_dependency(dependencies: [librbd, librados])
1443 elif get_option('rbd').enabled()
1444 error('librbd >= 1.12.0 required')
1446 warning('librbd >= 1.12.0 not found, disabling')
1451 glusterfs = not_found
1452 glusterfs_ftruncate_has_stat = false
1453 glusterfs_iocb_has_stat = false
1454 if not get_option('glusterfs').auto() or have_block
1455 glusterfs = dependency('glusterfs-api', version: '>=3',
1456 required: get_option('glusterfs'),
1457 method: 'pkg-config')
1458 if glusterfs.found()
1459 glusterfs_ftruncate_has_stat = cc.links('''
1460 #include <glusterfs/api/glfs.h>
1465 /* new glfs_ftruncate() passes two additional args */
1466 return glfs_ftruncate(NULL, 0, NULL, NULL);
1468 ''', dependencies: glusterfs)
1469 glusterfs_iocb_has_stat = cc.links('''
1470 #include <glusterfs/api/glfs.h>
1472 /* new glfs_io_cbk() passes two additional glfs_stat structs */
1474 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
1480 glfs_io_cbk iocb = &glusterfs_iocb;
1481 iocb(NULL, 0 , NULL, NULL, NULL);
1484 ''', dependencies: glusterfs)
1489 if get_option('hv_balloon').allowed() and have_system
1492 #include <gmodule.h>
1496 tree = g_tree_new((GCompareFunc)strcmp);
1497 (void)g_tree_node_first(tree);
1498 g_tree_destroy(tree);
1501 ''', dependencies: glib)
1504 if get_option('hv_balloon').enabled()
1505 error('could not enable hv-balloon, update your glib')
1507 warning('could not find glib support for hv-balloon, disabling')
1513 if not get_option('libssh').auto() or have_block
1514 libssh = dependency('libssh', version: '>=0.8.7',
1515 method: 'pkg-config',
1516 required: get_option('libssh'))
1519 libbzip2 = not_found
1520 if not get_option('bzip2').auto() or have_block
1521 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
1522 required: get_option('bzip2'))
1523 if libbzip2.found() and not cc.links('''
1525 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
1526 libbzip2 = not_found
1527 if get_option('bzip2').enabled()
1528 error('could not link libbzip2')
1530 warning('could not link libbzip2, disabling')
1535 liblzfse = not_found
1536 if not get_option('lzfse').auto() or have_block
1537 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
1538 required: get_option('lzfse'))
1540 if liblzfse.found() and not cc.links('''
1542 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
1543 liblzfse = not_found
1544 if get_option('lzfse').enabled()
1545 error('could not link liblzfse')
1547 warning('could not link liblzfse, disabling')
1552 if get_option('oss').allowed() and have_system
1553 if not cc.has_header('sys/soundcard.h')
1555 elif host_os == 'netbsd'
1556 oss = cc.find_library('ossaudio', required: get_option('oss'))
1558 oss = declare_dependency()
1562 if get_option('oss').enabled()
1563 error('OSS not found')
1568 if not get_option('dsound').auto() or (host_os == 'windows' and have_system)
1569 if cc.has_header('dsound.h')
1570 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
1573 if not dsound.found()
1574 if get_option('dsound').enabled()
1575 error('DirectSound not found')
1580 coreaudio = not_found
1581 if not get_option('coreaudio').auto() or (host_os == 'darwin' and have_system)
1582 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
1583 required: get_option('coreaudio'))
1587 if not get_option('opengl').auto() or have_system or have_vhost_user_gpu
1588 epoxy = dependency('epoxy', method: 'pkg-config',
1589 required: get_option('opengl'))
1590 if cc.has_header('epoxy/egl.h', dependencies: epoxy)
1592 elif get_option('opengl').enabled()
1593 error('epoxy/egl.h not found')
1597 if (have_system or have_tools) and (virgl.found() or opengl.found())
1598 gbm = dependency('gbm', method: 'pkg-config', required: false)
1600 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and opengl.found() and gbm.found()
1603 gnutls_crypto = not_found
1604 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1605 # For general TLS support our min gnutls matches
1606 # that implied by our platform support matrix
1608 # For the crypto backends, we look for a newer
1611 # Version 3.6.8 is needed to get XTS
1612 # Version 3.6.13 is needed to get PBKDF
1613 # Version 3.6.14 is needed to get HW accelerated XTS
1615 # If newer enough gnutls isn't available, we can
1616 # still use a different crypto backend to satisfy
1617 # the platform support requirements
1618 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1619 method: 'pkg-config',
1621 if gnutls_crypto.found()
1622 gnutls = gnutls_crypto
1624 # Our min version if all we need is TLS
1625 gnutls = dependency('gnutls', version: '>=3.5.18',
1626 method: 'pkg-config',
1627 required: get_option('gnutls'))
1631 # We prefer use of gnutls for crypto, unless the options
1632 # explicitly asked for nettle or gcrypt.
1634 # If gnutls isn't available for crypto, then we'll prefer
1635 # gcrypt over nettle for performance reasons.
1639 crypto_sm4 = not_found
1642 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1643 error('Only one of gcrypt & nettle can be enabled')
1646 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1647 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1648 gnutls_crypto = not_found
1651 if not gnutls_crypto.found()
1652 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1653 gcrypt = dependency('libgcrypt', version: '>=1.8',
1654 method: 'config-tool',
1655 required: get_option('gcrypt'))
1656 # Debian has removed -lgpg-error from libgcrypt-config
1657 # as it "spreads unnecessary dependencies" which in
1658 # turn breaks static builds...
1659 if gcrypt.found() and get_option('prefer_static')
1660 gcrypt = declare_dependency(dependencies:
1662 cc.find_library('gpg-error', required: true)],
1663 version: gcrypt.version())
1666 # SM4 ALG is available in libgcrypt >= 1.9
1667 if gcrypt.found() and not cc.links('''
1670 gcry_cipher_hd_t handler;
1671 gcry_cipher_open(&handler, GCRY_CIPHER_SM4, GCRY_CIPHER_MODE_ECB, 0);
1673 }''', dependencies: gcrypt)
1674 crypto_sm4 = not_found
1677 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1678 nettle = dependency('nettle', version: '>=3.4',
1679 method: 'pkg-config',
1680 required: get_option('nettle'))
1681 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1685 # SM4 ALG is available in nettle >= 3.9
1686 if nettle.found() and not cc.links('''
1687 #include <nettle/sm4.h>
1690 unsigned char key[16] = {0};
1691 sm4_set_encrypt_key(&ctx, key);
1693 }''', dependencies: nettle)
1694 crypto_sm4 = not_found
1699 capstone = not_found
1700 if not get_option('capstone').auto() or have_system or have_user
1701 capstone = dependency('capstone', version: '>=3.0.5',
1702 method: 'pkg-config',
1703 required: get_option('capstone'))
1705 # Some versions of capstone have broken pkg-config file
1706 # that reports a wrong -I path, causing the #include to
1707 # fail later. If the system has such a broken version
1709 if capstone.found() and not cc.compiles('#include <capstone.h>',
1710 dependencies: [capstone])
1711 capstone = not_found
1712 if get_option('capstone').enabled()
1713 error('capstone requested, but it does not appear to work')
1718 gmp = dependency('gmp', required: false, method: 'pkg-config')
1719 if nettle.found() and gmp.found()
1720 hogweed = dependency('hogweed', version: '>=3.4',
1721 method: 'pkg-config',
1722 required: get_option('nettle'))
1729 have_gtk_clipboard = get_option('gtk_clipboard').enabled()
1731 if get_option('gtk') \
1732 .disable_auto_if(not have_system) \
1733 .require(pixman.found(),
1734 error_message: 'cannot enable GTK if pixman is not available') \
1736 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1737 method: 'pkg-config',
1738 required: get_option('gtk'))
1740 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1741 method: 'pkg-config',
1743 gtk = declare_dependency(dependencies: [gtk, gtkx11],
1744 version: gtk.version())
1746 if not get_option('vte').auto() or have_system
1747 vte = dependency('vte-2.91',
1748 method: 'pkg-config',
1749 required: get_option('vte'))
1751 elif have_gtk_clipboard
1752 error('GTK clipboard requested, but GTK not found')
1758 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found())
1761 if get_option('png').allowed() and have_system
1762 png = dependency('libpng', version: '>=1.6.34', required: get_option('png'),
1763 method: 'pkg-config')
1768 if get_option('vnc') \
1769 .disable_auto_if(not have_system) \
1770 .require(pixman.found(),
1771 error_message: 'cannot enable VNC if pixman is not available') \
1773 vnc = declare_dependency() # dummy dependency
1774 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1775 method: 'pkg-config')
1776 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1777 required: get_option('vnc_sasl'))
1779 sasl = declare_dependency(dependencies: sasl,
1780 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1785 if not get_option('auth_pam').auto() or have_system
1786 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1787 required: get_option('auth_pam'))
1789 if pam.found() and not cc.links('''
1791 #include <security/pam_appl.h>
1793 const char *service_name = "qemu";
1794 const char *user = "frank";
1795 const struct pam_conv pam_conv = { 0 };
1796 pam_handle_t *pamh = NULL;
1797 pam_start(service_name, user, &pam_conv, &pamh);
1799 }''', dependencies: pam)
1801 if get_option('auth_pam').enabled()
1802 error('could not link libpam')
1804 warning('could not link libpam, disabling')
1809 if not get_option('snappy').auto() or have_system
1810 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1811 required: get_option('snappy'))
1813 if snappy.found() and not cc.links('''
1814 #include <snappy-c.h>
1815 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1817 if get_option('snappy').enabled()
1818 error('could not link libsnappy')
1820 warning('could not link libsnappy, disabling')
1825 if not get_option('lzo').auto() or have_system
1826 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1827 required: get_option('lzo'))
1829 if lzo.found() and not cc.links('''
1830 #include <lzo/lzo1x.h>
1831 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1833 if get_option('lzo').enabled()
1834 error('could not link liblzo2')
1836 warning('could not link liblzo2, disabling')
1841 if not get_option('numa').auto() or have_system or have_tools
1842 numa = cc.find_library('numa', has_headers: ['numa.h'],
1843 required: get_option('numa'))
1845 if numa.found() and not cc.links('''
1847 int main(void) { return numa_available(); }
1848 ''', dependencies: numa)
1850 if get_option('numa').enabled()
1851 error('could not link numa')
1853 warning('could not link numa, disabling')
1858 if not get_option('rdma').auto() or have_system
1859 libumad = cc.find_library('ibumad', required: get_option('rdma'))
1860 rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'],
1861 required: get_option('rdma')),
1862 cc.find_library('ibverbs', required: get_option('rdma')),
1864 rdma = declare_dependency(dependencies: rdma_libs)
1865 foreach lib: rdma_libs
1873 if not get_option('smartcard').auto() or have_system
1874 cacard = dependency('libcacard', required: get_option('smartcard'),
1875 version: '>=2.5.1', method: 'pkg-config')
1878 if not get_option('u2f').auto() or have_system
1879 u2f = dependency('u2f-emu', required: get_option('u2f'),
1880 method: 'pkg-config')
1883 if not get_option('canokey').auto() or have_system
1884 canokey = dependency('canokey-qemu', required: get_option('canokey'),
1885 method: 'pkg-config')
1887 usbredir = not_found
1888 if not get_option('usb_redir').auto() or have_system
1889 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1890 version: '>=0.6', method: 'pkg-config')
1893 if not get_option('libusb').auto() or have_system
1894 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1895 version: '>=1.0.13', method: 'pkg-config')
1899 if not get_option('libpmem').auto() or have_system
1900 libpmem = dependency('libpmem', required: get_option('libpmem'),
1901 method: 'pkg-config')
1903 libdaxctl = not_found
1904 if not get_option('libdaxctl').auto() or have_system
1905 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1906 version: '>=57', method: 'pkg-config')
1910 tasn1 = dependency('libtasn1',
1911 method: 'pkg-config')
1913 keyutils = not_found
1914 if not get_option('libkeyutils').auto() or have_block
1915 keyutils = dependency('libkeyutils', required: get_option('libkeyutils'),
1916 method: 'pkg-config')
1919 has_gettid = cc.has_function('gettid')
1922 selinux = dependency('libselinux',
1923 required: get_option('selinux'),
1924 method: 'pkg-config')
1929 if get_option('malloc') == 'system'
1931 get_option('malloc_trim').allowed() and \
1932 cc.has_function('malloc_trim', prefix: '#include <malloc.h>')
1934 has_malloc_trim = false
1935 malloc = cc.find_library(get_option('malloc'), required: true)
1937 if not has_malloc_trim and get_option('malloc_trim').enabled()
1938 if get_option('malloc') == 'system'
1939 error('malloc_trim not available on this platform.')
1941 error('malloc_trim not available with non-libc memory allocator')
1945 gnu_source_prefix = '''
1951 # Check whether the glibc provides STATX_BASIC_STATS
1953 has_statx = cc.has_header_symbol('sys/stat.h', 'STATX_BASIC_STATS', prefix: gnu_source_prefix)
1955 # Check whether statx() provides mount ID information
1957 has_statx_mnt_id = cc.has_header_symbol('sys/stat.h', 'STATX_MNT_ID', prefix: gnu_source_prefix)
1959 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
1960 .require(host_os == 'linux',
1961 error_message: 'vhost_user_blk_server requires linux') \
1962 .require(have_vhost_user,
1963 error_message: 'vhost_user_blk_server requires vhost-user support') \
1964 .disable_auto_if(not have_tools and not have_system) \
1967 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1968 error('Cannot enable fuse-lseek while fuse is disabled')
1971 fuse = dependency('fuse3', required: get_option('fuse'),
1972 version: '>=3.1', method: 'pkg-config')
1974 fuse_lseek = not_found
1975 if get_option('fuse_lseek').allowed()
1976 if fuse.version().version_compare('>=3.8')
1978 fuse_lseek = declare_dependency()
1979 elif get_option('fuse_lseek').enabled()
1981 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1983 error('fuse-lseek requires libfuse, which was not found')
1988 have_libvduse = (host_os == 'linux')
1989 if get_option('libvduse').enabled()
1990 if host_os != 'linux'
1991 error('libvduse requires linux')
1993 elif get_option('libvduse').disabled()
1994 have_libvduse = false
1997 have_vduse_blk_export = (have_libvduse and host_os == 'linux')
1998 if get_option('vduse_blk_export').enabled()
1999 if host_os != 'linux'
2000 error('vduse_blk_export requires linux')
2001 elif not have_libvduse
2002 error('vduse_blk_export requires libvduse support')
2004 elif get_option('vduse_blk_export').disabled()
2005 have_vduse_blk_export = false
2009 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
2010 if libbpf.found() and not cc.links('''
2011 #include <bpf/libbpf.h>
2014 bpf_object__destroy_skeleton(NULL);
2016 }''', dependencies: libbpf)
2018 if get_option('bpf').enabled()
2019 error('libbpf skeleton test failed')
2021 warning('libbpf skeleton test failed, disabling')
2027 if not get_option('af_xdp').auto() or have_system
2028 libxdp = dependency('libxdp', required: get_option('af_xdp'),
2029 version: '>=1.4.0', method: 'pkg-config')
2034 if not get_option('libdw').auto() or \
2035 (not get_option('prefer_static') and (have_system or have_user))
2036 libdw = dependency('libdw',
2037 method: 'pkg-config',
2038 required: get_option('libdw'))
2045 config_host_data = configuration_data()
2047 audio_drivers_selected = []
2049 audio_drivers_available = {
2050 'alsa': alsa.found(),
2051 'coreaudio': coreaudio.found(),
2052 'dsound': dsound.found(),
2053 'jack': jack.found(),
2055 'pa': pulse.found(),
2056 'pipewire': pipewire.found(),
2058 'sndio': sndio.found(),
2060 foreach k, v: audio_drivers_available
2061 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
2064 # Default to native drivers first, OSS second, SDL third
2065 audio_drivers_priority = \
2066 [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \
2067 (host_os == 'linux' ? [] : [ 'sdl' ])
2068 audio_drivers_default = []
2069 foreach k: audio_drivers_priority
2070 if audio_drivers_available[k]
2071 audio_drivers_default += k
2075 foreach k: get_option('audio_drv_list')
2077 audio_drivers_selected += audio_drivers_default
2078 elif not audio_drivers_available[k]
2079 error('Audio driver "@0@" not available.'.format(k))
2081 audio_drivers_selected += k
2085 config_host_data.set('CONFIG_AUDIO_DRIVERS',
2086 '"' + '", "'.join(audio_drivers_selected) + '", ')
2088 have_host_block_device = (host_os != 'darwin' or
2089 cc.has_header('IOKit/storage/IOMedia.h'))
2091 dbus_display = get_option('dbus_display') \
2092 .require(gio.version().version_compare('>=2.64'),
2093 error_message: '-display dbus requires glib>=2.64') \
2094 .require(gdbus_codegen.found(),
2095 error_message: gdbus_codegen_error.format('-display dbus')) \
2098 have_virtfs = get_option('virtfs') \
2099 .require(host_os == 'linux' or host_os == 'darwin',
2100 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
2101 .require(host_os == 'linux' or cc.has_function('pthread_fchdir_np'),
2102 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
2103 .require(host_os == 'darwin' or libattr.found(),
2104 error_message: 'virtio-9p (virtfs) on Linux requires libattr-devel') \
2105 .disable_auto_if(not have_tools and not have_system) \
2108 have_virtfs_proxy_helper = get_option('virtfs_proxy_helper') \
2109 .require(host_os != 'darwin', error_message: 'the virtfs proxy helper is incompatible with macOS') \
2110 .require(have_virtfs, error_message: 'the virtfs proxy helper requires that virtfs is enabled') \
2111 .disable_auto_if(not have_tools) \
2112 .require(libcap_ng.found(), error_message: 'the virtfs proxy helper requires libcap-ng') \
2115 if get_option('block_drv_ro_whitelist') == ''
2116 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
2118 config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
2119 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
2121 if get_option('block_drv_rw_whitelist') == ''
2122 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
2124 config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
2125 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
2128 foreach k : get_option('trace_backends')
2129 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
2131 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
2132 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
2134 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
2136 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
2137 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
2138 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
2139 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
2140 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
2142 qemu_firmwarepath = ''
2143 foreach k : get_option('qemu_firmwarepath')
2144 qemu_firmwarepath += '"' + get_option('prefix') / k + '", '
2146 config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath)
2148 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
2149 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
2150 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
2151 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
2152 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
2153 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
2156 config_host_data.set('CONFIG_STAMP', run_command(
2157 meson.current_source_dir() / 'scripts/qemu-stamp.py',
2158 meson.project_version(), get_option('pkgversion'), '--',
2159 meson.current_source_dir() / 'configure',
2160 capture: true, check: true).stdout().strip())
2163 have_slirp_smbd = get_option('slirp_smbd') \
2164 .require(host_os != 'windows', error_message: 'Host smbd not supported on this platform.') \
2167 smbd_path = get_option('smbd')
2169 smbd_path = (host_os == 'sunos' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
2171 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
2174 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
2176 kvm_targets_c = '""'
2177 if get_option('kvm').allowed() and host_os == 'linux'
2178 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
2180 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
2182 if get_option('module_upgrades') and not enable_modules
2183 error('Cannot enable module-upgrades as modules are not enabled')
2185 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
2187 config_host_data.set('CONFIG_ATTR', libattr.found())
2188 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
2189 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
2190 config_host_data.set('CONFIG_BSD', host_os in bsd_oses)
2191 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2192 config_host_data.set('CONFIG_COCOA', cocoa.found())
2193 config_host_data.set('CONFIG_DARWIN', host_os == 'darwin')
2194 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
2195 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
2196 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
2197 config_host_data.set('CONFIG_LINUX', host_os == 'linux')
2198 config_host_data.set('CONFIG_POSIX', host_os != 'windows')
2199 config_host_data.set('CONFIG_WIN32', host_os == 'windows')
2200 config_host_data.set('CONFIG_LZO', lzo.found())
2201 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
2202 config_host_data.set('CONFIG_BLKIO', blkio.found())
2204 config_host_data.set('CONFIG_BLKIO_VHOST_VDPA_FD',
2205 blkio.version().version_compare('>=1.3.0'))
2207 config_host_data.set('CONFIG_CURL', curl.found())
2208 config_host_data.set('CONFIG_CURSES', curses.found())
2209 config_host_data.set('CONFIG_GBM', gbm.found())
2210 config_host_data.set('CONFIG_GIO', gio.found())
2211 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
2212 if glusterfs.found()
2213 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
2214 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
2215 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
2216 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
2217 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
2218 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
2220 config_host_data.set('CONFIG_GTK', gtk.found())
2221 config_host_data.set('CONFIG_VTE', vte.found())
2222 config_host_data.set('CONFIG_GTK_CLIPBOARD', have_gtk_clipboard)
2223 config_host_data.set('CONFIG_HEXAGON_IDEF_PARSER', get_option('hexagon_idef_parser'))
2224 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
2225 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
2226 config_host_data.set('CONFIG_EBPF', libbpf.found())
2227 config_host_data.set('CONFIG_AF_XDP', libxdp.found())
2228 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
2229 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
2230 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
2231 config_host_data.set('CONFIG_LIBSSH', libssh.found())
2232 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
2233 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
2234 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
2235 config_host_data.set('CONFIG_MODULES', enable_modules)
2236 config_host_data.set('CONFIG_NUMA', numa.found())
2238 config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY',
2239 cc.has_function('numa_has_preferred_many',
2240 dependencies: numa))
2242 config_host_data.set('CONFIG_OPENGL', opengl.found())
2243 config_host_data.set('CONFIG_PLUGIN', get_option('plugins'))
2244 config_host_data.set('CONFIG_RBD', rbd.found())
2245 config_host_data.set('CONFIG_RDMA', rdma.found())
2246 config_host_data.set('CONFIG_RELOCATABLE', get_option('relocatable'))
2247 config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack'))
2248 config_host_data.set('CONFIG_SDL', sdl.found())
2249 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
2250 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
2252 config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc)
2254 config_host_data.set('CONFIG_PIXMAN', pixman.found())
2255 config_host_data.set('CONFIG_SLIRP', slirp.found())
2256 config_host_data.set('CONFIG_SNAPPY', snappy.found())
2257 config_host_data.set('CONFIG_SOLARIS', host_os == 'sunos')
2258 if get_option('tcg').allowed()
2259 config_host_data.set('CONFIG_TCG', 1)
2260 config_host_data.set('CONFIG_TCG_INTERPRETER', tcg_arch == 'tci')
2262 config_host_data.set('CONFIG_TPM', have_tpm)
2263 config_host_data.set('CONFIG_TSAN', get_option('tsan'))
2264 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
2265 config_host_data.set('CONFIG_VDE', vde.found())
2266 config_host_data.set('CONFIG_VHOST', have_vhost)
2267 config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
2268 config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
2269 config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)
2270 config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
2271 config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
2272 config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
2273 config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
2274 config_host_data.set('CONFIG_VMNET', vmnet.found())
2275 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
2276 config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export)
2277 config_host_data.set('CONFIG_PNG', png.found())
2278 config_host_data.set('CONFIG_VNC', vnc.found())
2279 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
2280 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
2282 config_host_data.set('HAVE_VIRGL_D3D_INFO_EXT',
2283 cc.has_member('struct virgl_renderer_resource_info_ext', 'd3d_tex2d',
2284 prefix: '#include <virglrenderer.h>',
2285 dependencies: virgl))
2287 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
2288 config_host_data.set('CONFIG_VTE', vte.found())
2289 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
2290 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
2291 config_host_data.set('CONFIG_GETTID', has_gettid)
2292 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
2293 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
2294 config_host_data.set('CONFIG_TASN1', tasn1.found())
2295 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
2296 config_host_data.set('CONFIG_NETTLE', nettle.found())
2297 config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found())
2298 config_host_data.set('CONFIG_HOGWEED', hogweed.found())
2299 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
2300 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
2301 config_host_data.set('CONFIG_STATX', has_statx)
2302 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
2303 config_host_data.set('CONFIG_ZSTD', zstd.found())
2304 config_host_data.set('CONFIG_FUSE', fuse.found())
2305 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
2306 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
2307 if spice_protocol.found()
2308 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
2309 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
2310 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
2312 config_host_data.set('CONFIG_SPICE', spice.found())
2313 config_host_data.set('CONFIG_X11', x11.found())
2314 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
2315 config_host_data.set('CONFIG_CFI', get_option('cfi'))
2316 config_host_data.set('CONFIG_SELINUX', selinux.found())
2317 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
2318 config_host_data.set('CONFIG_LIBDW', libdw.found())
2320 # protect from xen.version() having less than three components
2321 xen_version = xen.version().split('.') + ['0', '0']
2322 xen_ctrl_version = xen_version[0] + \
2323 ('0' + xen_version[1]).substring(-2) + \
2324 ('0' + xen_version[2]).substring(-2)
2325 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
2327 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
2328 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
2329 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
2330 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
2332 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
2333 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
2335 have_coroutine_pool = get_option('coroutine_pool')
2336 if get_option('debug_stack_usage') and have_coroutine_pool
2337 message('Disabling coroutine pool to measure stack usage')
2338 have_coroutine_pool = false
2340 config_host_data.set('CONFIG_COROUTINE_POOL', have_coroutine_pool)
2341 config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock'))
2342 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
2343 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
2344 config_host_data.set('CONFIG_DEBUG_TCG', get_option('debug_tcg'))
2345 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
2346 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
2347 config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
2350 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
2351 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
2352 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
2353 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
2354 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
2355 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
2356 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
2357 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
2358 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
2359 if host_os == 'windows'
2360 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h'))
2364 config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range'))
2365 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
2366 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
2367 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
2368 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
2369 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
2370 config_host_data.set('CONFIG_GETCPU', cc.has_function('getcpu', prefix: gnu_source_prefix))
2371 config_host_data.set('CONFIG_SCHED_GETCPU', cc.has_function('sched_getcpu', prefix: '#include <sched.h>'))
2372 # Note that we need to specify prefix: here to avoid incorrectly
2373 # thinking that Windows has posix_memalign()
2374 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
2375 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
2376 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
2377 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
2378 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
2379 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
2380 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
2381 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
2382 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
2383 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
2384 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
2385 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
2386 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
2387 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
2388 config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice)
2389 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
2390 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
2391 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
2393 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
2394 cc.has_function('rbd_namespace_exists',
2396 prefix: '#include <rbd/librbd.h>'))
2399 config_host_data.set('HAVE_IBV_ADVISE_MR',
2400 cc.has_function('ibv_advise_mr',
2402 prefix: '#include <infiniband/verbs.h>'))
2405 have_asan_fiber = false
2406 if get_option('sanitizers') and \
2407 not cc.has_function('__sanitizer_start_switch_fiber',
2408 args: '-fsanitize=address',
2409 prefix: '#include <sanitizer/asan_interface.h>')
2410 warning('Missing ASAN due to missing fiber annotation interface')
2411 warning('Without code annotation, the report may be inferior.')
2413 have_asan_fiber = true
2415 config_host_data.set('CONFIG_ASAN_IFACE_FIBER', have_asan_fiber)
2417 have_inotify_init = cc.has_header_symbol('sys/inotify.h', 'inotify_init')
2418 have_inotify_init1 = cc.has_header_symbol('sys/inotify.h', 'inotify_init1')
2420 if (have_inotify_init or have_inotify_init1) and host_os == 'freebsd'
2422 inotify = cc.find_library('inotify')
2423 if have_inotify_init
2424 have_inotify_init = inotify.found()
2426 if have_inotify_init1
2427 have_inotify_init1 = inotify.found()
2430 config_host_data.set('CONFIG_INOTIFY', have_inotify_init)
2431 config_host_data.set('CONFIG_INOTIFY1', have_inotify_init1)
2434 config_host_data.set('CONFIG_BLKZONED',
2435 cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE'))
2436 config_host_data.set('CONFIG_EPOLL_CREATE1',
2437 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
2438 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
2439 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
2440 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
2441 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
2442 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
2443 config_host_data.set('CONFIG_FIEMAP',
2444 cc.has_header('linux/fiemap.h') and
2445 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
2446 config_host_data.set('CONFIG_GETRANDOM',
2447 cc.has_function('getrandom') and
2448 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
2449 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
2450 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
2451 config_host_data.set('CONFIG_RTNETLINK',
2452 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
2453 config_host_data.set('CONFIG_SYSMACROS',
2454 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
2455 config_host_data.set('HAVE_OPTRESET',
2456 cc.has_header_symbol('getopt.h', 'optreset'))
2457 config_host_data.set('HAVE_IPPROTO_MPTCP',
2458 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
2461 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
2462 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
2463 prefix: '#include <signal.h>'))
2464 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
2465 cc.has_member('struct stat', 'st_atim',
2466 prefix: '#include <sys/stat.h>'))
2467 config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY',
2468 cc.has_member('struct blk_zone', 'capacity',
2469 prefix: '#include <linux/blkzoned.h>'))
2472 config_host_data.set('CONFIG_IOVEC',
2473 cc.has_type('struct iovec',
2474 prefix: '#include <sys/uio.h>'))
2475 config_host_data.set('HAVE_UTMPX',
2476 cc.has_type('struct utmpx',
2477 prefix: '#include <utmpx.h>'))
2479 config_host_data.set('CONFIG_EVENTFD', cc.links('''
2480 #include <sys/eventfd.h>
2481 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
2482 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
2485 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
2486 return fdatasync(0);
2488 #error Not supported
2492 has_madvise = cc.links(gnu_source_prefix + '''
2493 #include <sys/types.h>
2494 #include <sys/mman.h>
2496 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
2497 missing_madvise_proto = false
2499 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
2500 # but forget to prototype it. In this case, has_madvise will be true (the
2501 # test program links despite a compile warning). To detect the
2502 # missing-prototype case, we try again with a definitely-bogus prototype.
2503 # This will only compile if the system headers don't provide the prototype;
2504 # otherwise the conflicting prototypes will cause a compiler error.
2505 missing_madvise_proto = cc.links(gnu_source_prefix + '''
2506 #include <sys/types.h>
2507 #include <sys/mman.h>
2509 extern int madvise(int);
2510 int main(void) { return madvise(0); }''')
2512 config_host_data.set('CONFIG_MADVISE', has_madvise)
2513 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
2515 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
2516 #include <sys/mman.h>
2517 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
2518 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
2520 #if !defined(AT_EMPTY_PATH)
2521 # error missing definition
2523 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
2525 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
2526 #include <sys/mman.h>
2528 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
2530 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
2531 #include <pthread.h>
2533 static void *f(void *p) { return NULL; }
2537 pthread_create(&thread, 0, f, 0);
2538 pthread_setname_np(thread, "QEMU");
2540 }''', dependencies: threads))
2541 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
2542 #include <pthread.h>
2544 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
2548 pthread_create(&thread, 0, f, 0);
2550 }''', dependencies: threads))
2551 config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(gnu_source_prefix + '''
2552 #include <pthread.h>
2553 #include <pthread_np.h>
2555 static void *f(void *p) { return NULL; }
2559 pthread_create(&thread, 0, f, 0);
2560 pthread_set_name_np(thread, "QEMU");
2562 }''', dependencies: threads))
2563 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
2564 #include <pthread.h>
2569 pthread_condattr_t attr
2570 pthread_condattr_init(&attr);
2571 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
2573 }''', dependencies: threads))
2574 config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(gnu_source_prefix + '''
2575 #include <pthread.h>
2577 static void *f(void *p) { return NULL; }
2580 int setsize = CPU_ALLOC_SIZE(64);
2583 pthread_create(&thread, 0, f, 0);
2584 cpuset = CPU_ALLOC(64);
2585 CPU_ZERO_S(setsize, cpuset);
2586 pthread_setaffinity_np(thread, setsize, cpuset);
2587 pthread_getaffinity_np(thread, setsize, cpuset);
2590 }''', dependencies: threads))
2591 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
2592 #include <sys/signalfd.h>
2594 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
2595 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
2603 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
2604 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
2608 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
2609 #include <sys/mman.h>
2611 return mlockall(MCL_FUTURE);
2615 if get_option('l2tpv3').allowed() and have_system
2616 have_l2tpv3 = cc.has_type('struct mmsghdr',
2617 prefix: gnu_source_prefix + '''
2618 #include <sys/socket.h>
2619 #include <linux/ip.h>''')
2621 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2624 if get_option('netmap').allowed() and have_system
2625 have_netmap = cc.compiles('''
2626 #include <inttypes.h>
2628 #include <net/netmap.h>
2629 #include <net/netmap_user.h>
2630 #if (NETMAP_API < 11) || (NETMAP_API > 15)
2633 int main(void) { return 0; }''')
2634 if not have_netmap and get_option('netmap').enabled()
2635 error('Netmap headers not available')
2638 config_host_data.set('CONFIG_NETMAP', have_netmap)
2640 # Work around a system header bug with some kernel/XFS header
2641 # versions where they both try to define 'struct fsxattr':
2642 # xfs headers will not try to redefine structs from linux headers
2643 # if this macro is set.
2644 config_host_data.set('HAVE_FSXATTR', cc.links('''
2645 #include <linux/fs.h>
2651 # Some versions of Mac OS X incorrectly define SIZE_MAX
2652 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2656 return printf("%zu", SIZE_MAX);
2657 }''', args: ['-Werror']))
2659 # See if 64-bit atomic operations are supported.
2660 # Note that without __atomic builtins, we can only
2661 # assume atomic loads/stores max at pointer size.
2662 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
2666 uint64_t x = 0, y = 0;
2667 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2668 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2669 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2670 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2671 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2675 has_int128_type = cc.compiles('''
2678 int main(void) { b = a; }''')
2679 config_host_data.set('CONFIG_INT128_TYPE', has_int128_type)
2681 has_int128 = has_int128_type and cc.links('''
2690 config_host_data.set('CONFIG_INT128', has_int128)
2693 # "do we have 128-bit atomics which are handled inline and specifically not
2694 # via libatomic". The reason we can't use libatomic is documented in the
2695 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2696 # We only care about these operations on 16-byte aligned pointers, so
2697 # force 16-byte alignment of the pointer, which may be greater than
2698 # __alignof(unsigned __int128) for the host.
2699 atomic_test_128 = '''
2700 int main(int ac, char **av) {
2701 __uint128_t *p = __builtin_assume_aligned(av[ac - 1], 16);
2702 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED);
2703 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED);
2704 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2707 has_atomic128 = cc.links(atomic_test_128)
2709 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2711 if not has_atomic128
2712 # Even with __builtin_assume_aligned, the above test may have failed
2713 # without optimization enabled. Try again with optimizations locally
2714 # enabled for the function. See
2715 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389
2716 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128)
2717 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt)
2719 if not has_atomic128_opt
2720 config_host_data.set('CONFIG_CMPXCHG128', cc.links('''
2723 __uint128_t x = 0, y = 0;
2724 __sync_val_compare_and_swap_16(&x, y, x);
2732 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2733 #include <sys/auxv.h>
2735 return getauxval(AT_HWCAP) == 0;
2738 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2739 #include <linux/usbdevice_fs.h>
2741 #ifndef USBDEVFS_GET_CAPABILITIES
2742 #error "USBDEVFS_GET_CAPABILITIES undefined"
2745 #ifndef USBDEVFS_DISCONNECT_CLAIM
2746 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2749 int main(void) { return 0; }'''))
2751 have_keyring = get_option('keyring') \
2752 .require(host_os == 'linux', error_message: 'keyring is only available on Linux') \
2753 .require(cc.compiles('''
2755 #include <asm/unistd.h>
2756 #include <linux/keyctl.h>
2757 #include <sys/syscall.h>
2760 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2761 }'''), error_message: 'keyctl syscall not available on this system').allowed()
2762 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2764 have_cpuid_h = cc.links('''
2767 unsigned a, b, c, d;
2768 unsigned max = __get_cpuid_max(0, 0);
2771 __cpuid(1, a, b, c, d);
2775 __cpuid_count(7, 0, a, b, c, d);
2780 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2782 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2783 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2784 .require(cc.links('''
2786 #include <immintrin.h>
2787 static int __attribute__((target("avx2"))) bar(void *a) {
2788 __m256i x = *(__m256i *)a;
2789 return _mm256_testz_si256(x, x);
2791 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2792 '''), error_message: 'AVX2 not available').allowed())
2794 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2795 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2796 .require(cc.links('''
2798 #include <immintrin.h>
2799 static int __attribute__((target("avx512f"))) bar(void *a) {
2800 __m512i x = *(__m512i *)a;
2801 return _mm512_test_epi64_mask(x, x);
2803 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2804 '''), error_message: 'AVX512F not available').allowed())
2806 config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \
2807 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \
2808 .require(cc.links('''
2810 #include <immintrin.h>
2811 static int __attribute__((target("avx512bw"))) bar(void *a) {
2813 __m512i res= _mm512_abs_epi8(*x);
2816 int main(int argc, char *argv[]) { return bar(argv[0]); }
2817 '''), error_message: 'AVX512BW not available').allowed())
2819 # For both AArch64 and AArch32, detect if builtins are available.
2820 config_host_data.set('CONFIG_ARM_AES_BUILTIN', cc.compiles('''
2821 #include <arm_neon.h>
2822 #ifndef __ARM_FEATURE_AES
2823 __attribute__((target("+crypto")))
2825 void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); }
2828 have_pvrdma = get_option('pvrdma') \
2829 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
2830 .require(cc.compiles(gnu_source_prefix + '''
2831 #include <sys/mman.h>
2836 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2839 }'''), error_message: 'PVRDMA requires mremap').allowed()
2842 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.links('''
2843 #include <infiniband/verbs.h>
2847 struct ibv_pd *pd = NULL;
2853 mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2859 if get_option('membarrier').disabled()
2860 have_membarrier = false
2861 elif host_os == 'windows'
2862 have_membarrier = true
2863 elif host_os == 'linux'
2864 have_membarrier = cc.compiles('''
2865 #include <linux/membarrier.h>
2866 #include <sys/syscall.h>
2870 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2871 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2875 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2876 .require(have_membarrier, error_message: 'membarrier system call not available') \
2879 have_afalg = get_option('crypto_afalg') \
2880 .require(cc.compiles(gnu_source_prefix + '''
2882 #include <sys/types.h>
2883 #include <sys/socket.h>
2884 #include <linux/if_alg.h>
2887 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2890 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2891 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2893 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2894 'linux/vm_sockets.h', 'AF_VSOCK',
2895 prefix: '#include <sys/socket.h>',
2899 have_vss_sdk = false # old xp/2003 SDK
2900 if host_os == 'windows' and 'cpp' in all_languages
2901 have_vss = cxx.compiles('''
2902 #define __MIDL_user_allocate_free_DEFINED__
2904 int main(void) { return VSS_CTX_BACKUP; }''')
2905 have_vss_sdk = cxx.has_header('vscoordint.h')
2907 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2909 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2910 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2911 if host_os == 'windows'
2912 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2918 }''', name: '_lock_file and _unlock_file'))
2921 if host_os == 'windows'
2922 mingw_has_setjmp_longjmp = cc.links('''
2926 * These functions are not available in setjmp header, but may be
2927 * available at link time, from libmingwex.a.
2929 extern int __mingw_setjmp(jmp_buf);
2930 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
2932 __mingw_setjmp(env);
2933 __mingw_longjmp(env, 0);
2935 ''', name: 'mingw setjmp and longjmp')
2937 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp
2938 error('mingw must provide setjmp/longjmp for windows-arm64')
2942 ########################
2943 # Target configuration #
2944 ########################
2946 minikconf = find_program('scripts/minikconf.py')
2948 config_all_accel = {}
2949 config_all_devices = {}
2950 config_devices_mak_list = []
2951 config_devices_h = {}
2952 config_target_h = {}
2953 config_target_mak = {}
2956 'alpha' : ['CONFIG_ALPHA_DIS'],
2957 'avr' : ['CONFIG_AVR_DIS'],
2958 'cris' : ['CONFIG_CRIS_DIS'],
2959 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2960 'hppa' : ['CONFIG_HPPA_DIS'],
2961 'i386' : ['CONFIG_I386_DIS'],
2962 'x86_64' : ['CONFIG_I386_DIS'],
2963 'm68k' : ['CONFIG_M68K_DIS'],
2964 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2965 'mips' : ['CONFIG_MIPS_DIS'],
2966 'nios2' : ['CONFIG_NIOS2_DIS'],
2967 'or1k' : ['CONFIG_OPENRISC_DIS'],
2968 'ppc' : ['CONFIG_PPC_DIS'],
2969 'riscv' : ['CONFIG_RISCV_DIS'],
2970 'rx' : ['CONFIG_RX_DIS'],
2971 's390' : ['CONFIG_S390_DIS'],
2972 'sh4' : ['CONFIG_SH4_DIS'],
2973 'sparc' : ['CONFIG_SPARC_DIS'],
2974 'xtensa' : ['CONFIG_XTENSA_DIS'],
2975 'loongarch' : ['CONFIG_LOONGARCH_DIS'],
2978 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2980 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2981 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2982 (pixman.found() ? ['CONFIG_PIXMAN=y'] : []) + \
2983 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2984 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2985 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2986 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2987 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
2988 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2989 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2990 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2991 (host_os == 'linux' ? ['CONFIG_LINUX=y'] : []) + \
2992 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
2993 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
2994 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \
2995 (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : [])
2997 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2999 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
3000 actual_target_dirs = []
3002 foreach target : target_dirs
3003 config_target = { 'TARGET_NAME': target.split('-')[0] }
3004 if target.endswith('linux-user')
3005 if host_os != 'linux'
3009 error('Target @0@ is only available on a Linux host'.format(target))
3011 config_target += { 'CONFIG_LINUX_USER': 'y' }
3012 elif target.endswith('bsd-user')
3013 if host_os not in bsd_oses
3017 error('Target @0@ is only available on a BSD host'.format(target))
3019 config_target += { 'CONFIG_BSD_USER': 'y' }
3020 elif target.endswith('softmmu')
3021 config_target += { 'CONFIG_SYSTEM_ONLY': 'y' }
3022 config_target += { 'CONFIG_SOFTMMU': 'y' }
3024 if target.endswith('-user')
3026 'CONFIG_USER_ONLY': 'y',
3027 'CONFIG_QEMU_INTERP_PREFIX':
3028 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
3033 foreach sym: accelerators
3034 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
3035 config_target += { sym: 'y' }
3036 config_all_accel += { sym: 'y' }
3037 if target in modular_tcg
3038 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
3040 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
3042 accel_kconfig += [ sym + '=y' ]
3045 if accel_kconfig.length() == 0
3049 error('No accelerator available for target @0@'.format(target))
3052 actual_target_dirs += target
3053 config_target += keyval.load('configs/targets' / target + '.mak')
3054 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
3056 if 'TARGET_NEED_FDT' in config_target
3057 fdt_required += target
3061 if 'TARGET_BASE_ARCH' not in config_target
3062 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
3064 if 'TARGET_ABI_DIR' not in config_target
3065 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
3067 if 'TARGET_BIG_ENDIAN' not in config_target
3068 config_target += {'TARGET_BIG_ENDIAN': 'n'}
3071 foreach k, v: disassemblers
3072 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
3074 config_target += { sym: 'y' }
3079 config_target_data = configuration_data()
3080 foreach k, v: config_target
3081 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
3083 elif ignored.contains(k)
3085 elif k == 'TARGET_BASE_ARCH'
3086 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
3087 # not used to select files from sourcesets.
3088 config_target_data.set('TARGET_' + v.to_upper(), 1)
3089 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
3090 config_target_data.set_quoted(k, v)
3092 config_target_data.set(k, 1)
3094 config_target_data.set(k, 0)
3096 config_target_data.set(k, v)
3099 config_target_data.set('QEMU_ARCH',
3100 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
3101 config_target_h += {target: configure_file(output: target + '-config-target.h',
3102 configuration: config_target_data)}
3104 if target.endswith('-softmmu')
3105 config_input = meson.get_external_property(target, 'default')
3106 config_devices_mak = target + '-config-devices.mak'
3107 config_devices_mak = configure_file(
3108 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
3109 output: config_devices_mak,
3110 depfile: config_devices_mak + '.d',
3112 command: [minikconf,
3113 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
3114 config_devices_mak, '@DEPFILE@', '@INPUT@',
3115 host_kconfig, accel_kconfig,
3116 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
3118 config_devices_data = configuration_data()
3119 config_devices = keyval.load(config_devices_mak)
3120 foreach k, v: config_devices
3121 config_devices_data.set(k, 1)
3123 config_devices_mak_list += config_devices_mak
3124 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
3125 configuration: config_devices_data)}
3126 config_target += config_devices
3127 config_all_devices += config_devices
3129 config_target_mak += {target: config_target}
3131 target_dirs = actual_target_dirs
3133 target_configs_h = []
3134 foreach target: target_dirs
3135 target_configs_h += config_target_h[target]
3136 target_configs_h += config_devices_h.get(target, [])
3138 genh += custom_target('config-poison.h',
3139 input: [target_configs_h],
3140 output: 'config-poison.h',
3142 command: [find_program('scripts/make-config-poison.sh'),
3149 libvfio_user_dep = not_found
3150 if have_system and vfio_user_server_allowed
3151 libvfio_user_proj = subproject('libvfio-user', required: true)
3152 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep')
3156 fdt_opt = get_option('fdt')
3157 if fdt_required.length() > 0 or fdt_opt == 'enabled'
3158 if fdt_opt == 'disabled'
3159 error('fdt disabled but required by targets ' + ', '.join(fdt_required))
3162 if fdt_opt in ['enabled', 'auto', 'system']
3163 if get_option('wrap_mode') == 'nodownload'
3166 fdt = cc.find_library('fdt', required: fdt_opt == 'system')
3167 if fdt.found() and cc.links('''
3169 #include <libfdt_env.h>
3170 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
3173 elif fdt_opt == 'system'
3174 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
3176 fdt_opt = 'internal'
3181 assert(fdt_opt == 'internal')
3182 libfdt_proj = subproject('dtc', required: true,
3183 default_options: ['tools=false', 'yaml=disabled',
3184 'python=disabled', 'default_library=static'])
3185 fdt = libfdt_proj.get_variable('libfdt_dep')
3188 fdt_opt = 'disabled'
3191 config_host_data.set('CONFIG_FDT', fdt.found())
3193 vhost_user = not_found
3194 if host_os == 'linux' and have_vhost_user
3195 libvhost_user = subproject('libvhost-user')
3196 vhost_user = libvhost_user.get_variable('vhost_user_dep')
3199 libvduse = not_found
3201 libvduse_proj = subproject('libvduse')
3202 libvduse = libvduse_proj.get_variable('libvduse_dep')
3205 #####################
3206 # Generated sources #
3207 #####################
3209 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
3211 hxtool = find_program('scripts/hxtool')
3212 shaderinclude = find_program('scripts/shaderinclude.py')
3213 qapi_gen = find_program('scripts/qapi-gen.py')
3214 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
3215 meson.current_source_dir() / 'scripts/qapi/commands.py',
3216 meson.current_source_dir() / 'scripts/qapi/common.py',
3217 meson.current_source_dir() / 'scripts/qapi/error.py',
3218 meson.current_source_dir() / 'scripts/qapi/events.py',
3219 meson.current_source_dir() / 'scripts/qapi/expr.py',
3220 meson.current_source_dir() / 'scripts/qapi/gen.py',
3221 meson.current_source_dir() / 'scripts/qapi/introspect.py',
3222 meson.current_source_dir() / 'scripts/qapi/main.py',
3223 meson.current_source_dir() / 'scripts/qapi/parser.py',
3224 meson.current_source_dir() / 'scripts/qapi/schema.py',
3225 meson.current_source_dir() / 'scripts/qapi/source.py',
3226 meson.current_source_dir() / 'scripts/qapi/types.py',
3227 meson.current_source_dir() / 'scripts/qapi/visit.py',
3228 meson.current_source_dir() / 'scripts/qapi-gen.py'
3232 python, files('scripts/tracetool.py'),
3233 '--backend=' + ','.join(get_option('trace_backends'))
3235 tracetool_depends = files(
3236 'scripts/tracetool/backend/log.py',
3237 'scripts/tracetool/backend/__init__.py',
3238 'scripts/tracetool/backend/dtrace.py',
3239 'scripts/tracetool/backend/ftrace.py',
3240 'scripts/tracetool/backend/simple.py',
3241 'scripts/tracetool/backend/syslog.py',
3242 'scripts/tracetool/backend/ust.py',
3243 'scripts/tracetool/format/ust_events_c.py',
3244 'scripts/tracetool/format/ust_events_h.py',
3245 'scripts/tracetool/format/__init__.py',
3246 'scripts/tracetool/format/d.py',
3247 'scripts/tracetool/format/simpletrace_stap.py',
3248 'scripts/tracetool/format/c.py',
3249 'scripts/tracetool/format/h.py',
3250 'scripts/tracetool/format/log_stap.py',
3251 'scripts/tracetool/format/stap.py',
3252 'scripts/tracetool/__init__.py',
3253 'scripts/tracetool/vcpu.py'
3256 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
3257 meson.current_source_dir(),
3258 get_option('pkgversion'), meson.project_version()]
3259 qemu_version = custom_target('qemu-version.h',
3260 output: 'qemu-version.h',
3261 command: qemu_version_cmd,
3263 build_by_default: true,
3264 build_always_stale: true)
3265 genh += qemu_version
3269 ['qemu-options.hx', 'qemu-options.def'],
3270 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
3274 ['hmp-commands.hx', 'hmp-commands.h'],
3275 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
3278 foreach d : hx_headers
3279 hxdep += custom_target(d[1],
3283 command: [hxtool, '-h', '@INPUT0@'])
3291 # TODO: add each directory to the subdirs from its own meson.build, once
3293 trace_events_subdirs = [
3302 trace_events_subdirs += [ 'linux-user' ]
3305 trace_events_subdirs += [ 'bsd-user' ]
3308 trace_events_subdirs += [
3317 trace_events_subdirs += [
3382 if have_system or have_user
3383 trace_events_subdirs += [
3406 authz_ss = ss.source_set()
3407 blockdev_ss = ss.source_set()
3408 block_ss = ss.source_set()
3409 chardev_ss = ss.source_set()
3410 common_ss = ss.source_set()
3411 crypto_ss = ss.source_set()
3412 hwcore_ss = ss.source_set()
3413 io_ss = ss.source_set()
3414 qmp_ss = ss.source_set()
3415 qom_ss = ss.source_set()
3416 system_ss = ss.source_set()
3417 specific_fuzz_ss = ss.source_set()
3418 specific_ss = ss.source_set()
3419 stub_ss = ss.source_set()
3420 trace_ss = ss.source_set()
3421 user_ss = ss.source_set()
3422 util_ss = ss.source_set()
3425 qtest_module_ss = ss.source_set()
3426 tcg_module_ss = ss.source_set()
3432 target_system_arch = {}
3433 target_user_arch = {}
3435 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3436 # that is filled in by qapi/.
3450 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3451 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3454 qom_ss = qom_ss.apply({})
3455 libqom = static_library('qom', qom_ss.sources() + genh,
3456 dependencies: [qom_ss.dependencies()],
3458 build_by_default: false)
3459 qom = declare_dependency(link_whole: libqom)
3461 event_loop_base = files('event-loop-base.c')
3462 event_loop_base = static_library('event-loop-base',
3463 sources: event_loop_base + genh,
3465 build_by_default: false)
3466 event_loop_base = declare_dependency(link_whole: event_loop_base,
3467 dependencies: [qom])
3469 stub_ss = stub_ss.apply({})
3471 util_ss.add_all(trace_ss)
3472 util_ss = util_ss.apply({})
3473 libqemuutil = static_library('qemuutil',
3474 build_by_default: false,
3475 sources: util_ss.sources() + stub_ss.sources() + genh,
3476 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
3477 qemuutil = declare_dependency(link_with: libqemuutil,
3478 sources: genh + version_res,
3479 dependencies: [event_loop_base])
3481 if have_system or have_user
3482 decodetree = generator(find_program('scripts/decodetree.py'),
3483 output: 'decode-@BASENAME@.c.inc',
3484 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3485 subdir('libdecnumber')
3502 if config_host_data.get('CONFIG_REPLICATION')
3503 block_ss.add(files('replication.c'))
3510 blockdev_ss.add(files(
3517 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3518 # os-win32.c does not
3519 if host_os == 'windows'
3520 system_ss.add(files('os-win32.c'))
3522 blockdev_ss.add(files('os-posix.c'))
3526 common_ss.add(files('cpu-common.c'))
3527 specific_ss.add(files('cpu-target.c'))
3531 # Work around a gcc bug/misfeature wherein constant propagation looks
3533 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3534 # to guess that a const variable is always zero. Without lto, this is
3535 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
3536 # without lto, not even the alias is required -- we simply use different
3537 # declarations in different compilation units.
3538 pagevary = files('page-vary-common.c')
3539 if get_option('b_lto')
3540 pagevary_flags = ['-fno-lto']
3541 if get_option('cfi')
3542 pagevary_flags += '-fno-sanitize=cfi-icall'
3544 pagevary = static_library('page-vary-common', sources: pagevary + genh,
3545 c_args: pagevary_flags)
3546 pagevary = declare_dependency(link_with: pagevary)
3548 common_ss.add(pagevary)
3549 specific_ss.add(files('page-vary-target.c'))
3557 subdir('semihosting')
3565 common_user_inc = []
3567 subdir('common-user')
3569 subdir('linux-user')
3571 # needed for fuzzing binaries
3572 subdir('tests/qtest/libqos')
3573 subdir('tests/qtest/fuzz')
3576 tcg_real_module_ss = ss.source_set()
3577 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3578 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3579 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3580 'tcg': tcg_real_module_ss }}
3582 ##############################################
3583 # Internal static_libraries and dependencies #
3584 ##############################################
3586 modinfo_collect = find_program('scripts/modinfo-collect.py')
3587 modinfo_generate = find_program('scripts/modinfo-generate.py')
3592 foreach d, list : modules
3593 if not (d == 'block' ? have_block : have_system)
3597 foreach m, module_ss : list
3599 module_ss = module_ss.apply(config_all_devices, strict: false)
3600 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3601 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3607 if module_ss.sources() != []
3608 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3609 # input. Sources can be used multiple times but objects are
3610 # unique when it comes to lookup in compile_commands.json.
3611 # Depnds on a mesion version with
3612 # https://github.com/mesonbuild/meson/pull/8900
3613 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3614 output: d + '-' + m + '.modinfo',
3615 input: module_ss.sources() + genh,
3617 command: [modinfo_collect, module_ss.sources()])
3621 block_ss.add_all(module_ss)
3623 system_ss.add_all(module_ss)
3629 foreach d, list : target_modules
3630 foreach m, module_ss : list
3632 foreach target : target_dirs
3633 if target.endswith('-softmmu')
3634 config_target = config_target_mak[target]
3635 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3636 c_args = ['-DNEED_CPU_H',
3637 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3638 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3639 target_module_ss = module_ss.apply(config_target, strict: false)
3640 if target_module_ss.sources() != []
3641 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3642 sl = static_library(module_name,
3643 [genh, target_module_ss.sources()],
3644 dependencies: [modulecommon, target_module_ss.dependencies()],
3645 include_directories: target_inc,
3649 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3650 modinfo_files += custom_target(module_name + '.modinfo',
3651 output: module_name + '.modinfo',
3652 input: target_module_ss.sources() + genh,
3654 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3659 specific_ss.add_all(module_ss)
3665 foreach target : target_dirs
3666 if target.endswith('-softmmu')
3667 config_target = config_target_mak[target]
3668 config_devices_mak = target + '-config-devices.mak'
3669 modinfo_src = custom_target('modinfo-' + target + '.c',
3670 output: 'modinfo-' + target + '.c',
3671 input: modinfo_files,
3672 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'],
3675 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
3676 modinfo_dep = declare_dependency(link_with: modinfo_lib)
3678 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH']
3679 hw_arch[arch].add(modinfo_dep)
3684 nm = find_program('nm')
3685 undefsym = find_program('scripts/undefsym.py')
3686 block_syms = custom_target('block.syms', output: 'block.syms',
3687 input: [libqemuutil, block_mods],
3689 command: [undefsym, nm, '@INPUT@'])
3690 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3691 input: [libqemuutil, system_mods],
3693 command: [undefsym, nm, '@INPUT@'])
3695 authz_ss = authz_ss.apply({})
3696 libauthz = static_library('authz', authz_ss.sources() + genh,
3697 dependencies: [authz_ss.dependencies()],
3699 build_by_default: false)
3701 authz = declare_dependency(link_whole: libauthz,
3704 crypto_ss = crypto_ss.apply({})
3705 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3706 dependencies: [crypto_ss.dependencies()],
3708 build_by_default: false)
3710 crypto = declare_dependency(link_whole: libcrypto,
3711 dependencies: [authz, qom])
3713 io_ss = io_ss.apply({})
3714 libio = static_library('io', io_ss.sources() + genh,
3715 dependencies: [io_ss.dependencies()],
3716 link_with: libqemuutil,
3718 build_by_default: false)
3720 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3722 libmigration = static_library('migration', sources: migration_files + genh,
3724 build_by_default: false)
3725 migration = declare_dependency(link_with: libmigration,
3726 dependencies: [zlib, qom, io])
3727 system_ss.add(migration)
3729 block_ss = block_ss.apply({})
3730 libblock = static_library('block', block_ss.sources() + genh,
3731 dependencies: block_ss.dependencies(),
3732 link_depends: block_syms,
3734 build_by_default: false)
3736 block = declare_dependency(link_whole: [libblock],
3737 link_args: '@block.syms',
3738 dependencies: [crypto, io])
3740 blockdev_ss = blockdev_ss.apply({})
3741 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3742 dependencies: blockdev_ss.dependencies(),
3744 build_by_default: false)
3746 blockdev = declare_dependency(link_whole: [libblockdev],
3747 dependencies: [block, event_loop_base])
3749 qmp_ss = qmp_ss.apply({})
3750 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3751 dependencies: qmp_ss.dependencies(),
3753 build_by_default: false)
3755 qmp = declare_dependency(link_whole: [libqmp])
3757 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3759 dependencies: chardev_ss.dependencies(),
3760 build_by_default: false)
3762 chardev = declare_dependency(link_whole: libchardev)
3764 hwcore_ss = hwcore_ss.apply({})
3765 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3767 build_by_default: false)
3768 hwcore = declare_dependency(link_whole: libhwcore)
3769 common_ss.add(hwcore)
3775 emulator_modules = []
3776 foreach m : block_mods + system_mods
3777 emulator_modules += shared_module(m.name(),
3778 build_by_default: true,
3782 install_dir: qemu_moddir)
3784 if emulator_modules.length() > 0
3785 alias_target('modules', emulator_modules)
3788 system_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3789 common_ss.add(qom, qemuutil)
3791 common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss])
3792 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3794 # Note that this library is never used directly (only through extract_objects)
3795 # and is not built by default; therefore, source files not used by the build
3796 # configuration will be in build.ninja, but are never built by default.
3797 common_all = static_library('common',
3798 build_by_default: false,
3799 sources: common_ss.all_sources() + genh,
3800 include_directories: common_user_inc,
3801 implicit_include_directories: false,
3802 dependencies: common_ss.all_dependencies(),
3805 feature_to_c = find_program('scripts/feature_to_c.py')
3807 if host_os == 'darwin'
3808 entitlement = find_program('scripts/entitlement.sh')
3812 foreach target : target_dirs
3813 config_target = config_target_mak[target]
3814 target_name = config_target['TARGET_NAME']
3815 target_base_arch = config_target['TARGET_BASE_ARCH']
3816 arch_srcs = [config_target_h[target]]
3818 c_args = ['-DNEED_CPU_H',
3819 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3820 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3821 link_args = emulator_link_args
3823 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3824 if host_os == 'linux'
3825 target_inc += include_directories('linux-headers', is_system: true)
3827 if target.endswith('-softmmu')
3828 target_type='system'
3829 t = target_system_arch[target_base_arch].apply(config_target, strict: false)
3830 arch_srcs += t.sources()
3831 arch_deps += t.dependencies()
3833 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3834 if hw_arch.has_key(hw_dir)
3835 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3836 arch_srcs += hw.sources()
3837 arch_deps += hw.dependencies()
3840 arch_srcs += config_devices_h[target]
3841 link_args += ['@block.syms', '@qemu.syms']
3843 abi = config_target['TARGET_ABI_DIR']
3845 target_inc += common_user_inc
3846 if target_base_arch in target_user_arch
3847 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3848 arch_srcs += t.sources()
3849 arch_deps += t.dependencies()
3851 if 'CONFIG_LINUX_USER' in config_target
3852 base_dir = 'linux-user'
3854 if 'CONFIG_BSD_USER' in config_target
3855 base_dir = 'bsd-user'
3856 target_inc += include_directories('bsd-user/' / host_os)
3857 target_inc += include_directories('bsd-user/host/' / host_arch)
3858 dir = base_dir / abi
3859 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3861 target_inc += include_directories(
3865 if 'CONFIG_LINUX_USER' in config_target
3866 dir = base_dir / abi
3867 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3868 if config_target.has_key('TARGET_SYSTBL_ABI')
3870 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3871 extra_args : config_target['TARGET_SYSTBL_ABI'])
3876 if 'TARGET_XML_FILES' in config_target
3877 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3878 output: target + '-gdbstub-xml.c',
3879 input: files(config_target['TARGET_XML_FILES'].split()),
3880 command: [feature_to_c, '@INPUT@'],
3882 arch_srcs += gdbstub_xml
3885 t = target_arch[target_base_arch].apply(config_target, strict: false)
3886 arch_srcs += t.sources()
3887 arch_deps += t.dependencies()
3889 target_common = common_ss.apply(config_target, strict: false)
3890 objects = common_all.extract_objects(target_common.sources())
3891 deps = target_common.dependencies()
3893 target_specific = specific_ss.apply(config_target, strict: false)
3894 arch_srcs += target_specific.sources()
3895 arch_deps += target_specific.dependencies()
3897 lib = static_library('qemu-' + target,
3898 sources: arch_srcs + genh,
3899 dependencies: arch_deps,
3901 include_directories: target_inc,
3903 build_by_default: false,
3906 if target.endswith('-softmmu')
3908 'name': 'qemu-system-' + target_name,
3909 'win_subsystem': 'console',
3910 'sources': files('system/main.c'),
3913 if host_os == 'windows' and (sdl.found() or gtk.found())
3915 'name': 'qemu-system-' + target_name + 'w',
3916 'win_subsystem': 'windows',
3917 'sources': files('system/main.c'),
3921 if get_option('fuzzing')
3922 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3924 'name': 'qemu-fuzz-' + target_name,
3925 'win_subsystem': 'console',
3926 'sources': specific_fuzz.sources(),
3927 'dependencies': specific_fuzz.dependencies(),
3932 'name': 'qemu-' + target_name,
3933 'win_subsystem': 'console',
3939 exe_name = exe['name']
3940 if host_os == 'darwin'
3941 exe_name += '-unsigned'
3944 emulator = executable(exe_name, exe['sources'],
3947 dependencies: arch_deps + deps + exe['dependencies'],
3948 objects: lib.extract_all_objects(recursive: true),
3949 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3950 link_args: link_args,
3951 win_subsystem: exe['win_subsystem'])
3953 if host_os == 'darwin'
3954 icon = 'pc-bios/qemu.rsrc'
3955 build_input = [emulator, files(icon)]
3957 get_option('bindir') / exe_name,
3958 meson.current_source_dir() / icon
3960 if 'CONFIG_HVF' in config_target
3961 entitlements = 'accel/hvf/entitlements.plist'
3962 build_input += files(entitlements)
3963 install_input += meson.current_source_dir() / entitlements
3966 emulators += {exe['name'] : custom_target(exe['name'],
3968 output: exe['name'],
3969 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3972 meson.add_install_script(entitlement, '--install',
3973 get_option('bindir') / exe['name'],
3976 emulators += {exe['name']: emulator}
3981 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3982 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3983 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3984 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3986 custom_target(exe['name'] + stp['ext'],
3987 input: trace_events_all,
3988 output: exe['name'] + stp['ext'],
3989 install: stp['install'],
3990 install_dir: get_option('datadir') / 'systemtap/tapset',
3992 tracetool, '--group=all', '--format=' + stp['fmt'],
3993 '--binary=' + stp['bin'],
3994 '--target-name=' + target_name,
3995 '--target-type=' + target_type,
3996 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3997 '@INPUT@', '@OUTPUT@'
3999 depend_files: tracetool_depends)
4005 # Other build targets
4007 if get_option('plugins')
4008 install_headers('include/qemu/qemu-plugin.h')
4009 if host_os == 'windows'
4010 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer,
4011 # so that plugin authors can compile against it.
4012 install_data(win32_qemu_plugin_api_lib, install_dir: 'lib')
4018 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
4019 # when we don't build tools or system
4020 if xkbcommon.found()
4021 # used for the update-keymaps target, so include rules even if !have_tools
4022 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
4023 dependencies: [qemuutil, xkbcommon], install: have_tools)
4027 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
4028 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
4029 qemu_io = executable('qemu-io', files('qemu-io.c'),
4030 dependencies: [block, qemuutil], install: true)
4031 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
4032 dependencies: [blockdev, qemuutil, gnutls, selinux],
4035 subdir('storage-daemon')
4036 subdir('contrib/rdmacm-mux')
4037 subdir('contrib/elf2dmp')
4039 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
4040 dependencies: qemuutil,
4044 subdir('contrib/vhost-user-blk')
4045 subdir('contrib/vhost-user-gpu')
4046 subdir('contrib/vhost-user-input')
4047 subdir('contrib/vhost-user-scsi')
4050 if host_os == 'linux'
4051 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
4052 dependencies: [qemuutil, libcap_ng],
4054 install_dir: get_option('libexecdir'))
4056 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
4057 dependencies: [authz, crypto, io, qom, qemuutil,
4058 libcap_ng, mpathpersist],
4063 subdir('contrib/ivshmem-client')
4064 subdir('contrib/ivshmem-server')
4077 if host_machine.system() == 'windows'
4079 find_program('scripts/nsis.py'),
4081 get_option('prefix'),
4082 meson.current_source_dir(),
4083 glib_pc.get_variable('bindir'),
4086 '-DDISPLAYVERSION=' + meson.project_version(),
4089 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
4092 nsis_cmd += '-DCONFIG_GTK=y'
4095 nsis = custom_target('nsis',
4096 output: 'qemu-setup-' + meson.project_version() + '.exe',
4097 input: files('qemu.nsi'),
4098 build_always_stale: true,
4099 command: nsis_cmd + ['@INPUT@'])
4100 alias_target('installer', nsis)
4103 #########################
4104 # Configuration summary #
4105 #########################
4109 summary_info += {'Build directory': meson.current_build_dir()}
4110 summary_info += {'Source path': meson.current_source_dir()}
4111 summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'}
4112 summary(summary_info, bool_yn: true, section: 'Build environment')
4115 summary_info += {'Install prefix': get_option('prefix')}
4116 summary_info += {'BIOS directory': qemu_datadir}
4117 pathsep = host_os == 'windows' ? ';' : ':'
4118 summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))}
4119 summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
4120 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
4121 summary_info += {'module directory': qemu_moddir}
4122 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
4123 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
4124 summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')}
4125 if host_os != 'windows'
4126 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
4127 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')}
4129 summary_info += {'local state directory': 'queried at runtime'}
4131 summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
4132 summary(summary_info, bool_yn: true, section: 'Directories')
4136 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
4137 summary_info += {'sphinx-build': sphinx_build}
4139 # FIXME: the [binaries] section of machine files, which can be probed
4140 # with find_program(), would be great for passing gdb and genisoimage
4141 # paths from configure to Meson. However, there seems to be no way to
4142 # hide a program (for example if gdb is too old).
4143 if config_host.has_key('GDB')
4144 summary_info += {'gdb': config_host['GDB']}
4146 summary_info += {'iasl': iasl}
4147 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
4148 if host_os == 'windows' and have_ga
4149 summary_info += {'wixl': wixl}
4151 if slirp.found() and have_system
4152 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
4154 summary(summary_info, bool_yn: true, section: 'Host binaries')
4156 # Configurable features
4158 summary_info += {'Documentation': build_docs}
4159 summary_info += {'system-mode emulation': have_system}
4160 summary_info += {'user-mode emulation': have_user}
4161 summary_info += {'block layer': have_block}
4162 summary_info += {'Install blobs': get_option('install_blobs')}
4163 summary_info += {'module support': enable_modules}
4165 summary_info += {'alternative module path': get_option('module_upgrades')}
4167 summary_info += {'fuzzing support': get_option('fuzzing')}
4169 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
4171 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
4172 if 'simple' in get_option('trace_backends')
4173 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
4175 summary_info += {'D-Bus display': dbus_display}
4176 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
4177 summary_info += {'Relocatable install': get_option('relocatable')}
4178 summary_info += {'vhost-kernel support': have_vhost_kernel}
4179 summary_info += {'vhost-net support': have_vhost_net}
4180 summary_info += {'vhost-user support': have_vhost_user}
4181 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
4182 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
4183 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
4184 summary_info += {'build guest agent': have_ga}
4185 summary(summary_info, bool_yn: true, section: 'Configurable features')
4187 # Compilation information
4189 summary_info += {'host CPU': cpu}
4190 summary_info += {'host endianness': build_machine.endian()}
4191 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
4192 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
4193 if 'cpp' in all_languages
4194 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
4196 summary_info += {'C++ compiler': false}
4198 if 'objc' in all_languages
4199 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
4201 summary_info += {'Objective-C compiler': false}
4203 option_cflags = (get_option('debug') ? ['-g'] : [])
4204 if get_option('optimization') != 'plain'
4205 option_cflags += ['-O' + get_option('optimization')]
4207 summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)}
4208 if 'cpp' in all_languages
4209 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)}
4211 if 'objc' in all_languages
4212 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)}
4214 link_args = get_option('c_link_args')
4215 if link_args.length() > 0
4216 summary_info += {'LDFLAGS': ' '.join(link_args)}
4218 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)}
4219 if 'cpp' in all_languages
4220 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)}
4222 if 'objc' in all_languages
4223 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)}
4225 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
4226 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
4227 summary_info += {'PIE': get_option('b_pie')}
4228 summary_info += {'static build': get_option('prefer_static')}
4229 summary_info += {'malloc trim support': has_malloc_trim}
4230 summary_info += {'membarrier': have_membarrier}
4231 summary_info += {'debug graph lock': get_option('debug_graph_lock')}
4232 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
4233 summary_info += {'mutex debugging': get_option('debug_mutex')}
4234 summary_info += {'memory allocator': get_option('malloc')}
4235 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
4236 summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')}
4237 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
4238 summary_info += {'gcov': get_option('b_coverage')}
4239 summary_info += {'thread sanitizer': get_option('tsan')}
4240 summary_info += {'CFI support': get_option('cfi')}
4241 if get_option('cfi')
4242 summary_info += {'CFI debug support': get_option('cfi_debug')}
4244 summary_info += {'strip binaries': get_option('strip')}
4245 summary_info += {'sparse': sparse}
4246 summary_info += {'mingw32 support': host_os == 'windows'}
4247 summary(summary_info, bool_yn: true, section: 'Compilation')
4249 # snarf the cross-compilation information for tests
4252 foreach target: target_dirs
4253 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak'
4254 if fs.exists(tcg_mak)
4255 config_cross_tcg = keyval.load(tcg_mak)
4256 if 'CC' in config_cross_tcg
4257 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']}
4263 summary(summary_info, bool_yn: true, section: 'Cross compilers')
4266 # Targets and accelerators
4269 summary_info += {'KVM support': config_all_accel.has_key('CONFIG_KVM')}
4270 summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')}
4271 summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')}
4272 summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')}
4273 summary_info += {'Xen support': xen.found()}
4275 summary_info += {'xen ctrl version': xen.version()}
4277 summary_info += {'Xen emulation': config_all_devices.has_key('CONFIG_XEN_EMU')}
4279 summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')}
4280 if config_all_accel.has_key('CONFIG_TCG')
4281 if get_option('tcg_interpreter')
4282 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
4284 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
4286 summary_info += {'TCG plugins': get_option('plugins')}
4287 summary_info += {'TCG debug enabled': get_option('debug_tcg')}
4289 summary_info += {'target list': ' '.join(target_dirs)}
4291 summary_info += {'default devices': get_option('default_devices')}
4292 summary_info += {'out of process emulation': multiprocess_allowed}
4293 summary_info += {'vfio-user server': vfio_user_server_allowed}
4295 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
4299 summary_info += {'coroutine backend': coroutine_backend}
4300 summary_info += {'coroutine pool': have_coroutine_pool}
4302 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
4303 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
4304 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
4305 summary_info += {'VirtFS (9P) support': have_virtfs}
4306 summary_info += {'VirtFS (9P) Proxy Helper support (deprecated)': have_virtfs_proxy_helper}
4307 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
4308 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
4309 summary_info += {'bochs support': get_option('bochs').allowed()}
4310 summary_info += {'cloop support': get_option('cloop').allowed()}
4311 summary_info += {'dmg support': get_option('dmg').allowed()}
4312 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
4313 summary_info += {'vdi support': get_option('vdi').allowed()}
4314 summary_info += {'vhdx support': get_option('vhdx').allowed()}
4315 summary_info += {'vmdk support': get_option('vmdk').allowed()}
4316 summary_info += {'vpc support': get_option('vpc').allowed()}
4317 summary_info += {'vvfat support': get_option('vvfat').allowed()}
4318 summary_info += {'qed support': get_option('qed').allowed()}
4319 summary_info += {'parallels support': get_option('parallels').allowed()}
4320 summary_info += {'FUSE exports': fuse}
4321 summary_info += {'VDUSE block exports': have_vduse_blk_export}
4323 summary(summary_info, bool_yn: true, section: 'Block layer support')
4327 summary_info += {'TLS priority': get_option('tls_priority')}
4328 summary_info += {'GNUTLS support': gnutls}
4330 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
4332 summary_info += {'libgcrypt': gcrypt}
4333 summary_info += {'nettle': nettle}
4335 summary_info += {' XTS': xts != 'private'}
4337 summary_info += {'SM4 ALG support': crypto_sm4}
4338 summary_info += {'AF_ALG support': have_afalg}
4339 summary_info += {'rng-none': get_option('rng_none')}
4340 summary_info += {'Linux keyring': have_keyring}
4341 summary_info += {'Linux keyutils': keyutils}
4342 summary(summary_info, bool_yn: true, section: 'Crypto')
4346 if host_os == 'darwin'
4347 summary_info += {'Cocoa support': cocoa}
4349 summary_info += {'SDL support': sdl}
4350 summary_info += {'SDL image support': sdl_image}
4351 summary_info += {'GTK support': gtk}
4352 summary_info += {'pixman': pixman}
4353 summary_info += {'VTE support': vte}
4354 summary_info += {'PNG support': png}
4355 summary_info += {'VNC support': vnc}
4357 summary_info += {'VNC SASL support': sasl}
4358 summary_info += {'VNC JPEG support': jpeg}
4360 summary_info += {'spice protocol support': spice_protocol}
4361 if spice_protocol.found()
4362 summary_info += {' spice server support': spice}
4364 summary_info += {'curses support': curses}
4365 summary_info += {'brlapi support': brlapi}
4366 summary(summary_info, bool_yn: true, section: 'User interface')
4370 summary_info += {'VirGL support': virgl}
4371 summary_info += {'Rutabaga support': rutabaga}
4372 summary(summary_info, bool_yn: true, section: 'Graphics backends')
4376 if host_os not in ['darwin', 'haiku', 'windows']
4377 summary_info += {'OSS support': oss}
4378 summary_info += {'sndio support': sndio}
4379 elif host_os == 'darwin'
4380 summary_info += {'CoreAudio support': coreaudio}
4381 elif host_os == 'windows'
4382 summary_info += {'DirectSound support': dsound}
4384 if host_os == 'linux'
4385 summary_info += {'ALSA support': alsa}
4386 summary_info += {'PulseAudio support': pulse}
4388 summary_info += {'PipeWire support': pipewire}
4389 summary_info += {'JACK support': jack}
4390 summary(summary_info, bool_yn: true, section: 'Audio backends')
4394 if host_os == 'darwin'
4395 summary_info += {'vmnet.framework support': vmnet}
4397 summary_info += {'AF_XDP support': libxdp}
4398 summary_info += {'slirp support': slirp}
4399 summary_info += {'vde support': vde}
4400 summary_info += {'netmap support': have_netmap}
4401 summary_info += {'l2tpv3 support': have_l2tpv3}
4402 summary(summary_info, bool_yn: true, section: 'Network backends')
4406 summary_info += {'libtasn1': tasn1}
4407 summary_info += {'PAM': pam}
4408 summary_info += {'iconv support': iconv}
4409 summary_info += {'blkio support': blkio}
4410 summary_info += {'curl support': curl}
4411 summary_info += {'Multipath support': mpathpersist}
4412 summary_info += {'Linux AIO support': libaio}
4413 summary_info += {'Linux io_uring support': linux_io_uring}
4414 summary_info += {'ATTR/XATTR support': libattr}
4415 summary_info += {'RDMA support': rdma}
4416 summary_info += {'PVRDMA support': have_pvrdma}
4417 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
4418 summary_info += {'libcap-ng support': libcap_ng}
4419 summary_info += {'bpf support': libbpf}
4420 summary_info += {'rbd support': rbd}
4421 summary_info += {'smartcard support': cacard}
4422 summary_info += {'U2F support': u2f}
4423 summary_info += {'libusb': libusb}
4424 summary_info += {'usb net redir': usbredir}
4425 summary_info += {'OpenGL support (epoxy)': opengl}
4426 summary_info += {'GBM': gbm}
4427 summary_info += {'libiscsi support': libiscsi}
4428 summary_info += {'libnfs support': libnfs}
4429 if host_os == 'windows'
4431 summary_info += {'QGA VSS support': have_qga_vss}
4434 summary_info += {'seccomp support': seccomp}
4435 summary_info += {'GlusterFS support': glusterfs}
4436 summary_info += {'hv-balloon support': hv_balloon}
4437 summary_info += {'TPM support': have_tpm}
4438 summary_info += {'libssh support': libssh}
4439 summary_info += {'lzo support': lzo}
4440 summary_info += {'snappy support': snappy}
4441 summary_info += {'bzip2 support': libbzip2}
4442 summary_info += {'lzfse support': liblzfse}
4443 summary_info += {'zstd support': zstd}
4444 summary_info += {'NUMA host support': numa}
4445 summary_info += {'capstone': capstone}
4446 summary_info += {'libpmem support': libpmem}
4447 summary_info += {'libdaxctl support': libdaxctl}
4448 summary_info += {'libudev': libudev}
4449 # Dummy dependency, keep .found()
4450 summary_info += {'FUSE lseek': fuse_lseek.found()}
4451 summary_info += {'selinux': selinux}
4452 summary_info += {'libdw': libdw}
4453 if host_os == 'freebsd'
4454 summary_info += {'libinotify-kqueue': inotify}
4456 summary(summary_info, bool_yn: true, section: 'Dependencies')
4458 if host_arch == 'unknown'
4460 warning('UNSUPPORTED HOST CPU')
4462 message('Support for CPU host architecture ' + cpu + ' is not currently')
4463 message('maintained. The QEMU project does not guarantee that QEMU will')
4464 message('compile or work on this host CPU. You can help by volunteering')
4465 message('to maintain it and providing a build host for our continuous')
4466 message('integration setup.')
4467 if get_option('tcg').allowed() and target_dirs.length() > 0
4469 message('configure has succeeded and you can continue to build, but')
4470 message('QEMU will use a slow interpreter to emulate the target CPU.')
4474 if not supported_oses.contains(host_os)
4476 warning('UNSUPPORTED HOST OS')
4478 message('Support for host OS ' + host_os + 'is not currently maintained.')
4479 message('configure has succeeded and you can continue to build, but')
4480 message('the QEMU project does not guarantee that QEMU will compile or')
4481 message('work on this operating system. You can help by volunteering')
4482 message('to maintain it and providing a build host for our continuous')
4483 message('integration setup. This will ensure that future versions of QEMU')
4484 message('will keep working on ' + host_os + '.')
4487 if host_arch == 'unknown' or not supported_oses.contains(host_os)
4489 message('If you want to help supporting QEMU on this platform, please')
4490 message('contact the developers at qemu-devel@nongnu.org.')
4493 actually_reloc = get_option('relocatable')
4494 # check if get_relocated_path() is actually able to relocate paths
4495 if get_option('relocatable') and \
4496 not (get_option('prefix') / get_option('bindir')).startswith(get_option('prefix') / '')
4498 warning('bindir not included within prefix, the installation will not be relocatable.')
4499 actually_reloc = false
4501 if not actually_reloc and (host_os == 'windows' or get_option('relocatable'))
4502 if host_os == 'windows'
4504 warning('Windows installs should usually be relocatable.')
4507 message('QEMU will have to be installed under ' + get_option('prefix') + '.')
4508 message('Use --disable-relocatable to remove this warning.')