1 project('qemu', ['c'], meson_version: '>=1.5.0',
2 default_options: ['warning_level=2', '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')
19 ss = import('sourceset')
22 host_os = host_machine.system()
23 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
25 # Temporary directory used for files created while
26 # configure runs. Since it is in the build directory
27 # we can safely blow away any previous version of it
28 # (and we need not jump through hoops to try to delete
29 # it when configure exits.)
30 tmpdir = meson.current_build_dir() / 'meson-private/temp'
32 if get_option('qemu_suffix').startswith('/')
33 error('qemu_suffix cannot start with a /')
36 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
37 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
38 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
39 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
41 qemu_desktopdir = get_option('datadir') / 'applications'
42 qemu_icondir = get_option('datadir') / 'icons'
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()
56 # type of binaries to build
57 have_linux_user = false
60 foreach target : target_dirs
61 have_linux_user = have_linux_user or target.endswith('linux-user')
62 have_bsd_user = have_bsd_user or target.endswith('bsd-user')
63 have_system = have_system or target.endswith('-softmmu')
65 have_user = have_linux_user or have_bsd_user
71 sh = find_program('sh')
72 python = import('python').find_installation()
74 cc = meson.get_compiler('c')
76 if host_os == 'windows' and add_languages('cpp', required: false, native: false)
77 all_languages += ['cpp']
78 cxx = meson.get_compiler('cpp')
80 if host_os == 'darwin' and \
81 add_languages('objc', required: true, native: false)
82 all_languages += ['objc']
83 objc = meson.get_compiler('objc')
86 have_rust = add_languages('rust', native: false,
87 required: get_option('rust').disable_auto_if(not have_system))
88 have_rust = have_rust and add_languages('rust', native: true,
89 required: get_option('rust').disable_auto_if(not have_system))
91 rustc = meson.get_compiler('rust')
92 if rustc.version().version_compare('<1.63.0')
93 if get_option('rust').enabled()
94 error('rustc version ' + rustc.version() + ' is unsupported. Please upgrade to at least 1.63.0')
96 warning('rustc version ' + rustc.version() + ' is unsupported, disabling Rust compilation.')
97 message('Please upgrade to at least 1.63.0 to use Rust.')
104 bindgen = find_program('bindgen', required: get_option('rust'))
105 if not bindgen.found() or bindgen.version().version_compare('<0.60.0')
106 if get_option('rust').enabled()
107 error('bindgen version ' + bindgen.version() + ' is unsupported. You can install a new version with "cargo install bindgen-cli"')
110 warning('bindgen version ' + bindgen.version() + ' is unsupported, disabling Rust compilation.')
112 warning('bindgen not found, disabling Rust compilation.')
114 message('To use Rust you can install a new version with "cargo install bindgen-cli"')
121 rustfmt = find_program('rustfmt', required: false)
126 if 'dtrace' in get_option('trace_backends')
127 dtrace = find_program('dtrace', required: true)
128 stap = find_program('stap', required: false)
130 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
131 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
132 # instead. QEMU --enable-modules depends on this because the SystemTap
133 # semaphores are linked into the main binary and not the module's shared
135 add_global_arguments('-DSTAP_SDT_V2',
136 native: false, language: all_languages)
140 if get_option('iasl') == ''
141 iasl = find_program('iasl', required: false)
143 iasl = find_program(get_option('iasl'), required: true)
146 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu', 'riscv64-softmmu', 'loongarch64-softmmu' ]
147 unpack_edk2_blobs = false
148 foreach target : edk2_targets
149 if target in target_dirs
150 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
151 unpack_edk2_blobs = bzip2.found()
156 #####################
157 # Option validation #
158 #####################
161 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
164 #include <sys/types.h>
165 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
166 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
168 args: ['-Werror', '-fsanitize=fuzzer'])
169 error('Your compiler does not support -fsanitize=fuzzer')
173 if 'ftrace' in get_option('trace_backends') and host_os != 'linux'
174 error('ftrace is supported only on Linux')
176 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
179 openlog("qemu", LOG_PID, LOG_DAEMON);
180 syslog(LOG_INFO, "configure");
183 error('syslog is not supported on this system')
186 # Miscellaneous Linux-only features
187 get_option('mpath') \
188 .require(host_os == 'linux', error_message: 'Multipath is supported only on Linux')
190 multiprocess_allowed = get_option('multiprocess') \
191 .require(host_os == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
194 vfio_user_server_allowed = get_option('vfio_user_server') \
195 .require(host_os == 'linux', error_message: 'vfio-user server is supported only on Linux') \
198 have_tpm = get_option('tpm') \
199 .require(host_os != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
203 have_vhost_user = get_option('vhost_user') \
204 .disable_auto_if(host_os != 'linux') \
205 .require(host_os != 'windows',
206 error_message: 'vhost-user is not available on Windows').allowed()
207 have_vhost_vdpa = get_option('vhost_vdpa') \
208 .require(host_os == 'linux',
209 error_message: 'vhost-vdpa is only available on Linux').allowed()
210 have_vhost_kernel = get_option('vhost_kernel') \
211 .require(host_os == 'linux',
212 error_message: 'vhost-kernel is only available on Linux').allowed()
213 have_vhost_user_crypto = get_option('vhost_crypto') \
214 .require(have_vhost_user,
215 error_message: 'vhost-crypto requires vhost-user to be enabled').allowed()
217 have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel
219 have_vhost_net_user = have_vhost_user and get_option('vhost_net').allowed()
220 have_vhost_net_vdpa = have_vhost_vdpa and get_option('vhost_net').allowed()
221 have_vhost_net_kernel = have_vhost_kernel and get_option('vhost_net').allowed()
222 have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_vdpa
224 have_tools = get_option('tools') \
225 .disable_auto_if(not have_system) \
227 have_ga = get_option('guest_agent') \
228 .disable_auto_if(not have_system and not have_tools) \
229 .require(host_os in ['sunos', 'linux', 'windows', 'freebsd', 'netbsd', 'openbsd'],
230 error_message: 'unsupported OS for QEMU guest agent') \
232 have_block = have_system or have_tools
234 enable_modules = get_option('modules') \
235 .require(host_os != 'windows',
236 error_message: 'Modules are not available for Windows') \
237 .require(not get_option('prefer_static'),
238 error_message: 'Modules are incompatible with static linking') \
241 #######################################
242 # Variables for host and accelerators #
243 #######################################
245 if cpu not in supported_cpus
246 host_arch = 'unknown'
251 elif cpu in ['riscv32', 'riscv64']
257 if cpu in ['x86', 'x86_64']
258 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
259 elif cpu == 'aarch64'
260 kvm_targets = ['aarch64-softmmu']
262 kvm_targets = ['s390x-softmmu']
263 elif cpu in ['ppc', 'ppc64']
264 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
265 elif cpu in ['mips', 'mips64']
266 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
267 elif cpu in ['riscv32']
268 kvm_targets = ['riscv32-softmmu']
269 elif cpu in ['riscv64']
270 kvm_targets = ['riscv64-softmmu']
271 elif cpu in ['loongarch64']
272 kvm_targets = ['loongarch64-softmmu']
276 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
278 if cpu in ['x86', 'x86_64']
279 xen_targets = ['i386-softmmu', 'x86_64-softmmu']
280 elif cpu in ['arm', 'aarch64']
281 # i386 emulator provides xenpv machine type for multiple architectures
282 xen_targets = ['i386-softmmu', 'x86_64-softmmu', 'aarch64-softmmu']
286 accelerator_targets += { 'CONFIG_XEN': xen_targets }
288 if cpu in ['aarch64']
289 accelerator_targets += {
290 'CONFIG_HVF': ['aarch64-softmmu']
294 if cpu in ['x86', 'x86_64']
295 accelerator_targets += {
296 'CONFIG_HVF': ['x86_64-softmmu'],
297 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
298 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
303 # Darwin does not support references to thread-local variables in modules
304 if host_os != 'darwin'
305 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
312 foreach lang : all_languages
313 compiler = meson.get_compiler(lang)
314 if compiler.get_id() == 'gcc' and compiler.version().version_compare('>=7.4')
316 elif compiler.get_id() == 'clang' and compiler.compiles('''
317 #ifdef __apple_build_version__
318 # if __clang_major__ < 15 || (__clang_major__ == 15 && __clang_minor__ < 0)
319 # error You need at least XCode Clang v15.0 to compile QEMU
322 # if __clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 0)
323 # error You need at least Clang v10.0 to compile QEMU
328 error('You either need GCC v7.4 or Clang v10.0 (or XCode Clang v15.0) to compile QEMU')
332 # default flags for all hosts
333 # We use -fwrapv to tell the compiler that we require a C dialect where
334 # left shift of signed integers is well defined and has the expected
335 # 2s-complement style results. (Both clang and gcc agree that it
336 # provides these semantics.)
338 qemu_common_flags = [
339 '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE',
340 '-fno-strict-aliasing', '-fno-common', '-fwrapv' ]
344 if host_os == 'darwin'
345 # Disable attempts to use ObjectiveC features in os/object.h since they
346 # won't work when we're compiling with gcc as a C compiler.
347 if compiler.get_id() == 'gcc'
348 qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
350 elif host_os == 'sunos'
351 # needed for CMSG_ macros in sys/socket.h
352 qemu_common_flags += '-D_XOPEN_SOURCE=600'
353 # needed for TIOCWIN* defines in termios.h
354 qemu_common_flags += '-D__EXTENSIONS__'
355 elif host_os == 'haiku'
356 qemu_common_flags += ['-DB_USE_POSITIVE_POSIX_ERRORS', '-D_BSD_SOURCE', '-fPIC']
357 elif host_os == 'windows'
358 if not compiler.compiles('struct x { int y; } __attribute__((gcc_struct));',
360 error('Your compiler does not support __attribute__((gcc_struct)) - please use GCC instead of Clang')
364 # Choose instruction set (currently x86-only)
368 # __sync_fetch_and_and requires at least -march=i486. Many toolchains
369 # use i686 as default anyway, but for those that don't, an explicit
370 # specification is necessary
371 if host_arch == 'i386' and not cc.links('''
372 static int sfaa(int *ptr)
374 return __sync_fetch_and_and(ptr, 0);
380 val = __sync_val_compare_and_swap(&val, 0, 1);
384 qemu_isa_flags += ['-march=i486']
387 # Pick x86-64 baseline version
388 if host_arch in ['i386', 'x86_64']
389 if get_option('x86_version') == '0' and host_arch == 'x86_64'
390 error('x86_64-v1 required for x86-64 hosts')
393 # add flags for individual instruction set extensions
394 if get_option('x86_version') >= '1'
395 if host_arch == 'i386'
396 qemu_common_flags = ['-mfpmath=sse'] + qemu_common_flags
398 # present on basically all processors but technically not part of
399 # x86-64-v1, so only include -mneeded for x86-64 version 2 and above
400 qemu_isa_flags += ['-mcx16']
403 if get_option('x86_version') >= '2'
404 qemu_isa_flags += ['-mpopcnt']
405 qemu_isa_flags += cc.get_supported_arguments('-mneeded')
407 if get_option('x86_version') >= '3'
408 qemu_isa_flags += ['-mmovbe', '-mabm', '-mbmi', '-mbmi2', '-mfma', '-mf16c']
411 # add required vector instruction set (each level implies those below)
412 if get_option('x86_version') == '1'
413 qemu_isa_flags += ['-msse2']
414 elif get_option('x86_version') == '2'
415 qemu_isa_flags += ['-msse4.2']
416 elif get_option('x86_version') == '3'
417 qemu_isa_flags += ['-mavx2']
418 elif get_option('x86_version') == '4'
419 qemu_isa_flags += ['-mavx512f', '-mavx512bw', '-mavx512cd', '-mavx512dq', '-mavx512vl']
423 qemu_common_flags = qemu_isa_flags + qemu_common_flags
425 if get_option('prefer_static')
426 qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
429 # Meson currently only handles pie as a boolean for now, so if the user
430 # has explicitly disabled PIE we need to extend our cflags.
432 # -no-pie is supposedly a linker flag that has no effect on the compiler
433 # command line, but some distros, that didn't quite know what they were
434 # doing, made local changes to gcc's specs file that turned it into
435 # a compiler command-line flag.
437 # What about linker flags? For a static build, no PIE is implied by -static
438 # which we added above (and if it's not because of the same specs patching,
439 # there's nothing we can do: compilation will fail, report a bug to your
440 # distro and do not use --disable-pie in the meanwhile). For dynamic linking,
441 # instead, we can't add -no-pie because it overrides -shared: the linker then
442 # tries to build an executable instead of a shared library and fails. So
443 # don't add -no-pie anywhere and cross fingers. :(
444 if not get_option('b_pie')
445 qemu_common_flags += cc.get_supported_arguments('-fno-pie', '-no-pie')
448 if not get_option('stack_protector').disabled()
449 stack_protector_probe = '''
450 int main(int argc, char *argv[])
452 char arr[64], *p = arr, *c = argv[argc - 1];
458 have_stack_protector = false
459 foreach arg : ['-fstack-protector-strong', '-fstack-protector-all']
460 # We need to check both a compile and a link, since some compiler
461 # setups fail only on a .c->.o compile and some only at link time
462 if cc.compiles(stack_protector_probe, args: ['-Werror', arg]) and \
463 cc.links(stack_protector_probe, args: ['-Werror', arg])
464 have_stack_protector = true
470 get_option('stack_protector') \
471 .require(have_stack_protector, error_message: 'Stack protector not supported')
474 coroutine_backend = get_option('coroutine_backend')
476 #include <ucontext.h>
477 #ifdef __stub_makecontext
478 #error Ignoring glibc stub makecontext which will always fail
480 int main(void) { makecontext(0, 0, 0); return 0; }'''
482 # On Windows the only valid backend is the Windows specific one.
483 # For POSIX prefer ucontext, but it's not always possible. The fallback
485 supported_backends = []
486 if host_os == 'windows'
487 supported_backends += ['windows']
489 if host_os != 'darwin' and cc.links(ucontext_probe)
490 supported_backends += ['ucontext']
492 supported_backends += ['sigaltstack']
495 if coroutine_backend == 'auto'
496 coroutine_backend = supported_backends[0]
497 elif coroutine_backend not in supported_backends
498 error('"@0@" backend requested but not available. Available backends: @1@' \
499 .format(coroutine_backend, ', '.join(supported_backends)))
502 # Compiles if SafeStack *not* enabled
503 safe_stack_probe = '''
506 #if defined(__has_feature)
507 #if __has_feature(safe_stack)
508 #error SafeStack Enabled
513 if get_option('safe_stack') != not cc.compiles(safe_stack_probe)
514 safe_stack_arg = get_option('safe_stack') ? '-fsanitize=safe-stack' : '-fno-sanitize=safe-stack'
515 if get_option('safe_stack') != not cc.compiles(safe_stack_probe, args: safe_stack_arg)
516 error(get_option('safe_stack') \
517 ? 'SafeStack not supported by your compiler' \
518 : 'Cannot disable SafeStack')
520 qemu_cflags += safe_stack_arg
521 qemu_ldflags += safe_stack_arg
523 if get_option('safe_stack') and coroutine_backend != 'ucontext'
524 error('SafeStack is only supported with the ucontext coroutine backend')
527 if get_option('asan')
528 if cc.has_argument('-fsanitize=address')
529 qemu_cflags = ['-fsanitize=address'] + qemu_cflags
530 qemu_ldflags = ['-fsanitize=address'] + qemu_ldflags
532 error('Your compiler does not support -fsanitize=address')
536 if get_option('ubsan')
537 # Detect static linking issue with ubsan:
538 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84285
539 if cc.links('int main(int argc, char **argv) { return argc + 1; }',
540 args: [qemu_ldflags, '-fsanitize=undefined'])
541 qemu_cflags += ['-fsanitize=undefined']
542 qemu_ldflags += ['-fsanitize=undefined']
544 # Suppress undefined behaviour from function call to mismatched type.
545 # In addition, tcg prologue does not emit function type prefix
546 # required by function call sanitizer.
547 if cc.has_argument('-fno-sanitize=function')
548 qemu_cflags += ['-fno-sanitize=function']
551 error('Your compiler does not support -fsanitize=undefined')
555 # Thread sanitizer is, for now, much noisier than the other sanitizers;
556 # keep it separate until that is not the case.
557 if get_option('tsan')
558 if get_option('asan') or get_option('ubsan')
559 error('TSAN is not supported with other sanitizers')
561 if not cc.has_function('__tsan_create_fiber',
562 args: '-fsanitize=thread',
563 prefix: '#include <sanitizer/tsan_interface.h>')
564 error('Cannot enable TSAN due to missing fiber annotation interface')
566 tsan_warn_suppress = []
567 # gcc (>=11) will report constructions not supported by tsan:
568 # "error: ‘atomic_thread_fence’ is not supported with ‘-fsanitize=thread’"
569 # https://gcc.gnu.org/gcc-11/changes.html
570 # However, clang does not support this warning and this triggers an error.
571 if cc.has_argument('-Wno-tsan')
572 tsan_warn_suppress = ['-Wno-tsan']
574 qemu_cflags = ['-fsanitize=thread'] + tsan_warn_suppress + qemu_cflags
575 qemu_ldflags = ['-fsanitize=thread'] + qemu_ldflags
578 # Detect support for PT_GNU_RELRO + DT_BIND_NOW.
579 # The combination is known as "full relro", because .got.plt is read-only too.
580 qemu_ldflags += cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now')
582 if host_os == 'windows'
583 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat')
584 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase', '-Wl,--high-entropy-va')
587 if get_option('fuzzing')
588 # Specify a filter to only instrument code that is directly related to
590 configure_file(output: 'instrumentation-filter',
591 input: 'scripts/oss-fuzz/instrumentation-filter-template',
594 if cc.compiles('int main () { return 0; }',
595 name: '-fsanitize-coverage-allowlist=/dev/null',
596 args: ['-fsanitize-coverage-allowlist=/dev/null',
597 '-fsanitize-coverage=trace-pc'] )
598 qemu_common_flags += ['-fsanitize-coverage-allowlist=instrumentation-filter']
601 if get_option('fuzzing_engine') == ''
602 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
603 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
604 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
605 # unable to bind the fuzzer-related callbacks added by instrumentation.
606 qemu_common_flags += ['-fsanitize=fuzzer-no-link']
607 qemu_ldflags += ['-fsanitize=fuzzer-no-link']
608 # For the actual fuzzer binaries, we need to link against the libfuzzer
609 # library. They need to be configurable, to support OSS-Fuzz
610 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
612 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
613 # the needed CFLAGS have already been provided
614 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
620 # Check for dependency on LTO
621 if not get_option('b_lto')
622 error('Selected Control-Flow Integrity but LTO is disabled')
625 error('Selected Control-Flow Integrity is not compatible with modules')
627 # Check for cfi flags. CFI requires LTO so we can't use
628 # get_supported_arguments, but need a more complex "compiles" which allows
630 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
631 args: ['-flto', '-fsanitize=cfi-icall'] )
632 cfi_flags += '-fsanitize=cfi-icall'
634 error('-fsanitize=cfi-icall is not supported by the compiler')
636 if cc.compiles('int main () { return 0; }',
637 name: '-fsanitize-cfi-icall-generalize-pointers',
638 args: ['-flto', '-fsanitize=cfi-icall',
639 '-fsanitize-cfi-icall-generalize-pointers'] )
640 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
642 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
644 if get_option('cfi_debug')
645 if cc.compiles('int main () { return 0; }',
646 name: '-fno-sanitize-trap=cfi-icall',
647 args: ['-flto', '-fsanitize=cfi-icall',
648 '-fno-sanitize-trap=cfi-icall'] )
649 cfi_flags += '-fno-sanitize-trap=cfi-icall'
651 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
654 add_global_arguments(cfi_flags, native: false, language: all_languages)
655 add_global_link_arguments(cfi_flags, native: false, language: all_languages)
658 # Check further flags that make QEMU more robust against malicious parties
661 # Initialize all stack variables to zero. This makes
662 # it harder to take advantage of uninitialized stack
663 # data to drive exploits
664 '-ftrivial-auto-var-init=zero',
667 # Zero out registers used during a function call
668 # upon its return. This makes it harder to assemble
669 # ROP gadgets into something usable
671 # NB: Clang 17 is broken and SEGVs
672 # https://github.com/llvm/llvm-project/issues/75168
674 # NB2: This clashes with the "retguard" extension of OpenBSD's Clang
675 # https://gitlab.com/qemu-project/qemu/-/issues/2278
676 if host_os != 'openbsd' and \
677 cc.compiles('extern struct { void (*cb)(void); } s; void f(void) { s.cb(); }',
678 name: '-fzero-call-used-regs=used-gpr',
679 args: ['-O2', '-fzero-call-used-regs=used-gpr'])
680 hardening_flags += '-fzero-call-used-regs=used-gpr'
683 qemu_common_flags += cc.get_supported_arguments(hardening_flags)
685 add_global_arguments(qemu_common_flags, native: false, language: all_languages)
686 add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
688 # Collect warning flags we want to set, sorted alphabetically
690 # First enable interesting warnings
693 '-Wexpansion-to-defined',
696 '-Wignored-qualifiers',
697 '-Wimplicit-fallthrough=2',
699 '-Wmissing-format-attribute',
700 '-Wmissing-prototypes',
702 '-Wold-style-declaration',
703 '-Wold-style-definition',
706 '-Wstrict-prototypes',
712 # Then disable some undesirable warnings
713 '-Wno-gnu-variable-sized-type-not-at-end',
714 '-Wno-initializer-overrides',
715 '-Wno-missing-field-initializers',
716 '-Wno-missing-include-dirs',
717 '-Wno-override-init',
719 '-Wno-shift-negative-value',
721 '-Wno-string-plus-int',
722 '-Wno-tautological-type-limit-compare',
723 '-Wno-unused-parameter',
724 '-Wno-gnu-variable-sized-type-not-at-end',
725 '-Wno-error=cast-function-type',
727 '-Wno-error=format-extra-args',
728 '-Wno-error=implicit-fallthrough',
729 '-Wno-error=parentheses',
731 '-Wno-typedef-redefinition',
734 if host_os != 'darwin'
735 tsa_has_cleanup = cc.compiles('''
736 struct __attribute__((capability("mutex"))) mutex {};
737 void lock(struct mutex *m) __attribute__((acquire_capability(m)));
738 void unlock(struct mutex *m) __attribute__((release_capability(m)));
741 struct mutex __attribute__((cleanup(unlock))) m;
744 ''', args: ['-Wthread-safety', '-Werror'])
746 warn_flags += ['-Wthread-safety']
750 # Set up C++ compiler flags
752 if 'cpp' in all_languages
753 qemu_cxxflags = ['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'] + qemu_cflags
756 add_project_arguments(qemu_cflags, native: false, language: 'c')
757 add_project_arguments(cc.get_supported_arguments(warn_flags), native: false, language: 'c')
758 if 'cpp' in all_languages
759 add_project_arguments(qemu_cxxflags, native: false, language: 'cpp')
760 add_project_arguments(cxx.get_supported_arguments(warn_flags), native: false, language: 'cpp')
762 if 'objc' in all_languages
763 # Note sanitizer flags are not applied to Objective-C sources!
764 add_project_arguments(objc.get_supported_arguments(warn_flags), native: false, language: 'objc')
766 if host_os == 'linux'
767 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
768 '-isystem', 'linux-headers',
769 language: all_languages)
772 add_project_arguments('-iquote', '.',
773 '-iquote', meson.current_source_dir(),
774 '-iquote', meson.current_source_dir() / 'include',
775 language: all_languages)
777 # If a host-specific include directory exists, list that first...
778 host_include = meson.current_source_dir() / 'host/include/'
779 if fs.is_dir(host_include / host_arch)
780 add_project_arguments('-iquote', host_include / host_arch,
781 language: all_languages)
783 # ... followed by the generic fallback.
784 add_project_arguments('-iquote', host_include / 'generic',
785 language: all_languages)
787 sparse = find_program('cgcc', required: get_option('sparse'))
790 command: [find_program('scripts/check_sparse.py'),
791 'compile_commands.json', sparse.full_path(), '-Wbitwise',
792 '-Wno-transparent-union', '-Wno-old-initializer',
793 '-Wno-non-pointer-null'])
796 #####################################
797 # Host-specific libraries and flags #
798 #####################################
800 libm = cc.find_library('m', required: false)
801 threads = dependency('threads')
802 util = cc.find_library('util', required: false)
808 emulator_link_args = []
813 if host_os == 'windows'
814 midl = find_program('midl', required: false)
815 widl = find_program('widl', required: false)
816 pathcch = cc.find_library('pathcch')
817 socket = cc.find_library('ws2_32')
818 winmm = cc.find_library('winmm')
820 win = import('windows')
821 version_res = win.compile_resources('version.rc',
822 depend_files: files('pc-bios/qemu-nsis.ico'),
823 include_directories: include_directories('.'))
825 elif host_os == 'darwin'
826 coref = dependency('appleframeworks', modules: 'CoreFoundation')
827 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
828 host_dsosuf = '.dylib'
829 elif host_os == 'sunos'
830 socket = [cc.find_library('socket'),
831 cc.find_library('nsl'),
832 cc.find_library('resolv')]
833 elif host_os == 'haiku'
834 socket = [cc.find_library('posix_error_mapper'),
835 cc.find_library('network'),
836 cc.find_library('bsd')]
837 elif host_os == 'openbsd'
838 if get_option('tcg').allowed() and target_dirs.length() > 0
839 # Disable OpenBSD W^X if available
840 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
844 ###############################################
845 # Host-specific configuration of accelerators #
846 ###############################################
849 if get_option('kvm').allowed() and host_os == 'linux'
850 accelerators += 'CONFIG_KVM'
852 if get_option('whpx').allowed() and host_os == 'windows'
853 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
854 error('WHPX requires 64-bit host')
855 elif cc.has_header('winhvplatform.h', required: get_option('whpx')) and \
856 cc.has_header('winhvemulation.h', required: get_option('whpx'))
857 accelerators += 'CONFIG_WHPX'
862 if get_option('hvf').allowed()
863 hvf = dependency('appleframeworks', modules: 'Hypervisor',
864 required: get_option('hvf'))
866 accelerators += 'CONFIG_HVF'
871 if host_os == 'netbsd'
872 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
874 accelerators += 'CONFIG_NVMM'
879 if get_option('tcg').allowed()
880 if host_arch == 'unknown'
881 if not get_option('tcg_interpreter')
882 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
884 elif get_option('tcg_interpreter')
885 warning('Use of the TCG interpreter is not recommended on this host')
886 warning('architecture. There is a native TCG execution backend available')
887 warning('which provides substantially better performance and reliability.')
888 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
889 warning('configuration option on this architecture to use the native')
892 if get_option('tcg_interpreter')
894 elif host_arch == 'x86_64'
896 elif host_arch == 'ppc64'
899 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
900 language: all_languages)
902 accelerators += 'CONFIG_TCG'
905 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
906 error('KVM not available on this platform')
908 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
909 error('HVF not available on this platform')
911 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
912 error('NVMM not available on this platform')
914 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
915 error('WHPX not available on this platform')
919 if get_option('xen').enabled() or (get_option('xen').auto() and have_system)
920 xencontrol = dependency('xencontrol', required: false,
921 method: 'pkg-config')
922 if xencontrol.found()
923 xen_pc = declare_dependency(version: xencontrol.version(),
926 # disabler: true makes xen_pc.found() return false if any is not found
927 dependency('xenstore', required: false,
928 method: 'pkg-config',
930 dependency('xenforeignmemory', required: false,
931 method: 'pkg-config',
933 dependency('xengnttab', required: false,
934 method: 'pkg-config',
936 dependency('xenevtchn', required: false,
937 method: 'pkg-config',
939 dependency('xendevicemodel', required: false,
940 method: 'pkg-config',
942 # optional, no "disabler: true"
943 dependency('xentoolcore', required: false,
944 method: 'pkg-config')])
950 xen_tests = [ '4.11.0', '4.10.0', '4.9.0', '4.8.0', '4.7.1' ]
952 '4.11.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
953 '4.10.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
954 '4.9.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
955 '4.8.0': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
956 '4.7.1': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
959 foreach ver: xen_tests
960 # cache the various library tests to avoid polluting the logs
962 foreach l: xen_libs[ver]
964 xen_deps += { l: cc.find_library(l, required: false) }
966 xen_test_deps += xen_deps[l]
969 # Use -D to pick just one of the test programs in scripts/xen-detect.c
970 xen_version = ver.split('.')
971 xen_ctrl_version = xen_version[0] + \
972 ('0' + xen_version[1]).substring(-2) + \
973 ('0' + xen_version[2]).substring(-2)
974 if cc.links(files('scripts/xen-detect.c'),
975 args: '-DCONFIG_XEN_CTRL_INTERFACE_VERSION=' + xen_ctrl_version,
976 dependencies: xen_test_deps)
977 xen = declare_dependency(version: ver, dependencies: xen_test_deps)
983 accelerators += 'CONFIG_XEN'
984 elif get_option('xen').enabled()
985 error('could not compile and link Xen test program')
988 have_xen_pci_passthrough = get_option('xen_pci_passthrough') \
989 .require(xen.found(),
990 error_message: 'Xen PCI passthrough requested but Xen not enabled') \
991 .require(host_os == 'linux',
992 error_message: 'Xen PCI passthrough not available on this platform') \
993 .require(cpu == 'x86' or cpu == 'x86_64',
994 error_message: 'Xen PCI passthrough not available on this platform') \
1001 # When bumping glib minimum version, please check also whether to increase
1002 # the _WIN32_WINNT setting in osdep.h according to the value from glib.
1003 # You should also check if any of the glib.version() checks
1004 # below can also be removed.
1005 glib_req_ver = '>=2.66.0'
1006 glib_pc = dependency('glib-2.0', version: glib_req_ver, required: true,
1007 method: 'pkg-config')
1010 gmodule = dependency('gmodule-export-2.0', version: glib_req_ver, required: true,
1011 method: 'pkg-config')
1012 elif get_option('plugins')
1013 gmodule = dependency('gmodule-no-export-2.0', version: glib_req_ver, required: true,
1014 method: 'pkg-config')
1019 # This workaround is required due to a bug in pkg-config file for glib as it
1020 # doesn't define GLIB_STATIC_COMPILATION for pkg-config --static
1021 if host_os == 'windows' and get_option('prefer_static')
1022 glib_cflags += ['-DGLIB_STATIC_COMPILATION']
1025 # Sanity check that the current size_t matches the
1026 # size that glib thinks it should be. This catches
1027 # problems on multi-arch where people try to build
1028 # 32-bit QEMU while pointing at 64-bit glib headers
1030 if not cc.compiles('''
1034 #define QEMU_BUILD_BUG_ON(x) \
1035 typedef char qemu_build_bug_on[(x)?-1:1] __attribute__((unused));
1038 QEMU_BUILD_BUG_ON(sizeof(size_t) != GLIB_SIZEOF_SIZE_T);
1040 }''', dependencies: glib_pc, args: glib_cflags)
1041 error('''sizeof(size_t) doesn't match GLIB_SIZEOF_SIZE_T.
1042 You probably need to set PKG_CONFIG_LIBDIR" to point
1043 to the right pkg-config files for your build target.''')
1046 glib = declare_dependency(dependencies: [glib_pc, gmodule],
1047 compile_args: glib_cflags,
1048 version: glib_pc.version())
1050 # Check whether glib has gslice, which we have to avoid for correctness.
1051 # TODO: remove this check and the corresponding workaround (qtree) when
1052 # the minimum supported glib is >= 2.75.3
1053 glib_has_gslice = glib.version().version_compare('<2.75.3')
1054 # Check whether glib has the aligned_alloc family of functions.
1055 # <https://docs.gtk.org/glib/func.aligned_alloc.html>
1056 glib_has_aligned_alloc = glib.version().version_compare('>=2.72.0')
1058 # override glib dep to include the above refinements
1059 meson.override_dependency('glib-2.0', glib)
1061 # The path to glib.h is added to all compilation commands.
1062 add_project_dependencies(glib.partial_dependency(compile_args: true, includes: true),
1063 native: false, language: all_languages)
1066 gdbus_codegen = not_found
1067 gdbus_codegen_error = '@0@ requires gdbus-codegen, please install libgio'
1068 if not get_option('gio').auto() or have_system
1069 gio = dependency('gio-2.0', required: get_option('gio'),
1070 method: 'pkg-config')
1071 if gio.found() and not cc.links('''
1072 #include <gio/gio.h>
1075 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
1077 }''', dependencies: [glib, gio])
1078 if get_option('gio').enabled()
1079 error('The installed libgio is broken for static linking')
1084 gdbus_codegen = find_program('gdbus-codegen',
1085 required: get_option('gio'))
1086 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
1087 method: 'pkg-config')
1088 gio = declare_dependency(dependencies: [gio, gio_unix],
1089 version: gio.version())
1092 if gdbus_codegen.found() and get_option('cfi')
1093 gdbus_codegen = not_found
1094 gdbus_codegen_error = '@0@ uses gdbus-codegen, which does not support control flow integrity'
1097 xml_pp = find_program('scripts/xml-preprocess.py')
1100 if 'ust' in get_option('trace_backends')
1101 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
1102 method: 'pkg-config')
1105 if not get_option('pixman').auto() or have_system or have_tools
1106 pixman = dependency('pixman-1', required: get_option('pixman'), version:'>=0.21.8',
1107 method: 'pkg-config')
1110 zlib = dependency('zlib', required: true)
1113 if not get_option('linux_aio').auto() or have_block
1114 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
1115 required: get_option('linux_aio'))
1118 linux_io_uring_test = '''
1119 #include <liburing.h>
1120 #include <linux/errqueue.h>
1122 int main(void) { return 0; }'''
1124 linux_io_uring = not_found
1125 if not get_option('linux_io_uring').auto() or have_block
1126 linux_io_uring = dependency('liburing', version: '>=0.3',
1127 required: get_option('linux_io_uring'),
1128 method: 'pkg-config')
1129 if not cc.links(linux_io_uring_test)
1130 linux_io_uring = not_found
1135 if not get_option('libnfs').auto() or have_block
1136 libnfs = dependency('libnfs', version: '>=1.9.3',
1137 required: get_option('libnfs'),
1138 method: 'pkg-config')
1143 #include <sys/types.h>
1144 #ifdef CONFIG_LIBATTR
1145 #include <attr/xattr.h>
1147 #include <sys/xattr.h>
1149 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
1152 have_old_libattr = false
1153 if get_option('attr').allowed()
1154 if cc.links(libattr_test)
1155 libattr = declare_dependency()
1157 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
1158 required: get_option('attr'))
1159 if libattr.found() and not \
1160 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
1162 if get_option('attr').enabled()
1163 error('could not link libattr')
1165 warning('could not link libattr, disabling')
1168 have_old_libattr = libattr.found()
1173 cocoa = dependency('appleframeworks',
1174 modules: ['Cocoa', 'CoreVideo', 'QuartzCore'],
1175 required: get_option('cocoa'))
1177 vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
1178 if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
1179 'VMNET_BRIDGED_MODE',
1180 dependencies: vmnet)
1182 if get_option('vmnet').enabled()
1183 error('vmnet.framework API is outdated')
1185 warning('vmnet.framework API is outdated, disabling')
1190 seccomp_has_sysrawrc = false
1191 if not get_option('seccomp').auto() or have_system or have_tools
1192 seccomp = dependency('libseccomp', version: '>=2.3.0',
1193 required: get_option('seccomp'),
1194 method: 'pkg-config')
1196 seccomp_has_sysrawrc = cc.has_header_symbol('seccomp.h',
1197 'SCMP_FLTATR_API_SYSRAWRC',
1198 dependencies: seccomp)
1202 libcap_ng = not_found
1203 if not get_option('cap_ng').auto() or have_system or have_tools
1204 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
1205 required: get_option('cap_ng'))
1207 if libcap_ng.found() and not cc.links('''
1211 capng_capability_to_name(CAPNG_EFFECTIVE);
1213 }''', dependencies: libcap_ng)
1214 libcap_ng = not_found
1215 if get_option('cap_ng').enabled()
1216 error('could not link libcap-ng')
1218 warning('could not link libcap-ng, disabling')
1222 if get_option('xkbcommon').auto() and not have_system and not have_tools
1223 xkbcommon = not_found
1225 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
1226 method: 'pkg-config')
1230 if not get_option('slirp').auto() or have_system
1231 slirp = dependency('slirp', required: get_option('slirp'),
1232 method: 'pkg-config')
1233 # slirp < 4.7 is incompatible with CFI support in QEMU. This is because
1234 # it passes function pointers within libslirp as callbacks for timers.
1235 # When using a system-wide shared libslirp, the type information for the
1236 # callback is missing and the timer call produces a false positive with CFI.
1237 # Do not use the "version" keyword argument to produce a better error.
1238 # with control-flow integrity.
1239 if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
1240 if get_option('slirp').enabled()
1241 error('Control-Flow Integrity requires libslirp 4.7.')
1243 warning('Cannot use libslirp since Control-Flow Integrity requires libslirp >= 4.7.')
1250 if not get_option('vde').auto() or have_system or have_tools
1251 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
1252 required: get_option('vde'))
1254 if vde.found() and not cc.links('''
1255 #include <libvdeplug.h>
1258 struct vde_open_args a = {0, 0, 0};
1262 }''', dependencies: vde)
1264 if get_option('cap_ng').enabled()
1265 error('could not link libvdeplug')
1267 warning('could not link libvdeplug, disabling')
1272 if not get_option('pa').auto() or (host_os == 'linux' and have_system)
1273 pulse = dependency('libpulse', required: get_option('pa'),
1274 method: 'pkg-config')
1277 if not get_option('alsa').auto() or (host_os == 'linux' and have_system)
1278 alsa = dependency('alsa', required: get_option('alsa'),
1279 method: 'pkg-config')
1282 if not get_option('jack').auto() or have_system
1283 jack = dependency('jack', required: get_option('jack'),
1284 method: 'pkg-config')
1286 pipewire = not_found
1287 if not get_option('pipewire').auto() or (host_os == 'linux' and have_system)
1288 pipewire = dependency('libpipewire-0.3', version: '>=0.3.60',
1289 required: get_option('pipewire'),
1290 method: 'pkg-config')
1293 if not get_option('sndio').auto() or have_system
1294 sndio = dependency('sndio', required: get_option('sndio'),
1295 method: 'pkg-config')
1298 spice_protocol = not_found
1299 if not get_option('spice_protocol').auto() or have_system
1300 spice_protocol = dependency('spice-protocol', version: '>=0.14.0',
1301 required: get_option('spice_protocol'),
1302 method: 'pkg-config')
1305 if get_option('spice') \
1306 .disable_auto_if(not have_system) \
1307 .require(pixman.found(),
1308 error_message: 'cannot enable SPICE if pixman is not available') \
1310 spice = dependency('spice-server', version: '>=0.14.0',
1311 required: get_option('spice'),
1312 method: 'pkg-config')
1314 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
1316 rt = cc.find_library('rt', required: false)
1318 libiscsi = not_found
1319 if not get_option('libiscsi').auto() or have_block
1320 libiscsi = dependency('libiscsi', version: '>=1.9.0',
1321 required: get_option('libiscsi'),
1322 method: 'pkg-config')
1325 if not get_option('zstd').auto() or have_block
1326 zstd = dependency('libzstd', version: '>=1.4.0',
1327 required: get_option('zstd'),
1328 method: 'pkg-config')
1331 if not get_option('qpl').auto() or have_system
1332 qpl = dependency('qpl', version: '>=1.5.0',
1333 required: get_option('qpl'),
1334 method: 'pkg-config')
1337 if not get_option('uadk').auto() or have_system
1338 libwd = dependency('libwd', version: '>=2.6',
1339 required: get_option('uadk'),
1340 method: 'pkg-config')
1341 libwd_comp = dependency('libwd_comp', version: '>=2.6',
1342 required: get_option('uadk'),
1343 method: 'pkg-config')
1344 if libwd.found() and libwd_comp.found()
1345 uadk = declare_dependency(dependencies: [libwd, libwd_comp])
1350 if not get_option('qatzip').auto() or have_system
1351 qatzip = dependency('qatzip', version: '>=1.1.2',
1352 required: get_option('qatzip'),
1353 method: 'pkg-config')
1358 have_vhost_user_gpu = have_tools and host_os == 'linux' and pixman.found()
1359 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
1360 virgl = dependency('virglrenderer',
1361 method: 'pkg-config',
1362 required: get_option('virglrenderer'))
1364 rutabaga = not_found
1365 if not get_option('rutabaga_gfx').auto() or have_system or have_vhost_user_gpu
1366 rutabaga = dependency('rutabaga_gfx_ffi',
1367 method: 'pkg-config',
1368 required: get_option('rutabaga_gfx'))
1371 if not get_option('blkio').auto() or have_block
1372 blkio = dependency('blkio',
1373 method: 'pkg-config',
1374 required: get_option('blkio'))
1377 if not get_option('curl').auto() or have_block
1378 curl = dependency('libcurl', version: '>=7.29.0',
1379 method: 'pkg-config',
1380 required: get_option('curl'))
1383 if host_os == 'linux' and (have_system or have_tools)
1384 libudev = dependency('libudev',
1385 method: 'pkg-config',
1386 required: get_option('libudev'))
1389 mpathlibs = [libudev]
1390 mpathpersist = not_found
1391 if host_os == 'linux' and have_tools and get_option('mpath').allowed()
1392 mpath_test_source = '''
1393 #include <libudev.h>
1394 #include <mpath_persist.h>
1395 unsigned mpath_mx_alloc_len = 1024;
1397 static struct config *multipath_conf;
1398 extern struct udev *udev;
1399 extern struct config *get_multipath_config(void);
1400 extern void put_multipath_config(struct config *conf);
1402 struct config *get_multipath_config(void) { return multipath_conf; }
1403 void put_multipath_config(struct config *conf) { }
1406 multipath_conf = mpath_lib_init();
1409 libmpathpersist = cc.find_library('mpathpersist',
1410 required: get_option('mpath'))
1411 if libmpathpersist.found()
1412 mpathlibs += libmpathpersist
1413 if get_option('prefer_static')
1414 mpathlibs += cc.find_library('devmapper',
1415 required: get_option('mpath'))
1417 mpathlibs += cc.find_library('multipath',
1418 required: get_option('mpath'))
1419 foreach lib: mpathlibs
1425 if mpathlibs.length() == 0
1426 msg = 'Dependencies missing for libmpathpersist'
1427 elif cc.links(mpath_test_source, dependencies: mpathlibs)
1428 mpathpersist = declare_dependency(dependencies: mpathlibs)
1430 msg = 'Cannot detect libmpathpersist API'
1432 if not mpathpersist.found()
1433 if get_option('mpath').enabled()
1436 warning(msg + ', disabling')
1444 if have_system and get_option('curses').allowed()
1447 #define _XOPEN_SOURCE_EXTENDED 1
1454 setlocale(LC_ALL, "");
1456 addwstr(L"wide chars\n");
1458 add_wch(WACS_DEGREE);
1462 curses_dep_list = host_os == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
1463 curses = dependency(curses_dep_list,
1465 method: 'pkg-config')
1466 msg = get_option('curses').enabled() ? 'curses library not found' : ''
1467 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
1469 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
1470 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses],
1471 version: curses.version())
1473 msg = 'curses package not usable'
1477 if not curses.found()
1478 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1479 if host_os != 'windows' and not has_curses_h
1480 message('Trying with /usr/include/ncursesw')
1481 curses_compile_args += ['-I/usr/include/ncursesw']
1482 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1485 curses_libname_list = (host_os == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
1486 foreach curses_libname : curses_libname_list
1487 libcurses = cc.find_library(curses_libname,
1489 if libcurses.found()
1490 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
1491 curses = declare_dependency(compile_args: curses_compile_args,
1492 dependencies: [libcurses])
1495 msg = 'curses library not usable'
1501 if get_option('iconv').allowed()
1502 foreach link_args : [ ['-liconv'], [] ]
1503 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
1504 # We need to use libiconv if available because mixing libiconv's headers with
1505 # the system libc does not work.
1506 # However, without adding glib to the dependencies -L/usr/local/lib will not be
1507 # included in the command line and libiconv will not be found.
1511 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
1512 return conv != (iconv_t) -1;
1513 }''', args: link_args, dependencies: glib)
1514 iconv = declare_dependency(link_args: link_args, dependencies: glib)
1519 if curses.found() and not iconv.found()
1520 if get_option('iconv').enabled()
1521 error('iconv not available')
1523 msg = 'iconv required for curses UI but not available'
1526 if not curses.found() and msg != ''
1527 if get_option('curses').enabled()
1530 warning(msg + ', disabling')
1536 if not get_option('brlapi').auto() or have_system
1537 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
1538 required: get_option('brlapi'))
1539 if brlapi.found() and not cc.links('''
1542 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
1544 if get_option('brlapi').enabled()
1545 error('could not link brlapi')
1547 warning('could not link brlapi, disabling')
1553 if not get_option('sdl').auto() or have_system
1554 sdl = dependency('sdl2', required: get_option('sdl'))
1555 sdl_image = not_found
1558 # Some versions of SDL have problems with -Wundef
1559 if not cc.compiles('''
1561 #include <SDL_syswm.h>
1562 int main(int argc, char *argv[]) { return 0; }
1563 ''', dependencies: sdl, args: '-Werror=undef')
1564 sdl = declare_dependency(compile_args: '-Wno-undef',
1566 version: sdl.version())
1568 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
1569 method: 'pkg-config')
1571 if get_option('sdl_image').enabled()
1572 error('sdl-image required, but SDL was @0@'.format(
1573 get_option('sdl').disabled() ? 'disabled' : 'not found'))
1575 sdl_image = not_found
1579 if not get_option('rbd').auto() or have_block
1580 librados = cc.find_library('rados', required: get_option('rbd'))
1581 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
1582 required: get_option('rbd'))
1583 if librados.found() and librbd.found()
1586 #include <rbd/librbd.h>
1589 rados_create(&cluster, NULL);
1590 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
1594 }''', dependencies: [librbd, librados])
1595 rbd = declare_dependency(dependencies: [librbd, librados])
1596 elif get_option('rbd').enabled()
1597 error('librbd >= 1.12.0 required')
1599 warning('librbd >= 1.12.0 not found, disabling')
1604 glusterfs = not_found
1605 glusterfs_ftruncate_has_stat = false
1606 glusterfs_iocb_has_stat = false
1607 if not get_option('glusterfs').auto() or have_block
1608 glusterfs = dependency('glusterfs-api', version: '>=3',
1609 required: get_option('glusterfs'),
1610 method: 'pkg-config')
1611 if glusterfs.found()
1612 glusterfs_ftruncate_has_stat = cc.links('''
1613 #include <glusterfs/api/glfs.h>
1618 /* new glfs_ftruncate() passes two additional args */
1619 return glfs_ftruncate(NULL, 0, NULL, NULL);
1621 ''', dependencies: glusterfs)
1622 glusterfs_iocb_has_stat = cc.links('''
1623 #include <glusterfs/api/glfs.h>
1625 /* new glfs_io_cbk() passes two additional glfs_stat structs */
1627 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
1633 glfs_io_cbk iocb = &glusterfs_iocb;
1634 iocb(NULL, 0 , NULL, NULL, NULL);
1637 ''', dependencies: glusterfs)
1642 if get_option('hv_balloon').allowed() and have_system
1645 #include <gmodule.h>
1649 tree = g_tree_new((GCompareFunc)strcmp);
1650 (void)g_tree_node_first(tree);
1651 g_tree_destroy(tree);
1654 ''', dependencies: glib)
1657 if get_option('hv_balloon').enabled()
1658 error('could not enable hv-balloon, update your glib')
1660 warning('could not find glib support for hv-balloon, disabling')
1666 if not get_option('libssh').auto() or have_block
1667 libssh = dependency('libssh', version: '>=0.8.7',
1668 method: 'pkg-config',
1669 required: get_option('libssh'))
1672 libbzip2 = not_found
1673 if not get_option('bzip2').auto() or have_block
1674 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
1675 required: get_option('bzip2'))
1676 if libbzip2.found() and not cc.links('''
1678 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
1679 libbzip2 = not_found
1680 if get_option('bzip2').enabled()
1681 error('could not link libbzip2')
1683 warning('could not link libbzip2, disabling')
1688 liblzfse = not_found
1689 if not get_option('lzfse').auto() or have_block
1690 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
1691 required: get_option('lzfse'))
1693 if liblzfse.found() and not cc.links('''
1695 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
1696 liblzfse = not_found
1697 if get_option('lzfse').enabled()
1698 error('could not link liblzfse')
1700 warning('could not link liblzfse, disabling')
1705 if get_option('oss').allowed() and have_system
1706 if not cc.has_header('sys/soundcard.h')
1708 elif host_os == 'netbsd'
1709 oss = cc.find_library('ossaudio', required: get_option('oss'))
1711 oss = declare_dependency()
1715 if get_option('oss').enabled()
1716 error('OSS not found')
1721 if not get_option('dsound').auto() or (host_os == 'windows' and have_system)
1722 if cc.has_header('dsound.h')
1723 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
1726 if not dsound.found()
1727 if get_option('dsound').enabled()
1728 error('DirectSound not found')
1733 coreaudio = not_found
1734 if not get_option('coreaudio').auto() or (host_os == 'darwin' and have_system)
1735 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
1736 required: get_option('coreaudio'))
1740 if not get_option('opengl').auto() or have_system or have_vhost_user_gpu
1741 epoxy = dependency('epoxy', method: 'pkg-config',
1742 required: get_option('opengl'))
1743 if cc.has_header('epoxy/egl.h', dependencies: epoxy)
1745 elif get_option('opengl').enabled()
1746 error('epoxy/egl.h not found')
1750 if (have_system or have_tools) and (virgl.found() or opengl.found())
1751 gbm = dependency('gbm', method: 'pkg-config', required: false)
1753 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and opengl.found() and gbm.found()
1756 if not get_option('libcbor').auto() or have_system
1757 libcbor = dependency('libcbor', version: '>=0.7.0',
1758 required: get_option('libcbor'))
1762 gnutls_crypto = not_found
1763 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1764 # For general TLS support our min gnutls matches
1765 # that implied by our platform support matrix
1767 # For the crypto backends, we look for a newer
1770 # Version 3.6.8 is needed to get XTS
1771 # Version 3.6.13 is needed to get PBKDF
1772 # Version 3.6.14 is needed to get HW accelerated XTS
1774 # If newer enough gnutls isn't available, we can
1775 # still use a different crypto backend to satisfy
1776 # the platform support requirements
1777 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1778 method: 'pkg-config',
1780 if gnutls_crypto.found()
1781 gnutls = gnutls_crypto
1783 # Our min version if all we need is TLS
1784 gnutls = dependency('gnutls', version: '>=3.5.18',
1785 method: 'pkg-config',
1786 required: get_option('gnutls'))
1790 # We prefer use of gnutls for crypto, unless the options
1791 # explicitly asked for nettle or gcrypt.
1793 # If gnutls isn't available for crypto, then we'll prefer
1794 # gcrypt over nettle for performance reasons.
1798 crypto_sm4 = not_found
1799 crypto_sm3 = not_found
1802 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1803 error('Only one of gcrypt & nettle can be enabled')
1806 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1807 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1808 gnutls_crypto = not_found
1811 if not gnutls_crypto.found()
1812 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1813 gcrypt = dependency('libgcrypt', version: '>=1.8',
1814 required: get_option('gcrypt'))
1815 # Debian has removed -lgpg-error from libgcrypt-config
1816 # as it "spreads unnecessary dependencies" which in
1817 # turn breaks static builds...
1818 if gcrypt.found() and get_option('prefer_static')
1819 gcrypt = declare_dependency(dependencies:
1821 cc.find_library('gpg-error', required: true)],
1822 version: gcrypt.version())
1825 # SM4 ALG is available in libgcrypt >= 1.9
1826 if gcrypt.found() and not cc.links('''
1829 gcry_cipher_hd_t handler;
1830 gcry_cipher_open(&handler, GCRY_CIPHER_SM4, GCRY_CIPHER_MODE_ECB, 0);
1832 }''', dependencies: gcrypt)
1833 crypto_sm4 = not_found
1836 # SM3 ALG is available in libgcrypt >= 1.9
1837 if gcrypt.found() and not cc.links('''
1840 gcry_md_hd_t handler;
1841 gcry_md_open(&handler, GCRY_MD_SM3, 0);
1843 }''', dependencies: gcrypt)
1844 crypto_sm3 = not_found
1847 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1848 nettle = dependency('nettle', version: '>=3.4',
1849 method: 'pkg-config',
1850 required: get_option('nettle'))
1851 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1855 # SM4 ALG is available in nettle >= 3.9
1856 if nettle.found() and not cc.links('''
1857 #include <nettle/sm4.h>
1860 unsigned char key[16] = {0};
1861 sm4_set_encrypt_key(&ctx, key);
1863 }''', dependencies: nettle)
1864 crypto_sm4 = not_found
1867 # SM3 ALG is available in nettle >= 3.8
1868 if nettle.found() and not cc.links('''
1869 #include <nettle/sm3.h>
1870 #include <nettle/hmac.h>
1873 struct hmac_sm3_ctx hmac_ctx;
1874 unsigned char data[64] = {0};
1875 unsigned char output[32];
1877 // SM3 hash function test
1879 sm3_update(&ctx, 64, data);
1880 sm3_digest(&ctx, 32, data);
1883 hmac_sm3_set_key(&hmac_ctx, 32, data);
1884 hmac_sm3_update(&hmac_ctx, 64, data);
1885 hmac_sm3_digest(&hmac_ctx, 32, output);
1888 }''', dependencies: nettle)
1889 crypto_sm3 = not_found
1894 capstone = not_found
1895 if not get_option('capstone').auto() or have_system or have_user
1896 capstone = dependency('capstone', version: '>=3.0.5',
1897 method: 'pkg-config',
1898 required: get_option('capstone'))
1900 # Some versions of capstone have broken pkg-config file
1901 # that reports a wrong -I path, causing the #include to
1902 # fail later. If the system has such a broken version
1904 if capstone.found() and not cc.compiles('#include <capstone.h>',
1905 dependencies: [capstone])
1906 capstone = not_found
1907 if get_option('capstone').enabled()
1908 error('capstone requested, but it does not appear to work')
1913 gmp = dependency('gmp', required: false, method: 'pkg-config')
1914 if nettle.found() and gmp.found()
1915 hogweed = dependency('hogweed', version: '>=3.4',
1916 method: 'pkg-config',
1917 required: get_option('nettle'))
1924 have_gtk_clipboard = get_option('gtk_clipboard').enabled()
1926 if get_option('gtk') \
1927 .disable_auto_if(not have_system) \
1928 .require(pixman.found(),
1929 error_message: 'cannot enable GTK if pixman is not available') \
1931 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1932 method: 'pkg-config',
1933 required: get_option('gtk'))
1935 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1936 method: 'pkg-config',
1938 gtk = declare_dependency(dependencies: [gtk, gtkx11],
1939 version: gtk.version())
1941 if not get_option('vte').auto() or have_system
1942 vte = dependency('vte-2.91',
1943 method: 'pkg-config',
1944 required: get_option('vte'))
1946 elif have_gtk_clipboard
1947 error('GTK clipboard requested, but GTK not found')
1953 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found())
1956 if get_option('png').allowed() and have_system
1957 png = dependency('libpng', version: '>=1.6.34', required: get_option('png'),
1958 method: 'pkg-config')
1963 if get_option('vnc') \
1964 .disable_auto_if(not have_system) \
1965 .require(pixman.found(),
1966 error_message: 'cannot enable VNC if pixman is not available') \
1968 vnc = declare_dependency() # dummy dependency
1969 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1970 method: 'pkg-config')
1971 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1972 required: get_option('vnc_sasl'))
1974 sasl = declare_dependency(dependencies: sasl,
1975 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1980 if not get_option('auth_pam').auto() or have_system
1981 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1982 required: get_option('auth_pam'))
1984 if pam.found() and not cc.links('''
1986 #include <security/pam_appl.h>
1988 const char *service_name = "qemu";
1989 const char *user = "frank";
1990 const struct pam_conv pam_conv = { 0 };
1991 pam_handle_t *pamh = NULL;
1992 pam_start(service_name, user, &pam_conv, &pamh);
1994 }''', dependencies: pam)
1996 if get_option('auth_pam').enabled()
1997 error('could not link libpam')
1999 warning('could not link libpam, disabling')
2004 if not get_option('snappy').auto() or have_system
2005 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
2006 required: get_option('snappy'))
2008 if snappy.found() and not cc.links('''
2009 #include <snappy-c.h>
2010 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
2012 if get_option('snappy').enabled()
2013 error('could not link libsnappy')
2015 warning('could not link libsnappy, disabling')
2020 if not get_option('lzo').auto() or have_system
2021 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
2022 required: get_option('lzo'))
2024 if lzo.found() and not cc.links('''
2025 #include <lzo/lzo1x.h>
2026 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
2028 if get_option('lzo').enabled()
2029 error('could not link liblzo2')
2031 warning('could not link liblzo2, disabling')
2036 if not get_option('numa').auto() or have_system or have_tools
2037 numa = cc.find_library('numa', has_headers: ['numa.h'],
2038 required: get_option('numa'))
2040 if numa.found() and not cc.links('''
2042 int main(void) { return numa_available(); }
2043 ''', dependencies: numa)
2045 if get_option('numa').enabled()
2046 error('could not link numa')
2048 warning('could not link numa, disabling')
2053 fdt_opt = get_option('fdt')
2054 if fdt_opt == 'enabled' and get_option('wrap_mode') == 'nodownload'
2057 if fdt_opt in ['enabled', 'system'] or (fdt_opt == 'auto' and have_system)
2058 fdt = cc.find_library('fdt', required: fdt_opt == 'system')
2059 if fdt.found() and cc.links('''
2061 #include <libfdt_env.h>
2062 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2065 elif fdt_opt != 'system'
2066 fdt_opt = get_option('wrap_mode') == 'nodownload' ? 'disabled' : 'internal'
2069 error('system libfdt is too old (1.5.1 or newer required)')
2072 if fdt_opt == 'internal'
2073 assert(not fdt.found())
2074 libfdt_proj = subproject('dtc', required: true,
2075 default_options: ['tools=false', 'yaml=disabled',
2076 'python=disabled', 'default_library=static'])
2077 fdt = libfdt_proj.get_variable('libfdt_dep')
2081 if not get_option('rdma').auto() or have_system
2082 rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'],
2083 required: get_option('rdma')),
2084 cc.find_library('ibverbs', required: get_option('rdma'))]
2085 rdma = declare_dependency(dependencies: rdma_libs)
2086 foreach lib: rdma_libs
2094 if not get_option('smartcard').auto() or have_system
2095 cacard = dependency('libcacard', required: get_option('smartcard'),
2096 version: '>=2.5.1', method: 'pkg-config')
2099 if not get_option('u2f').auto() or have_system
2100 u2f = dependency('u2f-emu', required: get_option('u2f'),
2101 method: 'pkg-config')
2104 if not get_option('canokey').auto() or have_system
2105 canokey = dependency('canokey-qemu', required: get_option('canokey'),
2106 method: 'pkg-config')
2108 usbredir = not_found
2109 if not get_option('usb_redir').auto() or have_system
2110 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
2111 version: '>=0.6', method: 'pkg-config')
2114 if not get_option('libusb').auto() or have_system
2115 libusb = dependency('libusb-1.0', required: get_option('libusb'),
2116 version: '>=1.0.13', method: 'pkg-config')
2120 if not get_option('libpmem').auto() or have_system
2121 libpmem = dependency('libpmem', required: get_option('libpmem'),
2122 method: 'pkg-config')
2124 libdaxctl = not_found
2125 if not get_option('libdaxctl').auto() or have_system
2126 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
2127 version: '>=57', method: 'pkg-config')
2131 tasn1 = dependency('libtasn1',
2133 method: 'pkg-config')
2135 keyutils = not_found
2136 if not get_option('libkeyutils').auto() or have_block
2137 keyutils = dependency('libkeyutils', required: get_option('libkeyutils'),
2138 method: 'pkg-config')
2141 has_gettid = cc.has_function('gettid')
2144 selinux = dependency('libselinux',
2145 required: get_option('selinux'),
2146 method: 'pkg-config')
2151 if get_option('malloc') == 'system'
2153 get_option('malloc_trim').allowed() and \
2154 cc.has_function('malloc_trim', prefix: '#include <malloc.h>')
2156 has_malloc_trim = false
2157 malloc = cc.find_library(get_option('malloc'), required: true)
2159 if not has_malloc_trim and get_option('malloc_trim').enabled()
2160 if get_option('malloc') == 'system'
2161 error('malloc_trim not available on this platform.')
2163 error('malloc_trim not available with non-libc memory allocator')
2167 gnu_source_prefix = '''
2173 # Check whether the glibc provides STATX_BASIC_STATS
2175 has_statx = cc.has_header_symbol('sys/stat.h', 'STATX_BASIC_STATS', prefix: gnu_source_prefix)
2177 # Check whether statx() provides mount ID information
2179 has_statx_mnt_id = cc.has_header_symbol('sys/stat.h', 'STATX_MNT_ID', prefix: gnu_source_prefix)
2181 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
2182 .require(host_os == 'linux',
2183 error_message: 'vhost_user_blk_server requires linux') \
2184 .require(have_vhost_user,
2185 error_message: 'vhost_user_blk_server requires vhost-user support') \
2186 .disable_auto_if(not have_tools and not have_system) \
2189 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
2190 error('Cannot enable fuse-lseek while fuse is disabled')
2193 fuse = dependency('fuse3', required: get_option('fuse'),
2194 version: '>=3.1', method: 'pkg-config')
2196 fuse_lseek = not_found
2197 if get_option('fuse_lseek').allowed()
2198 if fuse.version().version_compare('>=3.8')
2200 fuse_lseek = declare_dependency()
2201 elif get_option('fuse_lseek').enabled()
2203 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
2205 error('fuse-lseek requires libfuse, which was not found')
2210 have_libvduse = (host_os == 'linux')
2211 if get_option('libvduse').enabled()
2212 if host_os != 'linux'
2213 error('libvduse requires linux')
2215 elif get_option('libvduse').disabled()
2216 have_libvduse = false
2219 have_vduse_blk_export = (have_libvduse and host_os == 'linux')
2220 if get_option('vduse_blk_export').enabled()
2221 if host_os != 'linux'
2222 error('vduse_blk_export requires linux')
2223 elif not have_libvduse
2224 error('vduse_blk_export requires libvduse support')
2226 elif get_option('vduse_blk_export').disabled()
2227 have_vduse_blk_export = false
2231 bpf_version = '1.1.0'
2232 libbpf = dependency('libbpf', version: '>=' + bpf_version, required: get_option('bpf'), method: 'pkg-config')
2233 if libbpf.found() and not cc.links('''
2234 #include <bpf/libbpf.h>
2235 #include <linux/bpf.h>
2238 // check flag availability
2239 int flag = BPF_F_MMAPABLE;
2240 bpf_object__destroy_skeleton(NULL);
2242 }''', dependencies: libbpf)
2244 if get_option('bpf').enabled()
2245 error('libbpf skeleton/mmaping test failed')
2247 warning('libbpf skeleton/mmaping test failed, disabling')
2253 if not get_option('af_xdp').auto() or have_system
2255 libxdp = dependency('libxdp', required: get_option('af_xdp'),
2256 version: '>=1.4.0', method: 'pkg-config')
2258 if get_option('af_xdp').enabled()
2259 error('libxdp requested, but libbpf is not available')
2266 if not get_option('libdw').auto() or \
2267 (not get_option('prefer_static') and (have_system or have_user))
2268 libdw = dependency('libdw',
2269 method: 'pkg-config',
2270 required: get_option('libdw'))
2277 config_host_data = configuration_data()
2279 config_host_data.set('CONFIG_HAVE_RUST', have_rust)
2280 audio_drivers_selected = []
2282 audio_drivers_available = {
2283 'alsa': alsa.found(),
2284 'coreaudio': coreaudio.found(),
2285 'dsound': dsound.found(),
2286 'jack': jack.found(),
2288 'pa': pulse.found(),
2289 'pipewire': pipewire.found(),
2291 'sndio': sndio.found(),
2293 foreach k, v: audio_drivers_available
2294 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
2297 # Default to native drivers first, OSS second, SDL third
2298 audio_drivers_priority = \
2299 [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \
2300 (host_os == 'linux' ? [] : [ 'sdl' ])
2301 audio_drivers_default = []
2302 foreach k: audio_drivers_priority
2303 if audio_drivers_available[k]
2304 audio_drivers_default += k
2308 foreach k: get_option('audio_drv_list')
2310 audio_drivers_selected += audio_drivers_default
2311 elif not audio_drivers_available[k]
2312 error('Audio driver "@0@" not available.'.format(k))
2314 audio_drivers_selected += k
2318 config_host_data.set('CONFIG_AUDIO_DRIVERS',
2319 '"' + '", "'.join(audio_drivers_selected) + '", ')
2321 have_host_block_device = (host_os != 'darwin' or
2322 cc.has_header('IOKit/storage/IOMedia.h'))
2324 dbus_display = get_option('dbus_display') \
2325 .require(gio.version().version_compare('>=2.64'),
2326 error_message: '-display dbus requires glib>=2.64') \
2327 .require(gdbus_codegen.found(),
2328 error_message: gdbus_codegen_error.format('-display dbus')) \
2331 have_virtfs = get_option('virtfs') \
2332 .require(host_os == 'linux' or host_os == 'darwin',
2333 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
2334 .require(host_os == 'linux' or cc.has_function('pthread_fchdir_np'),
2335 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
2336 .require(host_os == 'darwin' or libattr.found(),
2337 error_message: 'virtio-9p (virtfs) on Linux requires libattr-devel') \
2338 .disable_auto_if(not have_tools and not have_system) \
2341 qga_fsfreeze = false
2343 if host_os == 'linux'
2344 if cc.has_header_symbol('linux/fs.h', 'FIFREEZE')
2347 if cc.has_header_symbol('linux/fs.h', 'FITRIM')
2350 elif host_os == 'freebsd' and cc.has_header_symbol('ufs/ffs/fs.h', 'UFSSUSPEND')
2354 if get_option('block_drv_ro_whitelist') == ''
2355 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
2357 config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
2358 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
2360 if get_option('block_drv_rw_whitelist') == ''
2361 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
2363 config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
2364 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
2367 foreach k : get_option('trace_backends')
2368 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
2370 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
2371 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
2373 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
2375 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
2376 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
2377 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
2378 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
2379 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
2381 qemu_firmwarepath = ''
2382 foreach k : get_option('qemu_firmwarepath')
2383 qemu_firmwarepath += '"' + get_option('prefix') / k + '", '
2385 config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath)
2387 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
2388 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
2389 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
2390 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
2391 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
2392 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
2395 config_host_data.set('CONFIG_STAMP', run_command(
2396 meson.current_source_dir() / 'scripts/qemu-stamp.py',
2397 meson.project_version(), get_option('pkgversion'), '--',
2398 meson.current_source_dir() / 'configure',
2399 capture: true, check: true).stdout().strip())
2402 have_slirp_smbd = get_option('slirp_smbd') \
2403 .require(host_os != 'windows', error_message: 'Host smbd not supported on this platform.') \
2406 smbd_path = get_option('smbd')
2408 smbd_path = (host_os == 'sunos' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
2410 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
2413 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
2415 kvm_targets_c = '""'
2416 if get_option('kvm').allowed() and host_os == 'linux'
2417 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
2419 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
2421 if get_option('module_upgrades') and not enable_modules
2422 error('Cannot enable module-upgrades as modules are not enabled')
2424 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
2426 config_host_data.set('CONFIG_ATTR', libattr.found())
2427 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
2428 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
2429 config_host_data.set('CONFIG_BSD', host_os in bsd_oses)
2430 config_host_data.set('CONFIG_FREEBSD', host_os == 'freebsd')
2431 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2432 config_host_data.set('CONFIG_COCOA', cocoa.found())
2433 config_host_data.set('CONFIG_DARWIN', host_os == 'darwin')
2434 config_host_data.set('CONFIG_FDT', fdt.found())
2435 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
2436 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
2437 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
2438 config_host_data.set('CONFIG_LINUX', host_os == 'linux')
2439 config_host_data.set('CONFIG_POSIX', host_os != 'windows')
2440 config_host_data.set('CONFIG_WIN32', host_os == 'windows')
2441 config_host_data.set('CONFIG_LZO', lzo.found())
2442 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
2443 config_host_data.set('CONFIG_BLKIO', blkio.found())
2445 config_host_data.set('CONFIG_BLKIO_VHOST_VDPA_FD',
2446 blkio.version().version_compare('>=1.3.0'))
2447 config_host_data.set('CONFIG_BLKIO_WRITE_ZEROS_FUA',
2448 blkio.version().version_compare('>=1.4.0'))
2450 config_host_data.set('CONFIG_CURL', curl.found())
2451 config_host_data.set('CONFIG_CURSES', curses.found())
2452 config_host_data.set('CONFIG_GBM', gbm.found())
2453 config_host_data.set('CONFIG_GIO', gio.found())
2454 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
2455 if glusterfs.found()
2456 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
2457 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
2458 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
2459 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
2460 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
2461 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
2463 config_host_data.set('CONFIG_GTK', gtk.found())
2464 config_host_data.set('CONFIG_VTE', vte.found())
2465 config_host_data.set('CONFIG_GTK_CLIPBOARD', have_gtk_clipboard)
2466 config_host_data.set('CONFIG_HEXAGON_IDEF_PARSER', get_option('hexagon_idef_parser'))
2467 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
2468 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
2469 config_host_data.set('CONFIG_EBPF', libbpf.found())
2470 config_host_data.set('CONFIG_AF_XDP', libxdp.found())
2471 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
2472 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
2473 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
2474 config_host_data.set('CONFIG_LIBSSH', libssh.found())
2475 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
2476 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
2477 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
2478 config_host_data.set('CONFIG_MODULES', enable_modules)
2479 config_host_data.set('CONFIG_NUMA', numa.found())
2481 config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY',
2482 cc.has_function('numa_has_preferred_many',
2483 dependencies: numa))
2485 config_host_data.set('CONFIG_OPENGL', opengl.found())
2486 config_host_data.set('CONFIG_PLUGIN', get_option('plugins'))
2487 config_host_data.set('CONFIG_RBD', rbd.found())
2488 config_host_data.set('CONFIG_RDMA', rdma.found())
2489 config_host_data.set('CONFIG_RELOCATABLE', get_option('relocatable'))
2490 config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack'))
2491 config_host_data.set('CONFIG_SDL', sdl.found())
2492 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
2493 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
2495 config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc)
2497 config_host_data.set('CONFIG_PIXMAN', pixman.found())
2498 config_host_data.set('CONFIG_SLIRP', slirp.found())
2499 config_host_data.set('CONFIG_SNAPPY', snappy.found())
2500 config_host_data.set('CONFIG_SOLARIS', host_os == 'sunos')
2501 if get_option('tcg').allowed()
2502 config_host_data.set('CONFIG_TCG', 1)
2503 config_host_data.set('CONFIG_TCG_INTERPRETER', tcg_arch == 'tci')
2505 config_host_data.set('CONFIG_TPM', have_tpm)
2506 config_host_data.set('CONFIG_TSAN', get_option('tsan'))
2507 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
2508 config_host_data.set('CONFIG_VDE', vde.found())
2509 config_host_data.set('CONFIG_VHOST', have_vhost)
2510 config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
2511 config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
2512 config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)
2513 config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
2514 config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
2515 config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
2516 config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
2517 config_host_data.set('CONFIG_VMNET', vmnet.found())
2518 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
2519 config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export)
2520 config_host_data.set('CONFIG_PNG', png.found())
2521 config_host_data.set('CONFIG_VNC', vnc.found())
2522 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
2523 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
2525 config_host_data.set('VIRGL_VERSION_MAJOR', virgl.version().split('.')[0])
2527 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
2528 config_host_data.set('CONFIG_VTE', vte.found())
2529 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
2530 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
2531 config_host_data.set('CONFIG_GETTID', has_gettid)
2532 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
2533 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
2534 config_host_data.set('CONFIG_TASN1', tasn1.found())
2535 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
2536 config_host_data.set('CONFIG_NETTLE', nettle.found())
2537 config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found())
2538 config_host_data.set('CONFIG_CRYPTO_SM3', crypto_sm3.found())
2539 config_host_data.set('CONFIG_HOGWEED', hogweed.found())
2540 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
2541 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
2542 config_host_data.set('CONFIG_STATX', has_statx)
2543 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
2544 config_host_data.set('CONFIG_ZSTD', zstd.found())
2545 config_host_data.set('CONFIG_QPL', qpl.found())
2546 config_host_data.set('CONFIG_UADK', uadk.found())
2547 config_host_data.set('CONFIG_QATZIP', qatzip.found())
2548 config_host_data.set('CONFIG_FUSE', fuse.found())
2549 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
2550 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
2551 if spice_protocol.found()
2552 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
2553 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
2554 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
2556 config_host_data.set('CONFIG_SPICE', spice.found())
2557 config_host_data.set('CONFIG_X11', x11.found())
2558 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
2559 config_host_data.set('CONFIG_CFI', get_option('cfi'))
2560 config_host_data.set('CONFIG_SELINUX', selinux.found())
2561 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
2562 config_host_data.set('CONFIG_LIBDW', libdw.found())
2564 # protect from xen.version() having less than three components
2565 xen_version = xen.version().split('.') + ['0', '0']
2566 xen_ctrl_version = xen_version[0] + \
2567 ('0' + xen_version[1]).substring(-2) + \
2568 ('0' + xen_version[2]).substring(-2)
2569 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
2571 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
2572 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
2573 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
2574 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
2576 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
2577 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
2579 have_coroutine_pool = get_option('coroutine_pool')
2580 if get_option('debug_stack_usage') and have_coroutine_pool
2581 message('Disabling coroutine pool to measure stack usage')
2582 have_coroutine_pool = false
2584 config_host_data.set('CONFIG_COROUTINE_POOL', have_coroutine_pool)
2585 config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock'))
2586 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
2587 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
2588 config_host_data.set('CONFIG_DEBUG_TCG', get_option('debug_tcg'))
2589 config_host_data.set('CONFIG_DEBUG_REMAP', get_option('debug_remap'))
2590 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
2591 config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
2592 config_host_data.set('CONFIG_FSFREEZE', qga_fsfreeze)
2593 config_host_data.set('CONFIG_FSTRIM', qga_fstrim)
2596 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
2597 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
2598 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
2599 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
2600 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
2601 config_host_data.set('HAVE_OPENAT2_H', cc.has_header('linux/openat2.h'))
2602 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
2603 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
2604 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
2605 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
2606 if host_os == 'windows'
2607 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h'))
2611 config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range'))
2612 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
2613 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
2614 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
2615 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
2616 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
2617 config_host_data.set('CONFIG_GETCPU', cc.has_function('getcpu', prefix: gnu_source_prefix))
2618 config_host_data.set('CONFIG_SCHED_GETCPU', cc.has_function('sched_getcpu', prefix: '#include <sched.h>'))
2619 # Note that we need to specify prefix: here to avoid incorrectly
2620 # thinking that Windows has posix_memalign()
2621 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
2622 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
2623 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
2624 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
2625 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
2626 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
2627 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
2628 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
2629 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
2630 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
2631 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
2632 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
2633 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
2634 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
2635 config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice)
2636 config_host_data.set('HAVE_GLIB_WITH_ALIGNED_ALLOC', glib_has_aligned_alloc)
2637 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
2638 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
2639 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
2641 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
2642 cc.has_function('rbd_namespace_exists',
2644 prefix: '#include <rbd/librbd.h>'))
2647 config_host_data.set('HAVE_IBV_ADVISE_MR',
2648 cc.has_function('ibv_advise_mr',
2650 prefix: '#include <infiniband/verbs.h>'))
2653 have_asan_fiber = false
2654 if get_option('asan') and \
2655 not cc.has_function('__sanitizer_start_switch_fiber',
2656 args: '-fsanitize=address',
2657 prefix: '#include <sanitizer/asan_interface.h>')
2658 warning('Missing ASAN due to missing fiber annotation interface')
2659 warning('Without code annotation, the report may be inferior.')
2661 have_asan_fiber = true
2663 config_host_data.set('CONFIG_ASAN_IFACE_FIBER', have_asan_fiber)
2665 have_inotify_init = cc.has_header_symbol('sys/inotify.h', 'inotify_init')
2666 have_inotify_init1 = cc.has_header_symbol('sys/inotify.h', 'inotify_init1')
2668 if (have_inotify_init or have_inotify_init1) and host_os == 'freebsd'
2670 inotify = cc.find_library('inotify')
2671 if have_inotify_init
2672 have_inotify_init = inotify.found()
2674 if have_inotify_init1
2675 have_inotify_init1 = inotify.found()
2678 config_host_data.set('CONFIG_INOTIFY', have_inotify_init)
2679 config_host_data.set('CONFIG_INOTIFY1', have_inotify_init1)
2682 config_host_data.set('CONFIG_BLKZONED',
2683 cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE'))
2684 config_host_data.set('CONFIG_EPOLL_CREATE1',
2685 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
2686 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
2687 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
2688 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
2689 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
2690 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
2691 config_host_data.set('CONFIG_FIEMAP',
2692 cc.has_header('linux/fiemap.h') and
2693 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
2694 config_host_data.set('CONFIG_GETRANDOM',
2695 cc.has_function('getrandom') and
2696 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
2697 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
2698 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
2699 config_host_data.set('CONFIG_RTNETLINK',
2700 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
2701 config_host_data.set('CONFIG_SYSMACROS',
2702 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
2703 config_host_data.set('HAVE_OPTRESET',
2704 cc.has_header_symbol('getopt.h', 'optreset'))
2705 config_host_data.set('HAVE_IPPROTO_MPTCP',
2706 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
2709 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
2710 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
2711 prefix: '#include <signal.h>'))
2712 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
2713 cc.has_member('struct stat', 'st_atim',
2714 prefix: '#include <sys/stat.h>'))
2715 config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY',
2716 cc.has_member('struct blk_zone', 'capacity',
2717 prefix: '#include <linux/blkzoned.h>'))
2720 config_host_data.set('CONFIG_IOVEC',
2721 cc.has_type('struct iovec',
2722 prefix: '#include <sys/uio.h>'))
2723 config_host_data.set('HAVE_UTMPX',
2724 cc.has_type('struct utmpx',
2725 prefix: '#include <utmpx.h>'))
2727 config_host_data.set('CONFIG_EVENTFD', cc.links('''
2728 #include <sys/eventfd.h>
2729 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
2730 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
2733 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
2734 return fdatasync(0);
2736 #error Not supported
2740 has_madvise = cc.links(gnu_source_prefix + '''
2741 #include <sys/types.h>
2742 #include <sys/mman.h>
2744 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
2745 missing_madvise_proto = false
2747 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
2748 # but forget to prototype it. In this case, has_madvise will be true (the
2749 # test program links despite a compile warning). To detect the
2750 # missing-prototype case, we try again with a definitely-bogus prototype.
2751 # This will only compile if the system headers don't provide the prototype;
2752 # otherwise the conflicting prototypes will cause a compiler error.
2753 missing_madvise_proto = cc.links(gnu_source_prefix + '''
2754 #include <sys/types.h>
2755 #include <sys/mman.h>
2757 extern int madvise(int);
2758 int main(void) { return madvise(0); }''')
2760 config_host_data.set('CONFIG_MADVISE', has_madvise)
2761 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
2763 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
2764 #include <sys/mman.h>
2765 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
2766 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
2768 #if !defined(AT_EMPTY_PATH)
2769 # error missing definition
2771 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
2774 # On Darwin posix_madvise() has the same return semantics as plain madvise(),
2775 # i.e. errno is set and -1 is returned. That's not really how POSIX defines the
2776 # function. On the flip side, it has madvise() which is preferred anyways.
2777 if host_os != 'darwin'
2778 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
2779 #include <sys/mman.h>
2781 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
2784 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
2785 #include <pthread.h>
2787 static void *f(void *p) { return NULL; }
2791 pthread_create(&thread, 0, f, 0);
2792 pthread_setname_np(thread, "QEMU");
2794 }''', dependencies: threads))
2795 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
2796 #include <pthread.h>
2798 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
2802 pthread_create(&thread, 0, f, 0);
2804 }''', dependencies: threads))
2805 config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(gnu_source_prefix + '''
2806 #include <pthread.h>
2807 #include <pthread_np.h>
2809 static void *f(void *p) { return NULL; }
2813 pthread_create(&thread, 0, f, 0);
2814 pthread_set_name_np(thread, "QEMU");
2816 }''', dependencies: threads))
2817 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
2818 #include <pthread.h>
2823 pthread_condattr_t attr
2824 pthread_condattr_init(&attr);
2825 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
2827 }''', dependencies: threads))
2828 config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(gnu_source_prefix + '''
2829 #include <pthread.h>
2831 static void *f(void *p) { return NULL; }
2834 int setsize = CPU_ALLOC_SIZE(64);
2837 pthread_create(&thread, 0, f, 0);
2838 cpuset = CPU_ALLOC(64);
2839 CPU_ZERO_S(setsize, cpuset);
2840 pthread_setaffinity_np(thread, setsize, cpuset);
2841 pthread_getaffinity_np(thread, setsize, cpuset);
2844 }''', dependencies: threads))
2845 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
2846 #include <sys/signalfd.h>
2848 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
2849 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
2857 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
2858 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
2862 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
2863 #include <sys/mman.h>
2865 return mlockall(MCL_FUTURE);
2869 if get_option('l2tpv3').allowed() and have_system
2870 have_l2tpv3 = cc.has_type('struct mmsghdr',
2871 prefix: gnu_source_prefix + '''
2872 #include <sys/socket.h>
2873 #include <linux/ip.h>''')
2875 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2878 if get_option('netmap').allowed() and have_system
2879 have_netmap = cc.compiles('''
2880 #include <inttypes.h>
2882 #include <net/netmap.h>
2883 #include <net/netmap_user.h>
2884 #if (NETMAP_API < 11) || (NETMAP_API > 15)
2887 int main(void) { return 0; }''')
2888 if not have_netmap and get_option('netmap').enabled()
2889 error('Netmap headers not available')
2892 config_host_data.set('CONFIG_NETMAP', have_netmap)
2894 # Work around a system header bug with some kernel/XFS header
2895 # versions where they both try to define 'struct fsxattr':
2896 # xfs headers will not try to redefine structs from linux headers
2897 # if this macro is set.
2898 config_host_data.set('HAVE_FSXATTR', cc.links('''
2899 #include <linux/fs.h>
2905 # Some versions of Mac OS X incorrectly define SIZE_MAX
2906 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2910 return printf("%zu", SIZE_MAX);
2911 }''', args: ['-Werror']))
2913 # See if 64-bit atomic operations are supported.
2914 # Note that without __atomic builtins, we can only
2915 # assume atomic loads/stores max at pointer size.
2916 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
2920 uint64_t x = 0, y = 0;
2921 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2922 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2923 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2924 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2925 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2927 }''', args: qemu_isa_flags))
2929 has_int128_type = cc.compiles('''
2932 int main(void) { b = a; }''')
2933 config_host_data.set('CONFIG_INT128_TYPE', has_int128_type)
2935 has_int128 = has_int128_type and cc.links('''
2944 config_host_data.set('CONFIG_INT128', has_int128)
2947 # "do we have 128-bit atomics which are handled inline and specifically not
2948 # via libatomic". The reason we can't use libatomic is documented in the
2949 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2950 # We only care about these operations on 16-byte aligned pointers, so
2951 # force 16-byte alignment of the pointer, which may be greater than
2952 # __alignof(unsigned __int128) for the host.
2953 atomic_test_128 = '''
2954 int main(int ac, char **av) {
2955 __uint128_t *p = __builtin_assume_aligned(av[ac - 1], 16);
2956 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED);
2957 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED);
2958 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2961 has_atomic128 = cc.links(atomic_test_128, args: qemu_isa_flags)
2963 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2965 if not has_atomic128
2966 # Even with __builtin_assume_aligned, the above test may have failed
2967 # without optimization enabled. Try again with optimizations locally
2968 # enabled for the function. See
2969 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389
2970 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128,
2971 args: qemu_isa_flags)
2972 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt)
2974 if not has_atomic128_opt
2975 config_host_data.set('CONFIG_CMPXCHG128', cc.links('''
2978 __uint128_t x = 0, y = 0;
2979 __sync_val_compare_and_swap_16(&x, y, x);
2982 ''', args: qemu_isa_flags))
2987 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2988 #include <sys/auxv.h>
2990 return getauxval(AT_HWCAP) == 0;
2993 config_host_data.set('CONFIG_ELF_AUX_INFO', cc.links(gnu_source_prefix + '''
2994 #include <sys/auxv.h>
2996 unsigned long hwcap = 0;
2997 elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap));
3001 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
3002 #include <linux/usbdevice_fs.h>
3004 #ifndef USBDEVFS_GET_CAPABILITIES
3005 #error "USBDEVFS_GET_CAPABILITIES undefined"
3008 #ifndef USBDEVFS_DISCONNECT_CLAIM
3009 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
3012 int main(void) { return 0; }'''))
3014 have_keyring = get_option('keyring') \
3015 .require(host_os == 'linux', error_message: 'keyring is only available on Linux') \
3016 .require(cc.compiles('''
3018 #include <asm/unistd.h>
3019 #include <linux/keyctl.h>
3020 #include <sys/syscall.h>
3023 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
3024 }'''), error_message: 'keyctl syscall not available on this system').allowed()
3025 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
3027 have_cpuid_h = cc.links('''
3030 unsigned a, b, c, d;
3031 unsigned max = __get_cpuid_max(0, 0);
3034 __cpuid(1, a, b, c, d);
3038 __cpuid_count(7, 0, a, b, c, d);
3043 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
3045 # Don't bother to advertise asm/hwprobe.h for old versions that do
3046 # not contain RISCV_HWPROBE_EXT_ZBA.
3047 config_host_data.set('CONFIG_ASM_HWPROBE_H',
3048 cc.has_header_symbol('asm/hwprobe.h',
3049 'RISCV_HWPROBE_EXT_ZBA'))
3051 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
3052 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
3053 .require(cc.links('''
3055 #include <immintrin.h>
3056 static int __attribute__((target("avx2"))) bar(void *a) {
3057 __m256i x = *(__m256i *)a;
3058 return _mm256_testz_si256(x, x);
3060 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
3061 '''), error_message: 'AVX2 not available').allowed())
3063 config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \
3064 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \
3065 .require(cc.links('''
3067 #include <immintrin.h>
3068 static int __attribute__((target("avx512bw"))) bar(void *a) {
3070 __m512i res= _mm512_abs_epi8(*x);
3073 int main(int argc, char *argv[]) { return bar(argv[0]); }
3074 '''), error_message: 'AVX512BW not available').allowed())
3076 # For both AArch64 and AArch32, detect if builtins are available.
3077 config_host_data.set('CONFIG_ARM_AES_BUILTIN', cc.compiles('''
3078 #include <arm_neon.h>
3079 #ifndef __ARM_FEATURE_AES
3080 __attribute__((target("+crypto")))
3082 void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); }
3085 if get_option('membarrier').disabled()
3086 have_membarrier = false
3087 elif host_os == 'windows'
3088 have_membarrier = true
3089 elif host_os == 'linux'
3090 have_membarrier = cc.compiles('''
3091 #include <linux/membarrier.h>
3092 #include <sys/syscall.h>
3096 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
3097 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
3101 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
3102 .require(have_membarrier, error_message: 'membarrier system call not available') \
3105 have_afalg = get_option('crypto_afalg') \
3106 .require(cc.compiles(gnu_source_prefix + '''
3108 #include <sys/types.h>
3109 #include <sys/socket.h>
3110 #include <linux/if_alg.h>
3113 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
3116 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
3117 config_host_data.set('CONFIG_AF_ALG', have_afalg)
3119 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
3120 'linux/vm_sockets.h', 'AF_VSOCK',
3121 prefix: '#include <sys/socket.h>',
3125 have_vss_sdk = false # old xp/2003 SDK
3126 if host_os == 'windows' and 'cpp' in all_languages
3127 have_vss = cxx.compiles('''
3128 #define __MIDL_user_allocate_free_DEFINED__
3130 int main(void) { return VSS_CTX_BACKUP; }''')
3131 have_vss_sdk = cxx.has_header('vscoordint.h')
3133 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
3135 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
3136 # This was fixed for v6.0.0 with commit b48e3ac8969d.
3137 if host_os == 'windows'
3138 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
3144 }''', name: '_lock_file and _unlock_file'))
3147 if host_os == 'windows'
3148 mingw_has_setjmp_longjmp = cc.links('''
3152 * These functions are not available in setjmp header, but may be
3153 * available at link time, from libmingwex.a.
3155 extern int __mingw_setjmp(jmp_buf);
3156 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
3158 __mingw_setjmp(env);
3159 __mingw_longjmp(env, 0);
3161 ''', name: 'mingw setjmp and longjmp')
3163 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp
3164 error('mingw must provide setjmp/longjmp for windows-arm64')
3168 ########################
3169 # Target configuration #
3170 ########################
3172 minikconf = find_program('scripts/minikconf.py')
3174 config_all_accel = {}
3175 config_all_devices = {}
3176 config_devices_mak_list = []
3177 config_devices_h = {}
3178 config_target_h = {}
3179 config_target_mak = {}
3182 'alpha' : ['CONFIG_ALPHA_DIS'],
3183 'avr' : ['CONFIG_AVR_DIS'],
3184 'hexagon' : ['CONFIG_HEXAGON_DIS'],
3185 'hppa' : ['CONFIG_HPPA_DIS'],
3186 'i386' : ['CONFIG_I386_DIS'],
3187 'x86_64' : ['CONFIG_I386_DIS'],
3188 'm68k' : ['CONFIG_M68K_DIS'],
3189 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
3190 'mips' : ['CONFIG_MIPS_DIS'],
3191 'or1k' : ['CONFIG_OPENRISC_DIS'],
3192 'ppc' : ['CONFIG_PPC_DIS'],
3193 'riscv' : ['CONFIG_RISCV_DIS'],
3194 'rx' : ['CONFIG_RX_DIS'],
3195 's390' : ['CONFIG_S390_DIS'],
3196 'sh4' : ['CONFIG_SH4_DIS'],
3197 'sparc' : ['CONFIG_SPARC_DIS'],
3198 'xtensa' : ['CONFIG_XTENSA_DIS'],
3199 'loongarch' : ['CONFIG_LOONGARCH_DIS'],
3202 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
3204 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
3205 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
3206 (pixman.found() ? ['CONFIG_PIXMAN=y'] : []) + \
3207 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
3208 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
3209 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
3210 (libcbor.found() ? ['CONFIG_LIBCBOR=y'] : []) + \
3211 (gnutls.found() ? ['CONFIG_GNUTLS=y'] : []) + \
3212 (x11.found() ? ['CONFIG_X11=y'] : []) + \
3213 (fdt.found() ? ['CONFIG_FDT=y'] : []) + \
3214 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
3215 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
3216 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
3217 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
3218 (host_os == 'linux' ? ['CONFIG_LINUX=y'] : []) + \
3219 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
3220 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \
3221 (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : []) + \
3222 (have_rust ? ['CONFIG_HAVE_RUST=y'] : [])
3224 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
3226 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
3227 actual_target_dirs = []
3229 foreach target : target_dirs
3230 config_target = { 'TARGET_NAME': target.split('-')[0] }
3231 if target.endswith('linux-user')
3232 if host_os != 'linux'
3236 error('Target @0@ is only available on a Linux host'.format(target))
3238 config_target += { 'CONFIG_LINUX_USER': 'y' }
3239 elif target.endswith('bsd-user')
3240 if host_os not in bsd_oses
3244 error('Target @0@ is only available on a BSD host'.format(target))
3246 config_target += { 'CONFIG_BSD_USER': 'y' }
3247 elif target.endswith('softmmu')
3248 config_target += { 'CONFIG_SYSTEM_ONLY': 'y' }
3249 config_target += { 'CONFIG_SOFTMMU': 'y' }
3251 if target.endswith('-user')
3253 'CONFIG_USER_ONLY': 'y',
3254 'CONFIG_QEMU_INTERP_PREFIX':
3255 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME']),
3256 'CONFIG_QEMU_RTSIG_MAP': get_option('rtsig_map'),
3261 foreach sym: accelerators
3262 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
3263 config_target += { sym: 'y' }
3264 config_all_accel += { sym: 'y' }
3265 if target in modular_tcg
3266 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
3268 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
3270 target_kconfig += [ sym + '=y' ]
3273 if target_kconfig.length() == 0
3277 error('No accelerator available for target @0@'.format(target))
3280 config_target += keyval.load('configs/targets' / target + '.mak')
3281 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
3283 if 'TARGET_NEED_FDT' in config_target and not fdt.found()
3285 warning('Disabling ' + target + ' due to missing libfdt')
3287 fdt_required += target
3292 actual_target_dirs += target
3295 if 'TARGET_BASE_ARCH' not in config_target
3296 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
3298 if 'TARGET_ABI_DIR' not in config_target
3299 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
3301 if 'TARGET_BIG_ENDIAN' not in config_target
3302 config_target += {'TARGET_BIG_ENDIAN': 'n'}
3305 foreach k, v: disassemblers
3306 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
3308 config_target += { sym: 'y' }
3313 config_target_data = configuration_data()
3314 foreach k, v: config_target
3315 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
3317 elif ignored.contains(k)
3319 elif k == 'TARGET_BASE_ARCH'
3320 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
3321 # not used to select files from sourcesets.
3322 config_target_data.set('TARGET_' + v.to_upper(), 1)
3323 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
3324 config_target_data.set_quoted(k, v)
3326 config_target_data.set(k, 1)
3328 config_target_data.set(k, 0)
3330 config_target_data.set(k, v)
3333 config_target_data.set('QEMU_ARCH',
3334 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
3335 config_target_h += {target: configure_file(output: target + '-config-target.h',
3336 configuration: config_target_data)}
3338 if target.endswith('-softmmu')
3339 target_kconfig += 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'
3340 target_kconfig += 'CONFIG_TARGET_BIG_ENDIAN=' + config_target['TARGET_BIG_ENDIAN']
3342 config_input = meson.get_external_property(target, 'default')
3343 config_devices_mak = target + '-config-devices.mak'
3344 config_devices_mak = configure_file(
3345 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
3346 output: config_devices_mak,
3347 depfile: config_devices_mak + '.d',
3349 command: [minikconf,
3350 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
3351 config_devices_mak, '@DEPFILE@', '@INPUT@',
3352 host_kconfig, target_kconfig])
3354 config_devices_data = configuration_data()
3355 config_devices = keyval.load(config_devices_mak)
3356 foreach k, v: config_devices
3357 config_devices_data.set(k, 1)
3359 config_devices_mak_list += config_devices_mak
3360 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
3361 configuration: config_devices_data)}
3362 config_target += config_devices
3363 config_all_devices += config_devices
3365 config_target_mak += {target: config_target}
3367 target_dirs = actual_target_dirs
3369 target_configs_h = []
3370 foreach target: target_dirs
3371 target_configs_h += config_target_h[target]
3372 target_configs_h += config_devices_h.get(target, [])
3374 genh += custom_target('config-poison.h',
3375 input: [target_configs_h],
3376 output: 'config-poison.h',
3378 command: [find_program('scripts/make-config-poison.sh'),
3381 if fdt_required.length() > 0
3382 error('fdt disabled but required by targets ' + ', '.join(fdt_required))
3389 libvfio_user_dep = not_found
3390 if have_system and vfio_user_server_allowed
3391 libvfio_user_proj = subproject('libvfio-user', required: true)
3392 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep')
3395 vhost_user = not_found
3396 if host_os == 'linux' and have_vhost_user
3397 libvhost_user = subproject('libvhost-user')
3398 vhost_user = libvhost_user.get_variable('vhost_user_dep')
3401 libvduse = not_found
3403 libvduse_proj = subproject('libvduse')
3404 libvduse = libvduse_proj.get_variable('libvduse_dep')
3407 #####################
3408 # Generated sources #
3409 #####################
3411 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
3414 rustc_args = run_command(
3415 find_program('scripts/rust/rustc_args.py'),
3416 '--config-headers', meson.project_build_root() / 'config-host.h',
3418 check: true).stdout().strip().split()
3420 # Prohibit code that is forbidden in Rust 2024
3421 rustc_args += ['-D', 'unsafe_op_in_unsafe_fn']
3423 # Occasionally, we may need to silence warnings and clippy lints that
3424 # were only introduced in newer Rust compiler versions. Do not croak
3425 # in that case; a CI job with rust_strict_lints == true ensures that
3426 # we do not have misspelled allow() attributes.
3427 if not get_option('strict_rust_lints')
3428 rustc_args += ['-A', 'unknown_lints']
3431 # Apart from procedural macros, our Rust executables will often link
3432 # with C code, so include all the libraries that C code needs. This
3433 # is safe; https://github.com/rust-lang/rust/pull/54675 says that
3434 # passing -nodefaultlibs to the linker "was more ideological to
3435 # start with than anything".
3436 add_project_arguments(rustc_args + ['-C', 'default-linker-libraries'],
3437 native: false, language: 'rust')
3439 add_project_arguments(rustc_args, native: true, language: 'rust')
3442 hxtool = find_program('scripts/hxtool')
3443 shaderinclude = find_program('scripts/shaderinclude.py')
3444 qapi_gen = find_program('scripts/qapi-gen.py')
3445 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
3446 meson.current_source_dir() / 'scripts/qapi/commands.py',
3447 meson.current_source_dir() / 'scripts/qapi/common.py',
3448 meson.current_source_dir() / 'scripts/qapi/error.py',
3449 meson.current_source_dir() / 'scripts/qapi/events.py',
3450 meson.current_source_dir() / 'scripts/qapi/expr.py',
3451 meson.current_source_dir() / 'scripts/qapi/gen.py',
3452 meson.current_source_dir() / 'scripts/qapi/introspect.py',
3453 meson.current_source_dir() / 'scripts/qapi/main.py',
3454 meson.current_source_dir() / 'scripts/qapi/parser.py',
3455 meson.current_source_dir() / 'scripts/qapi/schema.py',
3456 meson.current_source_dir() / 'scripts/qapi/source.py',
3457 meson.current_source_dir() / 'scripts/qapi/types.py',
3458 meson.current_source_dir() / 'scripts/qapi/visit.py',
3459 meson.current_source_dir() / 'scripts/qapi-gen.py'
3463 python, files('scripts/tracetool.py'),
3464 '--backend=' + ','.join(get_option('trace_backends'))
3466 tracetool_depends = files(
3467 'scripts/tracetool/backend/log.py',
3468 'scripts/tracetool/backend/__init__.py',
3469 'scripts/tracetool/backend/dtrace.py',
3470 'scripts/tracetool/backend/ftrace.py',
3471 'scripts/tracetool/backend/simple.py',
3472 'scripts/tracetool/backend/syslog.py',
3473 'scripts/tracetool/backend/ust.py',
3474 'scripts/tracetool/format/ust_events_c.py',
3475 'scripts/tracetool/format/ust_events_h.py',
3476 'scripts/tracetool/format/__init__.py',
3477 'scripts/tracetool/format/d.py',
3478 'scripts/tracetool/format/simpletrace_stap.py',
3479 'scripts/tracetool/format/c.py',
3480 'scripts/tracetool/format/h.py',
3481 'scripts/tracetool/format/log_stap.py',
3482 'scripts/tracetool/format/stap.py',
3483 'scripts/tracetool/__init__.py',
3486 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
3487 meson.current_source_dir(),
3488 get_option('pkgversion'), meson.project_version()]
3489 qemu_version = custom_target('qemu-version.h',
3490 output: 'qemu-version.h',
3491 command: qemu_version_cmd,
3493 build_by_default: true,
3494 build_always_stale: true)
3495 genh += qemu_version
3499 ['qemu-options.hx', 'qemu-options.def'],
3500 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
3504 ['hmp-commands.hx', 'hmp-commands.h'],
3505 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
3508 foreach d : hx_headers
3509 hxdep += custom_target(d[1],
3513 command: [hxtool, '-h', '@INPUT0@'])
3521 # TODO: add each directory to the subdirs from its own meson.build, once
3523 trace_events_subdirs = [
3532 trace_events_subdirs += [ 'linux-user' ]
3535 trace_events_subdirs += [ 'bsd-user' ]
3538 trace_events_subdirs += [
3548 trace_events_subdirs += [
3612 if have_system or have_user
3613 trace_events_subdirs += [
3635 authz_ss = ss.source_set()
3636 blockdev_ss = ss.source_set()
3637 block_ss = ss.source_set()
3638 chardev_ss = ss.source_set()
3639 common_ss = ss.source_set()
3640 crypto_ss = ss.source_set()
3641 hwcore_ss = ss.source_set()
3642 io_ss = ss.source_set()
3643 qmp_ss = ss.source_set()
3644 qom_ss = ss.source_set()
3645 system_ss = ss.source_set()
3646 specific_fuzz_ss = ss.source_set()
3647 specific_ss = ss.source_set()
3648 rust_devices_ss = ss.source_set()
3649 stub_ss = ss.source_set()
3650 trace_ss = ss.source_set()
3651 user_ss = ss.source_set()
3652 util_ss = ss.source_set()
3655 qtest_module_ss = ss.source_set()
3656 tcg_module_ss = ss.source_set()
3662 target_system_arch = {}
3663 target_user_arch = {}
3665 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3666 # that is filled in by qapi/.
3684 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3685 modulecommon = declare_dependency(objects: libmodulecommon.extract_all_objects(recursive: false), compile_args: '-DBUILD_DSO')
3688 qom_ss = qom_ss.apply({})
3689 libqom = static_library('qom', qom_ss.sources() + genh,
3690 dependencies: [qom_ss.dependencies()],
3691 build_by_default: false)
3692 qom = declare_dependency(objects: libqom.extract_all_objects(recursive: false),
3693 dependencies: qom_ss.dependencies())
3695 event_loop_base = files('event-loop-base.c')
3696 event_loop_base = static_library('event-loop-base',
3697 sources: event_loop_base + genh,
3698 build_by_default: false)
3699 event_loop_base = declare_dependency(objects: event_loop_base.extract_all_objects(recursive: false),
3700 dependencies: [qom])
3702 stub_ss = stub_ss.apply({})
3704 util_ss.add_all(trace_ss)
3705 util_ss = util_ss.apply({})
3706 libqemuutil = static_library('qemuutil',
3707 build_by_default: false,
3708 sources: util_ss.sources() + stub_ss.sources() + genh,
3709 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc])
3710 qemuutil = declare_dependency(link_with: libqemuutil,
3711 sources: genh + version_res,
3712 dependencies: [event_loop_base])
3714 if have_system or have_user
3715 decodetree = generator(find_program('scripts/decodetree.py'),
3716 output: 'decode-@BASENAME@.c.inc',
3717 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3718 subdir('libdecnumber')
3735 if config_host_data.get('CONFIG_REPLICATION')
3736 block_ss.add(files('replication.c'))
3743 blockdev_ss.add(files(
3750 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3751 # os-win32.c does not
3752 if host_os == 'windows'
3753 system_ss.add(files('os-win32.c'))
3755 blockdev_ss.add(files('os-posix.c'))
3759 common_ss.add(files('cpu-common.c'))
3760 specific_ss.add(files('cpu-target.c'))
3764 # Work around a gcc bug/misfeature wherein constant propagation looks
3766 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3767 # to guess that a const variable is always zero. Without lto, this is
3768 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
3769 # without lto, not even the alias is required -- we simply use different
3770 # declarations in different compilation units.
3771 pagevary = files('page-vary-common.c')
3772 if get_option('b_lto')
3773 pagevary_flags = ['-fno-lto']
3774 if get_option('cfi')
3775 pagevary_flags += '-fno-sanitize=cfi-icall'
3777 pagevary = static_library('page-vary-common', sources: pagevary + genh,
3778 c_args: pagevary_flags)
3779 pagevary = declare_dependency(link_with: pagevary)
3781 common_ss.add(pagevary)
3782 specific_ss.add(files('page-target.c', 'page-vary-target.c'))
3790 subdir('semihosting')
3798 if 'CONFIG_TCG' in config_all_accel
3799 subdir('contrib/plugins')
3802 common_user_inc = []
3804 subdir('common-user')
3806 subdir('linux-user')
3808 # needed for fuzzing binaries
3809 subdir('tests/qtest/libqos')
3810 subdir('tests/qtest/fuzz')
3813 tcg_real_module_ss = ss.source_set()
3814 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3815 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3816 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3817 'tcg': tcg_real_module_ss }}
3819 ##############################################
3820 # Internal static_libraries and dependencies #
3821 ##############################################
3823 modinfo_collect = find_program('scripts/modinfo-collect.py')
3824 modinfo_generate = find_program('scripts/modinfo-generate.py')
3829 emulator_modules = []
3830 foreach d, list : modules
3831 if not (d == 'block' ? have_block : have_system)
3835 foreach m, module_ss : list
3837 module_ss.add(modulecommon)
3838 module_ss = module_ss.apply(config_all_devices, strict: false)
3839 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3840 dependencies: module_ss.dependencies(), pic: true)
3846 emulator_modules += shared_module(sl.name(),
3848 objects: sl.extract_all_objects(recursive: false),
3849 dependencies: module_ss.dependencies(),
3851 install_dir: qemu_moddir)
3852 if module_ss.sources() != []
3853 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3854 # input. Sources can be used multiple times but objects are
3855 # unique when it comes to lookup in compile_commands.json.
3856 # Depnds on a mesion version with
3857 # https://github.com/mesonbuild/meson/pull/8900
3858 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3859 output: d + '-' + m + '.modinfo',
3860 input: module_ss.sources() + genh,
3862 command: [modinfo_collect, module_ss.sources()])
3866 block_ss.add_all(module_ss)
3868 system_ss.add_all(module_ss)
3874 foreach d, list : target_modules
3875 foreach m, module_ss : list
3877 module_ss.add(modulecommon)
3878 foreach target : target_dirs
3879 if target.endswith('-softmmu')
3880 config_target = config_target_mak[target]
3881 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3882 c_args = ['-DCOMPILING_PER_TARGET',
3883 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3884 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3885 target_module_ss = module_ss.apply(config_target, strict: false)
3886 if target_module_ss.sources() != []
3887 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3888 sl = static_library(module_name,
3889 [genh, target_module_ss.sources()],
3890 dependencies: target_module_ss.dependencies(),
3891 include_directories: target_inc,
3895 emulator_modules += shared_module(sl.name(),
3897 objects: sl.extract_all_objects(recursive: false),
3898 dependencies: target_module_ss.dependencies(),
3900 install_dir: qemu_moddir)
3901 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3902 modinfo_files += custom_target(module_name + '.modinfo',
3903 output: module_name + '.modinfo',
3904 input: target_module_ss.sources() + genh,
3906 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3911 specific_ss.add_all(module_ss)
3917 foreach target : target_dirs
3918 if target.endswith('-softmmu')
3919 config_target = config_target_mak[target]
3920 config_devices_mak = target + '-config-devices.mak'
3921 modinfo_src = custom_target('modinfo-' + target + '.c',
3922 output: 'modinfo-' + target + '.c',
3923 input: modinfo_files,
3924 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'],
3927 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
3928 modinfo_dep = declare_dependency(link_with: modinfo_lib)
3930 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH']
3931 hw_arch[arch].add(modinfo_dep)
3935 if emulator_modules.length() > 0
3936 alias_target('modules', emulator_modules)
3940 nm = find_program('nm')
3941 undefsym = find_program('scripts/undefsym.py')
3942 block_syms = custom_target('block.syms', output: 'block.syms',
3943 input: [libqemuutil, block_mods],
3945 command: [undefsym, nm, '@INPUT@'])
3946 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3947 input: [libqemuutil, system_mods],
3949 command: [undefsym, nm, '@INPUT@'])
3951 authz_ss = authz_ss.apply({})
3952 libauthz = static_library('authz', authz_ss.sources() + genh,
3953 dependencies: [authz_ss.dependencies()],
3954 build_by_default: false)
3956 authz = declare_dependency(objects: libauthz.extract_all_objects(recursive: false),
3957 dependencies: [authz_ss.dependencies(), qom])
3959 crypto_ss = crypto_ss.apply({})
3960 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3961 dependencies: [crypto_ss.dependencies()],
3962 build_by_default: false)
3964 crypto = declare_dependency(objects: libcrypto.extract_all_objects(recursive: false),
3965 dependencies: [crypto_ss.dependencies(), authz, qom])
3967 io_ss = io_ss.apply({})
3968 libio = static_library('io', io_ss.sources() + genh,
3969 dependencies: [io_ss.dependencies()],
3970 link_with: libqemuutil,
3971 build_by_default: false)
3973 io = declare_dependency(objects: libio.extract_all_objects(recursive: false),
3974 dependencies: [io_ss.dependencies(), crypto, qom])
3976 libmigration = static_library('migration', sources: migration_files + genh,
3977 build_by_default: false)
3978 migration = declare_dependency(objects: libmigration.extract_all_objects(recursive: false),
3979 dependencies: [qom, io])
3980 system_ss.add(migration)
3982 block_ss = block_ss.apply({})
3983 libblock = static_library('block', block_ss.sources() + genh,
3984 dependencies: block_ss.dependencies(),
3985 build_by_default: false)
3987 block = declare_dependency(objects: libblock.extract_all_objects(recursive: false),
3988 dependencies: [block_ss.dependencies(), crypto, io])
3990 blockdev_ss = blockdev_ss.apply({})
3991 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3992 dependencies: blockdev_ss.dependencies(),
3993 build_by_default: false)
3995 blockdev = declare_dependency(objects: libblockdev.extract_all_objects(recursive: false),
3996 dependencies: [blockdev_ss.dependencies(), block, event_loop_base])
3998 qmp_ss = qmp_ss.apply({})
3999 libqmp = static_library('qmp', qmp_ss.sources() + genh,
4000 dependencies: qmp_ss.dependencies(),
4001 build_by_default: false)
4003 qmp = declare_dependency(objects: libqmp.extract_all_objects(recursive: false),
4004 dependencies: qmp_ss.dependencies())
4006 libchardev = static_library('chardev', chardev_ss.sources() + genh,
4007 dependencies: chardev_ss.dependencies(),
4008 build_by_default: false)
4010 chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false),
4011 dependencies: chardev_ss.dependencies())
4013 hwcore_ss = hwcore_ss.apply({})
4014 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
4015 build_by_default: false)
4016 hwcore = declare_dependency(objects: libhwcore.extract_all_objects(recursive: false))
4017 common_ss.add(hwcore)
4023 system_ss.add(authz, blockdev, chardev, crypto, io, qmp)
4024 common_ss.add(qom, qemuutil)
4026 common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss])
4027 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
4029 # Note that this library is never used directly (only through extract_objects)
4030 # and is not built by default; therefore, source files not used by the build
4031 # configuration will be in build.ninja, but are never built by default.
4032 common_all = static_library('common',
4033 build_by_default: false,
4034 sources: common_ss.all_sources() + genh,
4035 include_directories: common_user_inc,
4036 implicit_include_directories: false,
4037 dependencies: common_ss.all_dependencies())
4040 # We would like to use --generate-cstr, but it is only available
4041 # starting with bindgen 0.66.0. The oldest supported versions
4042 # is 0.60.x (Debian 12 has 0.60.1) which introduces --allowlist-file.
4044 '--disable-header-comment',
4045 '--raw-line', '// @generated',
4046 '--ctypes-prefix', 'std::os::raw',
4049 '--no-doc-comments',
4050 '--with-derive-default',
4051 '--no-layout-tests',
4052 '--no-prepend-enum-name',
4053 '--allowlist-file', meson.project_source_root() + '/include/.*',
4054 '--allowlist-file', meson.project_source_root() + '/.*',
4055 '--allowlist-file', meson.project_build_root() + '/.*'
4057 if not rustfmt.found()
4058 if bindgen.version().version_compare('<0.65.0')
4059 bindgen_args += ['--no-rustfmt-bindings']
4061 bindgen_args += ['--formatter', 'none']
4064 if bindgen.version().version_compare('<0.61.0')
4066 bindgen_args += ['--size_t-is-usize']
4068 bindgen_args += ['--merge-extern-blocks']
4074 'MemoryDeviceInfoKind',
4076 'MigrationPriority',
4082 foreach enum : c_enums
4083 bindgen_args += ['--rustified-enum', enum]
4089 foreach enum : c_bitfields
4090 bindgen_args += ['--bitfield-enum', enum]
4093 # TODO: Remove this comment when the clang/libclang mismatch issue is solved.
4095 # Rust bindings generation with `bindgen` might fail in some cases where the
4096 # detected `libclang` does not match the expected `clang` version/target. In
4097 # this case you must pass the path to `clang` and `libclang` to your build
4098 # command invocation using the environment variables CLANG_PATH and
4100 bindings_rs = rust.bindgen(
4101 input: 'rust/wrapper.h',
4102 dependencies: common_ss.all_dependencies(),
4103 output: 'bindings.rs',
4104 include_directories: include_directories('.', 'include'),
4105 bindgen_version: ['>=0.60.0'],
4112 feature_to_c = find_program('scripts/feature_to_c.py')
4113 rust_root_crate = find_program('scripts/rust/rust_root_crate.sh')
4115 if host_os == 'darwin'
4116 entitlement = find_program('scripts/entitlement.sh')
4121 foreach target : target_dirs
4122 config_target = config_target_mak[target]
4123 target_name = config_target['TARGET_NAME']
4124 target_base_arch = config_target['TARGET_BASE_ARCH']
4125 arch_srcs = [config_target_h[target]]
4127 c_args = ['-DCOMPILING_PER_TARGET',
4128 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
4129 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
4130 link_args = emulator_link_args
4132 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
4133 if host_os == 'linux'
4134 target_inc += include_directories('linux-headers', is_system: true)
4136 if target.endswith('-softmmu')
4137 target_type='system'
4138 t = target_system_arch[target_base_arch].apply(config_target, strict: false)
4139 arch_srcs += t.sources()
4140 arch_deps += t.dependencies()
4142 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
4143 if hw_arch.has_key(hw_dir)
4144 hw = hw_arch[hw_dir].apply(config_target, strict: false)
4145 arch_srcs += hw.sources()
4146 arch_deps += hw.dependencies()
4149 arch_srcs += config_devices_h[target]
4150 link_args += ['@block.syms', '@qemu.syms']
4152 abi = config_target['TARGET_ABI_DIR']
4154 target_inc += common_user_inc
4155 if target_base_arch in target_user_arch
4156 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
4157 arch_srcs += t.sources()
4158 arch_deps += t.dependencies()
4160 if 'CONFIG_LINUX_USER' in config_target
4161 base_dir = 'linux-user'
4163 if 'CONFIG_BSD_USER' in config_target
4164 base_dir = 'bsd-user'
4165 target_inc += include_directories('bsd-user/' / host_os)
4166 target_inc += include_directories('bsd-user/host/' / host_arch)
4167 dir = base_dir / abi
4168 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
4170 target_inc += include_directories(
4174 if 'CONFIG_LINUX_USER' in config_target
4175 dir = base_dir / abi
4176 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
4177 if config_target.has_key('TARGET_SYSTBL_ABI')
4179 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
4180 extra_args : config_target['TARGET_SYSTBL_ABI'])
4185 if 'TARGET_XML_FILES' in config_target
4186 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
4187 output: target + '-gdbstub-xml.c',
4188 input: files(config_target['TARGET_XML_FILES'].split()),
4189 command: [feature_to_c, '@INPUT@'],
4191 arch_srcs += gdbstub_xml
4194 t = target_arch[target_base_arch].apply(config_target, strict: false)
4195 arch_srcs += t.sources()
4196 arch_deps += t.dependencies()
4198 target_common = common_ss.apply(config_target, strict: false)
4199 objects = common_all.extract_objects(target_common.sources())
4200 arch_deps += target_common.dependencies()
4202 target_specific = specific_ss.apply(config_target, strict: false)
4203 arch_srcs += target_specific.sources()
4204 arch_deps += target_specific.dependencies()
4206 if have_rust and target_type == 'system'
4207 target_rust = rust_devices_ss.apply(config_target, strict: false)
4209 foreach dep : target_rust.dependencies()
4210 crates += dep.get_variable('crate')
4212 if crates.length() > 0
4213 rlib_rs = custom_target('rust_' + target.underscorify() + '.rs',
4214 output: 'rust_' + target.underscorify() + '.rs',
4215 command: [rust_root_crate, crates],
4217 build_by_default: true,
4218 build_always_stale: true)
4219 rlib = static_library('rust_' + target.underscorify(),
4221 dependencies: target_rust.dependencies(),
4222 override_options: ['rust_std=2021', 'build.rust_std=2021'],
4224 arch_deps += declare_dependency(link_whole: [rlib])
4228 # allow using headers from the dependencies but do not include the sources,
4229 # because this emulator only needs those in "objects". For external
4230 # dependencies, the full dependency is included below in the executable.
4232 foreach dep : arch_deps
4233 lib_deps += dep.partial_dependency(compile_args: true, includes: true)
4236 lib = static_library('qemu-' + target,
4237 sources: arch_srcs + genh,
4238 dependencies: lib_deps,
4240 include_directories: target_inc,
4242 build_by_default: false)
4244 if target.endswith('-softmmu')
4246 'name': 'qemu-system-' + target_name,
4247 'win_subsystem': 'console',
4248 'sources': files('system/main.c'),
4249 'dependencies': [sdl]
4251 if host_os == 'windows' and (sdl.found() or gtk.found())
4253 'name': 'qemu-system-' + target_name + 'w',
4254 'win_subsystem': 'windows',
4255 'sources': files('system/main.c'),
4256 'dependencies': [sdl]
4259 if get_option('fuzzing')
4260 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
4262 'name': 'qemu-fuzz-' + target_name,
4263 'win_subsystem': 'console',
4264 'sources': specific_fuzz.sources(),
4265 'dependencies': specific_fuzz.dependencies(),
4270 'name': 'qemu-' + target_name,
4271 'win_subsystem': 'console',
4277 exe_name = exe['name']
4278 if host_os == 'darwin'
4279 exe_name += '-unsigned'
4282 emulator = executable(exe_name, exe['sources'],
4285 dependencies: arch_deps + exe['dependencies'],
4286 objects: lib.extract_all_objects(recursive: true),
4287 link_depends: [block_syms, qemu_syms],
4288 link_args: link_args,
4289 win_subsystem: exe['win_subsystem'])
4291 if host_os == 'darwin'
4292 icon = 'pc-bios/qemu.rsrc'
4293 build_input = [emulator, files(icon)]
4295 get_option('bindir') / exe_name,
4296 meson.current_source_dir() / icon
4298 if 'CONFIG_HVF' in config_target
4299 entitlements = 'accel/hvf/entitlements.plist'
4300 build_input += files(entitlements)
4301 install_input += meson.current_source_dir() / entitlements
4304 emulators += {exe['name'] : custom_target(exe['name'],
4306 output: exe['name'],
4307 command: [entitlement, '@OUTPUT@', '@INPUT@'])
4310 meson.add_install_script(entitlement, '--install',
4311 get_option('bindir') / exe['name'],
4314 emulators += {exe['name']: emulator}
4319 'probe-prefix': 'qemu.' + target_type + '.' + target_name,
4325 # Other build targets
4327 if get_option('plugins')
4328 install_headers('include/qemu/qemu-plugin.h')
4329 if host_os == 'windows'
4330 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer,
4331 # so that plugin authors can compile against it.
4332 install_data(win32_qemu_plugin_api_lib, install_dir: 'lib')
4338 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
4339 # when we don't build tools or system
4340 if xkbcommon.found()
4341 # used for the update-keymaps target, so include rules even if !have_tools
4342 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
4343 dependencies: [qemuutil, xkbcommon], install: have_tools)
4347 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
4348 link_args: '@block.syms', link_depends: block_syms,
4349 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
4350 qemu_io = executable('qemu-io', files('qemu-io.c'),
4351 link_args: '@block.syms', link_depends: block_syms,
4352 dependencies: [block, qemuutil], install: true)
4353 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
4354 link_args: '@block.syms', link_depends: block_syms,
4355 dependencies: [blockdev, qemuutil, selinux],
4358 subdir('storage-daemon')
4360 foreach exe: [ 'qemu-img', 'qemu-io', 'qemu-nbd', 'qemu-storage-daemon']
4363 'probe-prefix': 'qemu.' + exe.substring(5).replace('-', '_')
4367 subdir('contrib/elf2dmp')
4369 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
4370 dependencies: qemuutil,
4374 subdir('contrib/vhost-user-blk')
4375 subdir('contrib/vhost-user-gpu')
4376 subdir('contrib/vhost-user-input')
4377 subdir('contrib/vhost-user-scsi')
4380 if host_os == 'linux'
4381 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
4382 dependencies: [qemuutil, libcap_ng],
4384 install_dir: get_option('libexecdir'))
4386 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
4387 dependencies: [authz, crypto, io, qom, qemuutil,
4388 libcap_ng, mpathpersist],
4391 if cpu in ['x86', 'x86_64']
4392 executable('qemu-vmsr-helper', files('tools/i386/qemu-vmsr-helper.c'),
4393 dependencies: [authz, crypto, io, qom, qemuutil,
4394 libcap_ng, mpathpersist],
4400 subdir('contrib/ivshmem-client')
4401 subdir('contrib/ivshmem-server')
4406 foreach t: traceable
4408 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / t['exe'], 'install': false},
4409 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / t['exe'], 'install': true},
4410 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
4411 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
4414 tracetool, '--group=all', '--format=' + stp['fmt'],
4415 '--binary=' + stp['bin'],
4416 '--probe-prefix=' + t['probe-prefix'],
4417 '@INPUT@', '@OUTPUT@'
4420 custom_target(t['exe'] + stp['ext'],
4421 input: trace_events_all,
4422 output: t['exe'] + stp['ext'],
4423 install: stp['install'],
4424 install_dir: get_option('datadir') / 'systemtap/tapset',
4426 depend_files: tracetool_depends)
4440 if host_machine.system() == 'windows'
4442 find_program('scripts/nsis.py'),
4444 get_option('prefix'),
4445 meson.current_source_dir(),
4446 glib_pc.get_variable('bindir'),
4449 '-DDISPLAYVERSION=' + meson.project_version(),
4452 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
4455 nsis_cmd += '-DCONFIG_GTK=y'
4458 nsis = custom_target('nsis',
4459 output: 'qemu-setup-' + meson.project_version() + '.exe',
4460 input: files('qemu.nsi'),
4461 build_always_stale: true,
4462 command: nsis_cmd + ['@INPUT@'])
4463 alias_target('installer', nsis)
4466 #########################
4467 # Configuration summary #
4468 #########################
4472 summary_info += {'Build directory': meson.current_build_dir()}
4473 summary_info += {'Source path': meson.current_source_dir()}
4474 summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'}
4475 summary(summary_info, bool_yn: true, section: 'Build environment')
4478 summary_info += {'Install prefix': get_option('prefix')}
4479 summary_info += {'BIOS directory': qemu_datadir}
4480 pathsep = host_os == 'windows' ? ';' : ':'
4481 summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))}
4482 summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
4483 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
4484 summary_info += {'module directory': qemu_moddir}
4485 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
4486 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
4487 summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')}
4488 if host_os != 'windows'
4489 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
4490 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')}
4492 summary_info += {'local state directory': 'queried at runtime'}
4494 summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
4495 summary(summary_info, bool_yn: true, section: 'Directories')
4499 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
4500 summary_info += {'sphinx-build': sphinx_build}
4502 # FIXME: the [binaries] section of machine files, which can be probed
4503 # with find_program(), would be great for passing gdb and genisoimage
4504 # paths from configure to Meson. However, there seems to be no way to
4505 # hide a program (for example if gdb is too old).
4506 if config_host.has_key('GDB')
4507 summary_info += {'gdb': config_host['GDB']}
4509 summary_info += {'iasl': iasl}
4510 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
4511 if host_os == 'windows' and have_ga
4512 summary_info += {'wixl': wixl}
4514 if slirp.found() and have_system
4515 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
4517 summary(summary_info, bool_yn: true, section: 'Host binaries')
4519 # Configurable features
4521 summary_info += {'Documentation': build_docs}
4522 summary_info += {'system-mode emulation': have_system}
4523 summary_info += {'user-mode emulation': have_user}
4524 summary_info += {'block layer': have_block}
4525 summary_info += {'Install blobs': get_option('install_blobs')}
4526 summary_info += {'module support': enable_modules}
4528 summary_info += {'alternative module path': get_option('module_upgrades')}
4530 summary_info += {'fuzzing support': get_option('fuzzing')}
4532 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
4534 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
4535 if 'simple' in get_option('trace_backends')
4536 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
4538 summary_info += {'D-Bus display': dbus_display}
4539 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
4540 summary_info += {'Relocatable install': get_option('relocatable')}
4541 summary_info += {'vhost-kernel support': have_vhost_kernel}
4542 summary_info += {'vhost-net support': have_vhost_net}
4543 summary_info += {'vhost-user support': have_vhost_user}
4544 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
4545 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
4546 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
4547 summary_info += {'build guest agent': have_ga}
4548 summary(summary_info, bool_yn: true, section: 'Configurable features')
4550 # Compilation information
4552 summary_info += {'host CPU': cpu}
4553 summary_info += {'host endianness': build_machine.endian()}
4554 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
4555 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
4556 if 'cpp' in all_languages
4557 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
4559 summary_info += {'C++ compiler': false}
4561 if 'objc' in all_languages
4562 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
4564 summary_info += {'Objective-C compiler': false}
4566 summary_info += {'Rust support': have_rust}
4568 summary_info += {'Rust target': config_host['RUST_TARGET_TRIPLE']}
4569 summary_info += {'rustc': ' '.join(rustc.cmd_array())}
4570 summary_info += {'rustc version': rustc.version()}
4571 summary_info += {'bindgen': bindgen.full_path()}
4572 summary_info += {'bindgen version': bindgen.version()}
4574 option_cflags = (get_option('debug') ? ['-g'] : [])
4575 if get_option('optimization') != 'plain'
4576 option_cflags += ['-O' + get_option('optimization')]
4578 summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)}
4579 if 'cpp' in all_languages
4580 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)}
4582 if 'objc' in all_languages
4583 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)}
4585 link_args = get_option('c_link_args')
4586 if link_args.length() > 0
4587 summary_info += {'LDFLAGS': ' '.join(link_args)}
4589 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)}
4590 if 'cpp' in all_languages
4591 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)}
4593 if 'objc' in all_languages
4594 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)}
4596 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
4597 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
4598 summary_info += {'PIE': get_option('b_pie')}
4599 summary_info += {'static build': get_option('prefer_static')}
4600 summary_info += {'malloc trim support': has_malloc_trim}
4601 summary_info += {'membarrier': have_membarrier}
4602 summary_info += {'debug graph lock': get_option('debug_graph_lock')}
4603 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
4604 summary_info += {'mutex debugging': get_option('debug_mutex')}
4605 summary_info += {'memory allocator': get_option('malloc')}
4606 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
4607 summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')}
4608 summary_info += {'gcov': get_option('b_coverage')}
4609 summary_info += {'thread sanitizer': get_option('tsan')}
4610 summary_info += {'CFI support': get_option('cfi')}
4611 if get_option('cfi')
4612 summary_info += {'CFI debug support': get_option('cfi_debug')}
4614 summary_info += {'strip binaries': get_option('strip')}
4615 summary_info += {'sparse': sparse}
4616 summary_info += {'mingw32 support': host_os == 'windows'}
4617 summary(summary_info, bool_yn: true, section: 'Compilation')
4619 # snarf the cross-compilation information for tests
4622 foreach target: target_dirs
4623 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak'
4624 if fs.exists(tcg_mak)
4625 config_cross_tcg = keyval.load(tcg_mak)
4626 if 'CC' in config_cross_tcg
4627 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']}
4633 summary(summary_info, bool_yn: true, section: 'Cross compilers')
4636 # Targets and accelerators
4639 summary_info += {'KVM support': config_all_accel.has_key('CONFIG_KVM')}
4640 summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')}
4641 summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')}
4642 summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')}
4643 summary_info += {'Xen support': xen.found()}
4645 summary_info += {'xen ctrl version': xen.version()}
4647 summary_info += {'Xen emulation': config_all_devices.has_key('CONFIG_XEN_EMU')}
4649 summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')}
4650 if config_all_accel.has_key('CONFIG_TCG')
4651 if get_option('tcg_interpreter')
4652 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
4654 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
4656 summary_info += {'TCG plugins': get_option('plugins')}
4657 summary_info += {'TCG debug enabled': get_option('debug_tcg')}
4658 if have_linux_user or have_bsd_user
4659 summary_info += {'syscall buffer debugging support': get_option('debug_remap')}
4662 summary_info += {'target list': ' '.join(target_dirs)}
4664 summary_info += {'default devices': get_option('default_devices')}
4665 summary_info += {'out of process emulation': multiprocess_allowed}
4666 summary_info += {'vfio-user server': vfio_user_server_allowed}
4668 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
4672 summary_info += {'coroutine backend': coroutine_backend}
4673 summary_info += {'coroutine pool': have_coroutine_pool}
4675 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
4676 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
4677 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
4678 summary_info += {'VirtFS (9P) support': have_virtfs}
4679 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
4680 summary_info += {'bochs support': get_option('bochs').allowed()}
4681 summary_info += {'cloop support': get_option('cloop').allowed()}
4682 summary_info += {'dmg support': get_option('dmg').allowed()}
4683 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
4684 summary_info += {'vdi support': get_option('vdi').allowed()}
4685 summary_info += {'vhdx support': get_option('vhdx').allowed()}
4686 summary_info += {'vmdk support': get_option('vmdk').allowed()}
4687 summary_info += {'vpc support': get_option('vpc').allowed()}
4688 summary_info += {'vvfat support': get_option('vvfat').allowed()}
4689 summary_info += {'qed support': get_option('qed').allowed()}
4690 summary_info += {'parallels support': get_option('parallels').allowed()}
4691 summary_info += {'FUSE exports': fuse}
4692 summary_info += {'VDUSE block exports': have_vduse_blk_export}
4694 summary(summary_info, bool_yn: true, section: 'Block layer support')
4698 summary_info += {'TLS priority': get_option('tls_priority')}
4699 summary_info += {'GNUTLS support': gnutls}
4701 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
4703 summary_info += {'libgcrypt': gcrypt}
4704 summary_info += {'nettle': nettle}
4706 summary_info += {' XTS': xts != 'private'}
4708 summary_info += {'SM4 ALG support': crypto_sm4}
4709 summary_info += {'SM3 ALG support': crypto_sm3}
4710 summary_info += {'AF_ALG support': have_afalg}
4711 summary_info += {'rng-none': get_option('rng_none')}
4712 summary_info += {'Linux keyring': have_keyring}
4713 summary_info += {'Linux keyutils': keyutils}
4714 summary(summary_info, bool_yn: true, section: 'Crypto')
4718 if host_os == 'darwin'
4719 summary_info += {'Cocoa support': cocoa}
4721 summary_info += {'SDL support': sdl}
4722 summary_info += {'SDL image support': sdl_image}
4723 summary_info += {'GTK support': gtk}
4724 summary_info += {'pixman': pixman}
4725 summary_info += {'VTE support': vte}
4726 summary_info += {'PNG support': png}
4727 summary_info += {'VNC support': vnc}
4729 summary_info += {'VNC SASL support': sasl}
4730 summary_info += {'VNC JPEG support': jpeg}
4732 summary_info += {'spice protocol support': spice_protocol}
4733 if spice_protocol.found()
4734 summary_info += {' spice server support': spice}
4736 summary_info += {'curses support': curses}
4737 summary_info += {'brlapi support': brlapi}
4738 summary(summary_info, bool_yn: true, section: 'User interface')
4742 summary_info += {'VirGL support': virgl}
4743 summary_info += {'Rutabaga support': rutabaga}
4744 summary(summary_info, bool_yn: true, section: 'Graphics backends')
4748 if host_os not in ['darwin', 'haiku', 'windows']
4749 summary_info += {'OSS support': oss}
4750 summary_info += {'sndio support': sndio}
4751 elif host_os == 'darwin'
4752 summary_info += {'CoreAudio support': coreaudio}
4753 elif host_os == 'windows'
4754 summary_info += {'DirectSound support': dsound}
4756 if host_os == 'linux'
4757 summary_info += {'ALSA support': alsa}
4758 summary_info += {'PulseAudio support': pulse}
4760 summary_info += {'PipeWire support': pipewire}
4761 summary_info += {'JACK support': jack}
4762 summary(summary_info, bool_yn: true, section: 'Audio backends')
4766 if host_os == 'darwin'
4767 summary_info += {'vmnet.framework support': vmnet}
4769 summary_info += {'AF_XDP support': libxdp}
4770 summary_info += {'slirp support': slirp}
4771 summary_info += {'vde support': vde}
4772 summary_info += {'netmap support': have_netmap}
4773 summary_info += {'l2tpv3 support': have_l2tpv3}
4774 summary(summary_info, bool_yn: true, section: 'Network backends')
4778 summary_info += {'libtasn1': tasn1}
4779 summary_info += {'PAM': pam}
4780 summary_info += {'iconv support': iconv}
4781 summary_info += {'blkio support': blkio}
4782 summary_info += {'curl support': curl}
4783 summary_info += {'Multipath support': mpathpersist}
4784 summary_info += {'Linux AIO support': libaio}
4785 summary_info += {'Linux io_uring support': linux_io_uring}
4786 summary_info += {'ATTR/XATTR support': libattr}
4787 summary_info += {'RDMA support': rdma}
4788 summary_info += {'fdt support': fdt_opt == 'internal' ? 'internal' : fdt}
4789 summary_info += {'libcap-ng support': libcap_ng}
4790 summary_info += {'bpf support': libbpf}
4791 summary_info += {'rbd support': rbd}
4792 summary_info += {'smartcard support': cacard}
4793 summary_info += {'U2F support': u2f}
4794 summary_info += {'libusb': libusb}
4795 summary_info += {'usb net redir': usbredir}
4796 summary_info += {'OpenGL support (epoxy)': opengl}
4797 summary_info += {'GBM': gbm}
4798 summary_info += {'libiscsi support': libiscsi}
4799 summary_info += {'libnfs support': libnfs}
4800 if host_os == 'windows'
4802 summary_info += {'QGA VSS support': have_qga_vss}
4805 summary_info += {'seccomp support': seccomp}
4806 summary_info += {'GlusterFS support': glusterfs}
4807 summary_info += {'hv-balloon support': hv_balloon}
4808 summary_info += {'TPM support': have_tpm}
4809 summary_info += {'libssh support': libssh}
4810 summary_info += {'lzo support': lzo}
4811 summary_info += {'snappy support': snappy}
4812 summary_info += {'bzip2 support': libbzip2}
4813 summary_info += {'lzfse support': liblzfse}
4814 summary_info += {'zstd support': zstd}
4815 summary_info += {'Query Processing Library support': qpl}
4816 summary_info += {'UADK Library support': uadk}
4817 summary_info += {'qatzip support': qatzip}
4818 summary_info += {'NUMA host support': numa}
4819 summary_info += {'capstone': capstone}
4820 summary_info += {'libpmem support': libpmem}
4821 summary_info += {'libdaxctl support': libdaxctl}
4822 summary_info += {'libcbor support': libcbor}
4823 summary_info += {'libudev': libudev}
4824 # Dummy dependency, keep .found()
4825 summary_info += {'FUSE lseek': fuse_lseek.found()}
4826 summary_info += {'selinux': selinux}
4827 summary_info += {'libdw': libdw}
4828 if host_os == 'freebsd'
4829 summary_info += {'libinotify-kqueue': inotify}
4831 summary(summary_info, bool_yn: true, section: 'Dependencies')
4833 if host_arch == 'unknown'
4835 warning('UNSUPPORTED HOST CPU')
4837 message('Support for CPU host architecture ' + cpu + ' is not currently')
4838 message('maintained. The QEMU project does not guarantee that QEMU will')
4839 message('compile or work on this host CPU. You can help by volunteering')
4840 message('to maintain it and providing a build host for our continuous')
4841 message('integration setup.')
4842 if get_option('tcg').allowed() and target_dirs.length() > 0
4844 message('configure has succeeded and you can continue to build, but')
4845 message('QEMU will use a slow interpreter to emulate the target CPU.')
4847 elif host_arch == 'mips'
4849 warning('DEPRECATED HOST CPU')
4851 message('Support for CPU host architecture ' + cpu + ' is going to be')
4852 message('dropped as soon as the QEMU project stops supporting Debian 12')
4853 message('("Bookworm"). Going forward, the QEMU project will not guarantee')
4854 message('that QEMU will compile or work on this host CPU.')
4857 if not supported_oses.contains(host_os)
4859 warning('UNSUPPORTED HOST OS')
4861 message('Support for host OS ' + host_os + 'is not currently maintained.')
4862 message('configure has succeeded and you can continue to build, but')
4863 message('the QEMU project does not guarantee that QEMU will compile or')
4864 message('work on this operating system. You can help by volunteering')
4865 message('to maintain it and providing a build host for our continuous')
4866 message('integration setup. This will ensure that future versions of QEMU')
4867 message('will keep working on ' + host_os + '.')
4870 if host_arch == 'unknown' or not supported_oses.contains(host_os)
4872 message('If you want to help supporting QEMU on this platform, please')
4873 message('contact the developers at qemu-devel@nongnu.org.')
4876 actually_reloc = get_option('relocatable')
4877 # check if get_relocated_path() is actually able to relocate paths
4878 if get_option('relocatable') and \
4879 not (get_option('prefix') / get_option('bindir')).startswith(get_option('prefix') / '')
4881 warning('bindir not included within prefix, the installation will not be relocatable.')
4882 actually_reloc = false
4884 if not actually_reloc and (host_os == 'windows' or get_option('relocatable'))
4885 if host_os == 'windows'
4887 warning('Windows installs should usually be relocatable.')
4890 message('QEMU will have to be installed under ' + get_option('prefix') + '.')
4891 message('Use --disable-relocatable to remove this warning.')