1 project('qemu', ['c'], meson_version: '>=0.63.0',
2 default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
3 'b_staticpic=false', 'stdsplit=false', 'optimization=2', 'b_pie=true'],
4 version: files('VERSION'))
6 add_test_setup('quick', exclude_suites: ['slow', 'thorough'], is_default: true)
7 add_test_setup('slow', exclude_suites: ['thorough'], env: ['G_TEST_SLOW=1', 'SPEED=slow'])
8 add_test_setup('thorough', env: ['G_TEST_SLOW=1', 'SPEED=thorough'])
10 meson.add_postconf_script(find_program('scripts/symlink-install-tree.py'))
16 not_found = dependency('', required: false)
17 keyval = import('keyval')
18 ss = import('sourceset')
21 targetos = host_machine.system()
22 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
24 # Temporary directory used for files created while
25 # configure runs. Since it is in the build directory
26 # we can safely blow away any previous version of it
27 # (and we need not jump through hoops to try to delete
28 # it when configure exits.)
29 tmpdir = meson.current_build_dir() / 'meson-private/temp'
31 if get_option('qemu_suffix').startswith('/')
32 error('qemu_suffix cannot start with a /')
35 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
36 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
37 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
38 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
40 qemu_desktopdir = get_option('datadir') / 'applications'
41 qemu_icondir = get_option('datadir') / 'icons'
43 config_host_data = configuration_data()
45 qapi_trace_events = []
47 bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
48 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
49 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
50 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64']
52 cpu = host_machine.cpu_family()
54 target_dirs = config_host['TARGET_DIRS'].split()
60 sh = find_program('sh')
61 python = import('python').find_installation()
63 cc = meson.get_compiler('c')
65 if targetos == 'windows' and add_languages('cpp', required: false, native: false)
66 all_languages += ['cpp']
67 cxx = meson.get_compiler('cpp')
69 if targetos == 'darwin' and \
70 add_languages('objc', required: get_option('cocoa'), native: false)
71 all_languages += ['objc']
72 objc = meson.get_compiler('objc')
77 if 'dtrace' in get_option('trace_backends')
78 dtrace = find_program('dtrace', required: true)
79 stap = find_program('stap', required: false)
81 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
82 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
83 # instead. QEMU --enable-modules depends on this because the SystemTap
84 # semaphores are linked into the main binary and not the module's shared
86 add_global_arguments('-DSTAP_SDT_V2',
87 native: false, language: all_languages)
91 if get_option('iasl') == ''
92 iasl = find_program('iasl', required: false)
94 iasl = find_program(get_option('iasl'), required: true)
97 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
98 unpack_edk2_blobs = false
99 foreach target : edk2_targets
100 if target in target_dirs
101 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
102 unpack_edk2_blobs = bzip2.found()
107 #####################
108 # Option validation #
109 #####################
112 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
115 #include <sys/types.h>
116 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
117 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
119 args: ['-Werror', '-fsanitize=fuzzer'])
120 error('Your compiler does not support -fsanitize=fuzzer')
124 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
125 error('ftrace is supported only on Linux')
127 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
130 openlog("qemu", LOG_PID, LOG_DAEMON);
131 syslog(LOG_INFO, "configure");
134 error('syslog is not supported on this system')
137 # Miscellaneous Linux-only features
138 get_option('mpath') \
139 .require(targetos == 'linux', error_message: 'Multipath is supported only on Linux')
141 multiprocess_allowed = get_option('multiprocess') \
142 .require(targetos == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
145 vfio_user_server_allowed = get_option('vfio_user_server') \
146 .require(targetos == 'linux', error_message: 'vfio-user server is supported only on Linux') \
149 have_tpm = get_option('tpm') \
150 .require(targetos != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
154 have_vhost_user = get_option('vhost_user') \
155 .disable_auto_if(targetos != 'linux') \
156 .require(targetos != 'windows',
157 error_message: 'vhost-user is not available on Windows').allowed()
158 have_vhost_vdpa = get_option('vhost_vdpa') \
159 .require(targetos == 'linux',
160 error_message: 'vhost-vdpa is only available on Linux').allowed()
161 have_vhost_kernel = get_option('vhost_kernel') \
162 .require(targetos == 'linux',
163 error_message: 'vhost-kernel is only available on Linux').allowed()
164 have_vhost_user_crypto = get_option('vhost_crypto') \
165 .require(have_vhost_user,
166 error_message: 'vhost-crypto requires vhost-user to be enabled').allowed()
168 have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel
170 have_vhost_net_user = have_vhost_user and get_option('vhost_net').allowed()
171 have_vhost_net_vdpa = have_vhost_vdpa and get_option('vhost_net').allowed()
172 have_vhost_net_kernel = have_vhost_kernel and get_option('vhost_net').allowed()
173 have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_vdpa
175 # type of binaries to build
176 have_linux_user = false
177 have_bsd_user = false
179 foreach target : target_dirs
180 have_linux_user = have_linux_user or target.endswith('linux-user')
181 have_bsd_user = have_bsd_user or target.endswith('bsd-user')
182 have_system = have_system or target.endswith('-softmmu')
184 have_user = have_linux_user or have_bsd_user
186 have_tools = get_option('tools') \
187 .disable_auto_if(not have_system) \
189 have_ga = get_option('guest_agent') \
190 .disable_auto_if(not have_system and not have_tools) \
191 .require(targetos in ['sunos', 'linux', 'windows', 'freebsd', 'netbsd', 'openbsd'],
192 error_message: 'unsupported OS for QEMU guest agent') \
194 have_block = have_system or have_tools
196 enable_modules = get_option('modules') \
197 .require(targetos != 'windows',
198 error_message: 'Modules are not available for Windows') \
199 .require(not get_option('prefer_static'),
200 error_message: 'Modules are incompatible with static linking') \
203 #######################################
204 # Variables for host and accelerators #
205 #######################################
207 if cpu not in supported_cpus
208 host_arch = 'unknown'
213 elif cpu in ['riscv32', 'riscv64']
219 if cpu in ['x86', 'x86_64']
220 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
221 elif cpu == 'aarch64'
222 kvm_targets = ['aarch64-softmmu']
224 kvm_targets = ['s390x-softmmu']
225 elif cpu in ['ppc', 'ppc64']
226 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
227 elif cpu in ['mips', 'mips64']
228 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
229 elif cpu in ['riscv32']
230 kvm_targets = ['riscv32-softmmu']
231 elif cpu in ['riscv64']
232 kvm_targets = ['riscv64-softmmu']
238 if get_option('kvm').allowed() and targetos == 'linux'
239 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
241 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
242 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
244 if cpu in ['x86', 'x86_64']
245 xen_targets = ['i386-softmmu', 'x86_64-softmmu']
246 elif cpu in ['arm', 'aarch64']
247 # i386 emulator provides xenpv machine type for multiple architectures
248 xen_targets = ['i386-softmmu', 'x86_64-softmmu', 'aarch64-softmmu']
252 accelerator_targets += { 'CONFIG_XEN': xen_targets }
254 if cpu in ['aarch64']
255 accelerator_targets += {
256 'CONFIG_HVF': ['aarch64-softmmu']
260 if cpu in ['x86', 'x86_64']
261 accelerator_targets += {
262 'CONFIG_HVF': ['x86_64-softmmu'],
263 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
264 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
269 # Darwin does not support references to thread-local variables in modules
270 if targetos != 'darwin'
271 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
278 foreach lang : all_languages
279 compiler = meson.get_compiler(lang)
280 if compiler.get_id() == 'gcc' and compiler.version().version_compare('>=7.4')
282 elif compiler.get_id() == 'clang' and compiler.compiles('''
283 #ifdef __apple_build_version__
284 # if __clang_major__ < 12 || (__clang_major__ == 12 && __clang_minor__ < 0)
285 # error You need at least XCode Clang v12.0 to compile QEMU
288 # if __clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 0)
289 # error You need at least Clang v10.0 to compile QEMU
294 error('You either need GCC v7.4 or Clang v10.0 (or XCode Clang v12.0) to compile QEMU')
298 # default flags for all hosts
299 # We use -fwrapv to tell the compiler that we require a C dialect where
300 # left shift of signed integers is well defined and has the expected
301 # 2s-complement style results. (Both clang and gcc agree that it
302 # provides these semantics.)
304 qemu_common_flags = [
305 '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE',
306 '-fno-strict-aliasing', '-fno-common', '-fwrapv' ]
310 if targetos == 'darwin'
311 # Disable attempts to use ObjectiveC features in os/object.h since they
312 # won't work when we're compiling with gcc as a C compiler.
313 if compiler.get_id() == 'gcc'
314 qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
316 elif targetos == 'sunos'
317 # needed for CMSG_ macros in sys/socket.h
318 qemu_common_flags += '-D_XOPEN_SOURCE=600'
319 # needed for TIOCWIN* defines in termios.h
320 qemu_common_flags += '-D__EXTENSIONS__'
321 elif targetos == 'haiku'
322 qemu_common_flags += ['-DB_USE_POSITIVE_POSIX_ERRORS', '-D_BSD_SOURCE', '-fPIC']
325 # __sync_fetch_and_and requires at least -march=i486. Many toolchains
326 # use i686 as default anyway, but for those that don't, an explicit
327 # specification is necessary
328 if host_arch == 'i386' and not cc.links('''
329 static int sfaa(int *ptr)
331 return __sync_fetch_and_and(ptr, 0);
337 val = __sync_val_compare_and_swap(&val, 0, 1);
341 qemu_common_flags = ['-march=i486'] + qemu_common_flags
344 if get_option('prefer_static')
345 qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
348 # Meson currently only handles pie as a boolean for now, so if the user
349 # has explicitly disabled PIE we need to extend our cflags.
351 # -no-pie is supposedly a linker flag that has no effect on the compiler
352 # command line, but some distros, that didn't quite know what they were
353 # doing, made local changes to gcc's specs file that turned it into
354 # a compiler command-line flag.
356 # What about linker flags? For a static build, no PIE is implied by -static
357 # which we added above (and if it's not because of the same specs patching,
358 # there's nothing we can do: compilation will fail, report a bug to your
359 # distro and do not use --disable-pie in the meanwhile). For dynamic linking,
360 # instead, we can't add -no-pie because it overrides -shared: the linker then
361 # tries to build an executable instead of a shared library and fails. So
362 # don't add -no-pie anywhere and cross fingers. :(
363 if not get_option('b_pie')
364 qemu_common_flags += cc.get_supported_arguments('-fno-pie', '-no-pie')
367 if not get_option('stack_protector').disabled()
368 stack_protector_probe = '''
369 int main(int argc, char *argv[])
371 char arr[64], *p = arr, *c = argv[argc - 1];
377 have_stack_protector = false
378 foreach arg : ['-fstack-protector-strong', '-fstack-protector-all']
379 # We need to check both a compile and a link, since some compiler
380 # setups fail only on a .c->.o compile and some only at link time
381 if cc.compiles(stack_protector_probe, args: ['-Werror', arg]) and \
382 cc.links(stack_protector_probe, args: ['-Werror', arg])
383 have_stack_protector = true
389 get_option('stack_protector') \
390 .require(have_stack_protector, error_message: 'Stack protector not supported')
393 coroutine_backend = get_option('coroutine_backend')
395 #include <ucontext.h>
396 #ifdef __stub_makecontext
397 #error Ignoring glibc stub makecontext which will always fail
399 int main(void) { makecontext(0, 0, 0); return 0; }'''
401 # On Windows the only valid backend is the Windows specific one.
402 # For POSIX prefer ucontext, but it's not always possible. The fallback
404 supported_backends = []
405 if targetos == 'windows'
406 supported_backends += ['windows']
408 if targetos != 'darwin' and cc.links(ucontext_probe)
409 supported_backends += ['ucontext']
411 supported_backends += ['sigaltstack']
414 if coroutine_backend == 'auto'
415 coroutine_backend = supported_backends[0]
416 elif coroutine_backend not in supported_backends
417 error('"@0@" backend requested but not available. Available backends: @1@' \
418 .format(coroutine_backend, ', '.join(supported_backends)))
421 # Compiles if SafeStack *not* enabled
422 safe_stack_probe = '''
425 #if defined(__has_feature)
426 #if __has_feature(safe_stack)
427 #error SafeStack Enabled
432 if get_option('safe_stack') != not cc.compiles(safe_stack_probe)
433 safe_stack_arg = get_option('safe_stack') ? '-fsanitize=safe-stack' : '-fno-sanitize=safe-stack'
434 if get_option('safe_stack') != not cc.compiles(safe_stack_probe, args: safe_stack_arg)
435 error(get_option('safe_stack') \
436 ? 'SafeStack not supported by your compiler' \
437 : 'Cannot disable SafeStack')
439 qemu_cflags += safe_stack_arg
440 qemu_ldflags += safe_stack_arg
442 if get_option('safe_stack') and coroutine_backend != 'ucontext'
443 error('SafeStack is only supported with the ucontext coroutine backend')
446 if get_option('sanitizers')
447 if cc.has_argument('-fsanitize=address')
448 qemu_cflags = ['-fsanitize=address'] + qemu_cflags
449 qemu_ldflags = ['-fsanitize=address'] + qemu_ldflags
452 # Detect static linking issue with ubsan - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84285
453 if cc.links('int main(int argc, char **argv) { return argc + 1; }',
454 args: [qemu_ldflags, '-fsanitize=undefined'])
455 qemu_cflags = ['-fsanitize=undefined'] + qemu_cflags
456 qemu_ldflags = ['-fsanitize=undefined'] + qemu_ldflags
460 # Thread sanitizer is, for now, much noisier than the other sanitizers;
461 # keep it separate until that is not the case.
462 if get_option('tsan')
463 if get_option('sanitizers')
464 error('TSAN is not supported with other sanitizers')
466 if not cc.has_function('__tsan_create_fiber',
467 args: '-fsanitize=thread',
468 prefix: '#include <sanitizer/tsan_interface.h>')
469 error('Cannot enable TSAN due to missing fiber annotation interface')
471 qemu_cflags = ['-fsanitize=thread'] + qemu_cflags
472 qemu_ldflags = ['-fsanitize=thread'] + qemu_ldflags
475 # Detect support for PT_GNU_RELRO + DT_BIND_NOW.
476 # The combination is known as "full relro", because .got.plt is read-only too.
477 qemu_ldflags += cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now')
479 if targetos == 'windows'
480 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat')
481 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase', '-Wl,--high-entropy-va')
484 # Exclude --warn-common with TSan to suppress warnings from the TSan libraries.
485 if targetos != 'sunos' and not get_option('tsan')
486 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--warn-common')
489 if get_option('fuzzing')
490 # Specify a filter to only instrument code that is directly related to
492 configure_file(output: 'instrumentation-filter',
493 input: 'scripts/oss-fuzz/instrumentation-filter-template',
496 if cc.compiles('int main () { return 0; }',
497 name: '-fsanitize-coverage-allowlist=/dev/null',
498 args: ['-fsanitize-coverage-allowlist=/dev/null',
499 '-fsanitize-coverage=trace-pc'] )
500 qemu_common_flags += ['-fsanitize-coverage-allowlist=instrumentation-filter']
503 if get_option('fuzzing_engine') == ''
504 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
505 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
506 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
507 # unable to bind the fuzzer-related callbacks added by instrumentation.
508 qemu_common_flags += ['-fsanitize=fuzzer-no-link']
509 qemu_ldflags += ['-fsanitize=fuzzer-no-link']
510 # For the actual fuzzer binaries, we need to link against the libfuzzer
511 # library. They need to be configurable, to support OSS-Fuzz
512 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
514 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
515 # the needed CFLAGS have already been provided
516 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
522 # Check for dependency on LTO
523 if not get_option('b_lto')
524 error('Selected Control-Flow Integrity but LTO is disabled')
527 error('Selected Control-Flow Integrity is not compatible with modules')
529 # Check for cfi flags. CFI requires LTO so we can't use
530 # get_supported_arguments, but need a more complex "compiles" which allows
532 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
533 args: ['-flto', '-fsanitize=cfi-icall'] )
534 cfi_flags += '-fsanitize=cfi-icall'
536 error('-fsanitize=cfi-icall is not supported by the compiler')
538 if cc.compiles('int main () { return 0; }',
539 name: '-fsanitize-cfi-icall-generalize-pointers',
540 args: ['-flto', '-fsanitize=cfi-icall',
541 '-fsanitize-cfi-icall-generalize-pointers'] )
542 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
544 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
546 if get_option('cfi_debug')
547 if cc.compiles('int main () { return 0; }',
548 name: '-fno-sanitize-trap=cfi-icall',
549 args: ['-flto', '-fsanitize=cfi-icall',
550 '-fno-sanitize-trap=cfi-icall'] )
551 cfi_flags += '-fno-sanitize-trap=cfi-icall'
553 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
556 add_global_arguments(cfi_flags, native: false, language: all_languages)
557 add_global_link_arguments(cfi_flags, native: false, language: all_languages)
560 add_global_arguments(qemu_common_flags, native: false, language: all_languages)
561 add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
563 # Collect warnings that we want to enable
568 '-Wmissing-prototypes',
569 '-Wstrict-prototypes',
571 '-Wold-style-declaration',
572 '-Wold-style-definition',
577 '-Wignored-qualifiers',
581 '-Wexpansion-to-defined',
582 '-Wimplicit-fallthrough=2',
583 '-Wmissing-format-attribute',
584 '-Wno-initializer-overrides',
585 '-Wno-missing-include-dirs',
586 '-Wno-shift-negative-value',
587 '-Wno-string-plus-int',
588 '-Wno-typedef-redefinition',
589 '-Wno-tautological-type-limit-compare',
591 '-Wno-gnu-variable-sized-type-not-at-end',
595 if targetos != 'darwin'
596 warn_flags += ['-Wthread-safety']
599 # Set up C++ compiler flags
601 if 'cpp' in all_languages
602 qemu_cxxflags = ['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'] + qemu_cflags
605 add_project_arguments(qemu_cflags, native: false, language: 'c')
606 add_project_arguments(cc.get_supported_arguments(warn_flags), native: false, language: 'c')
607 if 'cpp' in all_languages
608 add_project_arguments(qemu_cxxflags, native: false, language: 'cpp')
609 add_project_arguments(cxx.get_supported_arguments(warn_flags), native: false, language: 'cpp')
611 if 'objc' in all_languages
612 # Note sanitizer flags are not applied to Objective-C sources!
613 add_project_arguments(objc.get_supported_arguments(warn_flags), native: false, language: 'objc')
615 if targetos == 'linux'
616 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
617 '-isystem', 'linux-headers',
618 language: all_languages)
621 add_project_arguments('-iquote', '.',
622 '-iquote', meson.current_source_dir(),
623 '-iquote', meson.current_source_dir() / 'include',
624 language: all_languages)
626 # If a host-specific include directory exists, list that first...
627 host_include = meson.current_source_dir() / 'host/include/'
628 if fs.is_dir(host_include / host_arch)
629 add_project_arguments('-iquote', host_include / host_arch,
630 language: all_languages)
632 # ... followed by the generic fallback.
633 add_project_arguments('-iquote', host_include / 'generic',
634 language: all_languages)
636 sparse = find_program('cgcc', required: get_option('sparse'))
639 command: [find_program('scripts/check_sparse.py'),
640 'compile_commands.json', sparse.full_path(), '-Wbitwise',
641 '-Wno-transparent-union', '-Wno-old-initializer',
642 '-Wno-non-pointer-null'])
645 #####################################
646 # Host-specific libraries and flags #
647 #####################################
649 libm = cc.find_library('m', required: false)
650 threads = dependency('threads')
651 util = cc.find_library('util', required: false)
657 emulator_link_args = []
662 if targetos == 'windows'
663 midl = find_program('midl', required: false)
664 widl = find_program('widl', required: false)
665 pathcch = cc.find_library('pathcch')
666 socket = cc.find_library('ws2_32')
667 winmm = cc.find_library('winmm')
669 win = import('windows')
670 version_res = win.compile_resources('version.rc',
671 depend_files: files('pc-bios/qemu-nsis.ico'),
672 include_directories: include_directories('.'))
674 elif targetos == 'darwin'
675 coref = dependency('appleframeworks', modules: 'CoreFoundation')
676 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
677 host_dsosuf = '.dylib'
678 elif targetos == 'sunos'
679 socket = [cc.find_library('socket'),
680 cc.find_library('nsl'),
681 cc.find_library('resolv')]
682 elif targetos == 'haiku'
683 socket = [cc.find_library('posix_error_mapper'),
684 cc.find_library('network'),
685 cc.find_library('bsd')]
686 elif targetos == 'openbsd'
687 if get_option('tcg').allowed() and target_dirs.length() > 0
688 # Disable OpenBSD W^X if available
689 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
693 ###############################################
694 # Host-specific configuration of accelerators #
695 ###############################################
698 if get_option('kvm').allowed() and targetos == 'linux'
699 accelerators += 'CONFIG_KVM'
701 if get_option('whpx').allowed() and targetos == 'windows'
702 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
703 error('WHPX requires 64-bit host')
704 elif cc.has_header('winhvplatform.h', required: get_option('whpx')) and \
705 cc.has_header('winhvemulation.h', required: get_option('whpx'))
706 accelerators += 'CONFIG_WHPX'
711 if get_option('hvf').allowed()
712 hvf = dependency('appleframeworks', modules: 'Hypervisor',
713 required: get_option('hvf'))
715 accelerators += 'CONFIG_HVF'
720 if targetos == 'netbsd'
721 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
723 accelerators += 'CONFIG_NVMM'
728 if get_option('tcg').allowed()
729 if host_arch == 'unknown'
730 if not get_option('tcg_interpreter')
731 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
733 elif get_option('tcg_interpreter')
734 warning('Use of the TCG interpreter is not recommended on this host')
735 warning('architecture. There is a native TCG execution backend available')
736 warning('which provides substantially better performance and reliability.')
737 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
738 warning('configuration option on this architecture to use the native')
741 if get_option('tcg_interpreter')
743 elif host_arch == 'x86_64'
745 elif host_arch == 'ppc64'
748 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
749 language: all_languages)
751 accelerators += 'CONFIG_TCG'
754 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
755 error('KVM not available on this platform')
757 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
758 error('HVF not available on this platform')
760 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
761 error('NVMM not available on this platform')
763 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
764 error('WHPX not available on this platform')
768 if get_option('xen').enabled() or (get_option('xen').auto() and have_system)
769 xencontrol = dependency('xencontrol', required: false,
770 method: 'pkg-config')
771 if xencontrol.found()
772 xen_pc = declare_dependency(version: xencontrol.version(),
775 # disabler: true makes xen_pc.found() return false if any is not found
776 dependency('xenstore', required: false,
777 method: 'pkg-config',
779 dependency('xenforeignmemory', required: false,
780 method: 'pkg-config',
782 dependency('xengnttab', required: false,
783 method: 'pkg-config',
785 dependency('xenevtchn', required: false,
786 method: 'pkg-config',
788 dependency('xendevicemodel', required: false,
789 method: 'pkg-config',
791 # optional, no "disabler: true"
792 dependency('xentoolcore', required: false,
793 method: 'pkg-config')])
799 xen_tests = [ '4.11.0', '4.10.0', '4.9.0', '4.8.0', '4.7.1' ]
801 '4.11.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
802 '4.10.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
803 '4.9.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
804 '4.8.0': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
805 '4.7.1': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
808 foreach ver: xen_tests
809 # cache the various library tests to avoid polluting the logs
811 foreach l: xen_libs[ver]
813 xen_deps += { l: cc.find_library(l, required: false) }
815 xen_test_deps += xen_deps[l]
818 # Use -D to pick just one of the test programs in scripts/xen-detect.c
819 xen_version = ver.split('.')
820 xen_ctrl_version = xen_version[0] + \
821 ('0' + xen_version[1]).substring(-2) + \
822 ('0' + xen_version[2]).substring(-2)
823 if cc.links(files('scripts/xen-detect.c'),
824 args: '-DCONFIG_XEN_CTRL_INTERFACE_VERSION=' + xen_ctrl_version,
825 dependencies: xen_test_deps)
826 xen = declare_dependency(version: ver, dependencies: xen_test_deps)
832 accelerators += 'CONFIG_XEN'
833 elif get_option('xen').enabled()
834 error('could not compile and link Xen test program')
837 have_xen_pci_passthrough = get_option('xen_pci_passthrough') \
838 .require(xen.found(),
839 error_message: 'Xen PCI passthrough requested but Xen not enabled') \
840 .require(targetos == 'linux',
841 error_message: 'Xen PCI passthrough not available on this platform') \
842 .require(cpu == 'x86' or cpu == 'x86_64',
843 error_message: 'Xen PCI passthrough not available on this platform') \
850 # When bumping glib minimum version, please check also whether to increase
851 # the _WIN32_WINNT setting in osdep.h according to the value from glib
852 glib_req_ver = '>=2.56.0'
853 glib_pc = dependency('glib-2.0', version: glib_req_ver, required: true,
854 method: 'pkg-config')
857 gmodule = dependency('gmodule-export-2.0', version: glib_req_ver, required: true,
858 method: 'pkg-config')
859 elif get_option('plugins')
860 gmodule = dependency('gmodule-no-export-2.0', version: glib_req_ver, required: true,
861 method: 'pkg-config')
866 # This workaround is required due to a bug in pkg-config file for glib as it
867 # doesn't define GLIB_STATIC_COMPILATION for pkg-config --static
868 if targetos == 'windows' and get_option('prefer_static')
869 glib_cflags += ['-DGLIB_STATIC_COMPILATION']
872 # Sanity check that the current size_t matches the
873 # size that glib thinks it should be. This catches
874 # problems on multi-arch where people try to build
875 # 32-bit QEMU while pointing at 64-bit glib headers
877 if not cc.compiles('''
881 #define QEMU_BUILD_BUG_ON(x) \
882 typedef char qemu_build_bug_on[(x)?-1:1] __attribute__((unused));
885 QEMU_BUILD_BUG_ON(sizeof(size_t) != GLIB_SIZEOF_SIZE_T);
887 }''', dependencies: glib_pc, args: glib_cflags)
888 error('''sizeof(size_t) doesn't match GLIB_SIZEOF_SIZE_T.
889 You probably need to set PKG_CONFIG_LIBDIR" to point
890 to the right pkg-config files for your build target.''')
893 # Silence clang warnings triggered by glib < 2.57.2
894 if not cc.compiles('''
899 static void foo_free(Foo *f)
903 G_DEFINE_AUTOPTR_CLEANUP_FUNC(Foo, foo_free)
904 int main(void) { return 0; }''', dependencies: glib_pc, args: ['-Wunused-function', '-Werror'])
905 glib_cflags += cc.get_supported_arguments('-Wno-unused-function')
907 glib = declare_dependency(dependencies: [glib_pc, gmodule],
908 compile_args: glib_cflags,
909 version: glib_pc.version())
911 # Check whether glib has gslice, which we have to avoid for correctness.
912 # TODO: remove this check and the corresponding workaround (qtree) when
913 # the minimum supported glib is >= 2.75.3
914 glib_has_gslice = glib.version().version_compare('<2.75.3')
916 # override glib dep to include the above refinements
917 meson.override_dependency('glib-2.0', glib)
919 # The path to glib.h is added to all compilation commands.
920 add_project_dependencies(glib.partial_dependency(compile_args: true, includes: true),
921 native: false, language: all_languages)
924 gdbus_codegen = not_found
925 gdbus_codegen_error = '@0@ requires gdbus-codegen, please install libgio'
926 if not get_option('gio').auto() or have_system
927 gio = dependency('gio-2.0', required: get_option('gio'),
928 method: 'pkg-config')
929 if gio.found() and not cc.links('''
933 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
935 }''', dependencies: [glib, gio])
936 if get_option('gio').enabled()
937 error('The installed libgio is broken for static linking')
942 gdbus_codegen = find_program(gio.get_variable('gdbus_codegen'),
943 required: get_option('gio'))
944 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
945 method: 'pkg-config')
946 gio = declare_dependency(dependencies: [gio, gio_unix],
947 version: gio.version())
950 if gdbus_codegen.found() and get_option('cfi')
951 gdbus_codegen = not_found
952 gdbus_codegen_error = '@0@ uses gdbus-codegen, which does not support control flow integrity'
955 xml_pp = find_program('scripts/xml-preprocess.py')
958 if 'ust' in get_option('trace_backends')
959 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
960 method: 'pkg-config')
963 if not get_option('pixman').auto() or have_system or have_tools
964 pixman = dependency('pixman-1', required: get_option('pixman'), version:'>=0.21.8',
965 method: 'pkg-config')
968 zlib = dependency('zlib', required: true)
971 if not get_option('linux_aio').auto() or have_block
972 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
973 required: get_option('linux_aio'))
976 linux_io_uring_test = '''
977 #include <liburing.h>
978 #include <linux/errqueue.h>
980 int main(void) { return 0; }'''
982 linux_io_uring = not_found
983 if not get_option('linux_io_uring').auto() or have_block
984 linux_io_uring = dependency('liburing', version: '>=0.3',
985 required: get_option('linux_io_uring'),
986 method: 'pkg-config')
987 if not cc.links(linux_io_uring_test)
988 linux_io_uring = not_found
993 if not get_option('libnfs').auto() or have_block
994 libnfs = dependency('libnfs', version: '>=1.9.3',
995 required: get_option('libnfs'),
996 method: 'pkg-config')
1001 #include <sys/types.h>
1002 #ifdef CONFIG_LIBATTR
1003 #include <attr/xattr.h>
1005 #include <sys/xattr.h>
1007 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
1010 have_old_libattr = false
1011 if get_option('attr').allowed()
1012 if cc.links(libattr_test)
1013 libattr = declare_dependency()
1015 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
1016 required: get_option('attr'))
1017 if libattr.found() and not \
1018 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
1020 if get_option('attr').enabled()
1021 error('could not link libattr')
1023 warning('could not link libattr, disabling')
1026 have_old_libattr = libattr.found()
1031 cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
1032 required: get_option('cocoa'))
1034 vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
1035 if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
1036 'VMNET_BRIDGED_MODE',
1037 dependencies: vmnet)
1039 if get_option('vmnet').enabled()
1040 error('vmnet.framework API is outdated')
1042 warning('vmnet.framework API is outdated, disabling')
1047 seccomp_has_sysrawrc = false
1048 if not get_option('seccomp').auto() or have_system or have_tools
1049 seccomp = dependency('libseccomp', version: '>=2.3.0',
1050 required: get_option('seccomp'),
1051 method: 'pkg-config')
1053 seccomp_has_sysrawrc = cc.has_header_symbol('seccomp.h',
1054 'SCMP_FLTATR_API_SYSRAWRC',
1055 dependencies: seccomp)
1059 libcap_ng = not_found
1060 if not get_option('cap_ng').auto() or have_system or have_tools
1061 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
1062 required: get_option('cap_ng'))
1064 if libcap_ng.found() and not cc.links('''
1068 capng_capability_to_name(CAPNG_EFFECTIVE);
1070 }''', dependencies: libcap_ng)
1071 libcap_ng = not_found
1072 if get_option('cap_ng').enabled()
1073 error('could not link libcap-ng')
1075 warning('could not link libcap-ng, disabling')
1079 if get_option('xkbcommon').auto() and not have_system and not have_tools
1080 xkbcommon = not_found
1082 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
1083 method: 'pkg-config')
1087 if not get_option('slirp').auto() or have_system
1088 slirp = dependency('slirp', required: get_option('slirp'),
1089 method: 'pkg-config')
1090 # slirp < 4.7 is incompatible with CFI support in QEMU. This is because
1091 # it passes function pointers within libslirp as callbacks for timers.
1092 # When using a system-wide shared libslirp, the type information for the
1093 # callback is missing and the timer call produces a false positive with CFI.
1094 # Do not use the "version" keyword argument to produce a better error.
1095 # with control-flow integrity.
1096 if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
1097 if get_option('slirp').enabled()
1098 error('Control-Flow Integrity requires libslirp 4.7.')
1100 warning('Cannot use libslirp since Control-Flow Integrity requires libslirp >= 4.7.')
1107 if not get_option('vde').auto() or have_system or have_tools
1108 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
1109 required: get_option('vde'))
1111 if vde.found() and not cc.links('''
1112 #include <libvdeplug.h>
1115 struct vde_open_args a = {0, 0, 0};
1119 }''', dependencies: vde)
1121 if get_option('cap_ng').enabled()
1122 error('could not link libvdeplug')
1124 warning('could not link libvdeplug, disabling')
1129 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
1130 pulse = dependency('libpulse', required: get_option('pa'),
1131 method: 'pkg-config')
1134 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
1135 alsa = dependency('alsa', required: get_option('alsa'),
1136 method: 'pkg-config')
1139 if not get_option('jack').auto() or have_system
1140 jack = dependency('jack', required: get_option('jack'),
1141 method: 'pkg-config')
1143 pipewire = not_found
1144 if not get_option('pipewire').auto() or (targetos == 'linux' and have_system)
1145 pipewire = dependency('libpipewire-0.3', version: '>=0.3.60',
1146 required: get_option('pipewire'),
1147 method: 'pkg-config')
1150 if not get_option('sndio').auto() or have_system
1151 sndio = dependency('sndio', required: get_option('sndio'),
1152 method: 'pkg-config')
1155 spice_protocol = not_found
1156 if not get_option('spice_protocol').auto() or have_system
1157 spice_protocol = dependency('spice-protocol', version: '>=0.14.0',
1158 required: get_option('spice_protocol'),
1159 method: 'pkg-config')
1162 if get_option('spice') \
1163 .disable_auto_if(not have_system) \
1164 .require(pixman.found(),
1165 error_message: 'cannot enable SPICE if pixman is not available') \
1167 spice = dependency('spice-server', version: '>=0.14.0',
1168 required: get_option('spice'),
1169 method: 'pkg-config')
1171 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
1173 rt = cc.find_library('rt', required: false)
1175 libiscsi = not_found
1176 if not get_option('libiscsi').auto() or have_block
1177 libiscsi = dependency('libiscsi', version: '>=1.9.0',
1178 required: get_option('libiscsi'),
1179 method: 'pkg-config')
1182 if not get_option('zstd').auto() or have_block
1183 zstd = dependency('libzstd', version: '>=1.4.0',
1184 required: get_option('zstd'),
1185 method: 'pkg-config')
1189 have_vhost_user_gpu = have_tools and targetos == 'linux' and pixman.found()
1190 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
1191 virgl = dependency('virglrenderer',
1192 method: 'pkg-config',
1193 required: get_option('virglrenderer'))
1195 config_host_data.set('HAVE_VIRGL_D3D_INFO_EXT',
1196 cc.has_member('struct virgl_renderer_resource_info_ext', 'd3d_tex2d',
1197 prefix: '#include <virglrenderer.h>',
1198 dependencies: virgl))
1201 rutabaga = not_found
1202 if not get_option('rutabaga_gfx').auto() or have_system or have_vhost_user_gpu
1203 rutabaga = dependency('rutabaga_gfx_ffi',
1204 method: 'pkg-config',
1205 required: get_option('rutabaga_gfx'))
1208 if not get_option('blkio').auto() or have_block
1209 blkio = dependency('blkio',
1210 method: 'pkg-config',
1211 required: get_option('blkio'))
1214 if not get_option('curl').auto() or have_block
1215 curl = dependency('libcurl', version: '>=7.29.0',
1216 method: 'pkg-config',
1217 required: get_option('curl'))
1220 if targetos == 'linux' and (have_system or have_tools)
1221 libudev = dependency('libudev',
1222 method: 'pkg-config',
1223 required: get_option('libudev'))
1226 mpathlibs = [libudev]
1227 mpathpersist = not_found
1228 if targetos == 'linux' and have_tools and get_option('mpath').allowed()
1229 mpath_test_source = '''
1230 #include <libudev.h>
1231 #include <mpath_persist.h>
1232 unsigned mpath_mx_alloc_len = 1024;
1234 static struct config *multipath_conf;
1235 extern struct udev *udev;
1236 extern struct config *get_multipath_config(void);
1237 extern void put_multipath_config(struct config *conf);
1239 struct config *get_multipath_config(void) { return multipath_conf; }
1240 void put_multipath_config(struct config *conf) { }
1243 multipath_conf = mpath_lib_init();
1246 libmpathpersist = cc.find_library('mpathpersist',
1247 required: get_option('mpath'))
1248 if libmpathpersist.found()
1249 mpathlibs += libmpathpersist
1250 if get_option('prefer_static')
1251 mpathlibs += cc.find_library('devmapper',
1252 required: get_option('mpath'))
1254 mpathlibs += cc.find_library('multipath',
1255 required: get_option('mpath'))
1256 foreach lib: mpathlibs
1262 if mpathlibs.length() == 0
1263 msg = 'Dependencies missing for libmpathpersist'
1264 elif cc.links(mpath_test_source, dependencies: mpathlibs)
1265 mpathpersist = declare_dependency(dependencies: mpathlibs)
1267 msg = 'Cannot detect libmpathpersist API'
1269 if not mpathpersist.found()
1270 if get_option('mpath').enabled()
1273 warning(msg + ', disabling')
1281 if have_system and get_option('curses').allowed()
1283 #if defined(__APPLE__) || defined(__OpenBSD__)
1284 #define _XOPEN_SOURCE_EXTENDED 1
1291 setlocale(LC_ALL, "");
1293 addwstr(L"wide chars\n");
1295 add_wch(WACS_DEGREE);
1299 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
1300 curses = dependency(curses_dep_list,
1302 method: 'pkg-config')
1303 msg = get_option('curses').enabled() ? 'curses library not found' : ''
1304 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
1306 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
1307 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses],
1308 version: curses.version())
1310 msg = 'curses package not usable'
1314 if not curses.found()
1315 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1316 if targetos != 'windows' and not has_curses_h
1317 message('Trying with /usr/include/ncursesw')
1318 curses_compile_args += ['-I/usr/include/ncursesw']
1319 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1322 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
1323 foreach curses_libname : curses_libname_list
1324 libcurses = cc.find_library(curses_libname,
1326 if libcurses.found()
1327 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
1328 curses = declare_dependency(compile_args: curses_compile_args,
1329 dependencies: [libcurses])
1332 msg = 'curses library not usable'
1338 if get_option('iconv').allowed()
1339 foreach link_args : [ ['-liconv'], [] ]
1340 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
1341 # We need to use libiconv if available because mixing libiconv's headers with
1342 # the system libc does not work.
1343 # However, without adding glib to the dependencies -L/usr/local/lib will not be
1344 # included in the command line and libiconv will not be found.
1348 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
1349 return conv != (iconv_t) -1;
1350 }''', args: link_args, dependencies: glib)
1351 iconv = declare_dependency(link_args: link_args, dependencies: glib)
1356 if curses.found() and not iconv.found()
1357 if get_option('iconv').enabled()
1358 error('iconv not available')
1360 msg = 'iconv required for curses UI but not available'
1363 if not curses.found() and msg != ''
1364 if get_option('curses').enabled()
1367 warning(msg + ', disabling')
1373 if not get_option('brlapi').auto() or have_system
1374 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
1375 required: get_option('brlapi'))
1376 if brlapi.found() and not cc.links('''
1379 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
1381 if get_option('brlapi').enabled()
1382 error('could not link brlapi')
1384 warning('could not link brlapi, disabling')
1390 if not get_option('sdl').auto() or have_system
1391 sdl = dependency('sdl2', required: get_option('sdl'))
1392 sdl_image = not_found
1395 # Some versions of SDL have problems with -Wundef
1396 if not cc.compiles('''
1398 #include <SDL_syswm.h>
1399 int main(int argc, char *argv[]) { return 0; }
1400 ''', dependencies: sdl, args: '-Werror=undef')
1401 sdl = declare_dependency(compile_args: '-Wno-undef',
1403 version: sdl.version())
1405 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
1406 method: 'pkg-config')
1408 if get_option('sdl_image').enabled()
1409 error('sdl-image required, but SDL was @0@'.format(
1410 get_option('sdl').disabled() ? 'disabled' : 'not found'))
1412 sdl_image = not_found
1416 if not get_option('rbd').auto() or have_block
1417 librados = cc.find_library('rados', required: get_option('rbd'))
1418 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
1419 required: get_option('rbd'))
1420 if librados.found() and librbd.found()
1423 #include <rbd/librbd.h>
1426 rados_create(&cluster, NULL);
1427 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
1431 }''', dependencies: [librbd, librados])
1432 rbd = declare_dependency(dependencies: [librbd, librados])
1433 elif get_option('rbd').enabled()
1434 error('librbd >= 1.12.0 required')
1436 warning('librbd >= 1.12.0 not found, disabling')
1441 glusterfs = not_found
1442 glusterfs_ftruncate_has_stat = false
1443 glusterfs_iocb_has_stat = false
1444 if not get_option('glusterfs').auto() or have_block
1445 glusterfs = dependency('glusterfs-api', version: '>=3',
1446 required: get_option('glusterfs'),
1447 method: 'pkg-config')
1448 if glusterfs.found()
1449 glusterfs_ftruncate_has_stat = cc.links('''
1450 #include <glusterfs/api/glfs.h>
1455 /* new glfs_ftruncate() passes two additional args */
1456 return glfs_ftruncate(NULL, 0, NULL, NULL);
1458 ''', dependencies: glusterfs)
1459 glusterfs_iocb_has_stat = cc.links('''
1460 #include <glusterfs/api/glfs.h>
1462 /* new glfs_io_cbk() passes two additional glfs_stat structs */
1464 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
1470 glfs_io_cbk iocb = &glusterfs_iocb;
1471 iocb(NULL, 0 , NULL, NULL, NULL);
1474 ''', dependencies: glusterfs)
1479 if get_option('hv_balloon').allowed() and have_system
1482 #include <gmodule.h>
1486 tree = g_tree_new((GCompareFunc)strcmp);
1487 (void)g_tree_node_first(tree);
1488 g_tree_destroy(tree);
1491 ''', dependencies: glib)
1494 if get_option('hv_balloon').enabled()
1495 error('could not enable hv-balloon, update your glib')
1497 warning('could not find glib support for hv-balloon, disabling')
1503 if not get_option('libssh').auto() or have_block
1504 libssh = dependency('libssh', version: '>=0.8.7',
1505 method: 'pkg-config',
1506 required: get_option('libssh'))
1509 libbzip2 = not_found
1510 if not get_option('bzip2').auto() or have_block
1511 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
1512 required: get_option('bzip2'))
1513 if libbzip2.found() and not cc.links('''
1515 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
1516 libbzip2 = not_found
1517 if get_option('bzip2').enabled()
1518 error('could not link libbzip2')
1520 warning('could not link libbzip2, disabling')
1525 liblzfse = not_found
1526 if not get_option('lzfse').auto() or have_block
1527 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
1528 required: get_option('lzfse'))
1530 if liblzfse.found() and not cc.links('''
1532 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
1533 liblzfse = not_found
1534 if get_option('lzfse').enabled()
1535 error('could not link liblzfse')
1537 warning('could not link liblzfse, disabling')
1542 if get_option('oss').allowed() and have_system
1543 if not cc.has_header('sys/soundcard.h')
1545 elif targetos == 'netbsd'
1546 oss = cc.find_library('ossaudio', required: get_option('oss'))
1548 oss = declare_dependency()
1552 if get_option('oss').enabled()
1553 error('OSS not found')
1558 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
1559 if cc.has_header('dsound.h')
1560 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
1563 if not dsound.found()
1564 if get_option('dsound').enabled()
1565 error('DirectSound not found')
1570 coreaudio = not_found
1571 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
1572 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
1573 required: get_option('coreaudio'))
1577 if not get_option('opengl').auto() or have_system or have_vhost_user_gpu
1578 epoxy = dependency('epoxy', method: 'pkg-config',
1579 required: get_option('opengl'))
1580 if cc.has_header('epoxy/egl.h', dependencies: epoxy)
1582 elif get_option('opengl').enabled()
1583 error('epoxy/egl.h not found')
1587 if (have_system or have_tools) and (virgl.found() or opengl.found())
1588 gbm = dependency('gbm', method: 'pkg-config', required: false)
1590 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and opengl.found() and gbm.found()
1593 gnutls_crypto = not_found
1594 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1595 # For general TLS support our min gnutls matches
1596 # that implied by our platform support matrix
1598 # For the crypto backends, we look for a newer
1601 # Version 3.6.8 is needed to get XTS
1602 # Version 3.6.13 is needed to get PBKDF
1603 # Version 3.6.14 is needed to get HW accelerated XTS
1605 # If newer enough gnutls isn't available, we can
1606 # still use a different crypto backend to satisfy
1607 # the platform support requirements
1608 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1609 method: 'pkg-config',
1611 if gnutls_crypto.found()
1612 gnutls = gnutls_crypto
1614 # Our min version if all we need is TLS
1615 gnutls = dependency('gnutls', version: '>=3.5.18',
1616 method: 'pkg-config',
1617 required: get_option('gnutls'))
1621 # We prefer use of gnutls for crypto, unless the options
1622 # explicitly asked for nettle or gcrypt.
1624 # If gnutls isn't available for crypto, then we'll prefer
1625 # gcrypt over nettle for performance reasons.
1631 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1632 error('Only one of gcrypt & nettle can be enabled')
1635 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1636 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1637 gnutls_crypto = not_found
1640 if not gnutls_crypto.found()
1641 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1642 gcrypt = dependency('libgcrypt', version: '>=1.8',
1643 method: 'config-tool',
1644 required: get_option('gcrypt'))
1645 # Debian has removed -lgpg-error from libgcrypt-config
1646 # as it "spreads unnecessary dependencies" which in
1647 # turn breaks static builds...
1648 if gcrypt.found() and get_option('prefer_static')
1649 gcrypt = declare_dependency(dependencies:
1651 cc.find_library('gpg-error', required: true)],
1652 version: gcrypt.version())
1655 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1656 nettle = dependency('nettle', version: '>=3.4',
1657 method: 'pkg-config',
1658 required: get_option('nettle'))
1659 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1665 capstone = not_found
1666 if not get_option('capstone').auto() or have_system or have_user
1667 capstone = dependency('capstone', version: '>=3.0.5',
1668 method: 'pkg-config',
1669 required: get_option('capstone'))
1671 # Some versions of capstone have broken pkg-config file
1672 # that reports a wrong -I path, causing the #include to
1673 # fail later. If the system has such a broken version
1675 if capstone.found() and not cc.compiles('#include <capstone.h>',
1676 dependencies: [capstone])
1677 capstone = not_found
1678 if get_option('capstone').enabled()
1679 error('capstone requested, but it does not appear to work')
1684 gmp = dependency('gmp', required: false, method: 'pkg-config')
1685 if nettle.found() and gmp.found()
1686 hogweed = dependency('hogweed', version: '>=3.4',
1687 method: 'pkg-config',
1688 required: get_option('nettle'))
1695 have_gtk_clipboard = get_option('gtk_clipboard').enabled()
1697 if get_option('gtk') \
1698 .disable_auto_if(not have_system) \
1699 .require(pixman.found(),
1700 error_message: 'cannot enable GTK if pixman is not available') \
1702 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1703 method: 'pkg-config',
1704 required: get_option('gtk'))
1706 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1707 method: 'pkg-config',
1709 gtk = declare_dependency(dependencies: [gtk, gtkx11],
1710 version: gtk.version())
1712 if not get_option('vte').auto() or have_system
1713 vte = dependency('vte-2.91',
1714 method: 'pkg-config',
1715 required: get_option('vte'))
1717 elif have_gtk_clipboard
1718 error('GTK clipboard requested, but GTK not found')
1724 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found())
1727 if get_option('png').allowed() and have_system
1728 png = dependency('libpng', version: '>=1.6.34', required: get_option('png'),
1729 method: 'pkg-config')
1734 if get_option('vnc') \
1735 .disable_auto_if(not have_system) \
1736 .require(pixman.found(),
1737 error_message: 'cannot enable VNC if pixman is not available') \
1739 vnc = declare_dependency() # dummy dependency
1740 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1741 method: 'pkg-config')
1742 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1743 required: get_option('vnc_sasl'))
1745 sasl = declare_dependency(dependencies: sasl,
1746 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1751 if not get_option('auth_pam').auto() or have_system
1752 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1753 required: get_option('auth_pam'))
1755 if pam.found() and not cc.links('''
1757 #include <security/pam_appl.h>
1759 const char *service_name = "qemu";
1760 const char *user = "frank";
1761 const struct pam_conv pam_conv = { 0 };
1762 pam_handle_t *pamh = NULL;
1763 pam_start(service_name, user, &pam_conv, &pamh);
1765 }''', dependencies: pam)
1767 if get_option('auth_pam').enabled()
1768 error('could not link libpam')
1770 warning('could not link libpam, disabling')
1775 if not get_option('snappy').auto() or have_system
1776 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1777 required: get_option('snappy'))
1779 if snappy.found() and not cc.links('''
1780 #include <snappy-c.h>
1781 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1783 if get_option('snappy').enabled()
1784 error('could not link libsnappy')
1786 warning('could not link libsnappy, disabling')
1791 if not get_option('lzo').auto() or have_system
1792 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1793 required: get_option('lzo'))
1795 if lzo.found() and not cc.links('''
1796 #include <lzo/lzo1x.h>
1797 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1799 if get_option('lzo').enabled()
1800 error('could not link liblzo2')
1802 warning('could not link liblzo2, disabling')
1807 if not get_option('numa').auto() or have_system or have_tools
1808 numa = cc.find_library('numa', has_headers: ['numa.h'],
1809 required: get_option('numa'))
1811 if numa.found() and not cc.links('''
1813 int main(void) { return numa_available(); }
1814 ''', dependencies: numa)
1816 if get_option('numa').enabled()
1817 error('could not link numa')
1819 warning('could not link numa, disabling')
1824 if not get_option('rdma').auto() or have_system
1825 libumad = cc.find_library('ibumad', required: get_option('rdma'))
1826 rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'],
1827 required: get_option('rdma')),
1828 cc.find_library('ibverbs', required: get_option('rdma')),
1830 rdma = declare_dependency(dependencies: rdma_libs)
1831 foreach lib: rdma_libs
1839 if not get_option('smartcard').auto() or have_system
1840 cacard = dependency('libcacard', required: get_option('smartcard'),
1841 version: '>=2.5.1', method: 'pkg-config')
1845 u2f = dependency('u2f-emu', required: get_option('u2f'),
1846 method: 'pkg-config')
1850 canokey = dependency('canokey-qemu', required: get_option('canokey'),
1851 method: 'pkg-config')
1853 usbredir = not_found
1854 if not get_option('usb_redir').auto() or have_system
1855 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1856 version: '>=0.6', method: 'pkg-config')
1859 if not get_option('libusb').auto() or have_system
1860 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1861 version: '>=1.0.13', method: 'pkg-config')
1865 if not get_option('libpmem').auto() or have_system
1866 libpmem = dependency('libpmem', required: get_option('libpmem'),
1867 method: 'pkg-config')
1869 libdaxctl = not_found
1870 if not get_option('libdaxctl').auto() or have_system
1871 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1872 version: '>=57', method: 'pkg-config')
1876 tasn1 = dependency('libtasn1',
1877 method: 'pkg-config')
1879 keyutils = not_found
1880 if not get_option('libkeyutils').auto() or have_block
1881 keyutils = dependency('libkeyutils', required: get_option('libkeyutils'),
1882 method: 'pkg-config')
1885 has_gettid = cc.has_function('gettid')
1888 selinux = dependency('libselinux',
1889 required: get_option('selinux'),
1890 method: 'pkg-config')
1895 if get_option('malloc') == 'system'
1897 get_option('malloc_trim').allowed() and \
1898 cc.has_function('malloc_trim', prefix: '#include <malloc.h>')
1900 has_malloc_trim = false
1901 malloc = cc.find_library(get_option('malloc'), required: true)
1903 if not has_malloc_trim and get_option('malloc_trim').enabled()
1904 if get_option('malloc') == 'system'
1905 error('malloc_trim not available on this platform.')
1907 error('malloc_trim not available with non-libc memory allocator')
1911 gnu_source_prefix = '''
1917 # Check whether the glibc provides STATX_BASIC_STATS
1919 has_statx = cc.has_header_symbol('sys/stat.h', 'STATX_BASIC_STATS', prefix: gnu_source_prefix)
1921 # Check whether statx() provides mount ID information
1923 has_statx_mnt_id = cc.has_header_symbol('sys/stat.h', 'STATX_MNT_ID', prefix: gnu_source_prefix)
1925 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
1926 .require(targetos == 'linux',
1927 error_message: 'vhost_user_blk_server requires linux') \
1928 .require(have_vhost_user,
1929 error_message: 'vhost_user_blk_server requires vhost-user support') \
1930 .disable_auto_if(not have_tools and not have_system) \
1933 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1934 error('Cannot enable fuse-lseek while fuse is disabled')
1937 fuse = dependency('fuse3', required: get_option('fuse'),
1938 version: '>=3.1', method: 'pkg-config')
1940 fuse_lseek = not_found
1941 if get_option('fuse_lseek').allowed()
1942 if fuse.version().version_compare('>=3.8')
1944 fuse_lseek = declare_dependency()
1945 elif get_option('fuse_lseek').enabled()
1947 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1949 error('fuse-lseek requires libfuse, which was not found')
1954 have_libvduse = (targetos == 'linux')
1955 if get_option('libvduse').enabled()
1956 if targetos != 'linux'
1957 error('libvduse requires linux')
1959 elif get_option('libvduse').disabled()
1960 have_libvduse = false
1963 have_vduse_blk_export = (have_libvduse and targetos == 'linux')
1964 if get_option('vduse_blk_export').enabled()
1965 if targetos != 'linux'
1966 error('vduse_blk_export requires linux')
1967 elif not have_libvduse
1968 error('vduse_blk_export requires libvduse support')
1970 elif get_option('vduse_blk_export').disabled()
1971 have_vduse_blk_export = false
1975 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1976 if libbpf.found() and not cc.links('''
1977 #include <bpf/libbpf.h>
1980 bpf_object__destroy_skeleton(NULL);
1982 }''', dependencies: libbpf)
1984 if get_option('bpf').enabled()
1985 error('libbpf skeleton test failed')
1987 warning('libbpf skeleton test failed, disabling')
1993 if not get_option('af_xdp').auto() or have_system
1994 libxdp = dependency('libxdp', required: get_option('af_xdp'),
1995 version: '>=1.4.0', method: 'pkg-config')
2000 if not get_option('libdw').auto() or \
2001 (not get_option('prefer_static') and (have_system or have_user))
2002 libdw = dependency('libdw',
2003 method: 'pkg-config',
2004 required: get_option('libdw'))
2011 audio_drivers_selected = []
2013 audio_drivers_available = {
2014 'alsa': alsa.found(),
2015 'coreaudio': coreaudio.found(),
2016 'dsound': dsound.found(),
2017 'jack': jack.found(),
2019 'pa': pulse.found(),
2020 'pipewire': pipewire.found(),
2022 'sndio': sndio.found(),
2024 foreach k, v: audio_drivers_available
2025 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
2028 # Default to native drivers first, OSS second, SDL third
2029 audio_drivers_priority = \
2030 [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \
2031 (targetos == 'linux' ? [] : [ 'sdl' ])
2032 audio_drivers_default = []
2033 foreach k: audio_drivers_priority
2034 if audio_drivers_available[k]
2035 audio_drivers_default += k
2039 foreach k: get_option('audio_drv_list')
2041 audio_drivers_selected += audio_drivers_default
2042 elif not audio_drivers_available[k]
2043 error('Audio driver "@0@" not available.'.format(k))
2045 audio_drivers_selected += k
2049 config_host_data.set('CONFIG_AUDIO_DRIVERS',
2050 '"' + '", "'.join(audio_drivers_selected) + '", ')
2052 have_host_block_device = (targetos != 'darwin' or
2053 cc.has_header('IOKit/storage/IOMedia.h'))
2055 dbus_display = get_option('dbus_display') \
2056 .require(gio.version().version_compare('>=2.64'),
2057 error_message: '-display dbus requires glib>=2.64') \
2058 .require(gdbus_codegen.found(),
2059 error_message: gdbus_codegen_error.format('-display dbus')) \
2062 have_virtfs = get_option('virtfs') \
2063 .require(targetos == 'linux' or targetos == 'darwin',
2064 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
2065 .require(targetos == 'linux' or cc.has_function('pthread_fchdir_np'),
2066 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
2067 .require(targetos == 'darwin' or libattr.found(),
2068 error_message: 'virtio-9p (virtfs) on Linux requires libattr-devel') \
2069 .disable_auto_if(not have_tools and not have_system) \
2072 have_virtfs_proxy_helper = get_option('virtfs_proxy_helper') \
2073 .require(targetos != 'darwin', error_message: 'the virtfs proxy helper is incompatible with macOS') \
2074 .require(have_virtfs, error_message: 'the virtfs proxy helper requires that virtfs is enabled') \
2075 .disable_auto_if(not have_tools) \
2076 .require(libcap_ng.found(), error_message: 'the virtfs proxy helper requires libcap-ng') \
2079 if get_option('block_drv_ro_whitelist') == ''
2080 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
2082 config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
2083 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
2085 if get_option('block_drv_rw_whitelist') == ''
2086 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
2088 config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
2089 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
2092 foreach k : get_option('trace_backends')
2093 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
2095 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
2096 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
2098 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
2100 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
2101 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
2102 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
2103 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
2104 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
2106 qemu_firmwarepath = ''
2107 foreach k : get_option('qemu_firmwarepath')
2108 qemu_firmwarepath += '"' + get_option('prefix') / k + '", '
2110 config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath)
2112 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
2113 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
2114 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
2115 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
2116 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
2117 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
2120 config_host_data.set('CONFIG_STAMP', run_command(
2121 meson.current_source_dir() / 'scripts/qemu-stamp.py',
2122 meson.project_version(), get_option('pkgversion'), '--',
2123 meson.current_source_dir() / 'configure',
2124 capture: true, check: true).stdout().strip())
2127 have_slirp_smbd = get_option('slirp_smbd') \
2128 .require(targetos != 'windows', error_message: 'Host smbd not supported on this platform.') \
2131 smbd_path = get_option('smbd')
2133 smbd_path = (targetos == 'sunos' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
2135 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
2138 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
2140 if get_option('module_upgrades') and not enable_modules
2141 error('Cannot enable module-upgrades as modules are not enabled')
2143 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
2145 config_host_data.set('CONFIG_ATTR', libattr.found())
2146 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
2147 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
2148 config_host_data.set('CONFIG_BSD', targetos in bsd_oses)
2149 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2150 config_host_data.set('CONFIG_COCOA', cocoa.found())
2151 config_host_data.set('CONFIG_DARWIN', targetos == 'darwin')
2152 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
2153 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
2154 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
2155 config_host_data.set('CONFIG_LINUX', targetos == 'linux')
2156 config_host_data.set('CONFIG_POSIX', targetos != 'windows')
2157 config_host_data.set('CONFIG_WIN32', targetos == 'windows')
2158 config_host_data.set('CONFIG_LZO', lzo.found())
2159 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
2160 config_host_data.set('CONFIG_BLKIO', blkio.found())
2162 config_host_data.set('CONFIG_BLKIO_VHOST_VDPA_FD',
2163 blkio.version().version_compare('>=1.3.0'))
2165 config_host_data.set('CONFIG_CURL', curl.found())
2166 config_host_data.set('CONFIG_CURSES', curses.found())
2167 config_host_data.set('CONFIG_GBM', gbm.found())
2168 config_host_data.set('CONFIG_GIO', gio.found())
2169 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
2170 if glusterfs.found()
2171 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
2172 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
2173 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
2174 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
2175 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
2176 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
2178 config_host_data.set('CONFIG_GTK', gtk.found())
2179 config_host_data.set('CONFIG_VTE', vte.found())
2180 config_host_data.set('CONFIG_GTK_CLIPBOARD', have_gtk_clipboard)
2181 config_host_data.set('CONFIG_HEXAGON_IDEF_PARSER', get_option('hexagon_idef_parser'))
2182 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
2183 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
2184 config_host_data.set('CONFIG_EBPF', libbpf.found())
2185 config_host_data.set('CONFIG_AF_XDP', libxdp.found())
2186 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
2187 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
2188 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
2189 config_host_data.set('CONFIG_LIBSSH', libssh.found())
2190 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
2191 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
2192 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
2193 config_host_data.set('CONFIG_MODULES', enable_modules)
2194 config_host_data.set('CONFIG_NUMA', numa.found())
2196 config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY',
2197 cc.has_function('numa_has_preferred_many',
2198 dependencies: numa))
2200 config_host_data.set('CONFIG_OPENGL', opengl.found())
2201 config_host_data.set('CONFIG_PLUGIN', get_option('plugins'))
2202 config_host_data.set('CONFIG_RBD', rbd.found())
2203 config_host_data.set('CONFIG_RDMA', rdma.found())
2204 config_host_data.set('CONFIG_RELOCATABLE', get_option('relocatable'))
2205 config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack'))
2206 config_host_data.set('CONFIG_SDL', sdl.found())
2207 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
2208 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
2210 config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc)
2212 config_host_data.set('CONFIG_PIXMAN', pixman.found())
2213 config_host_data.set('CONFIG_SLIRP', slirp.found())
2214 config_host_data.set('CONFIG_SNAPPY', snappy.found())
2215 config_host_data.set('CONFIG_SOLARIS', targetos == 'sunos')
2216 if get_option('tcg').allowed()
2217 config_host_data.set('CONFIG_TCG', 1)
2218 config_host_data.set('CONFIG_TCG_INTERPRETER', tcg_arch == 'tci')
2220 config_host_data.set('CONFIG_TPM', have_tpm)
2221 config_host_data.set('CONFIG_TSAN', get_option('tsan'))
2222 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
2223 config_host_data.set('CONFIG_VDE', vde.found())
2224 config_host_data.set('CONFIG_VHOST', have_vhost)
2225 config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
2226 config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
2227 config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)
2228 config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
2229 config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
2230 config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
2231 config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
2232 config_host_data.set('CONFIG_VMNET', vmnet.found())
2233 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
2234 config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export)
2235 config_host_data.set('CONFIG_PNG', png.found())
2236 config_host_data.set('CONFIG_VNC', vnc.found())
2237 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
2238 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
2239 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
2240 config_host_data.set('CONFIG_VTE', vte.found())
2241 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
2242 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
2243 config_host_data.set('CONFIG_GETTID', has_gettid)
2244 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
2245 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
2246 config_host_data.set('CONFIG_TASN1', tasn1.found())
2247 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
2248 config_host_data.set('CONFIG_NETTLE', nettle.found())
2249 config_host_data.set('CONFIG_HOGWEED', hogweed.found())
2250 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
2251 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
2252 config_host_data.set('CONFIG_STATX', has_statx)
2253 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
2254 config_host_data.set('CONFIG_ZSTD', zstd.found())
2255 config_host_data.set('CONFIG_FUSE', fuse.found())
2256 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
2257 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
2258 if spice_protocol.found()
2259 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
2260 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
2261 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
2263 config_host_data.set('CONFIG_SPICE', spice.found())
2264 config_host_data.set('CONFIG_X11', x11.found())
2265 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
2266 config_host_data.set('CONFIG_CFI', get_option('cfi'))
2267 config_host_data.set('CONFIG_SELINUX', selinux.found())
2268 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
2269 config_host_data.set('CONFIG_LIBDW', libdw.found())
2271 # protect from xen.version() having less than three components
2272 xen_version = xen.version().split('.') + ['0', '0']
2273 xen_ctrl_version = xen_version[0] + \
2274 ('0' + xen_version[1]).substring(-2) + \
2275 ('0' + xen_version[2]).substring(-2)
2276 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
2278 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
2279 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
2280 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
2281 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
2283 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
2284 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
2286 have_coroutine_pool = get_option('coroutine_pool')
2287 if get_option('debug_stack_usage') and have_coroutine_pool
2288 message('Disabling coroutine pool to measure stack usage')
2289 have_coroutine_pool = false
2291 config_host_data.set('CONFIG_COROUTINE_POOL', have_coroutine_pool)
2292 config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock'))
2293 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
2294 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
2295 config_host_data.set('CONFIG_DEBUG_TCG', get_option('debug_tcg'))
2296 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
2297 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
2298 config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
2301 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
2302 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
2303 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
2304 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
2305 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
2306 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
2307 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
2308 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
2309 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
2310 if targetos == 'windows'
2311 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h'))
2315 config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range'))
2316 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
2317 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
2318 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
2319 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
2320 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
2321 config_host_data.set('CONFIG_GETCPU', cc.has_function('getcpu', prefix: gnu_source_prefix))
2322 config_host_data.set('CONFIG_SCHED_GETCPU', cc.has_function('sched_getcpu', prefix: '#include <sched.h>'))
2323 # Note that we need to specify prefix: here to avoid incorrectly
2324 # thinking that Windows has posix_memalign()
2325 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
2326 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
2327 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
2328 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
2329 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
2330 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
2331 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
2332 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
2333 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
2334 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
2335 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
2336 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
2337 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
2338 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
2339 config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice)
2340 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
2341 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
2342 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
2343 config_host_data.set('HAVE_GETLOADAVG_FUNCTION', cc.has_function('getloadavg', prefix: '#include <stdlib.h>'))
2345 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
2346 cc.has_function('rbd_namespace_exists',
2348 prefix: '#include <rbd/librbd.h>'))
2351 config_host_data.set('HAVE_IBV_ADVISE_MR',
2352 cc.has_function('ibv_advise_mr',
2354 prefix: '#include <infiniband/verbs.h>'))
2357 have_asan_fiber = false
2358 if get_option('sanitizers') and \
2359 not cc.has_function('__sanitizer_start_switch_fiber',
2360 args: '-fsanitize=address',
2361 prefix: '#include <sanitizer/asan_interface.h>')
2362 warning('Missing ASAN due to missing fiber annotation interface')
2363 warning('Without code annotation, the report may be inferior.')
2365 have_asan_fiber = true
2367 config_host_data.set('CONFIG_ASAN_IFACE_FIBER', have_asan_fiber)
2370 config_host_data.set('CONFIG_BLKZONED',
2371 cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE'))
2372 config_host_data.set('CONFIG_EPOLL_CREATE1',
2373 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
2374 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
2375 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
2376 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
2377 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
2378 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
2379 config_host_data.set('CONFIG_FIEMAP',
2380 cc.has_header('linux/fiemap.h') and
2381 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
2382 config_host_data.set('CONFIG_GETRANDOM',
2383 cc.has_function('getrandom') and
2384 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
2385 config_host_data.set('CONFIG_INOTIFY',
2386 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
2387 config_host_data.set('CONFIG_INOTIFY1',
2388 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
2389 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
2390 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
2391 config_host_data.set('CONFIG_RTNETLINK',
2392 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
2393 config_host_data.set('CONFIG_SYSMACROS',
2394 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
2395 config_host_data.set('HAVE_OPTRESET',
2396 cc.has_header_symbol('getopt.h', 'optreset'))
2397 config_host_data.set('HAVE_IPPROTO_MPTCP',
2398 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
2401 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
2402 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
2403 prefix: '#include <signal.h>'))
2404 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
2405 cc.has_member('struct stat', 'st_atim',
2406 prefix: '#include <sys/stat.h>'))
2407 config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY',
2408 cc.has_member('struct blk_zone', 'capacity',
2409 prefix: '#include <linux/blkzoned.h>'))
2412 config_host_data.set('CONFIG_IOVEC',
2413 cc.has_type('struct iovec',
2414 prefix: '#include <sys/uio.h>'))
2415 config_host_data.set('HAVE_UTMPX',
2416 cc.has_type('struct utmpx',
2417 prefix: '#include <utmpx.h>'))
2419 config_host_data.set('CONFIG_EVENTFD', cc.links('''
2420 #include <sys/eventfd.h>
2421 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
2422 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
2425 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
2426 return fdatasync(0);
2428 #error Not supported
2432 has_madvise = cc.links(gnu_source_prefix + '''
2433 #include <sys/types.h>
2434 #include <sys/mman.h>
2436 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
2437 missing_madvise_proto = false
2439 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
2440 # but forget to prototype it. In this case, has_madvise will be true (the
2441 # test program links despite a compile warning). To detect the
2442 # missing-prototype case, we try again with a definitely-bogus prototype.
2443 # This will only compile if the system headers don't provide the prototype;
2444 # otherwise the conflicting prototypes will cause a compiler error.
2445 missing_madvise_proto = cc.links(gnu_source_prefix + '''
2446 #include <sys/types.h>
2447 #include <sys/mman.h>
2449 extern int madvise(int);
2450 int main(void) { return madvise(0); }''')
2452 config_host_data.set('CONFIG_MADVISE', has_madvise)
2453 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
2455 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
2456 #include <sys/mman.h>
2457 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
2458 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
2460 #if !defined(AT_EMPTY_PATH)
2461 # error missing definition
2463 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
2465 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
2466 #include <sys/mman.h>
2468 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
2470 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
2471 #include <pthread.h>
2473 static void *f(void *p) { return NULL; }
2477 pthread_create(&thread, 0, f, 0);
2478 pthread_setname_np(thread, "QEMU");
2480 }''', dependencies: threads))
2481 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
2482 #include <pthread.h>
2484 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
2488 pthread_create(&thread, 0, f, 0);
2490 }''', dependencies: threads))
2491 config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(gnu_source_prefix + '''
2492 #include <pthread.h>
2493 #include <pthread_np.h>
2495 static void *f(void *p) { return NULL; }
2499 pthread_create(&thread, 0, f, 0);
2500 pthread_set_name_np(thread, "QEMU");
2502 }''', dependencies: threads))
2503 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
2504 #include <pthread.h>
2509 pthread_condattr_t attr
2510 pthread_condattr_init(&attr);
2511 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
2513 }''', dependencies: threads))
2514 config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(gnu_source_prefix + '''
2515 #include <pthread.h>
2517 static void *f(void *p) { return NULL; }
2520 int setsize = CPU_ALLOC_SIZE(64);
2523 pthread_create(&thread, 0, f, 0);
2524 cpuset = CPU_ALLOC(64);
2525 CPU_ZERO_S(setsize, cpuset);
2526 pthread_setaffinity_np(thread, setsize, cpuset);
2527 pthread_getaffinity_np(thread, setsize, cpuset);
2530 }''', dependencies: threads))
2531 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
2532 #include <sys/signalfd.h>
2534 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
2535 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
2543 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
2544 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
2548 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
2549 #include <sys/mman.h>
2551 return mlockall(MCL_FUTURE);
2555 if get_option('l2tpv3').allowed() and have_system
2556 have_l2tpv3 = cc.has_type('struct mmsghdr',
2557 prefix: gnu_source_prefix + '''
2558 #include <sys/socket.h>
2559 #include <linux/ip.h>''')
2561 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2564 if get_option('netmap').allowed() and have_system
2565 have_netmap = cc.compiles('''
2566 #include <inttypes.h>
2568 #include <net/netmap.h>
2569 #include <net/netmap_user.h>
2570 #if (NETMAP_API < 11) || (NETMAP_API > 15)
2573 int main(void) { return 0; }''')
2574 if not have_netmap and get_option('netmap').enabled()
2575 error('Netmap headers not available')
2578 config_host_data.set('CONFIG_NETMAP', have_netmap)
2580 # Work around a system header bug with some kernel/XFS header
2581 # versions where they both try to define 'struct fsxattr':
2582 # xfs headers will not try to redefine structs from linux headers
2583 # if this macro is set.
2584 config_host_data.set('HAVE_FSXATTR', cc.links('''
2585 #include <linux/fs.h>
2591 # Some versions of Mac OS X incorrectly define SIZE_MAX
2592 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2596 return printf("%zu", SIZE_MAX);
2597 }''', args: ['-Werror']))
2599 # See if 64-bit atomic operations are supported.
2600 # Note that without __atomic builtins, we can only
2601 # assume atomic loads/stores max at pointer size.
2602 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
2606 uint64_t x = 0, y = 0;
2607 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2608 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2609 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2610 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2611 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2615 has_int128_type = cc.compiles('''
2618 int main(void) { b = a; }''')
2619 config_host_data.set('CONFIG_INT128_TYPE', has_int128_type)
2621 has_int128 = has_int128_type and cc.links('''
2630 config_host_data.set('CONFIG_INT128', has_int128)
2633 # "do we have 128-bit atomics which are handled inline and specifically not
2634 # via libatomic". The reason we can't use libatomic is documented in the
2635 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2636 # We only care about these operations on 16-byte aligned pointers, so
2637 # force 16-byte alignment of the pointer, which may be greater than
2638 # __alignof(unsigned __int128) for the host.
2639 atomic_test_128 = '''
2640 int main(int ac, char **av) {
2641 __uint128_t *p = __builtin_assume_aligned(av[ac - 1], 16);
2642 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED);
2643 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED);
2644 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2647 has_atomic128 = cc.links(atomic_test_128)
2649 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2651 if not has_atomic128
2652 # Even with __builtin_assume_aligned, the above test may have failed
2653 # without optimization enabled. Try again with optimizations locally
2654 # enabled for the function. See
2655 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389
2656 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128)
2657 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt)
2659 if not has_atomic128_opt
2660 config_host_data.set('CONFIG_CMPXCHG128', cc.links('''
2663 __uint128_t x = 0, y = 0;
2664 __sync_val_compare_and_swap_16(&x, y, x);
2672 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2673 #include <sys/auxv.h>
2675 return getauxval(AT_HWCAP) == 0;
2678 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2679 #include <linux/usbdevice_fs.h>
2681 #ifndef USBDEVFS_GET_CAPABILITIES
2682 #error "USBDEVFS_GET_CAPABILITIES undefined"
2685 #ifndef USBDEVFS_DISCONNECT_CLAIM
2686 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2689 int main(void) { return 0; }'''))
2691 have_keyring = get_option('keyring') \
2692 .require(targetos == 'linux', error_message: 'keyring is only available on Linux') \
2693 .require(cc.compiles('''
2695 #include <asm/unistd.h>
2696 #include <linux/keyctl.h>
2697 #include <sys/syscall.h>
2700 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2701 }'''), error_message: 'keyctl syscall not available on this system').allowed()
2702 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2704 have_cpuid_h = cc.links('''
2707 unsigned a, b, c, d;
2708 unsigned max = __get_cpuid_max(0, 0);
2711 __cpuid(1, a, b, c, d);
2715 __cpuid_count(7, 0, a, b, c, d);
2720 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2722 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2723 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2724 .require(cc.links('''
2726 #include <immintrin.h>
2727 static int __attribute__((target("avx2"))) bar(void *a) {
2728 __m256i x = *(__m256i *)a;
2729 return _mm256_testz_si256(x, x);
2731 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2732 '''), error_message: 'AVX2 not available').allowed())
2734 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2735 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2736 .require(cc.links('''
2738 #include <immintrin.h>
2739 static int __attribute__((target("avx512f"))) bar(void *a) {
2740 __m512i x = *(__m512i *)a;
2741 return _mm512_test_epi64_mask(x, x);
2743 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2744 '''), error_message: 'AVX512F not available').allowed())
2746 config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \
2747 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \
2748 .require(cc.links('''
2750 #include <immintrin.h>
2751 static int __attribute__((target("avx512bw"))) bar(void *a) {
2753 __m512i res= _mm512_abs_epi8(*x);
2756 int main(int argc, char *argv[]) { return bar(argv[0]); }
2757 '''), error_message: 'AVX512BW not available').allowed())
2759 # For both AArch64 and AArch32, detect if builtins are available.
2760 config_host_data.set('CONFIG_ARM_AES_BUILTIN', cc.compiles('''
2761 #include <arm_neon.h>
2762 #ifndef __ARM_FEATURE_AES
2763 __attribute__((target("+crypto")))
2765 void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); }
2768 have_pvrdma = get_option('pvrdma') \
2769 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
2770 .require(cc.compiles(gnu_source_prefix + '''
2771 #include <sys/mman.h>
2776 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2779 }'''), error_message: 'PVRDMA requires mremap').allowed()
2782 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.links('''
2783 #include <infiniband/verbs.h>
2787 struct ibv_pd *pd = NULL;
2793 mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2799 if get_option('membarrier').disabled()
2800 have_membarrier = false
2801 elif targetos == 'windows'
2802 have_membarrier = true
2803 elif targetos == 'linux'
2804 have_membarrier = cc.compiles('''
2805 #include <linux/membarrier.h>
2806 #include <sys/syscall.h>
2810 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2811 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2815 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2816 .require(have_membarrier, error_message: 'membarrier system call not available') \
2819 have_afalg = get_option('crypto_afalg') \
2820 .require(cc.compiles(gnu_source_prefix + '''
2822 #include <sys/types.h>
2823 #include <sys/socket.h>
2824 #include <linux/if_alg.h>
2827 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2830 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2831 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2833 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2834 'linux/vm_sockets.h', 'AF_VSOCK',
2835 prefix: '#include <sys/socket.h>',
2839 have_vss_sdk = false # old xp/2003 SDK
2840 if targetos == 'windows' and 'cpp' in all_languages
2841 have_vss = cxx.compiles('''
2842 #define __MIDL_user_allocate_free_DEFINED__
2844 int main(void) { return VSS_CTX_BACKUP; }''')
2845 have_vss_sdk = cxx.has_header('vscoordint.h')
2847 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2849 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2850 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2851 if targetos == 'windows'
2852 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2858 }''', name: '_lock_file and _unlock_file'))
2861 if targetos == 'windows'
2862 mingw_has_setjmp_longjmp = cc.links('''
2866 * These functions are not available in setjmp header, but may be
2867 * available at link time, from libmingwex.a.
2869 extern int __mingw_setjmp(jmp_buf);
2870 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
2872 __mingw_setjmp(env);
2873 __mingw_longjmp(env, 0);
2875 ''', name: 'mingw setjmp and longjmp')
2877 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp
2878 error('mingw must provide setjmp/longjmp for windows-arm64')
2882 ########################
2883 # Target configuration #
2884 ########################
2886 minikconf = find_program('scripts/minikconf.py')
2888 (targetos == 'windows' ? 'CONFIG_WIN32' : 'CONFIG_POSIX'): 'y'
2890 if targetos == 'darwin'
2891 config_targetos += {'CONFIG_DARWIN': 'y'}
2892 elif targetos == 'linux'
2893 config_targetos += {'CONFIG_LINUX': 'y'}
2895 if targetos in bsd_oses
2896 config_targetos += {'CONFIG_BSD': 'y'}
2900 config_all_devices = {}
2901 config_all_disas = {}
2902 config_devices_mak_list = []
2903 config_devices_h = {}
2904 config_target_h = {}
2905 config_target_mak = {}
2908 'alpha' : ['CONFIG_ALPHA_DIS'],
2909 'avr' : ['CONFIG_AVR_DIS'],
2910 'cris' : ['CONFIG_CRIS_DIS'],
2911 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2912 'hppa' : ['CONFIG_HPPA_DIS'],
2913 'i386' : ['CONFIG_I386_DIS'],
2914 'x86_64' : ['CONFIG_I386_DIS'],
2915 'm68k' : ['CONFIG_M68K_DIS'],
2916 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2917 'mips' : ['CONFIG_MIPS_DIS'],
2918 'nios2' : ['CONFIG_NIOS2_DIS'],
2919 'or1k' : ['CONFIG_OPENRISC_DIS'],
2920 'ppc' : ['CONFIG_PPC_DIS'],
2921 'riscv' : ['CONFIG_RISCV_DIS'],
2922 'rx' : ['CONFIG_RX_DIS'],
2923 's390' : ['CONFIG_S390_DIS'],
2924 'sh4' : ['CONFIG_SH4_DIS'],
2925 'sparc' : ['CONFIG_SPARC_DIS'],
2926 'xtensa' : ['CONFIG_XTENSA_DIS'],
2927 'loongarch' : ['CONFIG_LOONGARCH_DIS'],
2930 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2932 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2933 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2934 (pixman.found() ? ['CONFIG_PIXMAN=y'] : []) + \
2935 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2936 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2937 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2938 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2939 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
2940 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2941 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2942 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2943 (targetos == 'linux' ? ['CONFIG_LINUX=y'] : []) + \
2944 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
2945 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
2946 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \
2947 (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : [])
2949 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2951 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2952 actual_target_dirs = []
2954 foreach target : target_dirs
2955 config_target = { 'TARGET_NAME': target.split('-')[0] }
2956 if target.endswith('linux-user')
2957 if targetos != 'linux'
2961 error('Target @0@ is only available on a Linux host'.format(target))
2963 config_target += { 'CONFIG_LINUX_USER': 'y' }
2964 elif target.endswith('bsd-user')
2965 if targetos not in bsd_oses
2969 error('Target @0@ is only available on a BSD host'.format(target))
2971 config_target += { 'CONFIG_BSD_USER': 'y' }
2972 elif target.endswith('softmmu')
2973 config_target += { 'CONFIG_SYSTEM_ONLY': 'y' }
2974 config_target += { 'CONFIG_SOFTMMU': 'y' }
2976 if target.endswith('-user')
2978 'CONFIG_USER_ONLY': 'y',
2979 'CONFIG_QEMU_INTERP_PREFIX':
2980 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
2985 foreach sym: accelerators
2986 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2987 config_target += { sym: 'y' }
2988 config_all += { sym: 'y' }
2989 if target in modular_tcg
2990 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2992 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2994 accel_kconfig += [ sym + '=y' ]
2997 if accel_kconfig.length() == 0
3001 error('No accelerator available for target @0@'.format(target))
3004 actual_target_dirs += target
3005 config_target += keyval.load('configs/targets' / target + '.mak')
3006 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
3008 if 'TARGET_NEED_FDT' in config_target
3009 fdt_required += target
3013 if 'TARGET_BASE_ARCH' not in config_target
3014 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
3016 if 'TARGET_ABI_DIR' not in config_target
3017 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
3019 if 'TARGET_BIG_ENDIAN' not in config_target
3020 config_target += {'TARGET_BIG_ENDIAN': 'n'}
3023 foreach k, v: disassemblers
3024 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
3026 config_target += { sym: 'y' }
3027 config_all_disas += { sym: 'y' }
3032 config_target_data = configuration_data()
3033 foreach k, v: config_target
3034 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
3036 elif ignored.contains(k)
3038 elif k == 'TARGET_BASE_ARCH'
3039 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
3040 # not used to select files from sourcesets.
3041 config_target_data.set('TARGET_' + v.to_upper(), 1)
3042 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
3043 config_target_data.set_quoted(k, v)
3045 config_target_data.set(k, 1)
3047 config_target_data.set(k, 0)
3049 config_target_data.set(k, v)
3052 config_target_data.set('QEMU_ARCH',
3053 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
3054 config_target_h += {target: configure_file(output: target + '-config-target.h',
3055 configuration: config_target_data)}
3057 if target.endswith('-softmmu')
3058 config_input = meson.get_external_property(target, 'default')
3059 config_devices_mak = target + '-config-devices.mak'
3060 config_devices_mak = configure_file(
3061 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
3062 output: config_devices_mak,
3063 depfile: config_devices_mak + '.d',
3065 command: [minikconf,
3066 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
3067 config_devices_mak, '@DEPFILE@', '@INPUT@',
3068 host_kconfig, accel_kconfig,
3069 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
3071 config_devices_data = configuration_data()
3072 config_devices = keyval.load(config_devices_mak)
3073 foreach k, v: config_devices
3074 config_devices_data.set(k, 1)
3076 config_devices_mak_list += config_devices_mak
3077 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
3078 configuration: config_devices_data)}
3079 config_target += config_devices
3080 config_all_devices += config_devices
3082 config_target_mak += {target: config_target}
3084 target_dirs = actual_target_dirs
3086 # This configuration is used to build files that are shared by
3087 # multiple binaries, and then extracted out of the "common"
3088 # static_library target.
3090 # We do not use all_sources()/all_dependencies(), because it would
3091 # build literally all source files, including devices only used by
3092 # targets that are not built for this compilation. The CONFIG_ALL
3093 # pseudo symbol replaces it.
3095 config_all += config_all_devices
3096 config_all += config_targetos
3097 config_all += config_all_disas
3099 'CONFIG_XEN': xen.found(),
3100 'CONFIG_SYSTEM_ONLY': have_system,
3101 'CONFIG_USER_ONLY': have_user,
3105 target_configs_h = []
3106 foreach target: target_dirs
3107 target_configs_h += config_target_h[target]
3108 target_configs_h += config_devices_h.get(target, [])
3110 genh += custom_target('config-poison.h',
3111 input: [target_configs_h],
3112 output: 'config-poison.h',
3114 command: [find_program('scripts/make-config-poison.sh'),
3121 libvfio_user_dep = not_found
3122 if have_system and vfio_user_server_allowed
3123 libvfio_user_proj = subproject('libvfio-user', required: true)
3124 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep')
3128 fdt_opt = get_option('fdt')
3129 if fdt_required.length() > 0 or fdt_opt == 'enabled'
3130 if fdt_opt == 'disabled'
3131 error('fdt disabled but required by targets ' + ', '.join(fdt_required))
3134 if fdt_opt in ['enabled', 'auto', 'system']
3135 if get_option('wrap_mode') == 'nodownload'
3138 fdt = cc.find_library('fdt', required: fdt_opt == 'system')
3139 if fdt.found() and cc.links('''
3141 #include <libfdt_env.h>
3142 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
3145 elif fdt_opt == 'system'
3146 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
3148 fdt_opt = 'internal'
3153 assert(fdt_opt == 'internal')
3154 libfdt_proj = subproject('dtc', required: true,
3155 default_options: ['tools=false', 'yaml=disabled',
3156 'python=disabled', 'default_library=static'])
3157 fdt = libfdt_proj.get_variable('libfdt_dep')
3160 fdt_opt = 'disabled'
3163 config_host_data.set('CONFIG_FDT', fdt.found())
3165 vhost_user = not_found
3166 if targetos == 'linux' and have_vhost_user
3167 libvhost_user = subproject('libvhost-user')
3168 vhost_user = libvhost_user.get_variable('vhost_user_dep')
3171 libvduse = not_found
3173 libvduse_proj = subproject('libvduse')
3174 libvduse = libvduse_proj.get_variable('libvduse_dep')
3177 #####################
3178 # Generated sources #
3179 #####################
3181 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
3183 hxtool = find_program('scripts/hxtool')
3184 shaderinclude = find_program('scripts/shaderinclude.py')
3185 qapi_gen = find_program('scripts/qapi-gen.py')
3186 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
3187 meson.current_source_dir() / 'scripts/qapi/commands.py',
3188 meson.current_source_dir() / 'scripts/qapi/common.py',
3189 meson.current_source_dir() / 'scripts/qapi/error.py',
3190 meson.current_source_dir() / 'scripts/qapi/events.py',
3191 meson.current_source_dir() / 'scripts/qapi/expr.py',
3192 meson.current_source_dir() / 'scripts/qapi/gen.py',
3193 meson.current_source_dir() / 'scripts/qapi/introspect.py',
3194 meson.current_source_dir() / 'scripts/qapi/main.py',
3195 meson.current_source_dir() / 'scripts/qapi/parser.py',
3196 meson.current_source_dir() / 'scripts/qapi/schema.py',
3197 meson.current_source_dir() / 'scripts/qapi/source.py',
3198 meson.current_source_dir() / 'scripts/qapi/types.py',
3199 meson.current_source_dir() / 'scripts/qapi/visit.py',
3200 meson.current_source_dir() / 'scripts/qapi-gen.py'
3204 python, files('scripts/tracetool.py'),
3205 '--backend=' + ','.join(get_option('trace_backends'))
3207 tracetool_depends = files(
3208 'scripts/tracetool/backend/log.py',
3209 'scripts/tracetool/backend/__init__.py',
3210 'scripts/tracetool/backend/dtrace.py',
3211 'scripts/tracetool/backend/ftrace.py',
3212 'scripts/tracetool/backend/simple.py',
3213 'scripts/tracetool/backend/syslog.py',
3214 'scripts/tracetool/backend/ust.py',
3215 'scripts/tracetool/format/ust_events_c.py',
3216 'scripts/tracetool/format/ust_events_h.py',
3217 'scripts/tracetool/format/__init__.py',
3218 'scripts/tracetool/format/d.py',
3219 'scripts/tracetool/format/simpletrace_stap.py',
3220 'scripts/tracetool/format/c.py',
3221 'scripts/tracetool/format/h.py',
3222 'scripts/tracetool/format/log_stap.py',
3223 'scripts/tracetool/format/stap.py',
3224 'scripts/tracetool/__init__.py',
3225 'scripts/tracetool/vcpu.py'
3228 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
3229 meson.current_source_dir(),
3230 get_option('pkgversion'), meson.project_version()]
3231 qemu_version = custom_target('qemu-version.h',
3232 output: 'qemu-version.h',
3233 command: qemu_version_cmd,
3235 build_by_default: true,
3236 build_always_stale: true)
3237 genh += qemu_version
3241 ['qemu-options.hx', 'qemu-options.def'],
3242 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
3246 ['hmp-commands.hx', 'hmp-commands.h'],
3247 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
3250 foreach d : hx_headers
3251 hxdep += custom_target(d[1],
3255 command: [hxtool, '-h', '@INPUT0@'])
3263 authz_ss = ss.source_set()
3264 blockdev_ss = ss.source_set()
3265 block_ss = ss.source_set()
3266 chardev_ss = ss.source_set()
3267 common_ss = ss.source_set()
3268 crypto_ss = ss.source_set()
3269 hwcore_ss = ss.source_set()
3270 io_ss = ss.source_set()
3271 qmp_ss = ss.source_set()
3272 qom_ss = ss.source_set()
3273 system_ss = ss.source_set()
3274 specific_fuzz_ss = ss.source_set()
3275 specific_ss = ss.source_set()
3276 stub_ss = ss.source_set()
3277 trace_ss = ss.source_set()
3278 user_ss = ss.source_set()
3279 util_ss = ss.source_set()
3282 qtest_module_ss = ss.source_set()
3283 tcg_module_ss = ss.source_set()
3289 target_system_arch = {}
3290 target_user_arch = {}
3296 # TODO: add each directory to the subdirs from its own meson.build, once
3298 trace_events_subdirs = [
3307 trace_events_subdirs += [ 'linux-user' ]
3310 trace_events_subdirs += [ 'bsd-user' ]
3313 trace_events_subdirs += [
3322 trace_events_subdirs += [
3336 'hw/block/dataplane',
3387 if have_system or have_user
3388 trace_events_subdirs += [
3406 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3407 # that is filled in by qapi/.
3421 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3422 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3425 qom_ss = qom_ss.apply(config_targetos, strict: false)
3426 libqom = static_library('qom', qom_ss.sources() + genh,
3427 dependencies: [qom_ss.dependencies()],
3429 build_by_default: false)
3430 qom = declare_dependency(link_whole: libqom)
3432 event_loop_base = files('event-loop-base.c')
3433 event_loop_base = static_library('event-loop-base',
3434 sources: event_loop_base + genh,
3436 build_by_default: false)
3437 event_loop_base = declare_dependency(link_whole: event_loop_base,
3438 dependencies: [qom])
3440 stub_ss = stub_ss.apply(config_all, strict: false)
3442 util_ss.add_all(trace_ss)
3443 util_ss = util_ss.apply(config_all, strict: false)
3444 libqemuutil = static_library('qemuutil',
3445 build_by_default: false,
3446 sources: util_ss.sources() + stub_ss.sources() + genh,
3447 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
3448 qemuutil = declare_dependency(link_with: libqemuutil,
3449 sources: genh + version_res,
3450 dependencies: [event_loop_base])
3452 if have_system or have_user
3453 decodetree = generator(find_program('scripts/decodetree.py'),
3454 output: 'decode-@BASENAME@.c.inc',
3455 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3456 subdir('libdecnumber')
3473 if config_host_data.get('CONFIG_REPLICATION')
3474 block_ss.add(files('replication.c'))
3481 blockdev_ss.add(files(
3488 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3489 # os-win32.c does not
3490 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
3491 system_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
3494 common_ss.add(files('cpu-common.c'))
3495 specific_ss.add(files('cpu-target.c'))
3499 # Work around a gcc bug/misfeature wherein constant propagation looks
3501 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3502 # to guess that a const variable is always zero. Without lto, this is
3503 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
3504 # without lto, not even the alias is required -- we simply use different
3505 # declarations in different compilation units.
3506 pagevary = files('page-vary-common.c')
3507 if get_option('b_lto')
3508 pagevary_flags = ['-fno-lto']
3509 if get_option('cfi')
3510 pagevary_flags += '-fno-sanitize=cfi-icall'
3512 pagevary = static_library('page-vary-common', sources: pagevary + genh,
3513 c_args: pagevary_flags)
3514 pagevary = declare_dependency(link_with: pagevary)
3516 common_ss.add(pagevary)
3517 specific_ss.add(files('page-vary-target.c'))
3525 subdir('semihosting')
3533 common_user_inc = []
3535 subdir('common-user')
3537 subdir('linux-user')
3539 # needed for fuzzing binaries
3540 subdir('tests/qtest/libqos')
3541 subdir('tests/qtest/fuzz')
3544 tcg_real_module_ss = ss.source_set()
3545 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3546 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3547 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3548 'tcg': tcg_real_module_ss }}
3550 ##############################################
3551 # Internal static_libraries and dependencies #
3552 ##############################################
3554 modinfo_collect = find_program('scripts/modinfo-collect.py')
3555 modinfo_generate = find_program('scripts/modinfo-generate.py')
3560 foreach d, list : modules
3561 if not (d == 'block' ? have_block : have_system)
3565 foreach m, module_ss : list
3567 module_ss = module_ss.apply(config_all, strict: false)
3568 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3569 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3575 if module_ss.sources() != []
3576 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3577 # input. Sources can be used multiple times but objects are
3578 # unique when it comes to lookup in compile_commands.json.
3579 # Depnds on a mesion version with
3580 # https://github.com/mesonbuild/meson/pull/8900
3581 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3582 output: d + '-' + m + '.modinfo',
3583 input: module_ss.sources() + genh,
3585 command: [modinfo_collect, module_ss.sources()])
3589 block_ss.add_all(module_ss)
3591 system_ss.add_all(module_ss)
3597 foreach d, list : target_modules
3598 foreach m, module_ss : list
3600 foreach target : target_dirs
3601 if target.endswith('-softmmu')
3602 config_target = config_target_mak[target]
3603 config_target += config_targetos
3604 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3605 c_args = ['-DNEED_CPU_H',
3606 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3607 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3608 target_module_ss = module_ss.apply(config_target, strict: false)
3609 if target_module_ss.sources() != []
3610 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3611 sl = static_library(module_name,
3612 [genh, target_module_ss.sources()],
3613 dependencies: [modulecommon, target_module_ss.dependencies()],
3614 include_directories: target_inc,
3618 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3619 modinfo_files += custom_target(module_name + '.modinfo',
3620 output: module_name + '.modinfo',
3621 input: target_module_ss.sources() + genh,
3623 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3628 specific_ss.add_all(module_ss)
3634 foreach target : target_dirs
3635 if target.endswith('-softmmu')
3636 config_target = config_target_mak[target]
3637 config_devices_mak = target + '-config-devices.mak'
3638 modinfo_src = custom_target('modinfo-' + target + '.c',
3639 output: 'modinfo-' + target + '.c',
3640 input: modinfo_files,
3641 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'],
3644 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
3645 modinfo_dep = declare_dependency(link_with: modinfo_lib)
3647 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH']
3648 hw_arch[arch].add(modinfo_dep)
3653 nm = find_program('nm')
3654 undefsym = find_program('scripts/undefsym.py')
3655 block_syms = custom_target('block.syms', output: 'block.syms',
3656 input: [libqemuutil, block_mods],
3658 command: [undefsym, nm, '@INPUT@'])
3659 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3660 input: [libqemuutil, system_mods],
3662 command: [undefsym, nm, '@INPUT@'])
3664 authz_ss = authz_ss.apply(config_targetos, strict: false)
3665 libauthz = static_library('authz', authz_ss.sources() + genh,
3666 dependencies: [authz_ss.dependencies()],
3668 build_by_default: false)
3670 authz = declare_dependency(link_whole: libauthz,
3673 crypto_ss = crypto_ss.apply(config_targetos, strict: false)
3674 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3675 dependencies: [crypto_ss.dependencies()],
3677 build_by_default: false)
3679 crypto = declare_dependency(link_whole: libcrypto,
3680 dependencies: [authz, qom])
3682 io_ss = io_ss.apply(config_targetos, strict: false)
3683 libio = static_library('io', io_ss.sources() + genh,
3684 dependencies: [io_ss.dependencies()],
3685 link_with: libqemuutil,
3687 build_by_default: false)
3689 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3691 libmigration = static_library('migration', sources: migration_files + genh,
3693 build_by_default: false)
3694 migration = declare_dependency(link_with: libmigration,
3695 dependencies: [zlib, qom, io])
3696 system_ss.add(migration)
3698 block_ss = block_ss.apply(config_targetos, strict: false)
3699 libblock = static_library('block', block_ss.sources() + genh,
3700 dependencies: block_ss.dependencies(),
3701 link_depends: block_syms,
3703 build_by_default: false)
3705 block = declare_dependency(link_whole: [libblock],
3706 link_args: '@block.syms',
3707 dependencies: [crypto, io])
3709 blockdev_ss = blockdev_ss.apply(config_targetos, strict: false)
3710 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3711 dependencies: blockdev_ss.dependencies(),
3713 build_by_default: false)
3715 blockdev = declare_dependency(link_whole: [libblockdev],
3716 dependencies: [block, event_loop_base])
3718 qmp_ss = qmp_ss.apply(config_targetos, strict: false)
3719 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3720 dependencies: qmp_ss.dependencies(),
3722 build_by_default: false)
3724 qmp = declare_dependency(link_whole: [libqmp])
3726 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3728 dependencies: chardev_ss.dependencies(),
3729 build_by_default: false)
3731 chardev = declare_dependency(link_whole: libchardev)
3733 hwcore_ss = hwcore_ss.apply(config_targetos, strict: false)
3734 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3736 build_by_default: false)
3737 hwcore = declare_dependency(link_whole: libhwcore)
3738 common_ss.add(hwcore)
3744 emulator_modules = []
3745 foreach m : block_mods + system_mods
3746 emulator_modules += shared_module(m.name(),
3747 build_by_default: true,
3751 install_dir: qemu_moddir)
3753 if emulator_modules.length() > 0
3754 alias_target('modules', emulator_modules)
3757 system_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3758 common_ss.add(qom, qemuutil)
3760 common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss])
3761 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3763 common_all = common_ss.apply(config_all, strict: false)
3764 common_all = static_library('common',
3765 build_by_default: false,
3766 sources: common_all.sources() + genh,
3767 include_directories: common_user_inc,
3768 implicit_include_directories: false,
3769 dependencies: common_all.dependencies(),
3772 feature_to_c = find_program('scripts/feature_to_c.py')
3774 if targetos == 'darwin'
3775 entitlement = find_program('scripts/entitlement.sh')
3779 foreach target : target_dirs
3780 config_target = config_target_mak[target]
3781 target_name = config_target['TARGET_NAME']
3782 target_base_arch = config_target['TARGET_BASE_ARCH']
3783 arch_srcs = [config_target_h[target]]
3785 c_args = ['-DNEED_CPU_H',
3786 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3787 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3788 link_args = emulator_link_args
3790 config_target += config_targetos
3791 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3792 if targetos == 'linux'
3793 target_inc += include_directories('linux-headers', is_system: true)
3795 if target.endswith('-softmmu')
3796 target_type='system'
3797 t = target_system_arch[target_base_arch].apply(config_target, strict: false)
3798 arch_srcs += t.sources()
3799 arch_deps += t.dependencies()
3801 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3802 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3803 arch_srcs += hw.sources()
3804 arch_deps += hw.dependencies()
3806 arch_srcs += config_devices_h[target]
3807 link_args += ['@block.syms', '@qemu.syms']
3809 abi = config_target['TARGET_ABI_DIR']
3811 target_inc += common_user_inc
3812 if target_base_arch in target_user_arch
3813 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3814 arch_srcs += t.sources()
3815 arch_deps += t.dependencies()
3817 if 'CONFIG_LINUX_USER' in config_target
3818 base_dir = 'linux-user'
3820 if 'CONFIG_BSD_USER' in config_target
3821 base_dir = 'bsd-user'
3822 target_inc += include_directories('bsd-user/' / targetos)
3823 target_inc += include_directories('bsd-user/host/' / host_arch)
3824 dir = base_dir / abi
3825 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3827 target_inc += include_directories(
3831 if 'CONFIG_LINUX_USER' in config_target
3832 dir = base_dir / abi
3833 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3834 if config_target.has_key('TARGET_SYSTBL_ABI')
3836 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3837 extra_args : config_target['TARGET_SYSTBL_ABI'])
3842 if 'TARGET_XML_FILES' in config_target
3843 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3844 output: target + '-gdbstub-xml.c',
3845 input: files(config_target['TARGET_XML_FILES'].split()),
3846 command: [feature_to_c, '@INPUT@'],
3848 arch_srcs += gdbstub_xml
3851 t = target_arch[target_base_arch].apply(config_target, strict: false)
3852 arch_srcs += t.sources()
3853 arch_deps += t.dependencies()
3855 target_common = common_ss.apply(config_target, strict: false)
3856 objects = common_all.extract_objects(target_common.sources())
3857 deps = target_common.dependencies()
3859 target_specific = specific_ss.apply(config_target, strict: false)
3860 arch_srcs += target_specific.sources()
3861 arch_deps += target_specific.dependencies()
3863 lib = static_library('qemu-' + target,
3864 sources: arch_srcs + genh,
3865 dependencies: arch_deps,
3867 include_directories: target_inc,
3869 build_by_default: false,
3872 if target.endswith('-softmmu')
3874 'name': 'qemu-system-' + target_name,
3875 'win_subsystem': 'console',
3876 'sources': files('system/main.c'),
3879 if targetos == 'windows' and (sdl.found() or gtk.found())
3881 'name': 'qemu-system-' + target_name + 'w',
3882 'win_subsystem': 'windows',
3883 'sources': files('system/main.c'),
3887 if get_option('fuzzing')
3888 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3890 'name': 'qemu-fuzz-' + target_name,
3891 'win_subsystem': 'console',
3892 'sources': specific_fuzz.sources(),
3893 'dependencies': specific_fuzz.dependencies(),
3898 'name': 'qemu-' + target_name,
3899 'win_subsystem': 'console',
3905 exe_name = exe['name']
3906 if targetos == 'darwin'
3907 exe_name += '-unsigned'
3910 emulator = executable(exe_name, exe['sources'],
3913 dependencies: arch_deps + deps + exe['dependencies'],
3914 objects: lib.extract_all_objects(recursive: true),
3915 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3916 link_args: link_args,
3917 win_subsystem: exe['win_subsystem'])
3919 if targetos == 'darwin'
3920 icon = 'pc-bios/qemu.rsrc'
3921 build_input = [emulator, files(icon)]
3923 get_option('bindir') / exe_name,
3924 meson.current_source_dir() / icon
3926 if 'CONFIG_HVF' in config_target
3927 entitlements = 'accel/hvf/entitlements.plist'
3928 build_input += files(entitlements)
3929 install_input += meson.current_source_dir() / entitlements
3932 emulators += {exe['name'] : custom_target(exe['name'],
3934 output: exe['name'],
3935 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3938 meson.add_install_script(entitlement, '--install',
3939 get_option('bindir') / exe['name'],
3942 emulators += {exe['name']: emulator}
3947 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3948 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3949 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3950 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3952 custom_target(exe['name'] + stp['ext'],
3953 input: trace_events_all,
3954 output: exe['name'] + stp['ext'],
3955 install: stp['install'],
3956 install_dir: get_option('datadir') / 'systemtap/tapset',
3958 tracetool, '--group=all', '--format=' + stp['fmt'],
3959 '--binary=' + stp['bin'],
3960 '--target-name=' + target_name,
3961 '--target-type=' + target_type,
3962 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3963 '@INPUT@', '@OUTPUT@'
3965 depend_files: tracetool_depends)
3971 # Other build targets
3973 if get_option('plugins')
3974 install_headers('include/qemu/qemu-plugin.h')
3975 if targetos == 'windows'
3976 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer,
3977 # so that plugin authors can compile against it.
3978 install_data(win32_qemu_plugin_api_lib, install_dir: 'lib')
3984 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3985 # when we don't build tools or system
3986 if xkbcommon.found()
3987 # used for the update-keymaps target, so include rules even if !have_tools
3988 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3989 dependencies: [qemuutil, xkbcommon], install: have_tools)
3993 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3994 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3995 qemu_io = executable('qemu-io', files('qemu-io.c'),
3996 dependencies: [block, qemuutil], install: true)
3997 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3998 dependencies: [blockdev, qemuutil, gnutls, selinux],
4001 subdir('storage-daemon')
4002 subdir('contrib/rdmacm-mux')
4003 subdir('contrib/elf2dmp')
4005 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
4006 dependencies: qemuutil,
4010 subdir('contrib/vhost-user-blk')
4011 subdir('contrib/vhost-user-gpu')
4012 subdir('contrib/vhost-user-input')
4013 subdir('contrib/vhost-user-scsi')
4016 if targetos == 'linux'
4017 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
4018 dependencies: [qemuutil, libcap_ng],
4020 install_dir: get_option('libexecdir'))
4022 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
4023 dependencies: [authz, crypto, io, qom, qemuutil,
4024 libcap_ng, mpathpersist],
4029 subdir('contrib/ivshmem-client')
4030 subdir('contrib/ivshmem-server')
4043 if host_machine.system() == 'windows'
4045 find_program('scripts/nsis.py'),
4047 get_option('prefix'),
4048 meson.current_source_dir(),
4049 glib_pc.get_variable('bindir'),
4052 '-DDISPLAYVERSION=' + meson.project_version(),
4055 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
4058 nsis_cmd += '-DCONFIG_GTK=y'
4061 nsis = custom_target('nsis',
4062 output: 'qemu-setup-' + meson.project_version() + '.exe',
4063 input: files('qemu.nsi'),
4064 build_always_stale: true,
4065 command: nsis_cmd + ['@INPUT@'])
4066 alias_target('installer', nsis)
4069 #########################
4070 # Configuration summary #
4071 #########################
4075 summary_info += {'Build directory': meson.current_build_dir()}
4076 summary_info += {'Source path': meson.current_source_dir()}
4077 summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'}
4078 summary(summary_info, bool_yn: true, section: 'Build environment')
4081 summary_info += {'Install prefix': get_option('prefix')}
4082 summary_info += {'BIOS directory': qemu_datadir}
4083 pathsep = targetos == 'windows' ? ';' : ':'
4084 summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))}
4085 summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
4086 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
4087 summary_info += {'module directory': qemu_moddir}
4088 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
4089 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
4090 summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')}
4091 if targetos != 'windows'
4092 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
4093 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')}
4095 summary_info += {'local state directory': 'queried at runtime'}
4097 summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
4098 summary(summary_info, bool_yn: true, section: 'Directories')
4102 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
4103 summary_info += {'sphinx-build': sphinx_build}
4105 # FIXME: the [binaries] section of machine files, which can be probed
4106 # with find_program(), would be great for passing gdb and genisoimage
4107 # paths from configure to Meson. However, there seems to be no way to
4108 # hide a program (for example if gdb is too old).
4109 if config_host.has_key('GDB')
4110 summary_info += {'gdb': config_host['GDB']}
4112 summary_info += {'iasl': iasl}
4113 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
4114 if targetos == 'windows' and have_ga
4115 summary_info += {'wixl': wixl}
4117 if slirp.found() and have_system
4118 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
4120 summary(summary_info, bool_yn: true, section: 'Host binaries')
4122 # Configurable features
4124 summary_info += {'Documentation': build_docs}
4125 summary_info += {'system-mode emulation': have_system}
4126 summary_info += {'user-mode emulation': have_user}
4127 summary_info += {'block layer': have_block}
4128 summary_info += {'Install blobs': get_option('install_blobs')}
4129 summary_info += {'module support': enable_modules}
4131 summary_info += {'alternative module path': get_option('module_upgrades')}
4133 summary_info += {'fuzzing support': get_option('fuzzing')}
4135 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
4137 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
4138 if 'simple' in get_option('trace_backends')
4139 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
4141 summary_info += {'D-Bus display': dbus_display}
4142 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
4143 summary_info += {'Relocatable install': get_option('relocatable')}
4144 summary_info += {'vhost-kernel support': have_vhost_kernel}
4145 summary_info += {'vhost-net support': have_vhost_net}
4146 summary_info += {'vhost-user support': have_vhost_user}
4147 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
4148 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
4149 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
4150 summary_info += {'build guest agent': have_ga}
4151 summary(summary_info, bool_yn: true, section: 'Configurable features')
4153 # Compilation information
4155 summary_info += {'host CPU': cpu}
4156 summary_info += {'host endianness': build_machine.endian()}
4157 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
4158 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
4159 if 'cpp' in all_languages
4160 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
4162 summary_info += {'C++ compiler': false}
4164 if 'objc' in all_languages
4165 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
4167 summary_info += {'Objective-C compiler': false}
4169 option_cflags = (get_option('debug') ? ['-g'] : [])
4170 if get_option('optimization') != 'plain'
4171 option_cflags += ['-O' + get_option('optimization')]
4173 summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)}
4174 if 'cpp' in all_languages
4175 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)}
4177 if 'objc' in all_languages
4178 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)}
4180 link_args = get_option('c_link_args')
4181 if link_args.length() > 0
4182 summary_info += {'LDFLAGS': ' '.join(link_args)}
4184 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)}
4185 if 'cpp' in all_languages
4186 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)}
4188 if 'objc' in all_languages
4189 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)}
4191 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
4192 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
4193 summary_info += {'PIE': get_option('b_pie')}
4194 summary_info += {'static build': get_option('prefer_static')}
4195 summary_info += {'malloc trim support': has_malloc_trim}
4196 summary_info += {'membarrier': have_membarrier}
4197 summary_info += {'debug graph lock': get_option('debug_graph_lock')}
4198 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
4199 summary_info += {'mutex debugging': get_option('debug_mutex')}
4200 summary_info += {'memory allocator': get_option('malloc')}
4201 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
4202 summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')}
4203 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
4204 summary_info += {'gcov': get_option('b_coverage')}
4205 summary_info += {'thread sanitizer': get_option('tsan')}
4206 summary_info += {'CFI support': get_option('cfi')}
4207 if get_option('cfi')
4208 summary_info += {'CFI debug support': get_option('cfi_debug')}
4210 summary_info += {'strip binaries': get_option('strip')}
4211 summary_info += {'sparse': sparse}
4212 summary_info += {'mingw32 support': targetos == 'windows'}
4213 summary(summary_info, bool_yn: true, section: 'Compilation')
4215 # snarf the cross-compilation information for tests
4218 foreach target: target_dirs
4219 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak'
4220 if fs.exists(tcg_mak)
4221 config_cross_tcg = keyval.load(tcg_mak)
4222 if 'CC' in config_cross_tcg
4223 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']}
4229 summary(summary_info, bool_yn: true, section: 'Cross compilers')
4232 # Targets and accelerators
4235 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
4236 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
4237 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
4238 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
4239 summary_info += {'Xen support': xen.found()}
4241 summary_info += {'xen ctrl version': xen.version()}
4243 summary_info += {'Xen emulation': config_all.has_key('CONFIG_XEN_EMU')}
4245 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
4246 if config_all.has_key('CONFIG_TCG')
4247 if get_option('tcg_interpreter')
4248 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
4250 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
4252 summary_info += {'TCG plugins': get_option('plugins')}
4253 summary_info += {'TCG debug enabled': get_option('debug_tcg')}
4255 summary_info += {'target list': ' '.join(target_dirs)}
4257 summary_info += {'default devices': get_option('default_devices')}
4258 summary_info += {'out of process emulation': multiprocess_allowed}
4259 summary_info += {'vfio-user server': vfio_user_server_allowed}
4261 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
4265 summary_info += {'coroutine backend': coroutine_backend}
4266 summary_info += {'coroutine pool': have_coroutine_pool}
4268 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
4269 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
4270 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
4271 summary_info += {'VirtFS (9P) support': have_virtfs}
4272 summary_info += {'VirtFS (9P) Proxy Helper support (deprecated)': have_virtfs_proxy_helper}
4273 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
4274 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
4275 summary_info += {'bochs support': get_option('bochs').allowed()}
4276 summary_info += {'cloop support': get_option('cloop').allowed()}
4277 summary_info += {'dmg support': get_option('dmg').allowed()}
4278 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
4279 summary_info += {'vdi support': get_option('vdi').allowed()}
4280 summary_info += {'vhdx support': get_option('vhdx').allowed()}
4281 summary_info += {'vmdk support': get_option('vmdk').allowed()}
4282 summary_info += {'vpc support': get_option('vpc').allowed()}
4283 summary_info += {'vvfat support': get_option('vvfat').allowed()}
4284 summary_info += {'qed support': get_option('qed').allowed()}
4285 summary_info += {'parallels support': get_option('parallels').allowed()}
4286 summary_info += {'FUSE exports': fuse}
4287 summary_info += {'VDUSE block exports': have_vduse_blk_export}
4289 summary(summary_info, bool_yn: true, section: 'Block layer support')
4293 summary_info += {'TLS priority': get_option('tls_priority')}
4294 summary_info += {'GNUTLS support': gnutls}
4296 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
4298 summary_info += {'libgcrypt': gcrypt}
4299 summary_info += {'nettle': nettle}
4301 summary_info += {' XTS': xts != 'private'}
4303 summary_info += {'AF_ALG support': have_afalg}
4304 summary_info += {'rng-none': get_option('rng_none')}
4305 summary_info += {'Linux keyring': have_keyring}
4306 summary_info += {'Linux keyutils': keyutils}
4307 summary(summary_info, bool_yn: true, section: 'Crypto')
4311 if targetos == 'darwin'
4312 summary_info += {'Cocoa support': cocoa}
4314 summary_info += {'SDL support': sdl}
4315 summary_info += {'SDL image support': sdl_image}
4316 summary_info += {'GTK support': gtk}
4317 summary_info += {'pixman': pixman}
4318 summary_info += {'VTE support': vte}
4319 summary_info += {'PNG support': png}
4320 summary_info += {'VNC support': vnc}
4322 summary_info += {'VNC SASL support': sasl}
4323 summary_info += {'VNC JPEG support': jpeg}
4325 summary_info += {'spice protocol support': spice_protocol}
4326 if spice_protocol.found()
4327 summary_info += {' spice server support': spice}
4329 summary_info += {'curses support': curses}
4330 summary_info += {'brlapi support': brlapi}
4331 summary(summary_info, bool_yn: true, section: 'User interface')
4335 if targetos not in ['darwin', 'haiku', 'windows']
4336 summary_info += {'OSS support': oss}
4337 summary_info += {'sndio support': sndio}
4338 elif targetos == 'darwin'
4339 summary_info += {'CoreAudio support': coreaudio}
4340 elif targetos == 'windows'
4341 summary_info += {'DirectSound support': dsound}
4343 if targetos == 'linux'
4344 summary_info += {'ALSA support': alsa}
4345 summary_info += {'PulseAudio support': pulse}
4347 summary_info += {'PipeWire support': pipewire}
4348 summary_info += {'JACK support': jack}
4349 summary(summary_info, bool_yn: true, section: 'Audio backends')
4353 if targetos == 'darwin'
4354 summary_info += {'vmnet.framework support': vmnet}
4356 summary_info += {'AF_XDP support': libxdp}
4357 summary_info += {'slirp support': slirp}
4358 summary_info += {'vde support': vde}
4359 summary_info += {'netmap support': have_netmap}
4360 summary_info += {'l2tpv3 support': have_l2tpv3}
4361 summary(summary_info, bool_yn: true, section: 'Network backends')
4365 summary_info += {'libtasn1': tasn1}
4366 summary_info += {'PAM': pam}
4367 summary_info += {'iconv support': iconv}
4368 summary_info += {'virgl support': virgl}
4369 summary_info += {'rutabaga support': rutabaga}
4370 summary_info += {'blkio support': blkio}
4371 summary_info += {'curl support': curl}
4372 summary_info += {'Multipath support': mpathpersist}
4373 summary_info += {'Linux AIO support': libaio}
4374 summary_info += {'Linux io_uring support': linux_io_uring}
4375 summary_info += {'ATTR/XATTR support': libattr}
4376 summary_info += {'RDMA support': rdma}
4377 summary_info += {'PVRDMA support': have_pvrdma}
4378 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
4379 summary_info += {'libcap-ng support': libcap_ng}
4380 summary_info += {'bpf support': libbpf}
4381 summary_info += {'rbd support': rbd}
4382 summary_info += {'smartcard support': cacard}
4383 summary_info += {'U2F support': u2f}
4384 summary_info += {'libusb': libusb}
4385 summary_info += {'usb net redir': usbredir}
4386 summary_info += {'OpenGL support (epoxy)': opengl}
4387 summary_info += {'GBM': gbm}
4388 summary_info += {'libiscsi support': libiscsi}
4389 summary_info += {'libnfs support': libnfs}
4390 if targetos == 'windows'
4392 summary_info += {'QGA VSS support': have_qga_vss}
4395 summary_info += {'seccomp support': seccomp}
4396 summary_info += {'GlusterFS support': glusterfs}
4397 summary_info += {'hv-balloon support': hv_balloon}
4398 summary_info += {'TPM support': have_tpm}
4399 summary_info += {'libssh support': libssh}
4400 summary_info += {'lzo support': lzo}
4401 summary_info += {'snappy support': snappy}
4402 summary_info += {'bzip2 support': libbzip2}
4403 summary_info += {'lzfse support': liblzfse}
4404 summary_info += {'zstd support': zstd}
4405 summary_info += {'NUMA host support': numa}
4406 summary_info += {'capstone': capstone}
4407 summary_info += {'libpmem support': libpmem}
4408 summary_info += {'libdaxctl support': libdaxctl}
4409 summary_info += {'libudev': libudev}
4410 # Dummy dependency, keep .found()
4411 summary_info += {'FUSE lseek': fuse_lseek.found()}
4412 summary_info += {'selinux': selinux}
4413 summary_info += {'libdw': libdw}
4414 summary(summary_info, bool_yn: true, section: 'Dependencies')
4416 if host_arch == 'unknown'
4418 warning('UNSUPPORTED HOST CPU')
4420 message('Support for CPU host architecture ' + cpu + ' is not currently')
4421 message('maintained. The QEMU project does not guarantee that QEMU will')
4422 message('compile or work on this host CPU. You can help by volunteering')
4423 message('to maintain it and providing a build host for our continuous')
4424 message('integration setup.')
4425 if get_option('tcg').allowed() and target_dirs.length() > 0
4427 message('configure has succeeded and you can continue to build, but')
4428 message('QEMU will use a slow interpreter to emulate the target CPU.')
4432 if not supported_oses.contains(targetos)
4434 warning('UNSUPPORTED HOST OS')
4436 message('Support for host OS ' + targetos + 'is not currently maintained.')
4437 message('configure has succeeded and you can continue to build, but')
4438 message('the QEMU project does not guarantee that QEMU will compile or')
4439 message('work on this operating system. You can help by volunteering')
4440 message('to maintain it and providing a build host for our continuous')
4441 message('integration setup. This will ensure that future versions of QEMU')
4442 message('will keep working on ' + targetos + '.')
4445 if host_arch == 'unknown' or not supported_oses.contains(targetos)
4447 message('If you want to help supporting QEMU on this platform, please')
4448 message('contact the developers at qemu-devel@nongnu.org.')
4451 actually_reloc = get_option('relocatable')
4452 # check if get_relocated_path() is actually able to relocate paths
4453 if get_option('relocatable') and \
4454 not (get_option('prefix') / get_option('bindir')).startswith(get_option('prefix') / '')
4456 warning('bindir not included within prefix, the installation will not be relocatable.')
4457 actually_reloc = false
4459 if not actually_reloc and (targetos == 'windows' or get_option('relocatable'))
4460 if targetos == 'windows'
4462 warning('Windows installs should usually be relocatable.')
4465 message('QEMU will have to be installed under ' + get_option('prefix') + '.')
4466 message('Use --disable-relocatable to remove this warning.')