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'))
12 not_found = dependency('', required: false)
13 keyval = import('keyval')
14 ss = import('sourceset')
17 targetos = host_machine.system()
18 sh = find_program('sh')
19 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
21 cc = meson.get_compiler('c')
23 if add_languages('cpp', required: false, native: false)
24 all_languages += ['cpp']
25 cxx = meson.get_compiler('cpp')
27 if targetos == 'darwin' and \
28 add_languages('objc', required: get_option('cocoa'), native: false)
29 all_languages += ['objc']
30 objc = meson.get_compiler('objc')
33 # Temporary directory used for files created while
34 # configure runs. Since it is in the build directory
35 # we can safely blow away any previous version of it
36 # (and we need not jump through hoops to try to delete
37 # it when configure exits.)
38 tmpdir = meson.current_build_dir() / 'meson-private/temp'
40 if get_option('qemu_suffix').startswith('/')
41 error('qemu_suffix cannot start with a /')
44 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
45 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
46 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
47 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
49 qemu_desktopdir = get_option('datadir') / 'applications'
50 qemu_icondir = get_option('datadir') / 'icons'
52 config_host_data = configuration_data()
54 qapi_trace_events = []
56 bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
57 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
58 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
59 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64']
61 cpu = host_machine.cpu_family()
63 # Unify riscv* to a single family.
64 if cpu in ['riscv32', 'riscv64']
68 target_dirs = config_host['TARGET_DIRS'].split()
69 have_linux_user = false
72 foreach target : target_dirs
73 have_linux_user = have_linux_user or target.endswith('linux-user')
74 have_bsd_user = have_bsd_user or target.endswith('bsd-user')
75 have_system = have_system or target.endswith('-softmmu')
77 have_user = have_linux_user or have_bsd_user
78 have_tools = get_option('tools') \
79 .disable_auto_if(not have_system) \
81 have_ga = get_option('guest_agent') \
82 .disable_auto_if(not have_system and not have_tools) \
83 .require(targetos in ['sunos', 'linux', 'windows', 'freebsd', 'netbsd', 'openbsd'],
84 error_message: 'unsupported OS for QEMU guest agent') \
86 enable_modules = get_option('modules') \
87 .require(targetos != 'windows',
88 error_message: 'Modules are not available for Windows') \
89 .require(not get_option('prefer_static'),
90 error_message: 'Modules are incompatible with static linking') \
92 have_block = have_system or have_tools
94 python = import('python').find_installation()
96 if cpu not in supported_cpus
106 if cpu in ['x86', 'x86_64']
107 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
108 elif cpu == 'aarch64'
109 kvm_targets = ['aarch64-softmmu']
111 kvm_targets = ['s390x-softmmu']
112 elif cpu in ['ppc', 'ppc64']
113 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
114 elif cpu in ['mips', 'mips64']
115 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
116 elif cpu in ['riscv']
117 kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
123 if get_option('kvm').allowed() and targetos == 'linux'
124 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
126 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
128 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
130 if cpu in ['aarch64']
131 accelerator_targets += {
132 'CONFIG_HVF': ['aarch64-softmmu']
136 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
137 # i386 emulator provides xenpv machine type for multiple architectures
138 accelerator_targets += {
139 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
142 if cpu in ['x86', 'x86_64']
143 accelerator_targets += {
144 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
145 'CONFIG_HVF': ['x86_64-softmmu'],
146 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
147 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
152 # Darwin does not support references to thread-local variables in modules
153 if targetos != 'darwin'
154 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
157 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
158 unpack_edk2_blobs = false
159 foreach target : edk2_targets
160 if target in target_dirs
161 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
162 unpack_edk2_blobs = bzip2.found()
169 if 'dtrace' in get_option('trace_backends')
170 dtrace = find_program('dtrace', required: true)
171 stap = find_program('stap', required: false)
173 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
174 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
175 # instead. QEMU --enable-modules depends on this because the SystemTap
176 # semaphores are linked into the main binary and not the module's shared
178 add_global_arguments('-DSTAP_SDT_V2',
179 native: false, language: all_languages)
183 if get_option('iasl') == ''
184 iasl = find_program('iasl', required: false)
186 iasl = find_program(get_option('iasl'), required: true)
193 foreach lang : all_languages
194 compiler = meson.get_compiler(lang)
195 if compiler.get_id() == 'gcc' and compiler.version().version_compare('>=7.4')
197 elif compiler.get_id() == 'clang' and compiler.compiles('''
198 #ifdef __apple_build_version__
199 # if __clang_major__ < 12 || (__clang_major__ == 12 && __clang_minor__ < 0)
200 # error You need at least XCode Clang v12.0 to compile QEMU
203 # if __clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 0)
204 # error You need at least Clang v10.0 to compile QEMU
209 error('You either need GCC v7.4 or Clang v10.0 (or XCode Clang v12.0) to compile QEMU')
213 # default flags for all hosts
214 # We use -fwrapv to tell the compiler that we require a C dialect where
215 # left shift of signed integers is well defined and has the expected
216 # 2s-complement style results. (Both clang and gcc agree that it
217 # provides these semantics.)
219 qemu_common_flags = [
220 '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE',
221 '-fno-strict-aliasing', '-fno-common', '-fwrapv' ]
225 if targetos == 'darwin'
226 # Disable attempts to use ObjectiveC features in os/object.h since they
227 # won't work when we're compiling with gcc as a C compiler.
228 qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
229 elif targetos == 'solaris'
230 # needed for CMSG_ macros in sys/socket.h
231 qemu_common_flags += '-D_XOPEN_SOURCE=600'
232 # needed for TIOCWIN* defines in termios.h
233 qemu_common_flags += '-D__EXTENSIONS__'
234 elif targetos == 'haiku'
235 qemu_common_flags += ['-DB_USE_POSITIVE_POSIX_ERRORS', '-D_BSD_SOURCE', '-fPIC']
238 # __sync_fetch_and_and requires at least -march=i486. Many toolchains
239 # use i686 as default anyway, but for those that don't, an explicit
240 # specification is necessary
241 if host_arch == 'i386' and not cc.links('''
242 static int sfaa(int *ptr)
244 return __sync_fetch_and_and(ptr, 0);
250 val = __sync_val_compare_and_swap(&val, 0, 1);
254 qemu_common_flags = ['-march=i486'] + qemu_common_flags
257 if get_option('gprof')
258 qemu_common_flags += ['-p']
259 qemu_ldflags += ['-p']
262 if get_option('prefer_static')
263 qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
266 # Meson currently only handles pie as a boolean for now, so if the user
267 # has explicitly disabled PIE we need to extend our cflags.
268 if not get_option('b_pie')
269 qemu_common_flags += cc.get_supported_arguments('-fno-pie')
270 if not get_option('prefer_static')
271 # No PIE is implied by -static which we added above.
272 qemu_ldflags += cc.get_supported_link_arguments('-no-pie')
276 if not get_option('stack_protector').disabled()
277 stack_protector_probe = '''
278 int main(int argc, char *argv[])
280 char arr[64], *p = arr, *c = argv[argc - 1];
286 have_stack_protector = false
287 foreach arg : ['-fstack-protector-strong', '-fstack-protector-all']
288 # We need to check both a compile and a link, since some compiler
289 # setups fail only on a .c->.o compile and some only at link time
290 if cc.compiles(stack_protector_probe, args: ['-Werror', arg]) and \
291 cc.links(stack_protector_probe, args: ['-Werror', arg])
292 have_stack_protector = true
298 get_option('stack_protector') \
299 .require(have_stack_protector, error_message: 'Stack protector not supported')
302 coroutine_backend = get_option('coroutine_backend')
304 #include <ucontext.h>
305 #ifdef __stub_makecontext
306 #error Ignoring glibc stub makecontext which will always fail
308 int main(void) { makecontext(0, 0, 0); return 0; }'''
310 # On Windows the only valid backend is the Windows specific one.
311 # For POSIX prefer ucontext, but it's not always possible. The fallback
313 supported_backends = []
314 if targetos == 'windows'
315 supported_backends += ['windows']
317 if targetos != 'darwin' and cc.links(ucontext_probe)
318 supported_backends += ['ucontext']
320 supported_backends += ['sigaltstack']
323 if coroutine_backend == 'auto'
324 coroutine_backend = supported_backends[0]
325 elif coroutine_backend not in supported_backends
326 error('"@0@" backend requested but not available. Available backends: @1@' \
327 .format(coroutine_backend, ', '.join(supported_backends)))
330 # Compiles if SafeStack *not* enabled
331 safe_stack_probe = '''
334 #if defined(__has_feature)
335 #if __has_feature(safe_stack)
336 #error SafeStack Enabled
341 if get_option('safe_stack') != not cc.compiles(safe_stack_probe)
342 safe_stack_arg = get_option('safe_stack') ? '-fsanitize=safe-stack' : '-fno-sanitize=safe-stack'
343 if get_option('safe_stack') != not cc.compiles(safe_stack_probe, args: safe_stack_arg)
344 error(get_option('safe_stack') \
345 ? 'SafeStack not supported by your compiler' \
346 : 'Cannot disable SafeStack')
348 qemu_cflags += safe_stack_arg
349 qemu_ldflags += safe_stack_arg
351 if get_option('safe_stack') and coroutine_backend != 'ucontext'
352 error('SafeStack is only supported with the ucontext coroutine backend')
355 if get_option('sanitizers')
356 if cc.has_argument('-fsanitize=address')
357 qemu_cflags = ['-fsanitize=address'] + qemu_cflags
358 qemu_ldflags = ['-fsanitize=address'] + qemu_ldflags
361 # Detect static linking issue with ubsan - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84285
362 if cc.links('int main(int argc, char **argv) { return argc + 1; }',
363 args: [qemu_ldflags, '-fsanitize=undefined'])
364 qemu_cflags = ['-fsanitize=undefined'] + qemu_cflags
365 qemu_ldflags = ['-fsanitize=undefined'] + qemu_ldflags
369 # Thread sanitizer is, for now, much noisier than the other sanitizers;
370 # keep it separate until that is not the case.
371 if get_option('tsan')
372 if get_option('sanitizers')
373 error('TSAN is not supported with other sanitizers')
375 if not cc.has_function('__tsan_create_fiber',
376 args: '-fsanitize=thread',
377 prefix: '#include <sanitizer/tsan_interface.h>')
378 error('Cannot enable TSAN due to missing fiber annotation interface')
380 qemu_cflags = ['-fsanitize=thread'] + qemu_cflags
381 qemu_ldflags = ['-fsanitize=thread'] + qemu_ldflags
384 # Detect support for PT_GNU_RELRO + DT_BIND_NOW.
385 # The combination is known as "full relro", because .got.plt is read-only too.
386 qemu_ldflags += cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now')
388 if targetos == 'windows'
389 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat')
390 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase', '-Wl,--high-entropy-va')
393 # Exclude --warn-common with TSan to suppress warnings from the TSan libraries.
394 if targetos != 'sunos' and not get_option('tsan')
395 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--warn-common')
398 # Specify linker-script with add_project_link_arguments so that it is not placed
399 # within a linker --start-group/--end-group pair
400 if get_option('fuzzing')
401 # Specify a filter to only instrument code that is directly related to
403 configure_file(output: 'instrumentation-filter',
404 input: 'scripts/oss-fuzz/instrumentation-filter-template',
407 if cc.compiles('int main () { return 0; }',
408 name: '-fsanitize-coverage-allowlist=/dev/null',
409 args: ['-fsanitize-coverage-allowlist=/dev/null',
410 '-fsanitize-coverage=trace-pc'] )
411 qemu_common_flags += ['-fsanitize-coverage-allowlist=instrumentation-filter']
414 if get_option('fuzzing_engine') == ''
415 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
416 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
417 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
418 # unable to bind the fuzzer-related callbacks added by instrumentation.
419 qemu_common_flags += ['-fsanitize=fuzzer-no-link']
420 qemu_ldflags += ['-fsanitize=fuzzer-no-link']
421 # For the actual fuzzer binaries, we need to link against the libfuzzer
422 # library. They need to be configurable, to support OSS-Fuzz
423 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
425 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
426 # the needed CFLAGS have already been provided
427 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
431 add_global_arguments(qemu_common_flags, native: false, language: all_languages)
432 add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
434 # Collect warnings that we want to enable
439 '-Wmissing-prototypes',
440 '-Wstrict-prototypes',
442 '-Wold-style-declaration',
443 '-Wold-style-definition',
448 '-Wignored-qualifiers',
452 '-Wexpansion-to-defined',
453 '-Wimplicit-fallthrough=2',
454 '-Wmissing-format-attribute',
455 '-Wno-initializer-overrides',
456 '-Wno-missing-include-dirs',
457 '-Wno-shift-negative-value',
458 '-Wno-string-plus-int',
459 '-Wno-typedef-redefinition',
460 '-Wno-tautological-type-limit-compare',
462 '-Wno-gnu-variable-sized-type-not-at-end',
465 if targetos != 'darwin'
466 warn_flags += ['-Wthread-safety']
469 # Check that the C++ compiler exists and works with the C compiler.
473 if 'cpp' in all_languages
474 qemu_cxxflags = ['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'] + qemu_cflags
475 if cxx.links(files('scripts/main.c'), args: qemu_cflags)
476 link_language = 'cpp'
479 message('C++ compiler does not work with C compiler')
480 message('Disabling C++-specific optional code')
484 # clang does not support glibc + FORTIFY_SOURCE (is it still true?)
485 if get_option('optimization') != '0' and targetos == 'linux'
486 if cc.get_id() == 'gcc'
487 qemu_cflags += ['-U_FORTIFY_SOURCE', '-D_FORTIFY_SOURCE=2']
489 if 'cpp' in all_languages and cxx.get_id() == 'gcc'
490 qemu_cxxflags += ['-U_FORTIFY_SOURCE', '-D_FORTIFY_SOURCE=2']
494 add_project_arguments(qemu_cflags, native: false, language: 'c')
495 add_project_arguments(cc.get_supported_arguments(warn_flags), native: false, language: 'c')
496 if 'cpp' in all_languages
497 add_project_arguments(qemu_cxxflags, native: false, language: 'cpp')
498 add_project_arguments(cxx.get_supported_arguments(warn_flags), native: false, language: 'cpp')
500 if 'objc' in all_languages
501 # Note sanitizer flags are not applied to Objective-C sources!
502 add_project_arguments(objc.get_supported_arguments(warn_flags), native: false, language: 'objc')
504 if targetos == 'linux'
505 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
506 '-isystem', 'linux-headers',
507 language: all_languages)
510 add_project_arguments('-iquote', '.',
511 '-iquote', meson.current_source_dir(),
512 '-iquote', meson.current_source_dir() / 'include',
513 language: all_languages)
515 sparse = find_program('cgcc', required: get_option('sparse'))
518 command: [find_program('scripts/check_sparse.py'),
519 'compile_commands.json', sparse.full_path(), '-Wbitwise',
520 '-Wno-transparent-union', '-Wno-old-initializer',
521 '-Wno-non-pointer-null'])
524 ###########################################
525 # Target-specific checks and dependencies #
526 ###########################################
529 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
532 #include <sys/types.h>
533 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
534 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
536 args: ['-Werror', '-fsanitize=fuzzer'])
537 error('Your compiler does not support -fsanitize=fuzzer')
541 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
542 error('ftrace is supported only on Linux')
544 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
547 openlog("qemu", LOG_PID, LOG_DAEMON);
548 syslog(LOG_INFO, "configure");
551 error('syslog is not supported on this system')
554 # Miscellaneous Linux-only features
555 get_option('mpath') \
556 .require(targetos == 'linux', error_message: 'Multipath is supported only on Linux')
558 multiprocess_allowed = get_option('multiprocess') \
559 .require(targetos == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
562 vfio_user_server_allowed = get_option('vfio_user_server') \
563 .require(targetos == 'linux', error_message: 'vfio-user server is supported only on Linux') \
566 have_tpm = get_option('tpm') \
567 .require(targetos != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
571 have_vhost_user = get_option('vhost_user') \
572 .disable_auto_if(targetos != 'linux') \
573 .require(targetos != 'windows',
574 error_message: 'vhost-user is not available on Windows').allowed()
575 have_vhost_vdpa = get_option('vhost_vdpa') \
576 .require(targetos == 'linux',
577 error_message: 'vhost-vdpa is only available on Linux').allowed()
578 have_vhost_kernel = get_option('vhost_kernel') \
579 .require(targetos == 'linux',
580 error_message: 'vhost-kernel is only available on Linux').allowed()
581 have_vhost_user_crypto = get_option('vhost_crypto') \
582 .require(have_vhost_user,
583 error_message: 'vhost-crypto requires vhost-user to be enabled').allowed()
585 have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel
587 have_vhost_net_user = have_vhost_user and get_option('vhost_net').allowed()
588 have_vhost_net_vdpa = have_vhost_vdpa and get_option('vhost_net').allowed()
589 have_vhost_net_kernel = have_vhost_kernel and get_option('vhost_net').allowed()
590 have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_vdpa
592 # Target-specific libraries and flags
593 libm = cc.find_library('m', required: false)
594 threads = dependency('threads')
595 util = cc.find_library('util', required: false)
601 emulator_link_args = []
608 if targetos == 'windows'
609 midl = find_program('midl', required: false)
610 widl = find_program('widl', required: false)
611 pathcch = cc.find_library('pathcch')
612 socket = cc.find_library('ws2_32')
613 winmm = cc.find_library('winmm')
615 win = import('windows')
616 version_res = win.compile_resources('version.rc',
617 depend_files: files('pc-bios/qemu-nsis.ico'),
618 include_directories: include_directories('.'))
620 elif targetos == 'darwin'
621 coref = dependency('appleframeworks', modules: 'CoreFoundation')
622 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
623 host_dsosuf = '.dylib'
624 elif targetos == 'sunos'
625 socket = [cc.find_library('socket'),
626 cc.find_library('nsl'),
627 cc.find_library('resolv')]
628 elif targetos == 'haiku'
629 socket = [cc.find_library('posix_error_mapper'),
630 cc.find_library('network'),
631 cc.find_library('bsd')]
632 elif targetos == 'openbsd'
633 if get_option('tcg').allowed() and target_dirs.length() > 0
634 # Disable OpenBSD W^X if available
635 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
639 # Target-specific configuration of accelerators
641 if get_option('kvm').allowed() and targetos == 'linux'
642 accelerators += 'CONFIG_KVM'
644 if get_option('whpx').allowed() and targetos == 'windows'
645 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
646 error('WHPX requires 64-bit host')
647 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
648 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
649 accelerators += 'CONFIG_WHPX'
652 if get_option('hvf').allowed()
653 hvf = dependency('appleframeworks', modules: 'Hypervisor',
654 required: get_option('hvf'))
656 accelerators += 'CONFIG_HVF'
659 if get_option('hax').allowed()
660 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
661 accelerators += 'CONFIG_HAX'
664 if targetos == 'netbsd'
665 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
667 accelerators += 'CONFIG_NVMM'
672 if get_option('tcg').allowed()
673 if host_arch == 'unknown'
674 if get_option('tcg_interpreter')
675 warning('Unsupported CPU @0@, will use TCG with TCI (slow)'.format(cpu))
677 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
679 elif get_option('tcg_interpreter')
680 warning('Use of the TCG interpreter is not recommended on this host')
681 warning('architecture. There is a native TCG execution backend available')
682 warning('which provides substantially better performance and reliability.')
683 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
684 warning('configuration option on this architecture to use the native')
687 if get_option('tcg_interpreter')
689 config_host += { 'CONFIG_TCG_INTERPRETER': 'y' }
690 elif host_arch == 'x86_64'
692 elif host_arch == 'ppc64'
695 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
696 language: all_languages)
698 accelerators += 'CONFIG_TCG'
699 config_host += { 'CONFIG_TCG': 'y' }
702 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
703 error('KVM not available on this platform')
705 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
706 error('HVF not available on this platform')
708 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
709 error('NVMM not available on this platform')
711 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
712 error('WHPX not available on this platform')
719 # When bumping glib minimum version, please check also whether to increase
720 # the _WIN32_WINNT setting in osdep.h according to the value from glib
721 glib_req_ver = '>=2.56.0'
722 glib_pc = dependency('glib-2.0', version: glib_req_ver, required: true,
723 method: 'pkg-config')
726 gmodule = dependency('gmodule-export-2.0', version: glib_req_ver, required: true,
727 method: 'pkg-config')
728 elif config_host.has_key('CONFIG_PLUGIN')
729 gmodule = dependency('gmodule-no-export-2.0', version: glib_req_ver, required: true,
730 method: 'pkg-config')
735 # This workaround is required due to a bug in pkg-config file for glib as it
736 # doesn't define GLIB_STATIC_COMPILATION for pkg-config --static
737 if targetos == 'windows' and get_option('prefer_static')
738 glib_cflags += ['-DGLIB_STATIC_COMPILATION']
741 # Sanity check that the current size_t matches the
742 # size that glib thinks it should be. This catches
743 # problems on multi-arch where people try to build
744 # 32-bit QEMU while pointing at 64-bit glib headers
746 if not cc.compiles('''
750 #define QEMU_BUILD_BUG_ON(x) \
751 typedef char qemu_build_bug_on[(x)?-1:1] __attribute__((unused));
754 QEMU_BUILD_BUG_ON(sizeof(size_t) != GLIB_SIZEOF_SIZE_T);
756 }''', dependencies: glib_pc, args: glib_cflags)
757 error('''sizeof(size_t) doesn't match GLIB_SIZEOF_SIZE_T.
758 You probably need to set PKG_CONFIG_LIBDIR" to point
759 to the right pkg-config files for your build target.''')
762 # Silence clang warnings triggered by glib < 2.57.2
763 if not cc.compiles('''
768 static void foo_free(Foo *f)
772 G_DEFINE_AUTOPTR_CLEANUP_FUNC(Foo, foo_free)
773 int main(void) { return 0; }''', dependencies: glib_pc, args: ['-Werror'])
774 glib_cflags += cc.get_supported_arguments('-Wno-unused-function')
776 glib = declare_dependency(dependencies: [glib_pc, gmodule],
777 compile_args: glib_cflags,
778 version: glib_pc.version())
780 # Check whether glib has gslice, which we have to avoid for correctness.
781 # TODO: remove this check and the corresponding workaround (qtree) when
782 # the minimum supported glib is >= 2.75.3
783 glib_has_gslice = glib.version().version_compare('<2.75.3')
785 # override glib dep to include the above refinements
786 meson.override_dependency('glib-2.0', glib)
788 # The path to glib.h is added to all compilation commands.
789 add_project_dependencies(glib.partial_dependency(compile_args: true, includes: true),
790 native: false, language: all_languages)
793 gdbus_codegen = not_found
794 gdbus_codegen_error = '@0@ requires gdbus-codegen, please install libgio'
795 if not get_option('gio').auto() or have_system
796 gio = dependency('gio-2.0', required: get_option('gio'),
797 method: 'pkg-config')
798 if gio.found() and not cc.links('''
802 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
804 }''', dependencies: [glib, gio])
805 if get_option('gio').enabled()
806 error('The installed libgio is broken for static linking')
811 gdbus_codegen = find_program(gio.get_variable('gdbus_codegen'),
812 required: get_option('gio'))
813 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
814 method: 'pkg-config')
815 gio = declare_dependency(dependencies: [gio, gio_unix],
816 version: gio.version())
819 if gdbus_codegen.found() and get_option('cfi')
820 gdbus_codegen = not_found
821 gdbus_codegen_error = '@0@ uses gdbus-codegen, which does not support control flow integrity'
825 if 'ust' in get_option('trace_backends')
826 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
827 method: 'pkg-config')
830 if have_system or have_tools
831 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
832 method: 'pkg-config')
834 zlib = dependency('zlib', required: true)
837 if not get_option('linux_aio').auto() or have_block
838 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
839 required: get_option('linux_aio'))
842 linux_io_uring_test = '''
843 #include <liburing.h>
844 #include <linux/errqueue.h>
846 int main(void) { return 0; }'''
848 linux_io_uring = not_found
849 if not get_option('linux_io_uring').auto() or have_block
850 linux_io_uring = dependency('liburing', version: '>=0.3',
851 required: get_option('linux_io_uring'),
852 method: 'pkg-config')
853 if not cc.links(linux_io_uring_test)
854 linux_io_uring = not_found
859 if not get_option('libnfs').auto() or have_block
860 libnfs = dependency('libnfs', version: '>=1.9.3',
861 required: get_option('libnfs'),
862 method: 'pkg-config')
867 #include <sys/types.h>
868 #ifdef CONFIG_LIBATTR
869 #include <attr/xattr.h>
871 #include <sys/xattr.h>
873 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
876 have_old_libattr = false
877 if get_option('attr').allowed()
878 if cc.links(libattr_test)
879 libattr = declare_dependency()
881 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
882 required: get_option('attr'))
883 if libattr.found() and not \
884 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
886 if get_option('attr').enabled()
887 error('could not link libattr')
889 warning('could not link libattr, disabling')
892 have_old_libattr = libattr.found()
897 cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
898 required: get_option('cocoa'))
900 vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
901 if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
902 'VMNET_BRIDGED_MODE',
905 if get_option('vmnet').enabled()
906 error('vmnet.framework API is outdated')
908 warning('vmnet.framework API is outdated, disabling')
913 seccomp_has_sysrawrc = false
914 if not get_option('seccomp').auto() or have_system or have_tools
915 seccomp = dependency('libseccomp', version: '>=2.3.0',
916 required: get_option('seccomp'),
917 method: 'pkg-config')
919 seccomp_has_sysrawrc = cc.has_header_symbol('seccomp.h',
920 'SCMP_FLTATR_API_SYSRAWRC',
921 dependencies: seccomp)
925 libcap_ng = not_found
926 if not get_option('cap_ng').auto() or have_system or have_tools
927 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
928 required: get_option('cap_ng'))
930 if libcap_ng.found() and not cc.links('''
934 capng_capability_to_name(CAPNG_EFFECTIVE);
936 }''', dependencies: libcap_ng)
937 libcap_ng = not_found
938 if get_option('cap_ng').enabled()
939 error('could not link libcap-ng')
941 warning('could not link libcap-ng, disabling')
945 if get_option('xkbcommon').auto() and not have_system and not have_tools
946 xkbcommon = not_found
948 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
949 method: 'pkg-config')
953 if not get_option('slirp').auto() or have_system
954 slirp = dependency('slirp', required: get_option('slirp'),
955 method: 'pkg-config')
956 # slirp < 4.7 is incompatible with CFI support in QEMU. This is because
957 # it passes function pointers within libslirp as callbacks for timers.
958 # When using a system-wide shared libslirp, the type information for the
959 # callback is missing and the timer call produces a false positive with CFI.
960 # Do not use the "version" keyword argument to produce a better error.
961 # with control-flow integrity.
962 if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
963 if get_option('slirp').enabled()
964 error('Control-Flow Integrity requires libslirp 4.7.')
966 warning('Cannot use libslirp since Control-Flow Integrity requires libslirp >= 4.7.')
973 if not get_option('vde').auto() or have_system or have_tools
974 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
975 required: get_option('vde'))
977 if vde.found() and not cc.links('''
978 #include <libvdeplug.h>
981 struct vde_open_args a = {0, 0, 0};
985 }''', dependencies: vde)
987 if get_option('cap_ng').enabled()
988 error('could not link libvdeplug')
990 warning('could not link libvdeplug, disabling')
995 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
996 pulse = dependency('libpulse', required: get_option('pa'),
997 method: 'pkg-config')
1000 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
1001 alsa = dependency('alsa', required: get_option('alsa'),
1002 method: 'pkg-config')
1005 if not get_option('jack').auto() or have_system
1006 jack = dependency('jack', required: get_option('jack'),
1007 method: 'pkg-config')
1009 pipewire = not_found
1010 if not get_option('pipewire').auto() or (targetos == 'linux' and have_system)
1011 pipewire = dependency('libpipewire-0.3', version: '>=0.3.60',
1012 required: get_option('pipewire'),
1013 method: 'pkg-config')
1016 if not get_option('sndio').auto() or have_system
1017 sndio = dependency('sndio', required: get_option('sndio'),
1018 method: 'pkg-config')
1021 spice_protocol = not_found
1022 if not get_option('spice_protocol').auto() or have_system
1023 spice_protocol = dependency('spice-protocol', version: '>=0.14.0',
1024 required: get_option('spice_protocol'),
1025 method: 'pkg-config')
1028 if not get_option('spice').auto() or have_system
1029 spice = dependency('spice-server', version: '>=0.14.0',
1030 required: get_option('spice'),
1031 method: 'pkg-config')
1033 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
1035 rt = cc.find_library('rt', required: false)
1037 libiscsi = not_found
1038 if not get_option('libiscsi').auto() or have_block
1039 libiscsi = dependency('libiscsi', version: '>=1.9.0',
1040 required: get_option('libiscsi'),
1041 method: 'pkg-config')
1044 if not get_option('zstd').auto() or have_block
1045 zstd = dependency('libzstd', version: '>=1.4.0',
1046 required: get_option('zstd'),
1047 method: 'pkg-config')
1051 have_vhost_user_gpu = have_tools and targetos == 'linux' and pixman.found()
1052 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
1053 virgl = dependency('virglrenderer',
1054 method: 'pkg-config',
1055 required: get_option('virglrenderer'))
1058 if not get_option('blkio').auto() or have_block
1059 blkio = dependency('blkio',
1060 method: 'pkg-config',
1061 required: get_option('blkio'))
1064 if not get_option('curl').auto() or have_block
1065 curl = dependency('libcurl', version: '>=7.29.0',
1066 method: 'pkg-config',
1067 required: get_option('curl'))
1070 if targetos == 'linux' and (have_system or have_tools)
1071 libudev = dependency('libudev',
1072 method: 'pkg-config',
1073 required: get_option('libudev'))
1076 mpathlibs = [libudev]
1077 mpathpersist = not_found
1078 mpathpersist_new_api = false
1079 if targetos == 'linux' and have_tools and get_option('mpath').allowed()
1080 mpath_test_source_new = '''
1081 #include <libudev.h>
1082 #include <mpath_persist.h>
1083 unsigned mpath_mx_alloc_len = 1024;
1085 static struct config *multipath_conf;
1086 extern struct udev *udev;
1087 extern struct config *get_multipath_config(void);
1088 extern void put_multipath_config(struct config *conf);
1090 struct config *get_multipath_config(void) { return multipath_conf; }
1091 void put_multipath_config(struct config *conf) { }
1094 multipath_conf = mpath_lib_init();
1097 mpath_test_source_old = '''
1098 #include <libudev.h>
1099 #include <mpath_persist.h>
1100 unsigned mpath_mx_alloc_len = 1024;
1103 struct udev *udev = udev_new();
1104 mpath_lib_init(udev);
1107 libmpathpersist = cc.find_library('mpathpersist',
1108 required: get_option('mpath'))
1109 if libmpathpersist.found()
1110 mpathlibs += libmpathpersist
1111 if get_option('prefer_static')
1112 mpathlibs += cc.find_library('devmapper',
1113 required: get_option('mpath'))
1115 mpathlibs += cc.find_library('multipath',
1116 required: get_option('mpath'))
1117 foreach lib: mpathlibs
1123 if mpathlibs.length() == 0
1124 msg = 'Dependencies missing for libmpathpersist'
1125 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
1126 mpathpersist = declare_dependency(dependencies: mpathlibs)
1127 mpathpersist_new_api = true
1128 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
1129 mpathpersist = declare_dependency(dependencies: mpathlibs)
1131 msg = 'Cannot detect libmpathpersist API'
1133 if not mpathpersist.found()
1134 if get_option('mpath').enabled()
1137 warning(msg + ', disabling')
1145 if have_system and get_option('curses').allowed()
1147 #if defined(__APPLE__) || defined(__OpenBSD__)
1148 #define _XOPEN_SOURCE_EXTENDED 1
1155 setlocale(LC_ALL, "");
1157 addwstr(L"wide chars\n");
1159 add_wch(WACS_DEGREE);
1163 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
1164 curses = dependency(curses_dep_list,
1166 method: 'pkg-config')
1167 msg = get_option('curses').enabled() ? 'curses library not found' : ''
1168 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
1170 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
1171 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses],
1172 version: curses.version())
1174 msg = 'curses package not usable'
1178 if not curses.found()
1179 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1180 if targetos != 'windows' and not has_curses_h
1181 message('Trying with /usr/include/ncursesw')
1182 curses_compile_args += ['-I/usr/include/ncursesw']
1183 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1186 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
1187 foreach curses_libname : curses_libname_list
1188 libcurses = cc.find_library(curses_libname,
1190 if libcurses.found()
1191 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
1192 curses = declare_dependency(compile_args: curses_compile_args,
1193 dependencies: [libcurses])
1196 msg = 'curses library not usable'
1202 if get_option('iconv').allowed()
1203 foreach link_args : [ ['-liconv'], [] ]
1204 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
1205 # We need to use libiconv if available because mixing libiconv's headers with
1206 # the system libc does not work.
1207 # However, without adding glib to the dependencies -L/usr/local/lib will not be
1208 # included in the command line and libiconv will not be found.
1212 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
1213 return conv != (iconv_t) -1;
1214 }''', args: link_args, dependencies: glib)
1215 iconv = declare_dependency(link_args: link_args, dependencies: glib)
1220 if curses.found() and not iconv.found()
1221 if get_option('iconv').enabled()
1222 error('iconv not available')
1224 msg = 'iconv required for curses UI but not available'
1227 if not curses.found() and msg != ''
1228 if get_option('curses').enabled()
1231 warning(msg + ', disabling')
1237 if not get_option('brlapi').auto() or have_system
1238 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
1239 required: get_option('brlapi'))
1240 if brlapi.found() and not cc.links('''
1243 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
1245 if get_option('brlapi').enabled()
1246 error('could not link brlapi')
1248 warning('could not link brlapi, disabling')
1254 if not get_option('sdl').auto() or have_system
1255 sdl = dependency('sdl2', required: get_option('sdl'))
1256 sdl_image = not_found
1259 # work around 2.0.8 bug
1260 sdl = declare_dependency(compile_args: '-Wno-undef',
1262 version: sdl.version())
1263 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
1264 method: 'pkg-config')
1266 if get_option('sdl_image').enabled()
1267 error('sdl-image required, but SDL was @0@'.format(
1268 get_option('sdl').disabled() ? 'disabled' : 'not found'))
1270 sdl_image = not_found
1274 if not get_option('rbd').auto() or have_block
1275 librados = cc.find_library('rados', required: get_option('rbd'))
1276 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
1277 required: get_option('rbd'))
1278 if librados.found() and librbd.found()
1281 #include <rbd/librbd.h>
1284 rados_create(&cluster, NULL);
1285 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
1289 }''', dependencies: [librbd, librados])
1290 rbd = declare_dependency(dependencies: [librbd, librados])
1291 elif get_option('rbd').enabled()
1292 error('librbd >= 1.12.0 required')
1294 warning('librbd >= 1.12.0 not found, disabling')
1299 glusterfs = not_found
1300 glusterfs_ftruncate_has_stat = false
1301 glusterfs_iocb_has_stat = false
1302 if not get_option('glusterfs').auto() or have_block
1303 glusterfs = dependency('glusterfs-api', version: '>=3',
1304 required: get_option('glusterfs'),
1305 method: 'pkg-config')
1306 if glusterfs.found()
1307 glusterfs_ftruncate_has_stat = cc.links('''
1308 #include <glusterfs/api/glfs.h>
1313 /* new glfs_ftruncate() passes two additional args */
1314 return glfs_ftruncate(NULL, 0, NULL, NULL);
1316 ''', dependencies: glusterfs)
1317 glusterfs_iocb_has_stat = cc.links('''
1318 #include <glusterfs/api/glfs.h>
1320 /* new glfs_io_cbk() passes two additional glfs_stat structs */
1322 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
1328 glfs_io_cbk iocb = &glusterfs_iocb;
1329 iocb(NULL, 0 , NULL, NULL, NULL);
1332 ''', dependencies: glusterfs)
1337 if not get_option('libssh').auto() or have_block
1338 libssh = dependency('libssh', version: '>=0.8.7',
1339 method: 'pkg-config',
1340 required: get_option('libssh'))
1343 libbzip2 = not_found
1344 if not get_option('bzip2').auto() or have_block
1345 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
1346 required: get_option('bzip2'))
1347 if libbzip2.found() and not cc.links('''
1349 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
1350 libbzip2 = not_found
1351 if get_option('bzip2').enabled()
1352 error('could not link libbzip2')
1354 warning('could not link libbzip2, disabling')
1359 liblzfse = not_found
1360 if not get_option('lzfse').auto() or have_block
1361 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
1362 required: get_option('lzfse'))
1364 if liblzfse.found() and not cc.links('''
1366 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
1367 liblzfse = not_found
1368 if get_option('lzfse').enabled()
1369 error('could not link liblzfse')
1371 warning('could not link liblzfse, disabling')
1376 if get_option('oss').allowed() and have_system
1377 if not cc.has_header('sys/soundcard.h')
1379 elif targetos == 'netbsd'
1380 oss = cc.find_library('ossaudio', required: get_option('oss'))
1382 oss = declare_dependency()
1386 if get_option('oss').enabled()
1387 error('OSS not found')
1392 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
1393 if cc.has_header('dsound.h')
1394 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
1397 if not dsound.found()
1398 if get_option('dsound').enabled()
1399 error('DirectSound not found')
1404 coreaudio = not_found
1405 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
1406 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
1407 required: get_option('coreaudio'))
1411 if not get_option('opengl').auto() or have_system or have_vhost_user_gpu
1412 epoxy = dependency('epoxy', method: 'pkg-config',
1413 required: get_option('opengl'))
1414 if cc.has_header('epoxy/egl.h', dependencies: epoxy)
1416 elif get_option('opengl').enabled()
1417 error('epoxy/egl.h not found')
1421 if (have_system or have_tools) and (virgl.found() or opengl.found())
1422 gbm = dependency('gbm', method: 'pkg-config', required: false)
1424 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and opengl.found() and gbm.found()
1427 gnutls_crypto = not_found
1428 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1429 # For general TLS support our min gnutls matches
1430 # that implied by our platform support matrix
1432 # For the crypto backends, we look for a newer
1435 # Version 3.6.8 is needed to get XTS
1436 # Version 3.6.13 is needed to get PBKDF
1437 # Version 3.6.14 is needed to get HW accelerated XTS
1439 # If newer enough gnutls isn't available, we can
1440 # still use a different crypto backend to satisfy
1441 # the platform support requirements
1442 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1443 method: 'pkg-config',
1445 if gnutls_crypto.found()
1446 gnutls = gnutls_crypto
1448 # Our min version if all we need is TLS
1449 gnutls = dependency('gnutls', version: '>=3.5.18',
1450 method: 'pkg-config',
1451 required: get_option('gnutls'))
1455 # We prefer use of gnutls for crypto, unless the options
1456 # explicitly asked for nettle or gcrypt.
1458 # If gnutls isn't available for crypto, then we'll prefer
1459 # gcrypt over nettle for performance reasons.
1465 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1466 error('Only one of gcrypt & nettle can be enabled')
1469 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1470 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1471 gnutls_crypto = not_found
1474 if not gnutls_crypto.found()
1475 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1476 gcrypt = dependency('libgcrypt', version: '>=1.8',
1477 method: 'config-tool',
1478 required: get_option('gcrypt'))
1479 # Debian has removed -lgpg-error from libgcrypt-config
1480 # as it "spreads unnecessary dependencies" which in
1481 # turn breaks static builds...
1482 if gcrypt.found() and get_option('prefer_static')
1483 gcrypt = declare_dependency(dependencies:
1485 cc.find_library('gpg-error', required: true)],
1486 version: gcrypt.version())
1489 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1490 nettle = dependency('nettle', version: '>=3.4',
1491 method: 'pkg-config',
1492 required: get_option('nettle'))
1493 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1499 gmp = dependency('gmp', required: false, method: 'pkg-config')
1500 if nettle.found() and gmp.found()
1501 hogweed = dependency('hogweed', version: '>=3.4',
1502 method: 'pkg-config',
1503 required: get_option('nettle'))
1510 have_gtk_clipboard = get_option('gtk_clipboard').enabled()
1512 if not get_option('gtk').auto() or have_system
1513 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1514 method: 'pkg-config',
1515 required: get_option('gtk'))
1517 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1518 method: 'pkg-config',
1520 gtk = declare_dependency(dependencies: [gtk, gtkx11],
1521 version: gtk.version())
1523 if not get_option('vte').auto() or have_system
1524 vte = dependency('vte-2.91',
1525 method: 'pkg-config',
1526 required: get_option('vte'))
1528 elif have_gtk_clipboard
1529 error('GTK clipboard requested, but GTK not found')
1535 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found())
1538 if get_option('png').allowed() and have_system
1539 png = dependency('libpng', version: '>=1.6.34', required: get_option('png'),
1540 method: 'pkg-config')
1545 if get_option('vnc').allowed() and have_system
1546 vnc = declare_dependency() # dummy dependency
1547 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1548 method: 'pkg-config')
1549 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1550 required: get_option('vnc_sasl'))
1552 sasl = declare_dependency(dependencies: sasl,
1553 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1558 if not get_option('auth_pam').auto() or have_system
1559 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1560 required: get_option('auth_pam'))
1562 if pam.found() and not cc.links('''
1564 #include <security/pam_appl.h>
1566 const char *service_name = "qemu";
1567 const char *user = "frank";
1568 const struct pam_conv pam_conv = { 0 };
1569 pam_handle_t *pamh = NULL;
1570 pam_start(service_name, user, &pam_conv, &pamh);
1572 }''', dependencies: pam)
1574 if get_option('auth_pam').enabled()
1575 error('could not link libpam')
1577 warning('could not link libpam, disabling')
1582 if not get_option('snappy').auto() or have_system
1583 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1584 required: get_option('snappy'))
1586 if snappy.found() and not linker.links('''
1587 #include <snappy-c.h>
1588 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1590 if get_option('snappy').enabled()
1591 error('could not link libsnappy')
1593 warning('could not link libsnappy, disabling')
1598 if not get_option('lzo').auto() or have_system
1599 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1600 required: get_option('lzo'))
1602 if lzo.found() and not cc.links('''
1603 #include <lzo/lzo1x.h>
1604 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1606 if get_option('lzo').enabled()
1607 error('could not link liblzo2')
1609 warning('could not link liblzo2, disabling')
1614 if not get_option('numa').auto() or have_system or have_tools
1615 numa = cc.find_library('numa', has_headers: ['numa.h'],
1616 required: get_option('numa'))
1618 if numa.found() and not cc.links('''
1620 int main(void) { return numa_available(); }
1621 ''', dependencies: numa)
1623 if get_option('numa').enabled()
1624 error('could not link numa')
1626 warning('could not link numa, disabling')
1631 if not get_option('rdma').auto() or have_system
1632 libumad = cc.find_library('ibumad', required: get_option('rdma'))
1633 rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'],
1634 required: get_option('rdma')),
1635 cc.find_library('ibverbs', required: get_option('rdma')),
1637 rdma = declare_dependency(dependencies: rdma_libs)
1638 foreach lib: rdma_libs
1646 if get_option('xen').enabled() or (get_option('xen').auto() and have_system)
1647 xencontrol = dependency('xencontrol', required: false,
1648 method: 'pkg-config')
1649 if xencontrol.found()
1650 xen_pc = declare_dependency(version: xencontrol.version(),
1653 # disabler: true makes xen_pc.found() return false if any is not found
1654 dependency('xenstore', required: false,
1655 method: 'pkg-config',
1657 dependency('xenforeignmemory', required: false,
1658 method: 'pkg-config',
1660 dependency('xengnttab', required: false,
1661 method: 'pkg-config',
1663 dependency('xenevtchn', required: false,
1664 method: 'pkg-config',
1666 dependency('xendevicemodel', required: false,
1667 method: 'pkg-config',
1669 # optional, no "disabler: true"
1670 dependency('xentoolcore', required: false,
1671 method: 'pkg-config')])
1677 xen_tests = [ '4.11.0', '4.10.0', '4.9.0', '4.8.0', '4.7.1', '4.6.0', '4.5.0', '4.2.0' ]
1679 '4.11.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
1680 '4.10.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
1681 '4.9.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1682 '4.8.0': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1683 '4.7.1': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1684 '4.6.0': [ 'xenstore', 'xenctrl' ],
1685 '4.5.0': [ 'xenstore', 'xenctrl' ],
1686 '4.2.0': [ 'xenstore', 'xenctrl' ],
1689 foreach ver: xen_tests
1690 # cache the various library tests to avoid polluting the logs
1692 foreach l: xen_libs[ver]
1693 if l not in xen_deps
1694 xen_deps += { l: cc.find_library(l, required: false) }
1696 xen_test_deps += xen_deps[l]
1699 # Use -D to pick just one of the test programs in scripts/xen-detect.c
1700 xen_version = ver.split('.')
1701 xen_ctrl_version = xen_version[0] + \
1702 ('0' + xen_version[1]).substring(-2) + \
1703 ('0' + xen_version[2]).substring(-2)
1704 if cc.links(files('scripts/xen-detect.c'),
1705 args: '-DCONFIG_XEN_CTRL_INTERFACE_VERSION=' + xen_ctrl_version,
1706 dependencies: xen_test_deps)
1707 xen = declare_dependency(version: ver, dependencies: xen_test_deps)
1713 accelerators += 'CONFIG_XEN'
1714 elif get_option('xen').enabled()
1715 error('could not compile and link Xen test program')
1718 have_xen_pci_passthrough = get_option('xen_pci_passthrough') \
1719 .require(xen.found(),
1720 error_message: 'Xen PCI passthrough requested but Xen not enabled') \
1721 .require(targetos == 'linux',
1722 error_message: 'Xen PCI passthrough not available on this platform') \
1727 if not get_option('smartcard').auto() or have_system
1728 cacard = dependency('libcacard', required: get_option('smartcard'),
1729 version: '>=2.5.1', method: 'pkg-config')
1733 u2f = dependency('u2f-emu', required: get_option('u2f'),
1734 method: 'pkg-config')
1738 canokey = dependency('canokey-qemu', required: get_option('canokey'),
1739 method: 'pkg-config')
1741 usbredir = not_found
1742 if not get_option('usb_redir').auto() or have_system
1743 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1744 version: '>=0.6', method: 'pkg-config')
1747 if not get_option('libusb').auto() or have_system
1748 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1749 version: '>=1.0.13', method: 'pkg-config')
1753 if not get_option('libpmem').auto() or have_system
1754 libpmem = dependency('libpmem', required: get_option('libpmem'),
1755 method: 'pkg-config')
1757 libdaxctl = not_found
1758 if not get_option('libdaxctl').auto() or have_system
1759 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1760 version: '>=57', method: 'pkg-config')
1764 tasn1 = dependency('libtasn1',
1765 method: 'pkg-config')
1767 keyutils = dependency('libkeyutils', required: false,
1768 method: 'pkg-config')
1770 has_gettid = cc.has_function('gettid')
1773 selinux = dependency('libselinux',
1774 required: get_option('selinux'),
1775 method: 'pkg-config')
1780 if get_option('malloc') == 'system'
1782 get_option('malloc_trim').allowed() and \
1783 cc.links('''#include <malloc.h>
1784 int main(void) { malloc_trim(0); return 0; }''')
1786 has_malloc_trim = false
1787 malloc = cc.find_library(get_option('malloc'), required: true)
1789 if not has_malloc_trim and get_option('malloc_trim').enabled()
1790 if get_option('malloc') == 'system'
1791 error('malloc_trim not available on this platform.')
1793 error('malloc_trim not available with non-libc memory allocator')
1797 # Check whether the glibc provides statx()
1799 gnu_source_prefix = '''
1804 statx_test = gnu_source_prefix + '''
1805 #include <sys/stat.h>
1807 struct statx statxbuf;
1808 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1812 has_statx = cc.links(statx_test)
1814 # Check whether statx() provides mount ID information
1816 statx_mnt_id_test = gnu_source_prefix + '''
1817 #include <sys/stat.h>
1819 struct statx statxbuf;
1820 statx(0, "", 0, STATX_BASIC_STATS | STATX_MNT_ID, &statxbuf);
1821 return statxbuf.stx_mnt_id;
1824 has_statx_mnt_id = cc.links(statx_mnt_id_test)
1826 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
1827 .require(targetos == 'linux',
1828 error_message: 'vhost_user_blk_server requires linux') \
1829 .require(have_vhost_user,
1830 error_message: 'vhost_user_blk_server requires vhost-user support') \
1831 .disable_auto_if(not have_tools and not have_system) \
1834 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1835 error('Cannot enable fuse-lseek while fuse is disabled')
1838 fuse = dependency('fuse3', required: get_option('fuse'),
1839 version: '>=3.1', method: 'pkg-config')
1841 fuse_lseek = not_found
1842 if get_option('fuse_lseek').allowed()
1843 if fuse.version().version_compare('>=3.8')
1845 fuse_lseek = declare_dependency()
1846 elif get_option('fuse_lseek').enabled()
1848 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1850 error('fuse-lseek requires libfuse, which was not found')
1855 have_libvduse = (targetos == 'linux')
1856 if get_option('libvduse').enabled()
1857 if targetos != 'linux'
1858 error('libvduse requires linux')
1860 elif get_option('libvduse').disabled()
1861 have_libvduse = false
1864 have_vduse_blk_export = (have_libvduse and targetos == 'linux')
1865 if get_option('vduse_blk_export').enabled()
1866 if targetos != 'linux'
1867 error('vduse_blk_export requires linux')
1868 elif not have_libvduse
1869 error('vduse_blk_export requires libvduse support')
1871 elif get_option('vduse_blk_export').disabled()
1872 have_vduse_blk_export = false
1876 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1877 if libbpf.found() and not cc.links('''
1878 #include <bpf/libbpf.h>
1881 bpf_object__destroy_skeleton(NULL);
1883 }''', dependencies: libbpf)
1885 if get_option('bpf').enabled()
1886 error('libbpf skeleton test failed')
1888 warning('libbpf skeleton test failed, disabling')
1894 if not get_option('libdw').auto() or \
1895 (not get_option('prefer_static') and (have_system or have_user))
1896 libdw = dependency('libdw',
1897 method: 'pkg-config',
1898 required: get_option('libdw'))
1905 audio_drivers_selected = []
1907 audio_drivers_available = {
1908 'alsa': alsa.found(),
1909 'coreaudio': coreaudio.found(),
1910 'dsound': dsound.found(),
1911 'jack': jack.found(),
1913 'pa': pulse.found(),
1914 'pipewire': pipewire.found(),
1916 'sndio': sndio.found(),
1918 foreach k, v: audio_drivers_available
1919 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1922 # Default to native drivers first, OSS second, SDL third
1923 audio_drivers_priority = \
1924 [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \
1925 (targetos == 'linux' ? [] : [ 'sdl' ])
1926 audio_drivers_default = []
1927 foreach k: audio_drivers_priority
1928 if audio_drivers_available[k]
1929 audio_drivers_default += k
1933 foreach k: get_option('audio_drv_list')
1935 audio_drivers_selected += audio_drivers_default
1936 elif not audio_drivers_available[k]
1937 error('Audio driver "@0@" not available.'.format(k))
1939 audio_drivers_selected += k
1943 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1944 '"' + '", "'.join(audio_drivers_selected) + '", ')
1946 if get_option('cfi')
1948 # Check for dependency on LTO
1949 if not get_option('b_lto')
1950 error('Selected Control-Flow Integrity but LTO is disabled')
1953 error('Selected Control-Flow Integrity is not compatible with modules')
1955 # Check for cfi flags. CFI requires LTO so we can't use
1956 # get_supported_arguments, but need a more complex "compiles" which allows
1958 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1959 args: ['-flto', '-fsanitize=cfi-icall'] )
1960 cfi_flags += '-fsanitize=cfi-icall'
1962 error('-fsanitize=cfi-icall is not supported by the compiler')
1964 if cc.compiles('int main () { return 0; }',
1965 name: '-fsanitize-cfi-icall-generalize-pointers',
1966 args: ['-flto', '-fsanitize=cfi-icall',
1967 '-fsanitize-cfi-icall-generalize-pointers'] )
1968 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1970 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1972 if get_option('cfi_debug')
1973 if cc.compiles('int main () { return 0; }',
1974 name: '-fno-sanitize-trap=cfi-icall',
1975 args: ['-flto', '-fsanitize=cfi-icall',
1976 '-fno-sanitize-trap=cfi-icall'] )
1977 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1979 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1982 add_global_arguments(cfi_flags, native: false, language: all_languages)
1983 add_global_link_arguments(cfi_flags, native: false, language: all_languages)
1986 have_host_block_device = (targetos != 'darwin' or
1987 cc.has_header('IOKit/storage/IOMedia.h'))
1989 dbus_display = get_option('dbus_display') \
1990 .require(gio.version().version_compare('>=2.64'),
1991 error_message: '-display dbus requires glib>=2.64') \
1992 .require(gdbus_codegen.found(),
1993 error_message: gdbus_codegen_error.format('-display dbus')) \
1994 .require(targetos != 'windows',
1995 error_message: '-display dbus is not available on Windows') \
1998 have_virtfs = get_option('virtfs') \
1999 .require(targetos == 'linux' or targetos == 'darwin',
2000 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
2001 .require(targetos == 'linux' or cc.has_function('pthread_fchdir_np'),
2002 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
2003 .require(targetos == 'darwin' or libattr.found(),
2004 error_message: 'virtio-9p (virtfs) on Linux requires libattr-devel') \
2005 .disable_auto_if(not have_tools and not have_system) \
2008 have_virtfs_proxy_helper = get_option('virtfs_proxy_helper') \
2009 .require(targetos != 'darwin', error_message: 'the virtfs proxy helper is incompatible with macOS') \
2010 .require(have_virtfs, error_message: 'the virtfs proxy helper requires that virtfs is enabled') \
2011 .disable_auto_if(not have_tools) \
2012 .require(libcap_ng.found(), error_message: 'the virtfs proxy helper requires libcap-ng') \
2015 if get_option('block_drv_ro_whitelist') == ''
2016 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
2018 config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
2019 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
2021 if get_option('block_drv_rw_whitelist') == ''
2022 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
2024 config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
2025 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
2028 foreach k : get_option('trace_backends')
2029 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
2031 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
2032 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
2034 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
2036 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
2037 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
2038 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
2039 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
2040 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
2042 qemu_firmwarepath = ''
2043 foreach k : get_option('qemu_firmwarepath')
2044 qemu_firmwarepath += '"' + get_option('prefix') / k + '", '
2046 config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath)
2048 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
2049 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
2050 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
2051 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
2052 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
2053 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
2056 config_host_data.set('CONFIG_STAMP', run_command(
2057 meson.current_source_dir() / 'scripts/qemu-stamp.py',
2058 meson.project_version(), get_option('pkgversion'), '--',
2059 meson.current_source_dir() / 'configure',
2060 capture: true, check: true).stdout().strip())
2063 have_slirp_smbd = get_option('slirp_smbd') \
2064 .require(targetos != 'windows', error_message: 'Host smbd not supported on this platform.') \
2067 smbd_path = get_option('smbd')
2069 smbd_path = (targetos == 'solaris' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
2071 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
2074 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
2076 if get_option('module_upgrades') and not enable_modules
2077 error('Cannot enable module-upgrades as modules are not enabled')
2079 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
2081 config_host_data.set('CONFIG_ATTR', libattr.found())
2082 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
2083 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
2084 config_host_data.set('CONFIG_COCOA', cocoa.found())
2085 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
2086 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
2087 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
2088 config_host_data.set('CONFIG_LZO', lzo.found())
2089 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
2090 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
2091 config_host_data.set('CONFIG_BLKIO', blkio.found())
2092 config_host_data.set('CONFIG_CURL', curl.found())
2093 config_host_data.set('CONFIG_CURSES', curses.found())
2094 config_host_data.set('CONFIG_GBM', gbm.found())
2095 config_host_data.set('CONFIG_GIO', gio.found())
2096 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
2097 if glusterfs.found()
2098 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
2099 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
2100 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
2101 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
2102 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
2103 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
2105 config_host_data.set('CONFIG_GTK', gtk.found())
2106 config_host_data.set('CONFIG_VTE', vte.found())
2107 config_host_data.set('CONFIG_GTK_CLIPBOARD', have_gtk_clipboard)
2108 config_host_data.set('CONFIG_HEXAGON_IDEF_PARSER', get_option('hexagon_idef_parser'))
2109 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
2110 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
2111 config_host_data.set('CONFIG_EBPF', libbpf.found())
2112 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
2113 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
2114 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
2115 config_host_data.set('CONFIG_LIBSSH', libssh.found())
2116 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
2117 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
2118 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
2119 config_host_data.set('CONFIG_MODULES', enable_modules)
2120 config_host_data.set('CONFIG_NUMA', numa.found())
2122 config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY',
2123 cc.has_function('numa_has_preferred_many',
2124 dependencies: numa))
2126 config_host_data.set('CONFIG_OPENGL', opengl.found())
2127 config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
2128 config_host_data.set('CONFIG_RBD', rbd.found())
2129 config_host_data.set('CONFIG_RDMA', rdma.found())
2130 config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack'))
2131 config_host_data.set('CONFIG_SDL', sdl.found())
2132 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
2133 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
2135 config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc)
2137 config_host_data.set('CONFIG_SNAPPY', snappy.found())
2138 config_host_data.set('CONFIG_TPM', have_tpm)
2139 config_host_data.set('CONFIG_TSAN', get_option('tsan'))
2140 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
2141 config_host_data.set('CONFIG_VDE', vde.found())
2142 config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
2143 config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
2144 config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)
2145 config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
2146 config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
2147 config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
2148 config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
2149 config_host_data.set('CONFIG_VMNET', vmnet.found())
2150 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
2151 config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export)
2152 config_host_data.set('CONFIG_PNG', png.found())
2153 config_host_data.set('CONFIG_VNC', vnc.found())
2154 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
2155 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
2156 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
2157 config_host_data.set('CONFIG_VTE', vte.found())
2158 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
2159 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
2160 config_host_data.set('CONFIG_GETTID', has_gettid)
2161 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
2162 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
2163 config_host_data.set('CONFIG_TASN1', tasn1.found())
2164 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
2165 config_host_data.set('CONFIG_NETTLE', nettle.found())
2166 config_host_data.set('CONFIG_HOGWEED', hogweed.found())
2167 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
2168 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
2169 config_host_data.set('CONFIG_STATX', has_statx)
2170 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
2171 config_host_data.set('CONFIG_ZSTD', zstd.found())
2172 config_host_data.set('CONFIG_FUSE', fuse.found())
2173 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
2174 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
2175 if spice_protocol.found()
2176 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
2177 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
2178 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
2180 config_host_data.set('CONFIG_SPICE', spice.found())
2181 config_host_data.set('CONFIG_X11', x11.found())
2182 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
2183 config_host_data.set('CONFIG_CFI', get_option('cfi'))
2184 config_host_data.set('CONFIG_SELINUX', selinux.found())
2185 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
2186 config_host_data.set('CONFIG_LIBDW', libdw.found())
2188 # protect from xen.version() having less than three components
2189 xen_version = xen.version().split('.') + ['0', '0']
2190 xen_ctrl_version = xen_version[0] + \
2191 ('0' + xen_version[1]).substring(-2) + \
2192 ('0' + xen_version[2]).substring(-2)
2193 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
2195 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
2196 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
2197 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
2198 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
2200 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
2201 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
2203 have_coroutine_pool = get_option('coroutine_pool')
2204 if get_option('debug_stack_usage') and have_coroutine_pool
2205 message('Disabling coroutine pool to measure stack usage')
2206 have_coroutine_pool = false
2208 config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool)
2209 config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock'))
2210 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
2211 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
2212 config_host_data.set('CONFIG_GPROF', get_option('gprof'))
2213 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
2214 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
2215 config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
2218 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
2219 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
2220 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
2221 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
2222 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
2223 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
2224 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
2225 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
2226 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
2227 if targetos == 'windows'
2228 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h'))
2232 config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range'))
2233 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
2234 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
2235 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
2236 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
2237 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
2238 # Note that we need to specify prefix: here to avoid incorrectly
2239 # thinking that Windows has posix_memalign()
2240 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
2241 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
2242 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
2243 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
2244 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
2245 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
2246 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
2247 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
2248 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
2249 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
2250 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
2251 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
2252 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
2253 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
2254 config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice)
2255 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
2256 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
2257 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
2259 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
2260 cc.has_function('rbd_namespace_exists',
2262 prefix: '#include <rbd/librbd.h>'))
2265 config_host_data.set('HAVE_IBV_ADVISE_MR',
2266 cc.has_function('ibv_advise_mr',
2268 prefix: '#include <infiniband/verbs.h>'))
2271 have_asan_fiber = false
2272 if get_option('sanitizers') and \
2273 not cc.has_function('__sanitizer_start_switch_fiber',
2274 args: '-fsanitize=address',
2275 prefix: '#include <sanitizer/asan_interface.h>')
2276 warning('Missing ASAN due to missing fiber annotation interface')
2277 warning('Without code annotation, the report may be inferior.')
2279 have_asan_fiber = true
2281 config_host_data.set('CONFIG_ASAN_IFACE_FIBER', have_asan_fiber)
2284 config_host_data.set('CONFIG_BLKZONED',
2285 cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE'))
2286 config_host_data.set('CONFIG_EPOLL_CREATE1',
2287 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
2288 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
2289 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
2290 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
2291 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
2292 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
2293 config_host_data.set('CONFIG_FIEMAP',
2294 cc.has_header('linux/fiemap.h') and
2295 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
2296 config_host_data.set('CONFIG_GETRANDOM',
2297 cc.has_function('getrandom') and
2298 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
2299 config_host_data.set('CONFIG_INOTIFY',
2300 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
2301 config_host_data.set('CONFIG_INOTIFY1',
2302 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
2303 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
2304 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
2305 config_host_data.set('CONFIG_RTNETLINK',
2306 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
2307 config_host_data.set('CONFIG_SYSMACROS',
2308 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
2309 config_host_data.set('HAVE_OPTRESET',
2310 cc.has_header_symbol('getopt.h', 'optreset'))
2311 config_host_data.set('HAVE_IPPROTO_MPTCP',
2312 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
2315 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
2316 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
2317 prefix: '#include <signal.h>'))
2318 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
2319 cc.has_member('struct stat', 'st_atim',
2320 prefix: '#include <sys/stat.h>'))
2321 config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY',
2322 cc.has_member('struct blk_zone', 'capacity',
2323 prefix: '#include <linux/blkzoned.h>'))
2326 config_host_data.set('CONFIG_IOVEC',
2327 cc.has_type('struct iovec',
2328 prefix: '#include <sys/uio.h>'))
2329 config_host_data.set('HAVE_UTMPX',
2330 cc.has_type('struct utmpx',
2331 prefix: '#include <utmpx.h>'))
2333 config_host_data.set('CONFIG_EVENTFD', cc.links('''
2334 #include <sys/eventfd.h>
2335 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
2336 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
2339 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
2340 return fdatasync(0);
2342 #error Not supported
2346 has_madvise = cc.links(gnu_source_prefix + '''
2347 #include <sys/types.h>
2348 #include <sys/mman.h>
2350 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
2351 missing_madvise_proto = false
2353 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
2354 # but forget to prototype it. In this case, has_madvise will be true (the
2355 # test program links despite a compile warning). To detect the
2356 # missing-prototype case, we try again with a definitely-bogus prototype.
2357 # This will only compile if the system headers don't provide the prototype;
2358 # otherwise the conflicting prototypes will cause a compiler error.
2359 missing_madvise_proto = cc.links(gnu_source_prefix + '''
2360 #include <sys/types.h>
2361 #include <sys/mman.h>
2363 extern int madvise(int);
2364 int main(void) { return madvise(0); }''')
2366 config_host_data.set('CONFIG_MADVISE', has_madvise)
2367 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
2369 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
2370 #include <sys/mman.h>
2371 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
2372 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
2374 #if !defined(AT_EMPTY_PATH)
2375 # error missing definition
2377 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
2379 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
2380 #include <sys/mman.h>
2382 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
2384 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
2385 #include <pthread.h>
2387 static void *f(void *p) { return NULL; }
2391 pthread_create(&thread, 0, f, 0);
2392 pthread_setname_np(thread, "QEMU");
2394 }''', dependencies: threads))
2395 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
2396 #include <pthread.h>
2398 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
2402 pthread_create(&thread, 0, f, 0);
2404 }''', dependencies: threads))
2405 config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(gnu_source_prefix + '''
2406 #include <pthread.h>
2407 #include <pthread_np.h>
2409 static void *f(void *p) { return NULL; }
2413 pthread_create(&thread, 0, f, 0);
2414 pthread_set_name_np(thread, "QEMU");
2416 }''', dependencies: threads))
2417 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
2418 #include <pthread.h>
2423 pthread_condattr_t attr
2424 pthread_condattr_init(&attr);
2425 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
2427 }''', dependencies: threads))
2428 config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(gnu_source_prefix + '''
2429 #include <pthread.h>
2431 static void *f(void *p) { return NULL; }
2434 int setsize = CPU_ALLOC_SIZE(64);
2437 pthread_create(&thread, 0, f, 0);
2438 cpuset = CPU_ALLOC(64);
2439 CPU_ZERO_S(setsize, cpuset);
2440 pthread_setaffinity_np(thread, setsize, cpuset);
2441 pthread_getaffinity_np(thread, setsize, cpuset);
2444 }''', dependencies: threads))
2445 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
2446 #include <sys/signalfd.h>
2448 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
2449 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
2457 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
2458 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
2462 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
2463 #include <sys/mman.h>
2465 return mlockall(MCL_FUTURE);
2469 if get_option('l2tpv3').allowed() and have_system
2470 have_l2tpv3 = cc.has_type('struct mmsghdr',
2471 prefix: gnu_source_prefix + '''
2472 #include <sys/socket.h>
2473 #include <linux/ip.h>''')
2475 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2478 if get_option('netmap').allowed() and have_system
2479 have_netmap = cc.compiles('''
2480 #include <inttypes.h>
2482 #include <net/netmap.h>
2483 #include <net/netmap_user.h>
2484 #if (NETMAP_API < 11) || (NETMAP_API > 15)
2487 int main(void) { return 0; }''')
2488 if not have_netmap and get_option('netmap').enabled()
2489 error('Netmap headers not available')
2492 config_host_data.set('CONFIG_NETMAP', have_netmap)
2494 # Work around a system header bug with some kernel/XFS header
2495 # versions where they both try to define 'struct fsxattr':
2496 # xfs headers will not try to redefine structs from linux headers
2497 # if this macro is set.
2498 config_host_data.set('HAVE_FSXATTR', cc.links('''
2499 #include <linux/fs.h>
2505 # Some versions of Mac OS X incorrectly define SIZE_MAX
2506 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2510 return printf("%zu", SIZE_MAX);
2511 }''', args: ['-Werror']))
2513 # See if 64-bit atomic operations are supported.
2514 # Note that without __atomic builtins, we can only
2515 # assume atomic loads/stores max at pointer size.
2516 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
2520 uint64_t x = 0, y = 0;
2521 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2522 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2523 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2524 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2525 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2529 has_int128 = cc.links('''
2539 config_host_data.set('CONFIG_INT128', has_int128)
2542 # "do we have 128-bit atomics which are handled inline and specifically not
2543 # via libatomic". The reason we can't use libatomic is documented in the
2544 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2545 # We only care about these operations on 16-byte aligned pointers, so
2546 # force 16-byte alignment of the pointer, which may be greater than
2547 # __alignof(unsigned __int128) for the host.
2548 atomic_test_128 = '''
2549 int main(int ac, char **av) {
2550 unsigned __int128 *p = __builtin_assume_aligned(av[ac - 1], sizeof(16));
2551 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED);
2552 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED);
2553 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2556 has_atomic128 = cc.links(atomic_test_128)
2558 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2560 if not has_atomic128
2561 # Even with __builtin_assume_aligned, the above test may have failed
2562 # without optimization enabled. Try again with optimizations locally
2563 # enabled for the function. See
2564 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389
2565 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128)
2566 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt)
2568 if not has_atomic128_opt
2569 config_host_data.set('CONFIG_CMPXCHG128', cc.links('''
2572 unsigned __int128 x = 0, y = 0;
2573 __sync_val_compare_and_swap_16(&x, y, x);
2581 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2582 #include <sys/auxv.h>
2584 return getauxval(AT_HWCAP) == 0;
2587 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2588 #include <linux/usbdevice_fs.h>
2590 #ifndef USBDEVFS_GET_CAPABILITIES
2591 #error "USBDEVFS_GET_CAPABILITIES undefined"
2594 #ifndef USBDEVFS_DISCONNECT_CLAIM
2595 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2598 int main(void) { return 0; }'''))
2600 have_keyring = get_option('keyring') \
2601 .require(targetos == 'linux', error_message: 'keyring is only available on Linux') \
2602 .require(cc.compiles('''
2604 #include <asm/unistd.h>
2605 #include <linux/keyctl.h>
2606 #include <sys/syscall.h>
2609 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2610 }'''), error_message: 'keyctl syscall not available on this system').allowed()
2611 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2613 have_cpuid_h = cc.links('''
2616 unsigned a, b, c, d;
2617 unsigned max = __get_cpuid_max(0, 0);
2620 __cpuid(1, a, b, c, d);
2624 __cpuid_count(7, 0, a, b, c, d);
2629 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2631 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2632 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2633 .require(cc.links('''
2635 #include <immintrin.h>
2636 static int __attribute__((target("avx2"))) bar(void *a) {
2637 __m256i x = *(__m256i *)a;
2638 return _mm256_testz_si256(x, x);
2640 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2641 '''), error_message: 'AVX2 not available').allowed())
2643 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2644 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2645 .require(cc.links('''
2647 #include <immintrin.h>
2648 static int __attribute__((target("avx512f"))) bar(void *a) {
2649 __m512i x = *(__m512i *)a;
2650 return _mm512_test_epi64_mask(x, x);
2652 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2653 '''), error_message: 'AVX512F not available').allowed())
2655 config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \
2656 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \
2657 .require(cc.links('''
2659 #include <immintrin.h>
2660 static int __attribute__((target("avx512bw"))) bar(void *a) {
2662 __m512i res= _mm512_abs_epi8(*x);
2665 int main(int argc, char *argv[]) { return bar(argv[0]); }
2666 '''), error_message: 'AVX512BW not available').allowed())
2668 have_pvrdma = get_option('pvrdma') \
2669 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
2670 .require(cc.compiles(gnu_source_prefix + '''
2671 #include <sys/mman.h>
2676 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2679 }'''), error_message: 'PVRDMA requires mremap').allowed()
2682 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.links('''
2683 #include <infiniband/verbs.h>
2687 struct ibv_pd *pd = NULL;
2693 mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2699 if get_option('membarrier').disabled()
2700 have_membarrier = false
2701 elif targetos == 'windows'
2702 have_membarrier = true
2703 elif targetos == 'linux'
2704 have_membarrier = cc.compiles('''
2705 #include <linux/membarrier.h>
2706 #include <sys/syscall.h>
2710 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2711 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2715 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2716 .require(have_membarrier, error_message: 'membarrier system call not available') \
2719 have_afalg = get_option('crypto_afalg') \
2720 .require(cc.compiles(gnu_source_prefix + '''
2722 #include <sys/types.h>
2723 #include <sys/socket.h>
2724 #include <linux/if_alg.h>
2727 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2730 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2731 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2733 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2734 'linux/vm_sockets.h', 'AF_VSOCK',
2735 prefix: '#include <sys/socket.h>',
2739 have_vss_sdk = false # old xp/2003 SDK
2740 if targetos == 'windows' and link_language == 'cpp'
2741 have_vss = cxx.compiles('''
2742 #define __MIDL_user_allocate_free_DEFINED__
2744 int main(void) { return VSS_CTX_BACKUP; }''')
2745 have_vss_sdk = cxx.has_header('vscoordint.h')
2747 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2749 foreach k, v: config_host
2750 if k.startswith('CONFIG_')
2751 config_host_data.set(k, v == 'y' ? 1 : v)
2755 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2756 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2757 if targetos == 'windows'
2758 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2764 }''', name: '_lock_file and _unlock_file'))
2767 if targetos == 'windows'
2768 mingw_has_setjmp_longjmp = cc.links('''
2772 * These functions are not available in setjmp header, but may be
2773 * available at link time, from libmingwex.a.
2775 extern int __mingw_setjmp(jmp_buf);
2776 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
2778 __mingw_setjmp(env);
2779 __mingw_longjmp(env, 0);
2781 ''', name: 'mingw setjmp and longjmp')
2783 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp
2784 error('mingw must provide setjmp/longjmp for windows-arm64')
2788 ########################
2789 # Target configuration #
2790 ########################
2792 minikconf = find_program('scripts/minikconf.py')
2794 config_all_devices = {}
2795 config_all_disas = {}
2796 config_devices_mak_list = []
2797 config_devices_h = {}
2798 config_target_h = {}
2799 config_target_mak = {}
2802 'alpha' : ['CONFIG_ALPHA_DIS'],
2803 'avr' : ['CONFIG_AVR_DIS'],
2804 'cris' : ['CONFIG_CRIS_DIS'],
2805 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2806 'hppa' : ['CONFIG_HPPA_DIS'],
2807 'i386' : ['CONFIG_I386_DIS'],
2808 'x86_64' : ['CONFIG_I386_DIS'],
2809 'm68k' : ['CONFIG_M68K_DIS'],
2810 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2811 'mips' : ['CONFIG_MIPS_DIS'],
2812 'nios2' : ['CONFIG_NIOS2_DIS'],
2813 'or1k' : ['CONFIG_OPENRISC_DIS'],
2814 'ppc' : ['CONFIG_PPC_DIS'],
2815 'riscv' : ['CONFIG_RISCV_DIS'],
2816 'rx' : ['CONFIG_RX_DIS'],
2817 's390' : ['CONFIG_S390_DIS'],
2818 'sh4' : ['CONFIG_SH4_DIS'],
2819 'sparc' : ['CONFIG_SPARC_DIS'],
2820 'xtensa' : ['CONFIG_XTENSA_DIS'],
2821 'loongarch' : ['CONFIG_LOONGARCH_DIS'],
2824 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2826 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2827 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2828 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2829 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2830 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2831 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2832 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
2833 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2834 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2835 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2836 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
2837 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
2838 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
2839 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : [])
2841 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2843 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2844 actual_target_dirs = []
2846 foreach target : target_dirs
2847 config_target = { 'TARGET_NAME': target.split('-')[0] }
2848 if target.endswith('linux-user')
2849 if targetos != 'linux'
2853 error('Target @0@ is only available on a Linux host'.format(target))
2855 config_target += { 'CONFIG_LINUX_USER': 'y' }
2856 elif target.endswith('bsd-user')
2857 if 'CONFIG_BSD' not in config_host
2861 error('Target @0@ is only available on a BSD host'.format(target))
2863 config_target += { 'CONFIG_BSD_USER': 'y' }
2864 elif target.endswith('softmmu')
2865 config_target += { 'CONFIG_SOFTMMU': 'y' }
2867 if target.endswith('-user')
2869 'CONFIG_USER_ONLY': 'y',
2870 'CONFIG_QEMU_INTERP_PREFIX':
2871 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
2876 foreach sym: accelerators
2877 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2878 config_target += { sym: 'y' }
2879 config_all += { sym: 'y' }
2880 if target in modular_tcg
2881 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2883 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2885 accel_kconfig += [ sym + '=y' ]
2888 if accel_kconfig.length() == 0
2892 error('No accelerator available for target @0@'.format(target))
2895 actual_target_dirs += target
2896 config_target += keyval.load('configs/targets' / target + '.mak')
2897 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
2899 if 'TARGET_NEED_FDT' in config_target
2900 fdt_required += target
2904 if 'TARGET_BASE_ARCH' not in config_target
2905 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2907 if 'TARGET_ABI_DIR' not in config_target
2908 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2910 if 'TARGET_BIG_ENDIAN' not in config_target
2911 config_target += {'TARGET_BIG_ENDIAN': 'n'}
2914 foreach k, v: disassemblers
2915 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
2917 config_target += { sym: 'y' }
2918 config_all_disas += { sym: 'y' }
2923 config_target_data = configuration_data()
2924 foreach k, v: config_target
2925 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2927 elif ignored.contains(k)
2929 elif k == 'TARGET_BASE_ARCH'
2930 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2931 # not used to select files from sourcesets.
2932 config_target_data.set('TARGET_' + v.to_upper(), 1)
2933 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
2934 config_target_data.set_quoted(k, v)
2936 config_target_data.set(k, 1)
2938 config_target_data.set(k, 0)
2940 config_target_data.set(k, v)
2943 config_target_data.set('QEMU_ARCH',
2944 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
2945 config_target_h += {target: configure_file(output: target + '-config-target.h',
2946 configuration: config_target_data)}
2948 if target.endswith('-softmmu')
2949 config_input = meson.get_external_property(target, 'default')
2950 config_devices_mak = target + '-config-devices.mak'
2951 config_devices_mak = configure_file(
2952 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2953 output: config_devices_mak,
2954 depfile: config_devices_mak + '.d',
2956 command: [minikconf,
2957 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2958 config_devices_mak, '@DEPFILE@', '@INPUT@',
2959 host_kconfig, accel_kconfig,
2960 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
2962 config_devices_data = configuration_data()
2963 config_devices = keyval.load(config_devices_mak)
2964 foreach k, v: config_devices
2965 config_devices_data.set(k, 1)
2967 config_devices_mak_list += config_devices_mak
2968 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2969 configuration: config_devices_data)}
2970 config_target += config_devices
2971 config_all_devices += config_devices
2973 config_target_mak += {target: config_target}
2975 target_dirs = actual_target_dirs
2977 # This configuration is used to build files that are shared by
2978 # multiple binaries, and then extracted out of the "common"
2979 # static_library target.
2981 # We do not use all_sources()/all_dependencies(), because it would
2982 # build literally all source files, including devices only used by
2983 # targets that are not built for this compilation. The CONFIG_ALL
2984 # pseudo symbol replaces it.
2986 config_all += config_all_devices
2987 config_all += config_host
2988 config_all += config_all_disas
2990 'CONFIG_XEN': xen.found(),
2991 'CONFIG_SOFTMMU': have_system,
2992 'CONFIG_USER_ONLY': have_user,
2996 target_configs_h = []
2997 foreach target: target_dirs
2998 target_configs_h += config_target_h[target]
2999 target_configs_h += config_devices_h.get(target, [])
3001 genh += custom_target('config-poison.h',
3002 input: [target_configs_h],
3003 output: 'config-poison.h',
3005 command: [find_program('scripts/make-config-poison.sh'),
3012 capstone = not_found
3013 if not get_option('capstone').auto() or have_system or have_user
3014 capstone = dependency('capstone', version: '>=3.0.5',
3015 method: 'pkg-config',
3016 required: get_option('capstone'))
3018 # Some versions of capstone have broken pkg-config file
3019 # that reports a wrong -I path, causing the #include to
3020 # fail later. If the system has such a broken version
3022 if capstone.found() and not cc.compiles('#include <capstone.h>',
3023 dependencies: [capstone])
3024 capstone = not_found
3025 if get_option('capstone').enabled()
3026 error('capstone requested, but it does not appear to work')
3031 libvfio_user_dep = not_found
3032 if have_system and vfio_user_server_allowed
3033 have_internal = fs.exists(meson.current_source_dir() / 'subprojects/libvfio-user/meson.build')
3035 if not have_internal
3036 error('libvfio-user source not found - please pull git submodule')
3039 libvfio_user_proj = subproject('libvfio-user')
3041 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep')
3046 fdt_opt = get_option('fdt')
3047 if fdt_opt in ['enabled', 'auto', 'system']
3048 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
3049 fdt = cc.find_library('fdt',
3050 required: fdt_opt == 'system' or
3051 fdt_opt == 'enabled' and not have_internal)
3052 if fdt.found() and cc.links('''
3054 #include <libfdt_env.h>
3055 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
3058 elif fdt_opt == 'system'
3059 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
3061 fdt_opt = 'internal'
3063 fdt_opt = 'disabled'
3067 if fdt_opt == 'internal'
3070 'dtc/libfdt/fdt_ro.c',
3071 'dtc/libfdt/fdt_wip.c',
3072 'dtc/libfdt/fdt_sw.c',
3073 'dtc/libfdt/fdt_rw.c',
3074 'dtc/libfdt/fdt_strerror.c',
3075 'dtc/libfdt/fdt_empty_tree.c',
3076 'dtc/libfdt/fdt_addresses.c',
3077 'dtc/libfdt/fdt_overlay.c',
3078 'dtc/libfdt/fdt_check.c',
3081 fdt_inc = include_directories('dtc/libfdt')
3082 libfdt = static_library('fdt',
3083 build_by_default: false,
3085 include_directories: fdt_inc)
3086 fdt = declare_dependency(link_with: libfdt,
3087 include_directories: fdt_inc)
3090 fdt_opt = 'disabled'
3092 if not fdt.found() and fdt_required.length() > 0
3093 error('fdt not available but required by targets ' + ', '.join(fdt_required))
3096 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
3097 config_host_data.set('CONFIG_FDT', fdt.found())
3098 config_host_data.set('CONFIG_SLIRP', slirp.found())
3100 #####################
3101 # Generated sources #
3102 #####################
3104 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
3106 hxtool = find_program('scripts/hxtool')
3107 shaderinclude = find_program('scripts/shaderinclude.py')
3108 qapi_gen = find_program('scripts/qapi-gen.py')
3109 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
3110 meson.current_source_dir() / 'scripts/qapi/commands.py',
3111 meson.current_source_dir() / 'scripts/qapi/common.py',
3112 meson.current_source_dir() / 'scripts/qapi/error.py',
3113 meson.current_source_dir() / 'scripts/qapi/events.py',
3114 meson.current_source_dir() / 'scripts/qapi/expr.py',
3115 meson.current_source_dir() / 'scripts/qapi/gen.py',
3116 meson.current_source_dir() / 'scripts/qapi/introspect.py',
3117 meson.current_source_dir() / 'scripts/qapi/main.py',
3118 meson.current_source_dir() / 'scripts/qapi/parser.py',
3119 meson.current_source_dir() / 'scripts/qapi/schema.py',
3120 meson.current_source_dir() / 'scripts/qapi/source.py',
3121 meson.current_source_dir() / 'scripts/qapi/types.py',
3122 meson.current_source_dir() / 'scripts/qapi/visit.py',
3123 meson.current_source_dir() / 'scripts/qapi-gen.py'
3127 python, files('scripts/tracetool.py'),
3128 '--backend=' + ','.join(get_option('trace_backends'))
3130 tracetool_depends = files(
3131 'scripts/tracetool/backend/log.py',
3132 'scripts/tracetool/backend/__init__.py',
3133 'scripts/tracetool/backend/dtrace.py',
3134 'scripts/tracetool/backend/ftrace.py',
3135 'scripts/tracetool/backend/simple.py',
3136 'scripts/tracetool/backend/syslog.py',
3137 'scripts/tracetool/backend/ust.py',
3138 'scripts/tracetool/format/ust_events_c.py',
3139 'scripts/tracetool/format/ust_events_h.py',
3140 'scripts/tracetool/format/__init__.py',
3141 'scripts/tracetool/format/d.py',
3142 'scripts/tracetool/format/simpletrace_stap.py',
3143 'scripts/tracetool/format/c.py',
3144 'scripts/tracetool/format/h.py',
3145 'scripts/tracetool/format/log_stap.py',
3146 'scripts/tracetool/format/stap.py',
3147 'scripts/tracetool/__init__.py',
3148 'scripts/tracetool/vcpu.py'
3151 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
3152 meson.current_source_dir(),
3153 get_option('pkgversion'), meson.project_version()]
3154 qemu_version = custom_target('qemu-version.h',
3155 output: 'qemu-version.h',
3156 command: qemu_version_cmd,
3158 build_by_default: true,
3159 build_always_stale: true)
3160 genh += qemu_version
3164 ['qemu-options.hx', 'qemu-options.def'],
3165 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
3169 ['hmp-commands.hx', 'hmp-commands.h'],
3170 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
3173 foreach d : hx_headers
3174 hxdep += custom_target(d[1],
3178 build_by_default: true, # to be removed when added to a target
3179 command: [hxtool, '-h', '@INPUT0@'])
3187 authz_ss = ss.source_set()
3188 blockdev_ss = ss.source_set()
3189 block_ss = ss.source_set()
3190 chardev_ss = ss.source_set()
3191 common_ss = ss.source_set()
3192 crypto_ss = ss.source_set()
3193 hwcore_ss = ss.source_set()
3194 io_ss = ss.source_set()
3195 qmp_ss = ss.source_set()
3196 qom_ss = ss.source_set()
3197 softmmu_ss = ss.source_set()
3198 specific_fuzz_ss = ss.source_set()
3199 specific_ss = ss.source_set()
3200 stub_ss = ss.source_set()
3201 trace_ss = ss.source_set()
3202 user_ss = ss.source_set()
3203 util_ss = ss.source_set()
3206 qtest_module_ss = ss.source_set()
3207 tcg_module_ss = ss.source_set()
3213 target_softmmu_arch = {}
3214 target_user_arch = {}
3220 # TODO: add each directory to the subdirs from its own meson.build, once
3222 trace_events_subdirs = [
3231 trace_events_subdirs += [ 'linux-user' ]
3234 trace_events_subdirs += [ 'bsd-user' ]
3237 trace_events_subdirs += [
3246 trace_events_subdirs += [
3260 'hw/block/dataplane',
3310 if have_system or have_user
3311 trace_events_subdirs += [
3329 vhost_user = not_found
3330 if targetos == 'linux' and have_vhost_user
3331 libvhost_user = subproject('libvhost-user')
3332 vhost_user = libvhost_user.get_variable('vhost_user_dep')
3335 libvduse = not_found
3337 libvduse_proj = subproject('libvduse')
3338 libvduse = libvduse_proj.get_variable('libvduse_dep')
3341 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3342 # that is filled in by qapi/.
3356 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3357 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3360 qom_ss = qom_ss.apply(config_host, strict: false)
3361 libqom = static_library('qom', qom_ss.sources() + genh,
3362 dependencies: [qom_ss.dependencies()],
3364 qom = declare_dependency(link_whole: libqom)
3366 event_loop_base = files('event-loop-base.c')
3367 event_loop_base = static_library('event-loop-base', sources: event_loop_base + genh,
3368 build_by_default: true)
3369 event_loop_base = declare_dependency(link_whole: event_loop_base,
3370 dependencies: [qom])
3372 stub_ss = stub_ss.apply(config_all, strict: false)
3374 util_ss.add_all(trace_ss)
3375 util_ss = util_ss.apply(config_all, strict: false)
3376 libqemuutil = static_library('qemuutil',
3377 sources: util_ss.sources() + stub_ss.sources() + genh,
3378 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
3379 qemuutil = declare_dependency(link_with: libqemuutil,
3380 sources: genh + version_res,
3381 dependencies: [event_loop_base])
3383 if have_system or have_user
3384 decodetree = generator(find_program('scripts/decodetree.py'),
3385 output: 'decode-@BASENAME@.c.inc',
3386 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3387 subdir('libdecnumber')
3404 if config_host_data.get('CONFIG_REPLICATION')
3405 block_ss.add(files('replication.c'))
3412 blockdev_ss.add(files(
3419 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3420 # os-win32.c does not
3421 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
3422 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
3425 common_ss.add(files('cpus-common.c'))
3426 specific_ss.add(files('cpu.c'))
3430 # Work around a gcc bug/misfeature wherein constant propagation looks
3432 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3433 # to guess that a const variable is always zero. Without lto, this is
3434 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
3435 # without lto, not even the alias is required -- we simply use different
3436 # declarations in different compilation units.
3437 pagevary = files('page-vary-common.c')
3438 if get_option('b_lto')
3439 pagevary_flags = ['-fno-lto']
3440 if get_option('cfi')
3441 pagevary_flags += '-fno-sanitize=cfi-icall'
3443 pagevary = static_library('page-vary-common', sources: pagevary + genh,
3444 c_args: pagevary_flags)
3445 pagevary = declare_dependency(link_with: pagevary)
3447 common_ss.add(pagevary)
3448 specific_ss.add(files('page-vary.c'))
3456 subdir('semihosting')
3464 common_user_inc = []
3466 subdir('common-user')
3468 subdir('linux-user')
3470 # needed for fuzzing binaries
3471 subdir('tests/qtest/libqos')
3472 subdir('tests/qtest/fuzz')
3475 tcg_real_module_ss = ss.source_set()
3476 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3477 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3478 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3479 'tcg': tcg_real_module_ss }}
3481 ########################
3482 # Library dependencies #
3483 ########################
3485 modinfo_collect = find_program('scripts/modinfo-collect.py')
3486 modinfo_generate = find_program('scripts/modinfo-generate.py')
3491 foreach d, list : modules
3492 if not (d == 'block' ? have_block : have_system)
3496 foreach m, module_ss : list
3498 module_ss = module_ss.apply(config_all, strict: false)
3499 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3500 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3506 if module_ss.sources() != []
3507 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3508 # input. Sources can be used multiple times but objects are
3509 # unique when it comes to lookup in compile_commands.json.
3510 # Depnds on a mesion version with
3511 # https://github.com/mesonbuild/meson/pull/8900
3512 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3513 output: d + '-' + m + '.modinfo',
3514 input: module_ss.sources() + genh,
3516 command: [modinfo_collect, module_ss.sources()])
3520 block_ss.add_all(module_ss)
3522 softmmu_ss.add_all(module_ss)
3528 foreach d, list : target_modules
3529 foreach m, module_ss : list
3531 foreach target : target_dirs
3532 if target.endswith('-softmmu')
3533 config_target = config_target_mak[target]
3534 config_target += config_host
3535 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3536 c_args = ['-DNEED_CPU_H',
3537 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3538 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3539 target_module_ss = module_ss.apply(config_target, strict: false)
3540 if target_module_ss.sources() != []
3541 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3542 sl = static_library(module_name,
3543 [genh, target_module_ss.sources()],
3544 dependencies: [modulecommon, target_module_ss.dependencies()],
3545 include_directories: target_inc,
3549 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3550 modinfo_files += custom_target(module_name + '.modinfo',
3551 output: module_name + '.modinfo',
3552 input: target_module_ss.sources() + genh,
3554 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3559 specific_ss.add_all(module_ss)
3565 foreach target : target_dirs
3566 if target.endswith('-softmmu')
3567 config_target = config_target_mak[target]
3568 config_devices_mak = target + '-config-devices.mak'
3569 modinfo_src = custom_target('modinfo-' + target + '.c',
3570 output: 'modinfo-' + target + '.c',
3571 input: modinfo_files,
3572 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'],
3575 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
3576 modinfo_dep = declare_dependency(link_with: modinfo_lib)
3578 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH']
3579 hw_arch[arch].add(modinfo_dep)
3584 nm = find_program('nm')
3585 undefsym = find_program('scripts/undefsym.py')
3586 block_syms = custom_target('block.syms', output: 'block.syms',
3587 input: [libqemuutil, block_mods],
3589 command: [undefsym, nm, '@INPUT@'])
3590 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3591 input: [libqemuutil, softmmu_mods],
3593 command: [undefsym, nm, '@INPUT@'])
3595 authz_ss = authz_ss.apply(config_host, strict: false)
3596 libauthz = static_library('authz', authz_ss.sources() + genh,
3597 dependencies: [authz_ss.dependencies()],
3599 build_by_default: false)
3601 authz = declare_dependency(link_whole: libauthz,
3604 crypto_ss = crypto_ss.apply(config_host, strict: false)
3605 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3606 dependencies: [crypto_ss.dependencies()],
3608 build_by_default: false)
3610 crypto = declare_dependency(link_whole: libcrypto,
3611 dependencies: [authz, qom])
3613 io_ss = io_ss.apply(config_host, strict: false)
3614 libio = static_library('io', io_ss.sources() + genh,
3615 dependencies: [io_ss.dependencies()],
3616 link_with: libqemuutil,
3618 build_by_default: false)
3620 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3622 libmigration = static_library('migration', sources: migration_files + genh,
3624 build_by_default: false)
3625 migration = declare_dependency(link_with: libmigration,
3626 dependencies: [zlib, qom, io])
3627 softmmu_ss.add(migration)
3629 block_ss = block_ss.apply(config_host, strict: false)
3630 libblock = static_library('block', block_ss.sources() + genh,
3631 dependencies: block_ss.dependencies(),
3632 link_depends: block_syms,
3634 build_by_default: false)
3636 block = declare_dependency(link_whole: [libblock],
3637 link_args: '@block.syms',
3638 dependencies: [crypto, io])
3640 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
3641 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3642 dependencies: blockdev_ss.dependencies(),
3644 build_by_default: false)
3646 blockdev = declare_dependency(link_whole: [libblockdev],
3647 dependencies: [block, event_loop_base])
3649 qmp_ss = qmp_ss.apply(config_host, strict: false)
3650 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3651 dependencies: qmp_ss.dependencies(),
3653 build_by_default: false)
3655 qmp = declare_dependency(link_whole: [libqmp])
3657 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3659 dependencies: chardev_ss.dependencies(),
3660 build_by_default: false)
3662 chardev = declare_dependency(link_whole: libchardev)
3664 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
3665 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3667 build_by_default: false)
3668 hwcore = declare_dependency(link_whole: libhwcore)
3669 common_ss.add(hwcore)
3675 emulator_modules = []
3676 foreach m : block_mods + softmmu_mods
3677 emulator_modules += shared_module(m.name(),
3678 build_by_default: true,
3682 install_dir: qemu_moddir)
3684 if emulator_modules.length() > 0
3685 alias_target('modules', emulator_modules)
3688 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3689 common_ss.add(qom, qemuutil)
3691 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
3692 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3694 common_all = common_ss.apply(config_all, strict: false)
3695 common_all = static_library('common',
3696 build_by_default: false,
3697 sources: common_all.sources() + genh,
3698 include_directories: common_user_inc,
3699 implicit_include_directories: false,
3700 dependencies: common_all.dependencies(),
3703 feature_to_c = find_program('scripts/feature_to_c.sh')
3705 if targetos == 'darwin'
3706 entitlement = find_program('scripts/entitlement.sh')
3710 foreach target : target_dirs
3711 config_target = config_target_mak[target]
3712 target_name = config_target['TARGET_NAME']
3713 target_base_arch = config_target['TARGET_BASE_ARCH']
3714 arch_srcs = [config_target_h[target]]
3716 c_args = ['-DNEED_CPU_H',
3717 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3718 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3719 link_args = emulator_link_args
3721 config_target += config_host
3722 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3723 if targetos == 'linux'
3724 target_inc += include_directories('linux-headers', is_system: true)
3726 if target.endswith('-softmmu')
3727 target_type='system'
3728 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3729 arch_srcs += t.sources()
3730 arch_deps += t.dependencies()
3732 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3733 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3734 arch_srcs += hw.sources()
3735 arch_deps += hw.dependencies()
3737 arch_srcs += config_devices_h[target]
3738 link_args += ['@block.syms', '@qemu.syms']
3740 abi = config_target['TARGET_ABI_DIR']
3742 target_inc += common_user_inc
3743 if target_base_arch in target_user_arch
3744 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3745 arch_srcs += t.sources()
3746 arch_deps += t.dependencies()
3748 if 'CONFIG_LINUX_USER' in config_target
3749 base_dir = 'linux-user'
3751 if 'CONFIG_BSD_USER' in config_target
3752 base_dir = 'bsd-user'
3753 target_inc += include_directories('bsd-user/' / targetos)
3754 target_inc += include_directories('bsd-user/host/' / host_arch)
3755 dir = base_dir / abi
3756 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3758 target_inc += include_directories(
3762 if 'CONFIG_LINUX_USER' in config_target
3763 dir = base_dir / abi
3764 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3765 if config_target.has_key('TARGET_SYSTBL_ABI')
3767 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3768 extra_args : config_target['TARGET_SYSTBL_ABI'])
3773 if 'TARGET_XML_FILES' in config_target
3774 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3775 output: target + '-gdbstub-xml.c',
3776 input: files(config_target['TARGET_XML_FILES'].split()),
3777 command: [feature_to_c, '@INPUT@'],
3779 arch_srcs += gdbstub_xml
3782 t = target_arch[target_base_arch].apply(config_target, strict: false)
3783 arch_srcs += t.sources()
3784 arch_deps += t.dependencies()
3786 target_common = common_ss.apply(config_target, strict: false)
3787 objects = common_all.extract_objects(target_common.sources())
3788 deps = target_common.dependencies()
3790 target_specific = specific_ss.apply(config_target, strict: false)
3791 arch_srcs += target_specific.sources()
3792 arch_deps += target_specific.dependencies()
3794 lib = static_library('qemu-' + target,
3795 sources: arch_srcs + genh,
3796 dependencies: arch_deps,
3798 include_directories: target_inc,
3800 build_by_default: false,
3803 if target.endswith('-softmmu')
3805 'name': 'qemu-system-' + target_name,
3806 'win_subsystem': 'console',
3807 'sources': files('softmmu/main.c'),
3810 if targetos == 'windows' and (sdl.found() or gtk.found())
3812 'name': 'qemu-system-' + target_name + 'w',
3813 'win_subsystem': 'windows',
3814 'sources': files('softmmu/main.c'),
3818 if get_option('fuzzing')
3819 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3821 'name': 'qemu-fuzz-' + target_name,
3822 'win_subsystem': 'console',
3823 'sources': specific_fuzz.sources(),
3824 'dependencies': specific_fuzz.dependencies(),
3829 'name': 'qemu-' + target_name,
3830 'win_subsystem': 'console',
3836 exe_name = exe['name']
3837 if targetos == 'darwin'
3838 exe_name += '-unsigned'
3841 emulator = executable(exe_name, exe['sources'],
3844 dependencies: arch_deps + deps + exe['dependencies'],
3845 objects: lib.extract_all_objects(recursive: true),
3846 link_language: link_language,
3847 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3848 link_args: link_args,
3849 win_subsystem: exe['win_subsystem'])
3851 if targetos == 'darwin'
3852 icon = 'pc-bios/qemu.rsrc'
3853 build_input = [emulator, files(icon)]
3855 get_option('bindir') / exe_name,
3856 meson.current_source_dir() / icon
3858 if 'CONFIG_HVF' in config_target
3859 entitlements = 'accel/hvf/entitlements.plist'
3860 build_input += files(entitlements)
3861 install_input += meson.current_source_dir() / entitlements
3864 emulators += {exe['name'] : custom_target(exe['name'],
3866 output: exe['name'],
3867 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3870 meson.add_install_script(entitlement, '--install',
3871 get_option('bindir') / exe['name'],
3874 emulators += {exe['name']: emulator}
3879 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3880 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3881 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3882 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3884 custom_target(exe['name'] + stp['ext'],
3885 input: trace_events_all,
3886 output: exe['name'] + stp['ext'],
3887 install: stp['install'],
3888 install_dir: get_option('datadir') / 'systemtap/tapset',
3890 tracetool, '--group=all', '--format=' + stp['fmt'],
3891 '--binary=' + stp['bin'],
3892 '--target-name=' + target_name,
3893 '--target-type=' + target_type,
3894 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3895 '@INPUT@', '@OUTPUT@'
3897 depend_files: tracetool_depends)
3903 # Other build targets
3905 if 'CONFIG_PLUGIN' in config_host
3906 install_headers('include/qemu/qemu-plugin.h')
3911 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3912 # when we don't build tools or system
3913 if xkbcommon.found()
3914 # used for the update-keymaps target, so include rules even if !have_tools
3915 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3916 dependencies: [qemuutil, xkbcommon], install: have_tools)
3920 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3921 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3922 qemu_io = executable('qemu-io', files('qemu-io.c'),
3923 dependencies: [block, qemuutil], install: true)
3924 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3925 dependencies: [blockdev, qemuutil, gnutls, selinux],
3928 subdir('storage-daemon')
3929 subdir('contrib/rdmacm-mux')
3930 subdir('contrib/elf2dmp')
3932 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3933 dependencies: qemuutil,
3937 subdir('contrib/vhost-user-blk')
3938 subdir('contrib/vhost-user-gpu')
3939 subdir('contrib/vhost-user-input')
3940 subdir('contrib/vhost-user-scsi')
3943 if targetos == 'linux'
3944 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3945 dependencies: [qemuutil, libcap_ng],
3947 install_dir: get_option('libexecdir'))
3949 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3950 dependencies: [authz, crypto, io, qom, qemuutil,
3951 libcap_ng, mpathpersist],
3956 subdir('contrib/ivshmem-client')
3957 subdir('contrib/ivshmem-server')
3970 if host_machine.system() == 'windows'
3972 find_program('scripts/nsis.py'),
3974 get_option('prefix'),
3975 meson.current_source_dir(),
3976 glib_pc.get_variable('bindir'),
3979 '-DDISPLAYVERSION=' + meson.project_version(),
3982 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3985 nsis_cmd += '-DCONFIG_GTK=y'
3988 nsis = custom_target('nsis',
3989 output: 'qemu-setup-' + meson.project_version() + '.exe',
3990 input: files('qemu.nsi'),
3991 build_always_stale: true,
3992 command: nsis_cmd + ['@INPUT@'])
3993 alias_target('installer', nsis)
3996 #########################
3997 # Configuration summary #
3998 #########################
4002 summary_info += {'Install prefix': get_option('prefix')}
4003 summary_info += {'BIOS directory': qemu_datadir}
4004 pathsep = targetos == 'windows' ? ';' : ':'
4005 summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))}
4006 summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
4007 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
4008 summary_info += {'module directory': qemu_moddir}
4009 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
4010 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
4011 summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')}
4012 if targetos != 'windows'
4013 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
4014 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')}
4016 summary_info += {'local state directory': 'queried at runtime'}
4018 summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
4019 summary_info += {'Build directory': meson.current_build_dir()}
4020 summary_info += {'Source path': meson.current_source_dir()}
4021 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
4022 summary(summary_info, bool_yn: true, section: 'Directories')
4026 summary_info += {'git': config_host['GIT']}
4027 summary_info += {'make': config_host['MAKE']}
4028 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
4029 summary_info += {'sphinx-build': sphinx_build}
4030 if config_host.has_key('HAVE_GDB_BIN')
4031 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
4033 summary_info += {'iasl': iasl}
4034 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
4035 if targetos == 'windows' and have_ga
4036 summary_info += {'wixl': wixl}
4038 if slirp.found() and have_system
4039 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
4041 summary(summary_info, bool_yn: true, section: 'Host binaries')
4043 # Configurable features
4045 summary_info += {'Documentation': build_docs}
4046 summary_info += {'system-mode emulation': have_system}
4047 summary_info += {'user-mode emulation': have_user}
4048 summary_info += {'block layer': have_block}
4049 summary_info += {'Install blobs': get_option('install_blobs')}
4050 summary_info += {'module support': enable_modules}
4052 summary_info += {'alternative module path': get_option('module_upgrades')}
4054 summary_info += {'fuzzing support': get_option('fuzzing')}
4056 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
4058 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
4059 if 'simple' in get_option('trace_backends')
4060 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
4062 summary_info += {'D-Bus display': dbus_display}
4063 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
4064 summary_info += {'vhost-kernel support': have_vhost_kernel}
4065 summary_info += {'vhost-net support': have_vhost_net}
4066 summary_info += {'vhost-user support': have_vhost_user}
4067 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
4068 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
4069 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
4070 summary_info += {'build guest agent': have_ga}
4071 summary(summary_info, bool_yn: true, section: 'Configurable features')
4073 # Compilation information
4075 summary_info += {'host CPU': cpu}
4076 summary_info += {'host endianness': build_machine.endian()}
4077 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
4078 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
4079 if link_language == 'cpp'
4080 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
4082 summary_info += {'C++ compiler': false}
4084 if targetos == 'darwin'
4085 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
4087 option_cflags = (get_option('debug') ? ['-g'] : [])
4088 if get_option('optimization') != 'plain'
4089 option_cflags += ['-O' + get_option('optimization')]
4091 summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)}
4092 if link_language == 'cpp'
4093 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)}
4095 if targetos == 'darwin'
4096 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)}
4098 link_args = get_option(link_language + '_link_args')
4099 if link_args.length() > 0
4100 summary_info += {'LDFLAGS': ' '.join(link_args)}
4102 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)}
4103 if 'cpp' in all_languages
4104 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)}
4106 if 'objc' in all_languages
4107 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)}
4109 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
4110 summary_info += {'profiler': get_option('profiler')}
4111 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
4112 summary_info += {'PIE': get_option('b_pie')}
4113 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
4114 summary_info += {'malloc trim support': has_malloc_trim}
4115 summary_info += {'membarrier': have_membarrier}
4116 summary_info += {'debug graph lock': get_option('debug_graph_lock')}
4117 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
4118 summary_info += {'mutex debugging': get_option('debug_mutex')}
4119 summary_info += {'memory allocator': get_option('malloc')}
4120 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
4121 summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')}
4122 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
4123 if get_option('gprof')
4124 gprof_info = 'YES (deprecated)'
4126 gprof_info = get_option('gprof')
4128 summary_info += {'gprof': gprof_info}
4129 summary_info += {'gcov': get_option('b_coverage')}
4130 summary_info += {'thread sanitizer': get_option('tsan')}
4131 summary_info += {'CFI support': get_option('cfi')}
4132 if get_option('cfi')
4133 summary_info += {'CFI debug support': get_option('cfi_debug')}
4135 summary_info += {'strip binaries': get_option('strip')}
4136 summary_info += {'sparse': sparse}
4137 summary_info += {'mingw32 support': targetos == 'windows'}
4138 summary(summary_info, bool_yn: true, section: 'Compilation')
4140 # snarf the cross-compilation information for tests
4143 foreach target: target_dirs
4144 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak'
4145 if fs.exists(tcg_mak)
4146 config_cross_tcg = keyval.load(tcg_mak)
4147 if 'CC' in config_cross_tcg
4148 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']}
4154 summary(summary_info, bool_yn: true, section: 'Cross compilers')
4157 # Targets and accelerators
4160 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
4161 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
4162 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
4163 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
4164 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
4165 summary_info += {'Xen support': xen.found()}
4167 summary_info += {'xen ctrl version': xen.version()}
4169 summary_info += {'Xen emulation': config_all.has_key('CONFIG_XEN_EMU')}
4171 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
4172 if config_all.has_key('CONFIG_TCG')
4173 if get_option('tcg_interpreter')
4174 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
4176 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
4178 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
4179 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
4181 summary_info += {'target list': ' '.join(target_dirs)}
4183 summary_info += {'default devices': get_option('default_devices')}
4184 summary_info += {'out of process emulation': multiprocess_allowed}
4185 summary_info += {'vfio-user server': vfio_user_server_allowed}
4187 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
4191 summary_info += {'coroutine backend': coroutine_backend}
4192 summary_info += {'coroutine pool': have_coroutine_pool}
4194 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
4195 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
4196 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
4197 summary_info += {'VirtFS (9P) support': have_virtfs}
4198 summary_info += {'VirtFS (9P) Proxy Helper support': have_virtfs_proxy_helper}
4199 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
4200 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
4201 summary_info += {'bochs support': get_option('bochs').allowed()}
4202 summary_info += {'cloop support': get_option('cloop').allowed()}
4203 summary_info += {'dmg support': get_option('dmg').allowed()}
4204 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
4205 summary_info += {'vdi support': get_option('vdi').allowed()}
4206 summary_info += {'vhdx support': get_option('vhdx').allowed()}
4207 summary_info += {'vmdk support': get_option('vmdk').allowed()}
4208 summary_info += {'vpc support': get_option('vpc').allowed()}
4209 summary_info += {'vvfat support': get_option('vvfat').allowed()}
4210 summary_info += {'qed support': get_option('qed').allowed()}
4211 summary_info += {'parallels support': get_option('parallels').allowed()}
4212 summary_info += {'FUSE exports': fuse}
4213 summary_info += {'VDUSE block exports': have_vduse_blk_export}
4215 summary(summary_info, bool_yn: true, section: 'Block layer support')
4219 summary_info += {'TLS priority': get_option('tls_priority')}
4220 summary_info += {'GNUTLS support': gnutls}
4222 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
4224 summary_info += {'libgcrypt': gcrypt}
4225 summary_info += {'nettle': nettle}
4227 summary_info += {' XTS': xts != 'private'}
4229 summary_info += {'AF_ALG support': have_afalg}
4230 summary_info += {'rng-none': get_option('rng_none')}
4231 summary_info += {'Linux keyring': have_keyring}
4232 summary(summary_info, bool_yn: true, section: 'Crypto')
4236 if targetos == 'darwin'
4237 summary_info += {'Cocoa support': cocoa}
4238 summary_info += {'vmnet.framework support': vmnet}
4240 summary_info += {'SDL support': sdl}
4241 summary_info += {'SDL image support': sdl_image}
4242 summary_info += {'GTK support': gtk}
4243 summary_info += {'pixman': pixman}
4244 summary_info += {'VTE support': vte}
4245 summary_info += {'slirp support': slirp}
4246 summary_info += {'libtasn1': tasn1}
4247 summary_info += {'PAM': pam}
4248 summary_info += {'iconv support': iconv}
4249 summary_info += {'curses support': curses}
4250 summary_info += {'virgl support': virgl}
4251 summary_info += {'blkio support': blkio}
4252 summary_info += {'curl support': curl}
4253 summary_info += {'Multipath support': mpathpersist}
4254 summary_info += {'PNG support': png}
4255 summary_info += {'VNC support': vnc}
4257 summary_info += {'VNC SASL support': sasl}
4258 summary_info += {'VNC JPEG support': jpeg}
4260 if targetos not in ['darwin', 'haiku', 'windows']
4261 summary_info += {'OSS support': oss}
4262 summary_info += {'sndio support': sndio}
4263 elif targetos == 'darwin'
4264 summary_info += {'CoreAudio support': coreaudio}
4265 elif targetos == 'windows'
4266 summary_info += {'DirectSound support': dsound}
4268 if targetos == 'linux'
4269 summary_info += {'ALSA support': alsa}
4270 summary_info += {'PulseAudio support': pulse}
4272 summary_info += {'Pipewire support': pipewire}
4273 summary_info += {'JACK support': jack}
4274 summary_info += {'brlapi support': brlapi}
4275 summary_info += {'vde support': vde}
4276 summary_info += {'netmap support': have_netmap}
4277 summary_info += {'l2tpv3 support': have_l2tpv3}
4278 summary_info += {'Linux AIO support': libaio}
4279 summary_info += {'Linux io_uring support': linux_io_uring}
4280 summary_info += {'ATTR/XATTR support': libattr}
4281 summary_info += {'RDMA support': rdma}
4282 summary_info += {'PVRDMA support': have_pvrdma}
4283 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
4284 summary_info += {'libcap-ng support': libcap_ng}
4285 summary_info += {'bpf support': libbpf}
4286 summary_info += {'spice protocol support': spice_protocol}
4287 if spice_protocol.found()
4288 summary_info += {' spice server support': spice}
4290 summary_info += {'rbd support': rbd}
4291 summary_info += {'smartcard support': cacard}
4292 summary_info += {'U2F support': u2f}
4293 summary_info += {'libusb': libusb}
4294 summary_info += {'usb net redir': usbredir}
4295 summary_info += {'OpenGL support (epoxy)': opengl}
4296 summary_info += {'GBM': gbm}
4297 summary_info += {'libiscsi support': libiscsi}
4298 summary_info += {'libnfs support': libnfs}
4299 if targetos == 'windows'
4301 summary_info += {'QGA VSS support': have_qga_vss}
4304 summary_info += {'seccomp support': seccomp}
4305 summary_info += {'GlusterFS support': glusterfs}
4306 summary_info += {'TPM support': have_tpm}
4307 summary_info += {'libssh support': libssh}
4308 summary_info += {'lzo support': lzo}
4309 summary_info += {'snappy support': snappy}
4310 summary_info += {'bzip2 support': libbzip2}
4311 summary_info += {'lzfse support': liblzfse}
4312 summary_info += {'zstd support': zstd}
4313 summary_info += {'NUMA host support': numa}
4314 summary_info += {'capstone': capstone}
4315 summary_info += {'libpmem support': libpmem}
4316 summary_info += {'libdaxctl support': libdaxctl}
4317 summary_info += {'libudev': libudev}
4318 # Dummy dependency, keep .found()
4319 summary_info += {'FUSE lseek': fuse_lseek.found()}
4320 summary_info += {'selinux': selinux}
4321 summary_info += {'libdw': libdw}
4322 summary(summary_info, bool_yn: true, section: 'Dependencies')
4324 if not supported_cpus.contains(cpu)
4326 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
4328 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
4329 message('The QEMU project intends to remove support for this host CPU in')
4330 message('a future release if nobody volunteers to maintain it and to')
4331 message('provide a build host for our continuous integration setup.')
4332 message('configure has succeeded and you can continue to build, but')
4333 message('if you care about QEMU on this platform you should contact')
4334 message('us upstream at qemu-devel@nongnu.org.')
4337 if not supported_oses.contains(targetos)
4339 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
4341 message('Host OS ' + targetos + 'support is not currently maintained.')
4342 message('The QEMU project intends to remove support for this host OS in')
4343 message('a future release if nobody volunteers to maintain it and to')
4344 message('provide a build host for our continuous integration setup.')
4345 message('configure has succeeded and you can continue to build, but')
4346 message('if you care about QEMU on this platform you should contact')
4347 message('us upstream at qemu-devel@nongnu.org.')