1 project('qemu', ['c'], meson_version: '>=1.5.0',
2 default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
3 'b_staticpic=false', 'stdsplit=false', 'optimization=2', 'b_pie=true'],
4 version: files('VERSION'))
6 add_test_setup('quick', exclude_suites: ['slow', 'thorough'], is_default: true)
7 add_test_setup('slow', exclude_suites: ['thorough'], env: ['G_TEST_SLOW=1', 'SPEED=slow'])
8 add_test_setup('thorough', env: ['G_TEST_SLOW=1', 'SPEED=thorough'])
10 meson.add_postconf_script(find_program('scripts/symlink-install-tree.py'))
16 not_found = dependency('', required: false)
17 keyval = import('keyval')
18 ss = import('sourceset')
21 host_os = host_machine.system()
22 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
24 # Temporary directory used for files created while
25 # configure runs. Since it is in the build directory
26 # we can safely blow away any previous version of it
27 # (and we need not jump through hoops to try to delete
28 # it when configure exits.)
29 tmpdir = meson.current_build_dir() / 'meson-private/temp'
31 if get_option('qemu_suffix').startswith('/')
32 error('qemu_suffix cannot start with a /')
35 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
36 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
37 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
38 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
40 qemu_desktopdir = get_option('datadir') / 'applications'
41 qemu_icondir = get_option('datadir') / 'icons'
44 qapi_trace_events = []
46 bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
47 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
48 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
49 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64']
51 cpu = host_machine.cpu_family()
53 target_dirs = config_host['TARGET_DIRS'].split()
59 sh = find_program('sh')
60 python = import('python').find_installation()
62 cc = meson.get_compiler('c')
64 if host_os == 'windows' and add_languages('cpp', required: false, native: false)
65 all_languages += ['cpp']
66 cxx = meson.get_compiler('cpp')
68 if host_os == 'darwin' and \
69 add_languages('objc', required: true, native: false)
70 all_languages += ['objc']
71 objc = meson.get_compiler('objc')
74 if not get_option('rust').disabled() and add_languages('rust', required: get_option('rust'), native: false) \
75 and add_languages('rust', required: get_option('rust'), native: true)
76 rustc = meson.get_compiler('rust')
78 if rustc.version().version_compare('<1.80.0')
79 if get_option('rust').enabled()
80 error('rustc version ' + rustc.version() + ' is unsupported: Please upgrade to at least 1.80.0')
82 warning('rustc version ' + rustc.version() + ' is unsupported: Disabling Rust compilation. Please upgrade to at least 1.80.0 to use Rust.')
90 if 'dtrace' in get_option('trace_backends')
91 dtrace = find_program('dtrace', required: true)
92 stap = find_program('stap', required: false)
94 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
95 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
96 # instead. QEMU --enable-modules depends on this because the SystemTap
97 # semaphores are linked into the main binary and not the module's shared
99 add_global_arguments('-DSTAP_SDT_V2',
100 native: false, language: all_languages)
104 if get_option('iasl') == ''
105 iasl = find_program('iasl', required: false)
107 iasl = find_program(get_option('iasl'), required: true)
110 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu', 'riscv64-softmmu', 'loongarch64-softmmu' ]
111 unpack_edk2_blobs = false
112 foreach target : edk2_targets
113 if target in target_dirs
114 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
115 unpack_edk2_blobs = bzip2.found()
120 #####################
121 # Option validation #
122 #####################
125 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
128 #include <sys/types.h>
129 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
130 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
132 args: ['-Werror', '-fsanitize=fuzzer'])
133 error('Your compiler does not support -fsanitize=fuzzer')
137 if 'ftrace' in get_option('trace_backends') and host_os != 'linux'
138 error('ftrace is supported only on Linux')
140 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
143 openlog("qemu", LOG_PID, LOG_DAEMON);
144 syslog(LOG_INFO, "configure");
147 error('syslog is not supported on this system')
150 # Miscellaneous Linux-only features
151 get_option('mpath') \
152 .require(host_os == 'linux', error_message: 'Multipath is supported only on Linux')
154 multiprocess_allowed = get_option('multiprocess') \
155 .require(host_os == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
158 vfio_user_server_allowed = get_option('vfio_user_server') \
159 .require(host_os == 'linux', error_message: 'vfio-user server is supported only on Linux') \
162 have_tpm = get_option('tpm') \
163 .require(host_os != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
167 have_vhost_user = get_option('vhost_user') \
168 .disable_auto_if(host_os != 'linux') \
169 .require(host_os != 'windows',
170 error_message: 'vhost-user is not available on Windows').allowed()
171 have_vhost_vdpa = get_option('vhost_vdpa') \
172 .require(host_os == 'linux',
173 error_message: 'vhost-vdpa is only available on Linux').allowed()
174 have_vhost_kernel = get_option('vhost_kernel') \
175 .require(host_os == 'linux',
176 error_message: 'vhost-kernel is only available on Linux').allowed()
177 have_vhost_user_crypto = get_option('vhost_crypto') \
178 .require(have_vhost_user,
179 error_message: 'vhost-crypto requires vhost-user to be enabled').allowed()
181 have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel
183 have_vhost_net_user = have_vhost_user and get_option('vhost_net').allowed()
184 have_vhost_net_vdpa = have_vhost_vdpa and get_option('vhost_net').allowed()
185 have_vhost_net_kernel = have_vhost_kernel and get_option('vhost_net').allowed()
186 have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_vdpa
188 # type of binaries to build
189 have_linux_user = false
190 have_bsd_user = false
192 foreach target : target_dirs
193 have_linux_user = have_linux_user or target.endswith('linux-user')
194 have_bsd_user = have_bsd_user or target.endswith('bsd-user')
195 have_system = have_system or target.endswith('-softmmu')
197 have_user = have_linux_user or have_bsd_user
199 have_tools = get_option('tools') \
200 .disable_auto_if(not have_system) \
202 have_ga = get_option('guest_agent') \
203 .disable_auto_if(not have_system and not have_tools) \
204 .require(host_os in ['sunos', 'linux', 'windows', 'freebsd', 'netbsd', 'openbsd'],
205 error_message: 'unsupported OS for QEMU guest agent') \
207 have_block = have_system or have_tools
209 enable_modules = get_option('modules') \
210 .require(host_os != 'windows',
211 error_message: 'Modules are not available for Windows') \
212 .require(not get_option('prefer_static'),
213 error_message: 'Modules are incompatible with static linking') \
216 #######################################
217 # Variables for host and accelerators #
218 #######################################
220 if cpu not in supported_cpus
221 host_arch = 'unknown'
226 elif cpu in ['riscv32', 'riscv64']
232 if cpu in ['x86', 'x86_64']
233 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
234 elif cpu == 'aarch64'
235 kvm_targets = ['aarch64-softmmu']
237 kvm_targets = ['s390x-softmmu']
238 elif cpu in ['ppc', 'ppc64']
239 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
240 elif cpu in ['mips', 'mips64']
241 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
242 elif cpu in ['riscv32']
243 kvm_targets = ['riscv32-softmmu']
244 elif cpu in ['riscv64']
245 kvm_targets = ['riscv64-softmmu']
246 elif cpu in ['loongarch64']
247 kvm_targets = ['loongarch64-softmmu']
251 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
253 if cpu in ['x86', 'x86_64']
254 xen_targets = ['i386-softmmu', 'x86_64-softmmu']
255 elif cpu in ['arm', 'aarch64']
256 # i386 emulator provides xenpv machine type for multiple architectures
257 xen_targets = ['i386-softmmu', 'x86_64-softmmu', 'aarch64-softmmu']
261 accelerator_targets += { 'CONFIG_XEN': xen_targets }
263 if cpu in ['aarch64']
264 accelerator_targets += {
265 'CONFIG_HVF': ['aarch64-softmmu']
269 if cpu in ['x86', 'x86_64']
270 accelerator_targets += {
271 'CONFIG_HVF': ['x86_64-softmmu'],
272 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
273 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
278 # Darwin does not support references to thread-local variables in modules
279 if host_os != 'darwin'
280 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
287 foreach lang : all_languages
288 compiler = meson.get_compiler(lang)
289 if compiler.get_id() == 'gcc' and compiler.version().version_compare('>=7.4')
291 elif compiler.get_id() == 'clang' and compiler.compiles('''
292 #ifdef __apple_build_version__
293 # if __clang_major__ < 12 || (__clang_major__ == 12 && __clang_minor__ < 0)
294 # error You need at least XCode Clang v12.0 to compile QEMU
297 # if __clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 0)
298 # error You need at least Clang v10.0 to compile QEMU
303 error('You either need GCC v7.4 or Clang v10.0 (or XCode Clang v12.0) to compile QEMU')
307 # default flags for all hosts
308 # We use -fwrapv to tell the compiler that we require a C dialect where
309 # left shift of signed integers is well defined and has the expected
310 # 2s-complement style results. (Both clang and gcc agree that it
311 # provides these semantics.)
313 qemu_common_flags = [
314 '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE',
315 '-fno-strict-aliasing', '-fno-common', '-fwrapv' ]
319 if host_os == 'darwin'
320 # Disable attempts to use ObjectiveC features in os/object.h since they
321 # won't work when we're compiling with gcc as a C compiler.
322 if compiler.get_id() == 'gcc'
323 qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
325 elif host_os == 'sunos'
326 # needed for CMSG_ macros in sys/socket.h
327 qemu_common_flags += '-D_XOPEN_SOURCE=600'
328 # needed for TIOCWIN* defines in termios.h
329 qemu_common_flags += '-D__EXTENSIONS__'
330 elif host_os == 'haiku'
331 qemu_common_flags += ['-DB_USE_POSITIVE_POSIX_ERRORS', '-D_BSD_SOURCE', '-fPIC']
332 elif host_os == 'windows'
333 if not compiler.compiles('struct x { int y; } __attribute__((gcc_struct));',
335 error('Your compiler does not support __attribute__((gcc_struct)) - please use GCC instead of Clang')
339 # Choose instruction set (currently x86-only)
343 # __sync_fetch_and_and requires at least -march=i486. Many toolchains
344 # use i686 as default anyway, but for those that don't, an explicit
345 # specification is necessary
346 if host_arch == 'i386' and not cc.links('''
347 static int sfaa(int *ptr)
349 return __sync_fetch_and_and(ptr, 0);
355 val = __sync_val_compare_and_swap(&val, 0, 1);
359 qemu_isa_flags += ['-march=i486']
362 # Pick x86-64 baseline version
363 if host_arch in ['i386', 'x86_64']
364 if get_option('x86_version') == '0' and host_arch == 'x86_64'
365 error('x86_64-v1 required for x86-64 hosts')
368 # add flags for individual instruction set extensions
369 if get_option('x86_version') >= '1'
370 if host_arch == 'i386'
371 qemu_common_flags = ['-mfpmath=sse'] + qemu_common_flags
373 # present on basically all processors but technically not part of
374 # x86-64-v1, so only include -mneeded for x86-64 version 2 and above
375 qemu_isa_flags += ['-mcx16']
378 if get_option('x86_version') >= '2'
379 qemu_isa_flags += ['-mpopcnt']
380 qemu_isa_flags += cc.get_supported_arguments('-mneeded')
382 if get_option('x86_version') >= '3'
383 qemu_isa_flags += ['-mmovbe', '-mabm', '-mbmi', '-mbmi2', '-mfma', '-mf16c']
386 # add required vector instruction set (each level implies those below)
387 if get_option('x86_version') == '1'
388 qemu_isa_flags += ['-msse2']
389 elif get_option('x86_version') == '2'
390 qemu_isa_flags += ['-msse4.2']
391 elif get_option('x86_version') == '3'
392 qemu_isa_flags += ['-mavx2']
393 elif get_option('x86_version') == '4'
394 qemu_isa_flags += ['-mavx512f', '-mavx512bw', '-mavx512cd', '-mavx512dq', '-mavx512vl']
398 qemu_common_flags = qemu_isa_flags + qemu_common_flags
400 if get_option('prefer_static')
401 qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
404 # Meson currently only handles pie as a boolean for now, so if the user
405 # has explicitly disabled PIE we need to extend our cflags.
407 # -no-pie is supposedly a linker flag that has no effect on the compiler
408 # command line, but some distros, that didn't quite know what they were
409 # doing, made local changes to gcc's specs file that turned it into
410 # a compiler command-line flag.
412 # What about linker flags? For a static build, no PIE is implied by -static
413 # which we added above (and if it's not because of the same specs patching,
414 # there's nothing we can do: compilation will fail, report a bug to your
415 # distro and do not use --disable-pie in the meanwhile). For dynamic linking,
416 # instead, we can't add -no-pie because it overrides -shared: the linker then
417 # tries to build an executable instead of a shared library and fails. So
418 # don't add -no-pie anywhere and cross fingers. :(
419 if not get_option('b_pie')
420 qemu_common_flags += cc.get_supported_arguments('-fno-pie', '-no-pie')
423 if not get_option('stack_protector').disabled()
424 stack_protector_probe = '''
425 int main(int argc, char *argv[])
427 char arr[64], *p = arr, *c = argv[argc - 1];
433 have_stack_protector = false
434 foreach arg : ['-fstack-protector-strong', '-fstack-protector-all']
435 # We need to check both a compile and a link, since some compiler
436 # setups fail only on a .c->.o compile and some only at link time
437 if cc.compiles(stack_protector_probe, args: ['-Werror', arg]) and \
438 cc.links(stack_protector_probe, args: ['-Werror', arg])
439 have_stack_protector = true
445 get_option('stack_protector') \
446 .require(have_stack_protector, error_message: 'Stack protector not supported')
449 coroutine_backend = get_option('coroutine_backend')
451 #include <ucontext.h>
452 #ifdef __stub_makecontext
453 #error Ignoring glibc stub makecontext which will always fail
455 int main(void) { makecontext(0, 0, 0); return 0; }'''
457 # On Windows the only valid backend is the Windows specific one.
458 # For POSIX prefer ucontext, but it's not always possible. The fallback
460 supported_backends = []
461 if host_os == 'windows'
462 supported_backends += ['windows']
464 if host_os != 'darwin' and cc.links(ucontext_probe)
465 supported_backends += ['ucontext']
467 supported_backends += ['sigaltstack']
470 if coroutine_backend == 'auto'
471 coroutine_backend = supported_backends[0]
472 elif coroutine_backend not in supported_backends
473 error('"@0@" backend requested but not available. Available backends: @1@' \
474 .format(coroutine_backend, ', '.join(supported_backends)))
477 # Compiles if SafeStack *not* enabled
478 safe_stack_probe = '''
481 #if defined(__has_feature)
482 #if __has_feature(safe_stack)
483 #error SafeStack Enabled
488 if get_option('safe_stack') != not cc.compiles(safe_stack_probe)
489 safe_stack_arg = get_option('safe_stack') ? '-fsanitize=safe-stack' : '-fno-sanitize=safe-stack'
490 if get_option('safe_stack') != not cc.compiles(safe_stack_probe, args: safe_stack_arg)
491 error(get_option('safe_stack') \
492 ? 'SafeStack not supported by your compiler' \
493 : 'Cannot disable SafeStack')
495 qemu_cflags += safe_stack_arg
496 qemu_ldflags += safe_stack_arg
498 if get_option('safe_stack') and coroutine_backend != 'ucontext'
499 error('SafeStack is only supported with the ucontext coroutine backend')
502 if get_option('asan')
503 if cc.has_argument('-fsanitize=address')
504 qemu_cflags = ['-fsanitize=address'] + qemu_cflags
505 qemu_ldflags = ['-fsanitize=address'] + qemu_ldflags
507 error('Your compiler does not support -fsanitize=address')
511 if get_option('ubsan')
512 # Detect static linking issue with ubsan:
513 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84285
514 if cc.links('int main(int argc, char **argv) { return argc + 1; }',
515 args: [qemu_ldflags, '-fsanitize=undefined'])
516 qemu_cflags += ['-fsanitize=undefined']
517 qemu_ldflags += ['-fsanitize=undefined']
519 # Suppress undefined behaviour from function call to mismatched type.
520 # In addition, tcg prologue does not emit function type prefix
521 # required by function call sanitizer.
522 if cc.has_argument('-fno-sanitize=function')
523 qemu_cflags += ['-fno-sanitize=function']
526 error('Your compiler does not support -fsanitize=undefined')
530 # Thread sanitizer is, for now, much noisier than the other sanitizers;
531 # keep it separate until that is not the case.
532 if get_option('tsan')
533 if get_option('asan') or get_option('ubsan')
534 error('TSAN is not supported with other sanitizers')
536 if not cc.has_function('__tsan_create_fiber',
537 args: '-fsanitize=thread',
538 prefix: '#include <sanitizer/tsan_interface.h>')
539 error('Cannot enable TSAN due to missing fiber annotation interface')
541 qemu_cflags = ['-fsanitize=thread'] + qemu_cflags
542 qemu_ldflags = ['-fsanitize=thread'] + qemu_ldflags
545 # Detect support for PT_GNU_RELRO + DT_BIND_NOW.
546 # The combination is known as "full relro", because .got.plt is read-only too.
547 qemu_ldflags += cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now')
549 if host_os == 'windows'
550 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat')
551 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase', '-Wl,--high-entropy-va')
554 if get_option('fuzzing')
555 # Specify a filter to only instrument code that is directly related to
557 configure_file(output: 'instrumentation-filter',
558 input: 'scripts/oss-fuzz/instrumentation-filter-template',
561 if cc.compiles('int main () { return 0; }',
562 name: '-fsanitize-coverage-allowlist=/dev/null',
563 args: ['-fsanitize-coverage-allowlist=/dev/null',
564 '-fsanitize-coverage=trace-pc'] )
565 qemu_common_flags += ['-fsanitize-coverage-allowlist=instrumentation-filter']
568 if get_option('fuzzing_engine') == ''
569 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
570 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
571 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
572 # unable to bind the fuzzer-related callbacks added by instrumentation.
573 qemu_common_flags += ['-fsanitize=fuzzer-no-link']
574 qemu_ldflags += ['-fsanitize=fuzzer-no-link']
575 # For the actual fuzzer binaries, we need to link against the libfuzzer
576 # library. They need to be configurable, to support OSS-Fuzz
577 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
579 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
580 # the needed CFLAGS have already been provided
581 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
587 # Check for dependency on LTO
588 if not get_option('b_lto')
589 error('Selected Control-Flow Integrity but LTO is disabled')
592 error('Selected Control-Flow Integrity is not compatible with modules')
594 # Check for cfi flags. CFI requires LTO so we can't use
595 # get_supported_arguments, but need a more complex "compiles" which allows
597 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
598 args: ['-flto', '-fsanitize=cfi-icall'] )
599 cfi_flags += '-fsanitize=cfi-icall'
601 error('-fsanitize=cfi-icall is not supported by the compiler')
603 if cc.compiles('int main () { return 0; }',
604 name: '-fsanitize-cfi-icall-generalize-pointers',
605 args: ['-flto', '-fsanitize=cfi-icall',
606 '-fsanitize-cfi-icall-generalize-pointers'] )
607 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
609 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
611 if get_option('cfi_debug')
612 if cc.compiles('int main () { return 0; }',
613 name: '-fno-sanitize-trap=cfi-icall',
614 args: ['-flto', '-fsanitize=cfi-icall',
615 '-fno-sanitize-trap=cfi-icall'] )
616 cfi_flags += '-fno-sanitize-trap=cfi-icall'
618 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
621 add_global_arguments(cfi_flags, native: false, language: all_languages)
622 add_global_link_arguments(cfi_flags, native: false, language: all_languages)
625 # Check further flags that make QEMU more robust against malicious parties
628 # Initialize all stack variables to zero. This makes
629 # it harder to take advantage of uninitialized stack
630 # data to drive exploits
631 '-ftrivial-auto-var-init=zero',
634 # Zero out registers used during a function call
635 # upon its return. This makes it harder to assemble
636 # ROP gadgets into something usable
638 # NB: Clang 17 is broken and SEGVs
639 # https://github.com/llvm/llvm-project/issues/75168
641 # NB2: This clashes with the "retguard" extension of OpenBSD's Clang
642 # https://gitlab.com/qemu-project/qemu/-/issues/2278
643 if host_os != 'openbsd' and \
644 cc.compiles('extern struct { void (*cb)(void); } s; void f(void) { s.cb(); }',
645 name: '-fzero-call-used-regs=used-gpr',
646 args: ['-O2', '-fzero-call-used-regs=used-gpr'])
647 hardening_flags += '-fzero-call-used-regs=used-gpr'
650 qemu_common_flags += cc.get_supported_arguments(hardening_flags)
652 add_global_arguments(qemu_common_flags, native: false, language: all_languages)
653 add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
655 # Collect warning flags we want to set, sorted alphabetically
657 # First enable interesting warnings
660 '-Wexpansion-to-defined',
663 '-Wignored-qualifiers',
664 '-Wimplicit-fallthrough=2',
666 '-Wmissing-format-attribute',
667 '-Wmissing-prototypes',
669 '-Wold-style-declaration',
670 '-Wold-style-definition',
673 '-Wstrict-prototypes',
679 # Then disable some undesirable warnings
680 '-Wno-gnu-variable-sized-type-not-at-end',
681 '-Wno-initializer-overrides',
682 '-Wno-missing-include-dirs',
684 '-Wno-shift-negative-value',
685 '-Wno-string-plus-int',
686 '-Wno-tautological-type-limit-compare',
687 '-Wno-typedef-redefinition',
690 if host_os != 'darwin'
691 tsa_has_cleanup = cc.compiles('''
692 struct __attribute__((capability("mutex"))) mutex {};
693 void lock(struct mutex *m) __attribute__((acquire_capability(m)));
694 void unlock(struct mutex *m) __attribute__((release_capability(m)));
697 struct mutex __attribute__((cleanup(unlock))) m;
700 ''', args: ['-Wthread-safety', '-Werror'])
702 warn_flags += ['-Wthread-safety']
706 # Set up C++ compiler flags
708 if 'cpp' in all_languages
709 qemu_cxxflags = ['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'] + qemu_cflags
712 add_project_arguments(qemu_cflags, native: false, language: 'c')
713 add_project_arguments(cc.get_supported_arguments(warn_flags), native: false, language: 'c')
714 if 'cpp' in all_languages
715 add_project_arguments(qemu_cxxflags, native: false, language: 'cpp')
716 add_project_arguments(cxx.get_supported_arguments(warn_flags), native: false, language: 'cpp')
718 if 'objc' in all_languages
719 # Note sanitizer flags are not applied to Objective-C sources!
720 add_project_arguments(objc.get_supported_arguments(warn_flags), native: false, language: 'objc')
722 if host_os == 'linux'
723 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
724 '-isystem', 'linux-headers',
725 language: all_languages)
728 add_project_arguments('-iquote', '.',
729 '-iquote', meson.current_source_dir(),
730 '-iquote', meson.current_source_dir() / 'include',
731 language: all_languages)
733 # If a host-specific include directory exists, list that first...
734 host_include = meson.current_source_dir() / 'host/include/'
735 if fs.is_dir(host_include / host_arch)
736 add_project_arguments('-iquote', host_include / host_arch,
737 language: all_languages)
739 # ... followed by the generic fallback.
740 add_project_arguments('-iquote', host_include / 'generic',
741 language: all_languages)
743 sparse = find_program('cgcc', required: get_option('sparse'))
746 command: [find_program('scripts/check_sparse.py'),
747 'compile_commands.json', sparse.full_path(), '-Wbitwise',
748 '-Wno-transparent-union', '-Wno-old-initializer',
749 '-Wno-non-pointer-null'])
752 #####################################
753 # Host-specific libraries and flags #
754 #####################################
756 libm = cc.find_library('m', required: false)
757 threads = dependency('threads')
758 util = cc.find_library('util', required: false)
764 emulator_link_args = []
769 if host_os == 'windows'
770 midl = find_program('midl', required: false)
771 widl = find_program('widl', required: false)
772 pathcch = cc.find_library('pathcch')
773 socket = cc.find_library('ws2_32')
774 winmm = cc.find_library('winmm')
776 win = import('windows')
777 version_res = win.compile_resources('version.rc',
778 depend_files: files('pc-bios/qemu-nsis.ico'),
779 include_directories: include_directories('.'))
781 elif host_os == 'darwin'
782 coref = dependency('appleframeworks', modules: 'CoreFoundation')
783 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
784 host_dsosuf = '.dylib'
785 elif host_os == 'sunos'
786 socket = [cc.find_library('socket'),
787 cc.find_library('nsl'),
788 cc.find_library('resolv')]
789 elif host_os == 'haiku'
790 socket = [cc.find_library('posix_error_mapper'),
791 cc.find_library('network'),
792 cc.find_library('bsd')]
793 elif host_os == 'openbsd'
794 if get_option('tcg').allowed() and target_dirs.length() > 0
795 # Disable OpenBSD W^X if available
796 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
800 ###############################################
801 # Host-specific configuration of accelerators #
802 ###############################################
805 if get_option('kvm').allowed() and host_os == 'linux'
806 accelerators += 'CONFIG_KVM'
808 if get_option('whpx').allowed() and host_os == 'windows'
809 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
810 error('WHPX requires 64-bit host')
811 elif cc.has_header('winhvplatform.h', required: get_option('whpx')) and \
812 cc.has_header('winhvemulation.h', required: get_option('whpx'))
813 accelerators += 'CONFIG_WHPX'
818 if get_option('hvf').allowed()
819 hvf = dependency('appleframeworks', modules: 'Hypervisor',
820 required: get_option('hvf'))
822 accelerators += 'CONFIG_HVF'
827 if host_os == 'netbsd'
828 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
830 accelerators += 'CONFIG_NVMM'
835 if get_option('tcg').allowed()
836 if host_arch == 'unknown'
837 if not get_option('tcg_interpreter')
838 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
840 elif get_option('tcg_interpreter')
841 warning('Use of the TCG interpreter is not recommended on this host')
842 warning('architecture. There is a native TCG execution backend available')
843 warning('which provides substantially better performance and reliability.')
844 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
845 warning('configuration option on this architecture to use the native')
848 if get_option('tcg_interpreter')
850 elif host_arch == 'x86_64'
852 elif host_arch == 'ppc64'
855 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
856 language: all_languages)
858 accelerators += 'CONFIG_TCG'
861 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
862 error('KVM not available on this platform')
864 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
865 error('HVF not available on this platform')
867 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
868 error('NVMM not available on this platform')
870 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
871 error('WHPX not available on this platform')
875 if get_option('xen').enabled() or (get_option('xen').auto() and have_system)
876 xencontrol = dependency('xencontrol', required: false,
877 method: 'pkg-config')
878 if xencontrol.found()
879 xen_pc = declare_dependency(version: xencontrol.version(),
882 # disabler: true makes xen_pc.found() return false if any is not found
883 dependency('xenstore', required: false,
884 method: 'pkg-config',
886 dependency('xenforeignmemory', required: false,
887 method: 'pkg-config',
889 dependency('xengnttab', required: false,
890 method: 'pkg-config',
892 dependency('xenevtchn', required: false,
893 method: 'pkg-config',
895 dependency('xendevicemodel', required: false,
896 method: 'pkg-config',
898 # optional, no "disabler: true"
899 dependency('xentoolcore', required: false,
900 method: 'pkg-config')])
906 xen_tests = [ '4.11.0', '4.10.0', '4.9.0', '4.8.0', '4.7.1' ]
908 '4.11.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
909 '4.10.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
910 '4.9.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
911 '4.8.0': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
912 '4.7.1': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
915 foreach ver: xen_tests
916 # cache the various library tests to avoid polluting the logs
918 foreach l: xen_libs[ver]
920 xen_deps += { l: cc.find_library(l, required: false) }
922 xen_test_deps += xen_deps[l]
925 # Use -D to pick just one of the test programs in scripts/xen-detect.c
926 xen_version = ver.split('.')
927 xen_ctrl_version = xen_version[0] + \
928 ('0' + xen_version[1]).substring(-2) + \
929 ('0' + xen_version[2]).substring(-2)
930 if cc.links(files('scripts/xen-detect.c'),
931 args: '-DCONFIG_XEN_CTRL_INTERFACE_VERSION=' + xen_ctrl_version,
932 dependencies: xen_test_deps)
933 xen = declare_dependency(version: ver, dependencies: xen_test_deps)
939 accelerators += 'CONFIG_XEN'
940 elif get_option('xen').enabled()
941 error('could not compile and link Xen test program')
944 have_xen_pci_passthrough = get_option('xen_pci_passthrough') \
945 .require(xen.found(),
946 error_message: 'Xen PCI passthrough requested but Xen not enabled') \
947 .require(host_os == 'linux',
948 error_message: 'Xen PCI passthrough not available on this platform') \
949 .require(cpu == 'x86' or cpu == 'x86_64',
950 error_message: 'Xen PCI passthrough not available on this platform') \
957 # When bumping glib minimum version, please check also whether to increase
958 # the _WIN32_WINNT setting in osdep.h according to the value from glib.
959 # You should also check if any of the glib.version() checks
960 # below can also be removed.
961 glib_req_ver = '>=2.66.0'
962 glib_pc = dependency('glib-2.0', version: glib_req_ver, required: true,
963 method: 'pkg-config')
966 gmodule = dependency('gmodule-export-2.0', version: glib_req_ver, required: true,
967 method: 'pkg-config')
968 elif get_option('plugins')
969 gmodule = dependency('gmodule-no-export-2.0', version: glib_req_ver, required: true,
970 method: 'pkg-config')
975 # This workaround is required due to a bug in pkg-config file for glib as it
976 # doesn't define GLIB_STATIC_COMPILATION for pkg-config --static
977 if host_os == 'windows' and get_option('prefer_static')
978 glib_cflags += ['-DGLIB_STATIC_COMPILATION']
981 # Sanity check that the current size_t matches the
982 # size that glib thinks it should be. This catches
983 # problems on multi-arch where people try to build
984 # 32-bit QEMU while pointing at 64-bit glib headers
986 if not cc.compiles('''
990 #define QEMU_BUILD_BUG_ON(x) \
991 typedef char qemu_build_bug_on[(x)?-1:1] __attribute__((unused));
994 QEMU_BUILD_BUG_ON(sizeof(size_t) != GLIB_SIZEOF_SIZE_T);
996 }''', dependencies: glib_pc, args: glib_cflags)
997 error('''sizeof(size_t) doesn't match GLIB_SIZEOF_SIZE_T.
998 You probably need to set PKG_CONFIG_LIBDIR" to point
999 to the right pkg-config files for your build target.''')
1002 glib = declare_dependency(dependencies: [glib_pc, gmodule],
1003 compile_args: glib_cflags,
1004 version: glib_pc.version())
1006 # Check whether glib has gslice, which we have to avoid for correctness.
1007 # TODO: remove this check and the corresponding workaround (qtree) when
1008 # the minimum supported glib is >= 2.75.3
1009 glib_has_gslice = glib.version().version_compare('<2.75.3')
1010 # Check whether glib has the aligned_alloc family of functions.
1011 # <https://docs.gtk.org/glib/func.aligned_alloc.html>
1012 glib_has_aligned_alloc = glib.version().version_compare('>=2.72.0')
1014 # override glib dep to include the above refinements
1015 meson.override_dependency('glib-2.0', glib)
1017 # The path to glib.h is added to all compilation commands.
1018 add_project_dependencies(glib.partial_dependency(compile_args: true, includes: true),
1019 native: false, language: all_languages)
1022 gdbus_codegen = not_found
1023 gdbus_codegen_error = '@0@ requires gdbus-codegen, please install libgio'
1024 if not get_option('gio').auto() or have_system
1025 gio = dependency('gio-2.0', required: get_option('gio'),
1026 method: 'pkg-config')
1027 if gio.found() and not cc.links('''
1028 #include <gio/gio.h>
1031 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
1033 }''', dependencies: [glib, gio])
1034 if get_option('gio').enabled()
1035 error('The installed libgio is broken for static linking')
1040 gdbus_codegen = find_program('gdbus-codegen',
1041 required: get_option('gio'))
1042 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
1043 method: 'pkg-config')
1044 gio = declare_dependency(dependencies: [gio, gio_unix],
1045 version: gio.version())
1048 if gdbus_codegen.found() and get_option('cfi')
1049 gdbus_codegen = not_found
1050 gdbus_codegen_error = '@0@ uses gdbus-codegen, which does not support control flow integrity'
1053 xml_pp = find_program('scripts/xml-preprocess.py')
1056 if 'ust' in get_option('trace_backends')
1057 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
1058 method: 'pkg-config')
1061 if not get_option('pixman').auto() or have_system or have_tools
1062 pixman = dependency('pixman-1', required: get_option('pixman'), version:'>=0.21.8',
1063 method: 'pkg-config')
1066 zlib = dependency('zlib', required: true)
1069 if not get_option('linux_aio').auto() or have_block
1070 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
1071 required: get_option('linux_aio'))
1074 linux_io_uring_test = '''
1075 #include <liburing.h>
1076 #include <linux/errqueue.h>
1078 int main(void) { return 0; }'''
1080 linux_io_uring = not_found
1081 if not get_option('linux_io_uring').auto() or have_block
1082 linux_io_uring = dependency('liburing', version: '>=0.3',
1083 required: get_option('linux_io_uring'),
1084 method: 'pkg-config')
1085 if not cc.links(linux_io_uring_test)
1086 linux_io_uring = not_found
1091 if not get_option('libnfs').auto() or have_block
1092 libnfs = dependency('libnfs', version: '>=1.9.3',
1093 required: get_option('libnfs'),
1094 method: 'pkg-config')
1099 #include <sys/types.h>
1100 #ifdef CONFIG_LIBATTR
1101 #include <attr/xattr.h>
1103 #include <sys/xattr.h>
1105 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
1108 have_old_libattr = false
1109 if get_option('attr').allowed()
1110 if cc.links(libattr_test)
1111 libattr = declare_dependency()
1113 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
1114 required: get_option('attr'))
1115 if libattr.found() and not \
1116 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
1118 if get_option('attr').enabled()
1119 error('could not link libattr')
1121 warning('could not link libattr, disabling')
1124 have_old_libattr = libattr.found()
1129 cocoa = dependency('appleframeworks',
1130 modules: ['Cocoa', 'CoreVideo', 'QuartzCore'],
1131 required: get_option('cocoa'))
1133 vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
1134 if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
1135 'VMNET_BRIDGED_MODE',
1136 dependencies: vmnet)
1138 if get_option('vmnet').enabled()
1139 error('vmnet.framework API is outdated')
1141 warning('vmnet.framework API is outdated, disabling')
1146 seccomp_has_sysrawrc = false
1147 if not get_option('seccomp').auto() or have_system or have_tools
1148 seccomp = dependency('libseccomp', version: '>=2.3.0',
1149 required: get_option('seccomp'),
1150 method: 'pkg-config')
1152 seccomp_has_sysrawrc = cc.has_header_symbol('seccomp.h',
1153 'SCMP_FLTATR_API_SYSRAWRC',
1154 dependencies: seccomp)
1158 libcap_ng = not_found
1159 if not get_option('cap_ng').auto() or have_system or have_tools
1160 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
1161 required: get_option('cap_ng'))
1163 if libcap_ng.found() and not cc.links('''
1167 capng_capability_to_name(CAPNG_EFFECTIVE);
1169 }''', dependencies: libcap_ng)
1170 libcap_ng = not_found
1171 if get_option('cap_ng').enabled()
1172 error('could not link libcap-ng')
1174 warning('could not link libcap-ng, disabling')
1178 if get_option('xkbcommon').auto() and not have_system and not have_tools
1179 xkbcommon = not_found
1181 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
1182 method: 'pkg-config')
1186 if not get_option('slirp').auto() or have_system
1187 slirp = dependency('slirp', required: get_option('slirp'),
1188 method: 'pkg-config')
1189 # slirp < 4.7 is incompatible with CFI support in QEMU. This is because
1190 # it passes function pointers within libslirp as callbacks for timers.
1191 # When using a system-wide shared libslirp, the type information for the
1192 # callback is missing and the timer call produces a false positive with CFI.
1193 # Do not use the "version" keyword argument to produce a better error.
1194 # with control-flow integrity.
1195 if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
1196 if get_option('slirp').enabled()
1197 error('Control-Flow Integrity requires libslirp 4.7.')
1199 warning('Cannot use libslirp since Control-Flow Integrity requires libslirp >= 4.7.')
1206 if not get_option('vde').auto() or have_system or have_tools
1207 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
1208 required: get_option('vde'))
1210 if vde.found() and not cc.links('''
1211 #include <libvdeplug.h>
1214 struct vde_open_args a = {0, 0, 0};
1218 }''', dependencies: vde)
1220 if get_option('cap_ng').enabled()
1221 error('could not link libvdeplug')
1223 warning('could not link libvdeplug, disabling')
1228 if not get_option('pa').auto() or (host_os == 'linux' and have_system)
1229 pulse = dependency('libpulse', required: get_option('pa'),
1230 method: 'pkg-config')
1233 if not get_option('alsa').auto() or (host_os == 'linux' and have_system)
1234 alsa = dependency('alsa', required: get_option('alsa'),
1235 method: 'pkg-config')
1238 if not get_option('jack').auto() or have_system
1239 jack = dependency('jack', required: get_option('jack'),
1240 method: 'pkg-config')
1242 pipewire = not_found
1243 if not get_option('pipewire').auto() or (host_os == 'linux' and have_system)
1244 pipewire = dependency('libpipewire-0.3', version: '>=0.3.60',
1245 required: get_option('pipewire'),
1246 method: 'pkg-config')
1249 if not get_option('sndio').auto() or have_system
1250 sndio = dependency('sndio', required: get_option('sndio'),
1251 method: 'pkg-config')
1254 spice_protocol = not_found
1255 if not get_option('spice_protocol').auto() or have_system
1256 spice_protocol = dependency('spice-protocol', version: '>=0.14.0',
1257 required: get_option('spice_protocol'),
1258 method: 'pkg-config')
1261 if get_option('spice') \
1262 .disable_auto_if(not have_system) \
1263 .require(pixman.found(),
1264 error_message: 'cannot enable SPICE if pixman is not available') \
1266 spice = dependency('spice-server', version: '>=0.14.0',
1267 required: get_option('spice'),
1268 method: 'pkg-config')
1270 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
1272 rt = cc.find_library('rt', required: false)
1274 libiscsi = not_found
1275 if not get_option('libiscsi').auto() or have_block
1276 libiscsi = dependency('libiscsi', version: '>=1.9.0',
1277 required: get_option('libiscsi'),
1278 method: 'pkg-config')
1281 if not get_option('zstd').auto() or have_block
1282 zstd = dependency('libzstd', version: '>=1.4.0',
1283 required: get_option('zstd'),
1284 method: 'pkg-config')
1287 if not get_option('qpl').auto() or have_system
1288 qpl = dependency('qpl', version: '>=1.5.0',
1289 required: get_option('qpl'),
1290 method: 'pkg-config')
1293 if not get_option('uadk').auto() or have_system
1294 libwd = dependency('libwd', version: '>=2.6',
1295 required: get_option('uadk'),
1296 method: 'pkg-config')
1297 libwd_comp = dependency('libwd_comp', version: '>=2.6',
1298 required: get_option('uadk'),
1299 method: 'pkg-config')
1300 if libwd.found() and libwd_comp.found()
1301 uadk = declare_dependency(dependencies: [libwd, libwd_comp])
1306 if not get_option('qatzip').auto() or have_system
1307 qatzip = dependency('qatzip', version: '>=1.1.2',
1308 required: get_option('qatzip'),
1309 method: 'pkg-config')
1314 have_vhost_user_gpu = have_tools and host_os == 'linux' and pixman.found()
1315 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
1316 virgl = dependency('virglrenderer',
1317 method: 'pkg-config',
1318 required: get_option('virglrenderer'))
1320 rutabaga = not_found
1321 if not get_option('rutabaga_gfx').auto() or have_system or have_vhost_user_gpu
1322 rutabaga = dependency('rutabaga_gfx_ffi',
1323 method: 'pkg-config',
1324 required: get_option('rutabaga_gfx'))
1327 if not get_option('blkio').auto() or have_block
1328 blkio = dependency('blkio',
1329 method: 'pkg-config',
1330 required: get_option('blkio'))
1333 if not get_option('curl').auto() or have_block
1334 curl = dependency('libcurl', version: '>=7.29.0',
1335 method: 'pkg-config',
1336 required: get_option('curl'))
1339 if host_os == 'linux' and (have_system or have_tools)
1340 libudev = dependency('libudev',
1341 method: 'pkg-config',
1342 required: get_option('libudev'))
1345 mpathlibs = [libudev]
1346 mpathpersist = not_found
1347 if host_os == 'linux' and have_tools and get_option('mpath').allowed()
1348 mpath_test_source = '''
1349 #include <libudev.h>
1350 #include <mpath_persist.h>
1351 unsigned mpath_mx_alloc_len = 1024;
1353 static struct config *multipath_conf;
1354 extern struct udev *udev;
1355 extern struct config *get_multipath_config(void);
1356 extern void put_multipath_config(struct config *conf);
1358 struct config *get_multipath_config(void) { return multipath_conf; }
1359 void put_multipath_config(struct config *conf) { }
1362 multipath_conf = mpath_lib_init();
1365 libmpathpersist = cc.find_library('mpathpersist',
1366 required: get_option('mpath'))
1367 if libmpathpersist.found()
1368 mpathlibs += libmpathpersist
1369 if get_option('prefer_static')
1370 mpathlibs += cc.find_library('devmapper',
1371 required: get_option('mpath'))
1373 mpathlibs += cc.find_library('multipath',
1374 required: get_option('mpath'))
1375 foreach lib: mpathlibs
1381 if mpathlibs.length() == 0
1382 msg = 'Dependencies missing for libmpathpersist'
1383 elif cc.links(mpath_test_source, dependencies: mpathlibs)
1384 mpathpersist = declare_dependency(dependencies: mpathlibs)
1386 msg = 'Cannot detect libmpathpersist API'
1388 if not mpathpersist.found()
1389 if get_option('mpath').enabled()
1392 warning(msg + ', disabling')
1400 if have_system and get_option('curses').allowed()
1402 #if defined(__APPLE__) || defined(__OpenBSD__)
1403 #define _XOPEN_SOURCE_EXTENDED 1
1410 setlocale(LC_ALL, "");
1412 addwstr(L"wide chars\n");
1414 add_wch(WACS_DEGREE);
1418 curses_dep_list = host_os == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
1419 curses = dependency(curses_dep_list,
1421 method: 'pkg-config')
1422 msg = get_option('curses').enabled() ? 'curses library not found' : ''
1423 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
1425 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
1426 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses],
1427 version: curses.version())
1429 msg = 'curses package not usable'
1433 if not curses.found()
1434 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1435 if host_os != 'windows' and not has_curses_h
1436 message('Trying with /usr/include/ncursesw')
1437 curses_compile_args += ['-I/usr/include/ncursesw']
1438 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
1441 curses_libname_list = (host_os == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
1442 foreach curses_libname : curses_libname_list
1443 libcurses = cc.find_library(curses_libname,
1445 if libcurses.found()
1446 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
1447 curses = declare_dependency(compile_args: curses_compile_args,
1448 dependencies: [libcurses])
1451 msg = 'curses library not usable'
1457 if get_option('iconv').allowed()
1458 foreach link_args : [ ['-liconv'], [] ]
1459 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
1460 # We need to use libiconv if available because mixing libiconv's headers with
1461 # the system libc does not work.
1462 # However, without adding glib to the dependencies -L/usr/local/lib will not be
1463 # included in the command line and libiconv will not be found.
1467 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
1468 return conv != (iconv_t) -1;
1469 }''', args: link_args, dependencies: glib)
1470 iconv = declare_dependency(link_args: link_args, dependencies: glib)
1475 if curses.found() and not iconv.found()
1476 if get_option('iconv').enabled()
1477 error('iconv not available')
1479 msg = 'iconv required for curses UI but not available'
1482 if not curses.found() and msg != ''
1483 if get_option('curses').enabled()
1486 warning(msg + ', disabling')
1492 if not get_option('brlapi').auto() or have_system
1493 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
1494 required: get_option('brlapi'))
1495 if brlapi.found() and not cc.links('''
1498 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
1500 if get_option('brlapi').enabled()
1501 error('could not link brlapi')
1503 warning('could not link brlapi, disabling')
1509 if not get_option('sdl').auto() or have_system
1510 sdl = dependency('sdl2', required: get_option('sdl'))
1511 sdl_image = not_found
1514 # Some versions of SDL have problems with -Wundef
1515 if not cc.compiles('''
1517 #include <SDL_syswm.h>
1518 int main(int argc, char *argv[]) { return 0; }
1519 ''', dependencies: sdl, args: '-Werror=undef')
1520 sdl = declare_dependency(compile_args: '-Wno-undef',
1522 version: sdl.version())
1524 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
1525 method: 'pkg-config')
1527 if get_option('sdl_image').enabled()
1528 error('sdl-image required, but SDL was @0@'.format(
1529 get_option('sdl').disabled() ? 'disabled' : 'not found'))
1531 sdl_image = not_found
1535 if not get_option('rbd').auto() or have_block
1536 librados = cc.find_library('rados', required: get_option('rbd'))
1537 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
1538 required: get_option('rbd'))
1539 if librados.found() and librbd.found()
1542 #include <rbd/librbd.h>
1545 rados_create(&cluster, NULL);
1546 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
1550 }''', dependencies: [librbd, librados])
1551 rbd = declare_dependency(dependencies: [librbd, librados])
1552 elif get_option('rbd').enabled()
1553 error('librbd >= 1.12.0 required')
1555 warning('librbd >= 1.12.0 not found, disabling')
1560 glusterfs = not_found
1561 glusterfs_ftruncate_has_stat = false
1562 glusterfs_iocb_has_stat = false
1563 if not get_option('glusterfs').auto() or have_block
1564 glusterfs = dependency('glusterfs-api', version: '>=3',
1565 required: get_option('glusterfs'),
1566 method: 'pkg-config')
1567 if glusterfs.found()
1568 glusterfs_ftruncate_has_stat = cc.links('''
1569 #include <glusterfs/api/glfs.h>
1574 /* new glfs_ftruncate() passes two additional args */
1575 return glfs_ftruncate(NULL, 0, NULL, NULL);
1577 ''', dependencies: glusterfs)
1578 glusterfs_iocb_has_stat = cc.links('''
1579 #include <glusterfs/api/glfs.h>
1581 /* new glfs_io_cbk() passes two additional glfs_stat structs */
1583 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
1589 glfs_io_cbk iocb = &glusterfs_iocb;
1590 iocb(NULL, 0 , NULL, NULL, NULL);
1593 ''', dependencies: glusterfs)
1598 if get_option('hv_balloon').allowed() and have_system
1601 #include <gmodule.h>
1605 tree = g_tree_new((GCompareFunc)strcmp);
1606 (void)g_tree_node_first(tree);
1607 g_tree_destroy(tree);
1610 ''', dependencies: glib)
1613 if get_option('hv_balloon').enabled()
1614 error('could not enable hv-balloon, update your glib')
1616 warning('could not find glib support for hv-balloon, disabling')
1622 if not get_option('libssh').auto() or have_block
1623 libssh = dependency('libssh', version: '>=0.8.7',
1624 method: 'pkg-config',
1625 required: get_option('libssh'))
1628 libbzip2 = not_found
1629 if not get_option('bzip2').auto() or have_block
1630 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
1631 required: get_option('bzip2'))
1632 if libbzip2.found() and not cc.links('''
1634 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
1635 libbzip2 = not_found
1636 if get_option('bzip2').enabled()
1637 error('could not link libbzip2')
1639 warning('could not link libbzip2, disabling')
1644 liblzfse = not_found
1645 if not get_option('lzfse').auto() or have_block
1646 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
1647 required: get_option('lzfse'))
1649 if liblzfse.found() and not cc.links('''
1651 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
1652 liblzfse = not_found
1653 if get_option('lzfse').enabled()
1654 error('could not link liblzfse')
1656 warning('could not link liblzfse, disabling')
1661 if get_option('oss').allowed() and have_system
1662 if not cc.has_header('sys/soundcard.h')
1664 elif host_os == 'netbsd'
1665 oss = cc.find_library('ossaudio', required: get_option('oss'))
1667 oss = declare_dependency()
1671 if get_option('oss').enabled()
1672 error('OSS not found')
1677 if not get_option('dsound').auto() or (host_os == 'windows' and have_system)
1678 if cc.has_header('dsound.h')
1679 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
1682 if not dsound.found()
1683 if get_option('dsound').enabled()
1684 error('DirectSound not found')
1689 coreaudio = not_found
1690 if not get_option('coreaudio').auto() or (host_os == 'darwin' and have_system)
1691 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
1692 required: get_option('coreaudio'))
1696 if not get_option('opengl').auto() or have_system or have_vhost_user_gpu
1697 epoxy = dependency('epoxy', method: 'pkg-config',
1698 required: get_option('opengl'))
1699 if cc.has_header('epoxy/egl.h', dependencies: epoxy)
1701 elif get_option('opengl').enabled()
1702 error('epoxy/egl.h not found')
1706 if (have_system or have_tools) and (virgl.found() or opengl.found())
1707 gbm = dependency('gbm', method: 'pkg-config', required: false)
1709 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and opengl.found() and gbm.found()
1712 gnutls_crypto = not_found
1713 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1714 # For general TLS support our min gnutls matches
1715 # that implied by our platform support matrix
1717 # For the crypto backends, we look for a newer
1720 # Version 3.6.8 is needed to get XTS
1721 # Version 3.6.13 is needed to get PBKDF
1722 # Version 3.6.14 is needed to get HW accelerated XTS
1724 # If newer enough gnutls isn't available, we can
1725 # still use a different crypto backend to satisfy
1726 # the platform support requirements
1727 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1728 method: 'pkg-config',
1730 if gnutls_crypto.found()
1731 gnutls = gnutls_crypto
1733 # Our min version if all we need is TLS
1734 gnutls = dependency('gnutls', version: '>=3.5.18',
1735 method: 'pkg-config',
1736 required: get_option('gnutls'))
1740 # We prefer use of gnutls for crypto, unless the options
1741 # explicitly asked for nettle or gcrypt.
1743 # If gnutls isn't available for crypto, then we'll prefer
1744 # gcrypt over nettle for performance reasons.
1748 crypto_sm4 = not_found
1751 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1752 error('Only one of gcrypt & nettle can be enabled')
1755 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1756 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1757 gnutls_crypto = not_found
1760 if not gnutls_crypto.found()
1761 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1762 gcrypt = dependency('libgcrypt', version: '>=1.8',
1763 required: get_option('gcrypt'))
1764 # Debian has removed -lgpg-error from libgcrypt-config
1765 # as it "spreads unnecessary dependencies" which in
1766 # turn breaks static builds...
1767 if gcrypt.found() and get_option('prefer_static')
1768 gcrypt = declare_dependency(dependencies:
1770 cc.find_library('gpg-error', required: true)],
1771 version: gcrypt.version())
1774 # SM4 ALG is available in libgcrypt >= 1.9
1775 if gcrypt.found() and not cc.links('''
1778 gcry_cipher_hd_t handler;
1779 gcry_cipher_open(&handler, GCRY_CIPHER_SM4, GCRY_CIPHER_MODE_ECB, 0);
1781 }''', dependencies: gcrypt)
1782 crypto_sm4 = not_found
1785 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1786 nettle = dependency('nettle', version: '>=3.4',
1787 method: 'pkg-config',
1788 required: get_option('nettle'))
1789 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1793 # SM4 ALG is available in nettle >= 3.9
1794 if nettle.found() and not cc.links('''
1795 #include <nettle/sm4.h>
1798 unsigned char key[16] = {0};
1799 sm4_set_encrypt_key(&ctx, key);
1801 }''', dependencies: nettle)
1802 crypto_sm4 = not_found
1807 capstone = not_found
1808 if not get_option('capstone').auto() or have_system or have_user
1809 capstone = dependency('capstone', version: '>=3.0.5',
1810 method: 'pkg-config',
1811 required: get_option('capstone'))
1813 # Some versions of capstone have broken pkg-config file
1814 # that reports a wrong -I path, causing the #include to
1815 # fail later. If the system has such a broken version
1817 if capstone.found() and not cc.compiles('#include <capstone.h>',
1818 dependencies: [capstone])
1819 capstone = not_found
1820 if get_option('capstone').enabled()
1821 error('capstone requested, but it does not appear to work')
1826 gmp = dependency('gmp', required: false, method: 'pkg-config')
1827 if nettle.found() and gmp.found()
1828 hogweed = dependency('hogweed', version: '>=3.4',
1829 method: 'pkg-config',
1830 required: get_option('nettle'))
1837 have_gtk_clipboard = get_option('gtk_clipboard').enabled()
1839 if get_option('gtk') \
1840 .disable_auto_if(not have_system) \
1841 .require(pixman.found(),
1842 error_message: 'cannot enable GTK if pixman is not available') \
1844 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1845 method: 'pkg-config',
1846 required: get_option('gtk'))
1848 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1849 method: 'pkg-config',
1851 gtk = declare_dependency(dependencies: [gtk, gtkx11],
1852 version: gtk.version())
1854 if not get_option('vte').auto() or have_system
1855 vte = dependency('vte-2.91',
1856 method: 'pkg-config',
1857 required: get_option('vte'))
1859 elif have_gtk_clipboard
1860 error('GTK clipboard requested, but GTK not found')
1866 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found())
1869 if get_option('png').allowed() and have_system
1870 png = dependency('libpng', version: '>=1.6.34', required: get_option('png'),
1871 method: 'pkg-config')
1876 if get_option('vnc') \
1877 .disable_auto_if(not have_system) \
1878 .require(pixman.found(),
1879 error_message: 'cannot enable VNC if pixman is not available') \
1881 vnc = declare_dependency() # dummy dependency
1882 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1883 method: 'pkg-config')
1884 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1885 required: get_option('vnc_sasl'))
1887 sasl = declare_dependency(dependencies: sasl,
1888 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1893 if not get_option('auth_pam').auto() or have_system
1894 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1895 required: get_option('auth_pam'))
1897 if pam.found() and not cc.links('''
1899 #include <security/pam_appl.h>
1901 const char *service_name = "qemu";
1902 const char *user = "frank";
1903 const struct pam_conv pam_conv = { 0 };
1904 pam_handle_t *pamh = NULL;
1905 pam_start(service_name, user, &pam_conv, &pamh);
1907 }''', dependencies: pam)
1909 if get_option('auth_pam').enabled()
1910 error('could not link libpam')
1912 warning('could not link libpam, disabling')
1917 if not get_option('snappy').auto() or have_system
1918 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1919 required: get_option('snappy'))
1921 if snappy.found() and not cc.links('''
1922 #include <snappy-c.h>
1923 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1925 if get_option('snappy').enabled()
1926 error('could not link libsnappy')
1928 warning('could not link libsnappy, disabling')
1933 if not get_option('lzo').auto() or have_system
1934 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1935 required: get_option('lzo'))
1937 if lzo.found() and not cc.links('''
1938 #include <lzo/lzo1x.h>
1939 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1941 if get_option('lzo').enabled()
1942 error('could not link liblzo2')
1944 warning('could not link liblzo2, disabling')
1949 if not get_option('numa').auto() or have_system or have_tools
1950 numa = cc.find_library('numa', has_headers: ['numa.h'],
1951 required: get_option('numa'))
1953 if numa.found() and not cc.links('''
1955 int main(void) { return numa_available(); }
1956 ''', dependencies: numa)
1958 if get_option('numa').enabled()
1959 error('could not link numa')
1961 warning('could not link numa, disabling')
1966 fdt_opt = get_option('fdt')
1967 if fdt_opt == 'enabled' and get_option('wrap_mode') == 'nodownload'
1970 if fdt_opt in ['enabled', 'system'] or (fdt_opt == 'auto' and have_system)
1971 fdt = cc.find_library('fdt', required: fdt_opt == 'system')
1972 if fdt.found() and cc.links('''
1974 #include <libfdt_env.h>
1975 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
1978 elif fdt_opt != 'system'
1979 fdt_opt = get_option('wrap_mode') == 'nodownload' ? 'disabled' : 'internal'
1982 error('system libfdt is too old (1.5.1 or newer required)')
1985 if fdt_opt == 'internal'
1986 assert(not fdt.found())
1987 libfdt_proj = subproject('dtc', required: true,
1988 default_options: ['tools=false', 'yaml=disabled',
1989 'python=disabled', 'default_library=static'])
1990 fdt = libfdt_proj.get_variable('libfdt_dep')
1994 if not get_option('rdma').auto() or have_system
1995 rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'],
1996 required: get_option('rdma')),
1997 cc.find_library('ibverbs', required: get_option('rdma'))]
1998 rdma = declare_dependency(dependencies: rdma_libs)
1999 foreach lib: rdma_libs
2007 if not get_option('smartcard').auto() or have_system
2008 cacard = dependency('libcacard', required: get_option('smartcard'),
2009 version: '>=2.5.1', method: 'pkg-config')
2012 if not get_option('u2f').auto() or have_system
2013 u2f = dependency('u2f-emu', required: get_option('u2f'),
2014 method: 'pkg-config')
2017 if not get_option('canokey').auto() or have_system
2018 canokey = dependency('canokey-qemu', required: get_option('canokey'),
2019 method: 'pkg-config')
2021 usbredir = not_found
2022 if not get_option('usb_redir').auto() or have_system
2023 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
2024 version: '>=0.6', method: 'pkg-config')
2027 if not get_option('libusb').auto() or have_system
2028 libusb = dependency('libusb-1.0', required: get_option('libusb'),
2029 version: '>=1.0.13', method: 'pkg-config')
2033 if not get_option('libpmem').auto() or have_system
2034 libpmem = dependency('libpmem', required: get_option('libpmem'),
2035 method: 'pkg-config')
2037 libdaxctl = not_found
2038 if not get_option('libdaxctl').auto() or have_system
2039 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
2040 version: '>=57', method: 'pkg-config')
2044 tasn1 = dependency('libtasn1',
2046 method: 'pkg-config')
2048 keyutils = not_found
2049 if not get_option('libkeyutils').auto() or have_block
2050 keyutils = dependency('libkeyutils', required: get_option('libkeyutils'),
2051 method: 'pkg-config')
2054 has_gettid = cc.has_function('gettid')
2057 selinux = dependency('libselinux',
2058 required: get_option('selinux'),
2059 method: 'pkg-config')
2064 if get_option('malloc') == 'system'
2066 get_option('malloc_trim').allowed() and \
2067 cc.has_function('malloc_trim', prefix: '#include <malloc.h>')
2069 has_malloc_trim = false
2070 malloc = cc.find_library(get_option('malloc'), required: true)
2072 if not has_malloc_trim and get_option('malloc_trim').enabled()
2073 if get_option('malloc') == 'system'
2074 error('malloc_trim not available on this platform.')
2076 error('malloc_trim not available with non-libc memory allocator')
2080 gnu_source_prefix = '''
2086 # Check whether the glibc provides STATX_BASIC_STATS
2088 has_statx = cc.has_header_symbol('sys/stat.h', 'STATX_BASIC_STATS', prefix: gnu_source_prefix)
2090 # Check whether statx() provides mount ID information
2092 has_statx_mnt_id = cc.has_header_symbol('sys/stat.h', 'STATX_MNT_ID', prefix: gnu_source_prefix)
2094 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
2095 .require(host_os == 'linux',
2096 error_message: 'vhost_user_blk_server requires linux') \
2097 .require(have_vhost_user,
2098 error_message: 'vhost_user_blk_server requires vhost-user support') \
2099 .disable_auto_if(not have_tools and not have_system) \
2102 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
2103 error('Cannot enable fuse-lseek while fuse is disabled')
2106 fuse = dependency('fuse3', required: get_option('fuse'),
2107 version: '>=3.1', method: 'pkg-config')
2109 fuse_lseek = not_found
2110 if get_option('fuse_lseek').allowed()
2111 if fuse.version().version_compare('>=3.8')
2113 fuse_lseek = declare_dependency()
2114 elif get_option('fuse_lseek').enabled()
2116 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
2118 error('fuse-lseek requires libfuse, which was not found')
2123 have_libvduse = (host_os == 'linux')
2124 if get_option('libvduse').enabled()
2125 if host_os != 'linux'
2126 error('libvduse requires linux')
2128 elif get_option('libvduse').disabled()
2129 have_libvduse = false
2132 have_vduse_blk_export = (have_libvduse and host_os == 'linux')
2133 if get_option('vduse_blk_export').enabled()
2134 if host_os != 'linux'
2135 error('vduse_blk_export requires linux')
2136 elif not have_libvduse
2137 error('vduse_blk_export requires libvduse support')
2139 elif get_option('vduse_blk_export').disabled()
2140 have_vduse_blk_export = false
2144 bpf_version = '1.1.0'
2145 libbpf = dependency('libbpf', version: '>=' + bpf_version, required: get_option('bpf'), method: 'pkg-config')
2146 if libbpf.found() and not cc.links('''
2147 #include <bpf/libbpf.h>
2148 #include <linux/bpf.h>
2151 // check flag availability
2152 int flag = BPF_F_MMAPABLE;
2153 bpf_object__destroy_skeleton(NULL);
2155 }''', dependencies: libbpf)
2157 if get_option('bpf').enabled()
2158 error('libbpf skeleton/mmaping test failed')
2160 warning('libbpf skeleton/mmaping test failed, disabling')
2166 if not get_option('af_xdp').auto() or have_system
2167 libxdp = dependency('libxdp', required: get_option('af_xdp'),
2168 version: '>=1.4.0', method: 'pkg-config')
2173 if not get_option('libdw').auto() or \
2174 (not get_option('prefer_static') and (have_system or have_user))
2175 libdw = dependency('libdw',
2176 method: 'pkg-config',
2177 required: get_option('libdw'))
2184 config_host_data = configuration_data()
2186 config_host_data.set('CONFIG_HAVE_RUST', have_rust)
2187 audio_drivers_selected = []
2189 audio_drivers_available = {
2190 'alsa': alsa.found(),
2191 'coreaudio': coreaudio.found(),
2192 'dsound': dsound.found(),
2193 'jack': jack.found(),
2195 'pa': pulse.found(),
2196 'pipewire': pipewire.found(),
2198 'sndio': sndio.found(),
2200 foreach k, v: audio_drivers_available
2201 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
2204 # Default to native drivers first, OSS second, SDL third
2205 audio_drivers_priority = \
2206 [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \
2207 (host_os == 'linux' ? [] : [ 'sdl' ])
2208 audio_drivers_default = []
2209 foreach k: audio_drivers_priority
2210 if audio_drivers_available[k]
2211 audio_drivers_default += k
2215 foreach k: get_option('audio_drv_list')
2217 audio_drivers_selected += audio_drivers_default
2218 elif not audio_drivers_available[k]
2219 error('Audio driver "@0@" not available.'.format(k))
2221 audio_drivers_selected += k
2225 config_host_data.set('CONFIG_AUDIO_DRIVERS',
2226 '"' + '", "'.join(audio_drivers_selected) + '", ')
2228 have_host_block_device = (host_os != 'darwin' or
2229 cc.has_header('IOKit/storage/IOMedia.h'))
2231 dbus_display = get_option('dbus_display') \
2232 .require(gio.version().version_compare('>=2.64'),
2233 error_message: '-display dbus requires glib>=2.64') \
2234 .require(gdbus_codegen.found(),
2235 error_message: gdbus_codegen_error.format('-display dbus')) \
2238 have_virtfs = get_option('virtfs') \
2239 .require(host_os == 'linux' or host_os == 'darwin',
2240 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
2241 .require(host_os == 'linux' or cc.has_function('pthread_fchdir_np'),
2242 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
2243 .require(host_os == 'darwin' or libattr.found(),
2244 error_message: 'virtio-9p (virtfs) on Linux requires libattr-devel') \
2245 .disable_auto_if(not have_tools and not have_system) \
2248 qga_fsfreeze = false
2250 if host_os == 'linux'
2251 if cc.has_header_symbol('linux/fs.h', 'FIFREEZE')
2254 if cc.has_header_symbol('linux/fs.h', 'FITRIM')
2257 elif host_os == 'freebsd' and cc.has_header_symbol('ufs/ffs/fs.h', 'UFSSUSPEND')
2261 if get_option('block_drv_ro_whitelist') == ''
2262 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
2264 config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
2265 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
2267 if get_option('block_drv_rw_whitelist') == ''
2268 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
2270 config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
2271 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
2274 foreach k : get_option('trace_backends')
2275 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
2277 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
2278 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
2280 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
2282 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
2283 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
2284 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
2285 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
2286 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
2288 qemu_firmwarepath = ''
2289 foreach k : get_option('qemu_firmwarepath')
2290 qemu_firmwarepath += '"' + get_option('prefix') / k + '", '
2292 config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath)
2294 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
2295 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
2296 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
2297 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
2298 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
2299 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
2302 config_host_data.set('CONFIG_STAMP', run_command(
2303 meson.current_source_dir() / 'scripts/qemu-stamp.py',
2304 meson.project_version(), get_option('pkgversion'), '--',
2305 meson.current_source_dir() / 'configure',
2306 capture: true, check: true).stdout().strip())
2309 have_slirp_smbd = get_option('slirp_smbd') \
2310 .require(host_os != 'windows', error_message: 'Host smbd not supported on this platform.') \
2313 smbd_path = get_option('smbd')
2315 smbd_path = (host_os == 'sunos' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
2317 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
2320 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
2322 kvm_targets_c = '""'
2323 if get_option('kvm').allowed() and host_os == 'linux'
2324 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
2326 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
2328 if get_option('module_upgrades') and not enable_modules
2329 error('Cannot enable module-upgrades as modules are not enabled')
2331 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
2333 config_host_data.set('CONFIG_ATTR', libattr.found())
2334 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
2335 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
2336 config_host_data.set('CONFIG_BSD', host_os in bsd_oses)
2337 config_host_data.set('CONFIG_FREEBSD', host_os == 'freebsd')
2338 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2339 config_host_data.set('CONFIG_COCOA', cocoa.found())
2340 config_host_data.set('CONFIG_DARWIN', host_os == 'darwin')
2341 config_host_data.set('CONFIG_FDT', fdt.found())
2342 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
2343 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
2344 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
2345 config_host_data.set('CONFIG_LINUX', host_os == 'linux')
2346 config_host_data.set('CONFIG_POSIX', host_os != 'windows')
2347 config_host_data.set('CONFIG_WIN32', host_os == 'windows')
2348 config_host_data.set('CONFIG_LZO', lzo.found())
2349 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
2350 config_host_data.set('CONFIG_BLKIO', blkio.found())
2352 config_host_data.set('CONFIG_BLKIO_VHOST_VDPA_FD',
2353 blkio.version().version_compare('>=1.3.0'))
2354 config_host_data.set('CONFIG_BLKIO_WRITE_ZEROS_FUA',
2355 blkio.version().version_compare('>=1.4.0'))
2357 config_host_data.set('CONFIG_CURL', curl.found())
2358 config_host_data.set('CONFIG_CURSES', curses.found())
2359 config_host_data.set('CONFIG_GBM', gbm.found())
2360 config_host_data.set('CONFIG_GIO', gio.found())
2361 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
2362 if glusterfs.found()
2363 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
2364 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
2365 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
2366 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
2367 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
2368 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
2370 config_host_data.set('CONFIG_GTK', gtk.found())
2371 config_host_data.set('CONFIG_VTE', vte.found())
2372 config_host_data.set('CONFIG_GTK_CLIPBOARD', have_gtk_clipboard)
2373 config_host_data.set('CONFIG_HEXAGON_IDEF_PARSER', get_option('hexagon_idef_parser'))
2374 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
2375 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
2376 config_host_data.set('CONFIG_EBPF', libbpf.found())
2377 config_host_data.set('CONFIG_AF_XDP', libxdp.found())
2378 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
2379 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
2380 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
2381 config_host_data.set('CONFIG_LIBSSH', libssh.found())
2382 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
2383 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
2384 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
2385 config_host_data.set('CONFIG_MODULES', enable_modules)
2386 config_host_data.set('CONFIG_NUMA', numa.found())
2388 config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY',
2389 cc.has_function('numa_has_preferred_many',
2390 dependencies: numa))
2392 config_host_data.set('CONFIG_OPENGL', opengl.found())
2393 config_host_data.set('CONFIG_PLUGIN', get_option('plugins'))
2394 config_host_data.set('CONFIG_RBD', rbd.found())
2395 config_host_data.set('CONFIG_RDMA', rdma.found())
2396 config_host_data.set('CONFIG_RELOCATABLE', get_option('relocatable'))
2397 config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack'))
2398 config_host_data.set('CONFIG_SDL', sdl.found())
2399 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
2400 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
2402 config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc)
2404 config_host_data.set('CONFIG_PIXMAN', pixman.found())
2405 config_host_data.set('CONFIG_SLIRP', slirp.found())
2406 config_host_data.set('CONFIG_SNAPPY', snappy.found())
2407 config_host_data.set('CONFIG_SOLARIS', host_os == 'sunos')
2408 if get_option('tcg').allowed()
2409 config_host_data.set('CONFIG_TCG', 1)
2410 config_host_data.set('CONFIG_TCG_INTERPRETER', tcg_arch == 'tci')
2412 config_host_data.set('CONFIG_TPM', have_tpm)
2413 config_host_data.set('CONFIG_TSAN', get_option('tsan'))
2414 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
2415 config_host_data.set('CONFIG_VDE', vde.found())
2416 config_host_data.set('CONFIG_VHOST', have_vhost)
2417 config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
2418 config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
2419 config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)
2420 config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
2421 config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
2422 config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
2423 config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
2424 config_host_data.set('CONFIG_VMNET', vmnet.found())
2425 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
2426 config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export)
2427 config_host_data.set('CONFIG_PNG', png.found())
2428 config_host_data.set('CONFIG_VNC', vnc.found())
2429 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
2430 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
2432 config_host_data.set('HAVE_VIRGL_D3D_INFO_EXT',
2433 cc.has_member('struct virgl_renderer_resource_info_ext', 'd3d_tex2d',
2434 prefix: '#include <virglrenderer.h>',
2435 dependencies: virgl))
2437 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
2438 config_host_data.set('CONFIG_VTE', vte.found())
2439 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
2440 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
2441 config_host_data.set('CONFIG_GETTID', has_gettid)
2442 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
2443 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
2444 config_host_data.set('CONFIG_TASN1', tasn1.found())
2445 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
2446 config_host_data.set('CONFIG_NETTLE', nettle.found())
2447 config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found())
2448 config_host_data.set('CONFIG_HOGWEED', hogweed.found())
2449 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
2450 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
2451 config_host_data.set('CONFIG_STATX', has_statx)
2452 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
2453 config_host_data.set('CONFIG_ZSTD', zstd.found())
2454 config_host_data.set('CONFIG_QPL', qpl.found())
2455 config_host_data.set('CONFIG_UADK', uadk.found())
2456 config_host_data.set('CONFIG_QATZIP', qatzip.found())
2457 config_host_data.set('CONFIG_FUSE', fuse.found())
2458 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
2459 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
2460 if spice_protocol.found()
2461 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
2462 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
2463 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
2465 config_host_data.set('CONFIG_SPICE', spice.found())
2466 config_host_data.set('CONFIG_X11', x11.found())
2467 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
2468 config_host_data.set('CONFIG_CFI', get_option('cfi'))
2469 config_host_data.set('CONFIG_SELINUX', selinux.found())
2470 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
2471 config_host_data.set('CONFIG_LIBDW', libdw.found())
2473 # protect from xen.version() having less than three components
2474 xen_version = xen.version().split('.') + ['0', '0']
2475 xen_ctrl_version = xen_version[0] + \
2476 ('0' + xen_version[1]).substring(-2) + \
2477 ('0' + xen_version[2]).substring(-2)
2478 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
2480 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
2481 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
2482 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
2483 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
2485 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
2486 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
2488 have_coroutine_pool = get_option('coroutine_pool')
2489 if get_option('debug_stack_usage') and have_coroutine_pool
2490 message('Disabling coroutine pool to measure stack usage')
2491 have_coroutine_pool = false
2493 config_host_data.set('CONFIG_COROUTINE_POOL', have_coroutine_pool)
2494 config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock'))
2495 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
2496 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
2497 config_host_data.set('CONFIG_DEBUG_TCG', get_option('debug_tcg'))
2498 config_host_data.set('CONFIG_DEBUG_REMAP', get_option('debug_remap'))
2499 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
2500 config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
2501 config_host_data.set('CONFIG_FSFREEZE', qga_fsfreeze)
2502 config_host_data.set('CONFIG_FSTRIM', qga_fstrim)
2505 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
2506 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
2507 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
2508 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
2509 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
2510 config_host_data.set('HAVE_OPENAT2_H', cc.has_header('linux/openat2.h'))
2511 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
2512 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
2513 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
2514 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
2515 if host_os == 'windows'
2516 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h'))
2520 config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range'))
2521 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
2522 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
2523 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
2524 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
2525 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
2526 config_host_data.set('CONFIG_GETCPU', cc.has_function('getcpu', prefix: gnu_source_prefix))
2527 config_host_data.set('CONFIG_SCHED_GETCPU', cc.has_function('sched_getcpu', prefix: '#include <sched.h>'))
2528 # Note that we need to specify prefix: here to avoid incorrectly
2529 # thinking that Windows has posix_memalign()
2530 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
2531 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
2532 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
2533 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
2534 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
2535 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
2536 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
2537 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
2538 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
2539 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
2540 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
2541 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
2542 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
2543 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
2544 config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice)
2545 config_host_data.set('HAVE_GLIB_WITH_ALIGNED_ALLOC', glib_has_aligned_alloc)
2546 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
2547 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
2548 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
2550 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
2551 cc.has_function('rbd_namespace_exists',
2553 prefix: '#include <rbd/librbd.h>'))
2556 config_host_data.set('HAVE_IBV_ADVISE_MR',
2557 cc.has_function('ibv_advise_mr',
2559 prefix: '#include <infiniband/verbs.h>'))
2562 have_asan_fiber = false
2563 if get_option('asan') and \
2564 not cc.has_function('__sanitizer_start_switch_fiber',
2565 args: '-fsanitize=address',
2566 prefix: '#include <sanitizer/asan_interface.h>')
2567 warning('Missing ASAN due to missing fiber annotation interface')
2568 warning('Without code annotation, the report may be inferior.')
2570 have_asan_fiber = true
2572 config_host_data.set('CONFIG_ASAN_IFACE_FIBER', have_asan_fiber)
2574 have_inotify_init = cc.has_header_symbol('sys/inotify.h', 'inotify_init')
2575 have_inotify_init1 = cc.has_header_symbol('sys/inotify.h', 'inotify_init1')
2577 if (have_inotify_init or have_inotify_init1) and host_os == 'freebsd'
2579 inotify = cc.find_library('inotify')
2580 if have_inotify_init
2581 have_inotify_init = inotify.found()
2583 if have_inotify_init1
2584 have_inotify_init1 = inotify.found()
2587 config_host_data.set('CONFIG_INOTIFY', have_inotify_init)
2588 config_host_data.set('CONFIG_INOTIFY1', have_inotify_init1)
2591 config_host_data.set('CONFIG_BLKZONED',
2592 cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE'))
2593 config_host_data.set('CONFIG_EPOLL_CREATE1',
2594 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
2595 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
2596 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
2597 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
2598 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
2599 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
2600 config_host_data.set('CONFIG_FIEMAP',
2601 cc.has_header('linux/fiemap.h') and
2602 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
2603 config_host_data.set('CONFIG_GETRANDOM',
2604 cc.has_function('getrandom') and
2605 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
2606 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
2607 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
2608 config_host_data.set('CONFIG_RTNETLINK',
2609 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
2610 config_host_data.set('CONFIG_SYSMACROS',
2611 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
2612 config_host_data.set('HAVE_OPTRESET',
2613 cc.has_header_symbol('getopt.h', 'optreset'))
2614 config_host_data.set('HAVE_IPPROTO_MPTCP',
2615 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
2618 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
2619 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
2620 prefix: '#include <signal.h>'))
2621 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
2622 cc.has_member('struct stat', 'st_atim',
2623 prefix: '#include <sys/stat.h>'))
2624 config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY',
2625 cc.has_member('struct blk_zone', 'capacity',
2626 prefix: '#include <linux/blkzoned.h>'))
2629 config_host_data.set('CONFIG_IOVEC',
2630 cc.has_type('struct iovec',
2631 prefix: '#include <sys/uio.h>'))
2632 config_host_data.set('HAVE_UTMPX',
2633 cc.has_type('struct utmpx',
2634 prefix: '#include <utmpx.h>'))
2636 config_host_data.set('CONFIG_EVENTFD', cc.links('''
2637 #include <sys/eventfd.h>
2638 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
2639 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
2642 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
2643 return fdatasync(0);
2645 #error Not supported
2649 has_madvise = cc.links(gnu_source_prefix + '''
2650 #include <sys/types.h>
2651 #include <sys/mman.h>
2653 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
2654 missing_madvise_proto = false
2656 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
2657 # but forget to prototype it. In this case, has_madvise will be true (the
2658 # test program links despite a compile warning). To detect the
2659 # missing-prototype case, we try again with a definitely-bogus prototype.
2660 # This will only compile if the system headers don't provide the prototype;
2661 # otherwise the conflicting prototypes will cause a compiler error.
2662 missing_madvise_proto = cc.links(gnu_source_prefix + '''
2663 #include <sys/types.h>
2664 #include <sys/mman.h>
2666 extern int madvise(int);
2667 int main(void) { return madvise(0); }''')
2669 config_host_data.set('CONFIG_MADVISE', has_madvise)
2670 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
2672 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
2673 #include <sys/mman.h>
2674 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
2675 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
2677 #if !defined(AT_EMPTY_PATH)
2678 # error missing definition
2680 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
2683 # On Darwin posix_madvise() has the same return semantics as plain madvise(),
2684 # i.e. errno is set and -1 is returned. That's not really how POSIX defines the
2685 # function. On the flip side, it has madvise() which is preferred anyways.
2686 if host_os != 'darwin'
2687 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
2688 #include <sys/mman.h>
2690 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
2693 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
2694 #include <pthread.h>
2696 static void *f(void *p) { return NULL; }
2700 pthread_create(&thread, 0, f, 0);
2701 pthread_setname_np(thread, "QEMU");
2703 }''', dependencies: threads))
2704 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
2705 #include <pthread.h>
2707 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
2711 pthread_create(&thread, 0, f, 0);
2713 }''', dependencies: threads))
2714 config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(gnu_source_prefix + '''
2715 #include <pthread.h>
2716 #include <pthread_np.h>
2718 static void *f(void *p) { return NULL; }
2722 pthread_create(&thread, 0, f, 0);
2723 pthread_set_name_np(thread, "QEMU");
2725 }''', dependencies: threads))
2726 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
2727 #include <pthread.h>
2732 pthread_condattr_t attr
2733 pthread_condattr_init(&attr);
2734 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
2736 }''', dependencies: threads))
2737 config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(gnu_source_prefix + '''
2738 #include <pthread.h>
2740 static void *f(void *p) { return NULL; }
2743 int setsize = CPU_ALLOC_SIZE(64);
2746 pthread_create(&thread, 0, f, 0);
2747 cpuset = CPU_ALLOC(64);
2748 CPU_ZERO_S(setsize, cpuset);
2749 pthread_setaffinity_np(thread, setsize, cpuset);
2750 pthread_getaffinity_np(thread, setsize, cpuset);
2753 }''', dependencies: threads))
2754 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
2755 #include <sys/signalfd.h>
2757 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
2758 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
2766 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
2767 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
2771 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
2772 #include <sys/mman.h>
2774 return mlockall(MCL_FUTURE);
2778 if get_option('l2tpv3').allowed() and have_system
2779 have_l2tpv3 = cc.has_type('struct mmsghdr',
2780 prefix: gnu_source_prefix + '''
2781 #include <sys/socket.h>
2782 #include <linux/ip.h>''')
2784 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2787 if get_option('netmap').allowed() and have_system
2788 have_netmap = cc.compiles('''
2789 #include <inttypes.h>
2791 #include <net/netmap.h>
2792 #include <net/netmap_user.h>
2793 #if (NETMAP_API < 11) || (NETMAP_API > 15)
2796 int main(void) { return 0; }''')
2797 if not have_netmap and get_option('netmap').enabled()
2798 error('Netmap headers not available')
2801 config_host_data.set('CONFIG_NETMAP', have_netmap)
2803 # Work around a system header bug with some kernel/XFS header
2804 # versions where they both try to define 'struct fsxattr':
2805 # xfs headers will not try to redefine structs from linux headers
2806 # if this macro is set.
2807 config_host_data.set('HAVE_FSXATTR', cc.links('''
2808 #include <linux/fs.h>
2814 # Some versions of Mac OS X incorrectly define SIZE_MAX
2815 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2819 return printf("%zu", SIZE_MAX);
2820 }''', args: ['-Werror']))
2822 # See if 64-bit atomic operations are supported.
2823 # Note that without __atomic builtins, we can only
2824 # assume atomic loads/stores max at pointer size.
2825 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
2829 uint64_t x = 0, y = 0;
2830 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2831 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2832 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2833 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2834 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2836 }''', args: qemu_isa_flags))
2838 has_int128_type = cc.compiles('''
2841 int main(void) { b = a; }''')
2842 config_host_data.set('CONFIG_INT128_TYPE', has_int128_type)
2844 has_int128 = has_int128_type and cc.links('''
2853 config_host_data.set('CONFIG_INT128', has_int128)
2856 # "do we have 128-bit atomics which are handled inline and specifically not
2857 # via libatomic". The reason we can't use libatomic is documented in the
2858 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2859 # We only care about these operations on 16-byte aligned pointers, so
2860 # force 16-byte alignment of the pointer, which may be greater than
2861 # __alignof(unsigned __int128) for the host.
2862 atomic_test_128 = '''
2863 int main(int ac, char **av) {
2864 __uint128_t *p = __builtin_assume_aligned(av[ac - 1], 16);
2865 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED);
2866 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED);
2867 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2870 has_atomic128 = cc.links(atomic_test_128, args: qemu_isa_flags)
2872 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2874 if not has_atomic128
2875 # Even with __builtin_assume_aligned, the above test may have failed
2876 # without optimization enabled. Try again with optimizations locally
2877 # enabled for the function. See
2878 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389
2879 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128,
2880 args: qemu_isa_flags)
2881 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt)
2883 if not has_atomic128_opt
2884 config_host_data.set('CONFIG_CMPXCHG128', cc.links('''
2887 __uint128_t x = 0, y = 0;
2888 __sync_val_compare_and_swap_16(&x, y, x);
2891 ''', args: qemu_isa_flags))
2896 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2897 #include <sys/auxv.h>
2899 return getauxval(AT_HWCAP) == 0;
2902 config_host_data.set('CONFIG_ELF_AUX_INFO', cc.links(gnu_source_prefix + '''
2903 #include <sys/auxv.h>
2905 unsigned long hwcap = 0;
2906 elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap));
2910 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2911 #include <linux/usbdevice_fs.h>
2913 #ifndef USBDEVFS_GET_CAPABILITIES
2914 #error "USBDEVFS_GET_CAPABILITIES undefined"
2917 #ifndef USBDEVFS_DISCONNECT_CLAIM
2918 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2921 int main(void) { return 0; }'''))
2923 have_keyring = get_option('keyring') \
2924 .require(host_os == 'linux', error_message: 'keyring is only available on Linux') \
2925 .require(cc.compiles('''
2927 #include <asm/unistd.h>
2928 #include <linux/keyctl.h>
2929 #include <sys/syscall.h>
2932 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2933 }'''), error_message: 'keyctl syscall not available on this system').allowed()
2934 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2936 have_cpuid_h = cc.links('''
2939 unsigned a, b, c, d;
2940 unsigned max = __get_cpuid_max(0, 0);
2943 __cpuid(1, a, b, c, d);
2947 __cpuid_count(7, 0, a, b, c, d);
2952 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2954 # Don't bother to advertise asm/hwprobe.h for old versions that do
2955 # not contain RISCV_HWPROBE_EXT_ZBA.
2956 config_host_data.set('CONFIG_ASM_HWPROBE_H',
2957 cc.has_header_symbol('asm/hwprobe.h',
2958 'RISCV_HWPROBE_EXT_ZBA'))
2960 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2961 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2962 .require(cc.links('''
2964 #include <immintrin.h>
2965 static int __attribute__((target("avx2"))) bar(void *a) {
2966 __m256i x = *(__m256i *)a;
2967 return _mm256_testz_si256(x, x);
2969 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2970 '''), error_message: 'AVX2 not available').allowed())
2972 config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \
2973 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \
2974 .require(cc.links('''
2976 #include <immintrin.h>
2977 static int __attribute__((target("avx512bw"))) bar(void *a) {
2979 __m512i res= _mm512_abs_epi8(*x);
2982 int main(int argc, char *argv[]) { return bar(argv[0]); }
2983 '''), error_message: 'AVX512BW not available').allowed())
2985 # For both AArch64 and AArch32, detect if builtins are available.
2986 config_host_data.set('CONFIG_ARM_AES_BUILTIN', cc.compiles('''
2987 #include <arm_neon.h>
2988 #ifndef __ARM_FEATURE_AES
2989 __attribute__((target("+crypto")))
2991 void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); }
2994 if get_option('membarrier').disabled()
2995 have_membarrier = false
2996 elif host_os == 'windows'
2997 have_membarrier = true
2998 elif host_os == 'linux'
2999 have_membarrier = cc.compiles('''
3000 #include <linux/membarrier.h>
3001 #include <sys/syscall.h>
3005 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
3006 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
3010 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
3011 .require(have_membarrier, error_message: 'membarrier system call not available') \
3014 have_afalg = get_option('crypto_afalg') \
3015 .require(cc.compiles(gnu_source_prefix + '''
3017 #include <sys/types.h>
3018 #include <sys/socket.h>
3019 #include <linux/if_alg.h>
3022 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
3025 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
3026 config_host_data.set('CONFIG_AF_ALG', have_afalg)
3028 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
3029 'linux/vm_sockets.h', 'AF_VSOCK',
3030 prefix: '#include <sys/socket.h>',
3034 have_vss_sdk = false # old xp/2003 SDK
3035 if host_os == 'windows' and 'cpp' in all_languages
3036 have_vss = cxx.compiles('''
3037 #define __MIDL_user_allocate_free_DEFINED__
3039 int main(void) { return VSS_CTX_BACKUP; }''')
3040 have_vss_sdk = cxx.has_header('vscoordint.h')
3042 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
3044 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
3045 # This was fixed for v6.0.0 with commit b48e3ac8969d.
3046 if host_os == 'windows'
3047 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
3053 }''', name: '_lock_file and _unlock_file'))
3056 if host_os == 'windows'
3057 mingw_has_setjmp_longjmp = cc.links('''
3061 * These functions are not available in setjmp header, but may be
3062 * available at link time, from libmingwex.a.
3064 extern int __mingw_setjmp(jmp_buf);
3065 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
3067 __mingw_setjmp(env);
3068 __mingw_longjmp(env, 0);
3070 ''', name: 'mingw setjmp and longjmp')
3072 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp
3073 error('mingw must provide setjmp/longjmp for windows-arm64')
3077 ########################
3078 # Target configuration #
3079 ########################
3081 minikconf = find_program('scripts/minikconf.py')
3083 config_all_accel = {}
3084 config_all_devices = {}
3085 config_devices_mak_list = []
3086 config_devices_h = {}
3087 config_target_h = {}
3088 config_target_mak = {}
3091 'alpha' : ['CONFIG_ALPHA_DIS'],
3092 'avr' : ['CONFIG_AVR_DIS'],
3093 'hexagon' : ['CONFIG_HEXAGON_DIS'],
3094 'hppa' : ['CONFIG_HPPA_DIS'],
3095 'i386' : ['CONFIG_I386_DIS'],
3096 'x86_64' : ['CONFIG_I386_DIS'],
3097 'm68k' : ['CONFIG_M68K_DIS'],
3098 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
3099 'mips' : ['CONFIG_MIPS_DIS'],
3100 'or1k' : ['CONFIG_OPENRISC_DIS'],
3101 'ppc' : ['CONFIG_PPC_DIS'],
3102 'riscv' : ['CONFIG_RISCV_DIS'],
3103 'rx' : ['CONFIG_RX_DIS'],
3104 's390' : ['CONFIG_S390_DIS'],
3105 'sh4' : ['CONFIG_SH4_DIS'],
3106 'sparc' : ['CONFIG_SPARC_DIS'],
3107 'xtensa' : ['CONFIG_XTENSA_DIS'],
3108 'loongarch' : ['CONFIG_LOONGARCH_DIS'],
3111 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
3113 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
3114 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
3115 (pixman.found() ? ['CONFIG_PIXMAN=y'] : []) + \
3116 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
3117 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
3118 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
3119 (x11.found() ? ['CONFIG_X11=y'] : []) + \
3120 (fdt.found() ? ['CONFIG_FDT=y'] : []) + \
3121 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
3122 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
3123 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
3124 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
3125 (host_os == 'linux' ? ['CONFIG_LINUX=y'] : []) + \
3126 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
3127 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \
3128 (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : []) + \
3129 (have_rust ? ['CONFIG_HAVE_RUST=y'] : [])
3131 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
3133 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
3134 actual_target_dirs = []
3136 foreach target : target_dirs
3137 config_target = { 'TARGET_NAME': target.split('-')[0] }
3138 if target.endswith('linux-user')
3139 if host_os != 'linux'
3143 error('Target @0@ is only available on a Linux host'.format(target))
3145 config_target += { 'CONFIG_LINUX_USER': 'y' }
3146 elif target.endswith('bsd-user')
3147 if host_os not in bsd_oses
3151 error('Target @0@ is only available on a BSD host'.format(target))
3153 config_target += { 'CONFIG_BSD_USER': 'y' }
3154 elif target.endswith('softmmu')
3155 config_target += { 'CONFIG_SYSTEM_ONLY': 'y' }
3156 config_target += { 'CONFIG_SOFTMMU': 'y' }
3158 if target.endswith('-user')
3160 'CONFIG_USER_ONLY': 'y',
3161 'CONFIG_QEMU_INTERP_PREFIX':
3162 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
3167 foreach sym: accelerators
3168 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
3169 config_target += { sym: 'y' }
3170 config_all_accel += { sym: 'y' }
3171 if target in modular_tcg
3172 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
3174 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
3176 target_kconfig += [ sym + '=y' ]
3179 if target_kconfig.length() == 0
3183 error('No accelerator available for target @0@'.format(target))
3186 config_target += keyval.load('configs/targets' / target + '.mak')
3187 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
3189 if 'TARGET_NEED_FDT' in config_target and not fdt.found()
3191 warning('Disabling ' + target + ' due to missing libfdt')
3193 fdt_required += target
3198 actual_target_dirs += target
3201 if 'TARGET_BASE_ARCH' not in config_target
3202 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
3204 if 'TARGET_ABI_DIR' not in config_target
3205 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
3207 if 'TARGET_BIG_ENDIAN' not in config_target
3208 config_target += {'TARGET_BIG_ENDIAN': 'n'}
3211 foreach k, v: disassemblers
3212 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
3214 config_target += { sym: 'y' }
3219 config_target_data = configuration_data()
3220 foreach k, v: config_target
3221 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
3223 elif ignored.contains(k)
3225 elif k == 'TARGET_BASE_ARCH'
3226 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
3227 # not used to select files from sourcesets.
3228 config_target_data.set('TARGET_' + v.to_upper(), 1)
3229 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
3230 config_target_data.set_quoted(k, v)
3232 config_target_data.set(k, 1)
3234 config_target_data.set(k, 0)
3236 config_target_data.set(k, v)
3239 config_target_data.set('QEMU_ARCH',
3240 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
3241 config_target_h += {target: configure_file(output: target + '-config-target.h',
3242 configuration: config_target_data)}
3244 if target.endswith('-softmmu')
3245 target_kconfig += 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'
3246 target_kconfig += 'CONFIG_TARGET_BIG_ENDIAN=' + config_target['TARGET_BIG_ENDIAN']
3248 config_input = meson.get_external_property(target, 'default')
3249 config_devices_mak = target + '-config-devices.mak'
3250 config_devices_mak = configure_file(
3251 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
3252 output: config_devices_mak,
3253 depfile: config_devices_mak + '.d',
3255 command: [minikconf,
3256 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
3257 config_devices_mak, '@DEPFILE@', '@INPUT@',
3258 host_kconfig, target_kconfig])
3260 config_devices_data = configuration_data()
3261 config_devices = keyval.load(config_devices_mak)
3262 foreach k, v: config_devices
3263 config_devices_data.set(k, 1)
3265 config_devices_mak_list += config_devices_mak
3266 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
3267 configuration: config_devices_data)}
3268 config_target += config_devices
3269 config_all_devices += config_devices
3271 config_target_mak += {target: config_target}
3273 target_dirs = actual_target_dirs
3275 target_configs_h = []
3276 foreach target: target_dirs
3277 target_configs_h += config_target_h[target]
3278 target_configs_h += config_devices_h.get(target, [])
3280 genh += custom_target('config-poison.h',
3281 input: [target_configs_h],
3282 output: 'config-poison.h',
3284 command: [find_program('scripts/make-config-poison.sh'),
3287 if fdt_required.length() > 0
3288 error('fdt disabled but required by targets ' + ', '.join(fdt_required))
3295 libvfio_user_dep = not_found
3296 if have_system and vfio_user_server_allowed
3297 libvfio_user_proj = subproject('libvfio-user', required: true)
3298 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep')
3301 vhost_user = not_found
3302 if host_os == 'linux' and have_vhost_user
3303 libvhost_user = subproject('libvhost-user')
3304 vhost_user = libvhost_user.get_variable('vhost_user_dep')
3307 libvduse = not_found
3309 libvduse_proj = subproject('libvduse')
3310 libvduse = libvduse_proj.get_variable('libvduse_dep')
3313 #####################
3314 # Generated sources #
3315 #####################
3317 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
3319 hxtool = find_program('scripts/hxtool')
3320 shaderinclude = find_program('scripts/shaderinclude.py')
3321 qapi_gen = find_program('scripts/qapi-gen.py')
3322 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
3323 meson.current_source_dir() / 'scripts/qapi/commands.py',
3324 meson.current_source_dir() / 'scripts/qapi/common.py',
3325 meson.current_source_dir() / 'scripts/qapi/error.py',
3326 meson.current_source_dir() / 'scripts/qapi/events.py',
3327 meson.current_source_dir() / 'scripts/qapi/expr.py',
3328 meson.current_source_dir() / 'scripts/qapi/gen.py',
3329 meson.current_source_dir() / 'scripts/qapi/introspect.py',
3330 meson.current_source_dir() / 'scripts/qapi/main.py',
3331 meson.current_source_dir() / 'scripts/qapi/parser.py',
3332 meson.current_source_dir() / 'scripts/qapi/schema.py',
3333 meson.current_source_dir() / 'scripts/qapi/source.py',
3334 meson.current_source_dir() / 'scripts/qapi/types.py',
3335 meson.current_source_dir() / 'scripts/qapi/visit.py',
3336 meson.current_source_dir() / 'scripts/qapi-gen.py'
3340 python, files('scripts/tracetool.py'),
3341 '--backend=' + ','.join(get_option('trace_backends'))
3343 tracetool_depends = files(
3344 'scripts/tracetool/backend/log.py',
3345 'scripts/tracetool/backend/__init__.py',
3346 'scripts/tracetool/backend/dtrace.py',
3347 'scripts/tracetool/backend/ftrace.py',
3348 'scripts/tracetool/backend/simple.py',
3349 'scripts/tracetool/backend/syslog.py',
3350 'scripts/tracetool/backend/ust.py',
3351 'scripts/tracetool/format/ust_events_c.py',
3352 'scripts/tracetool/format/ust_events_h.py',
3353 'scripts/tracetool/format/__init__.py',
3354 'scripts/tracetool/format/d.py',
3355 'scripts/tracetool/format/simpletrace_stap.py',
3356 'scripts/tracetool/format/c.py',
3357 'scripts/tracetool/format/h.py',
3358 'scripts/tracetool/format/log_stap.py',
3359 'scripts/tracetool/format/stap.py',
3360 'scripts/tracetool/__init__.py',
3363 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
3364 meson.current_source_dir(),
3365 get_option('pkgversion'), meson.project_version()]
3366 qemu_version = custom_target('qemu-version.h',
3367 output: 'qemu-version.h',
3368 command: qemu_version_cmd,
3370 build_by_default: true,
3371 build_always_stale: true)
3372 genh += qemu_version
3376 ['qemu-options.hx', 'qemu-options.def'],
3377 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
3381 ['hmp-commands.hx', 'hmp-commands.h'],
3382 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
3385 foreach d : hx_headers
3386 hxdep += custom_target(d[1],
3390 command: [hxtool, '-h', '@INPUT0@'])
3398 # TODO: add each directory to the subdirs from its own meson.build, once
3400 trace_events_subdirs = [
3409 trace_events_subdirs += [ 'linux-user' ]
3412 trace_events_subdirs += [ 'bsd-user' ]
3415 trace_events_subdirs += [
3425 trace_events_subdirs += [
3487 if have_system or have_user
3488 trace_events_subdirs += [
3510 authz_ss = ss.source_set()
3511 blockdev_ss = ss.source_set()
3512 block_ss = ss.source_set()
3513 chardev_ss = ss.source_set()
3514 common_ss = ss.source_set()
3515 crypto_ss = ss.source_set()
3516 hwcore_ss = ss.source_set()
3517 io_ss = ss.source_set()
3518 qmp_ss = ss.source_set()
3519 qom_ss = ss.source_set()
3520 system_ss = ss.source_set()
3521 specific_fuzz_ss = ss.source_set()
3522 specific_ss = ss.source_set()
3523 rust_devices_ss = ss.source_set()
3524 stub_ss = ss.source_set()
3525 trace_ss = ss.source_set()
3526 user_ss = ss.source_set()
3527 util_ss = ss.source_set()
3530 qtest_module_ss = ss.source_set()
3531 tcg_module_ss = ss.source_set()
3537 target_system_arch = {}
3538 target_user_arch = {}
3540 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3541 # that is filled in by qapi/.
3559 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3560 modulecommon = declare_dependency(objects: libmodulecommon.extract_all_objects(recursive: false), compile_args: '-DBUILD_DSO')
3563 qom_ss = qom_ss.apply({})
3564 libqom = static_library('qom', qom_ss.sources() + genh,
3565 dependencies: [qom_ss.dependencies()],
3566 build_by_default: false)
3567 qom = declare_dependency(objects: libqom.extract_all_objects(recursive: false),
3568 dependencies: qom_ss.dependencies())
3570 event_loop_base = files('event-loop-base.c')
3571 event_loop_base = static_library('event-loop-base',
3572 sources: event_loop_base + genh,
3573 build_by_default: false)
3574 event_loop_base = declare_dependency(objects: event_loop_base.extract_all_objects(recursive: false),
3575 dependencies: [qom])
3577 stub_ss = stub_ss.apply({})
3579 util_ss.add_all(trace_ss)
3580 util_ss = util_ss.apply({})
3581 libqemuutil = static_library('qemuutil',
3582 build_by_default: false,
3583 sources: util_ss.sources() + stub_ss.sources() + genh,
3584 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc])
3585 qemuutil = declare_dependency(link_with: libqemuutil,
3586 sources: genh + version_res,
3587 dependencies: [event_loop_base])
3589 if have_system or have_user
3590 decodetree = generator(find_program('scripts/decodetree.py'),
3591 output: 'decode-@BASENAME@.c.inc',
3592 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3593 subdir('libdecnumber')
3610 if config_host_data.get('CONFIG_REPLICATION')
3611 block_ss.add(files('replication.c'))
3618 blockdev_ss.add(files(
3625 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3626 # os-win32.c does not
3627 if host_os == 'windows'
3628 system_ss.add(files('os-win32.c'))
3630 blockdev_ss.add(files('os-posix.c'))
3634 common_ss.add(files('cpu-common.c'))
3635 specific_ss.add(files('cpu-target.c'))
3639 # Work around a gcc bug/misfeature wherein constant propagation looks
3641 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3642 # to guess that a const variable is always zero. Without lto, this is
3643 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
3644 # without lto, not even the alias is required -- we simply use different
3645 # declarations in different compilation units.
3646 pagevary = files('page-vary-common.c')
3647 if get_option('b_lto')
3648 pagevary_flags = ['-fno-lto']
3649 if get_option('cfi')
3650 pagevary_flags += '-fno-sanitize=cfi-icall'
3652 pagevary = static_library('page-vary-common', sources: pagevary + genh,
3653 c_args: pagevary_flags)
3654 pagevary = declare_dependency(link_with: pagevary)
3656 common_ss.add(pagevary)
3657 specific_ss.add(files('page-target.c', 'page-vary-target.c'))
3665 subdir('semihosting')
3673 common_user_inc = []
3675 subdir('common-user')
3677 subdir('linux-user')
3679 # needed for fuzzing binaries
3680 subdir('tests/qtest/libqos')
3681 subdir('tests/qtest/fuzz')
3684 tcg_real_module_ss = ss.source_set()
3685 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3686 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3687 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3688 'tcg': tcg_real_module_ss }}
3690 ##############################################
3691 # Internal static_libraries and dependencies #
3692 ##############################################
3694 modinfo_collect = find_program('scripts/modinfo-collect.py')
3695 modinfo_generate = find_program('scripts/modinfo-generate.py')
3700 emulator_modules = []
3701 foreach d, list : modules
3702 if not (d == 'block' ? have_block : have_system)
3706 foreach m, module_ss : list
3708 module_ss.add(modulecommon)
3709 module_ss = module_ss.apply(config_all_devices, strict: false)
3710 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3711 dependencies: module_ss.dependencies(), pic: true)
3717 emulator_modules += shared_module(sl.name(),
3719 objects: sl.extract_all_objects(recursive: false),
3720 dependencies: module_ss.dependencies(),
3722 install_dir: qemu_moddir)
3723 if module_ss.sources() != []
3724 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3725 # input. Sources can be used multiple times but objects are
3726 # unique when it comes to lookup in compile_commands.json.
3727 # Depnds on a mesion version with
3728 # https://github.com/mesonbuild/meson/pull/8900
3729 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3730 output: d + '-' + m + '.modinfo',
3731 input: module_ss.sources() + genh,
3733 command: [modinfo_collect, module_ss.sources()])
3737 block_ss.add_all(module_ss)
3739 system_ss.add_all(module_ss)
3745 foreach d, list : target_modules
3746 foreach m, module_ss : list
3748 module_ss.add(modulecommon)
3749 foreach target : target_dirs
3750 if target.endswith('-softmmu')
3751 config_target = config_target_mak[target]
3752 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3753 c_args = ['-DCOMPILING_PER_TARGET',
3754 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3755 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3756 target_module_ss = module_ss.apply(config_target, strict: false)
3757 if target_module_ss.sources() != []
3758 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3759 sl = static_library(module_name,
3760 [genh, target_module_ss.sources()],
3761 dependencies: target_module_ss.dependencies(),
3762 include_directories: target_inc,
3766 emulator_modules += shared_module(sl.name(),
3768 objects: sl.extract_all_objects(recursive: false),
3769 dependencies: target_module_ss.dependencies(),
3771 install_dir: qemu_moddir)
3772 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3773 modinfo_files += custom_target(module_name + '.modinfo',
3774 output: module_name + '.modinfo',
3775 input: target_module_ss.sources() + genh,
3777 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3782 specific_ss.add_all(module_ss)
3788 foreach target : target_dirs
3789 if target.endswith('-softmmu')
3790 config_target = config_target_mak[target]
3791 config_devices_mak = target + '-config-devices.mak'
3792 modinfo_src = custom_target('modinfo-' + target + '.c',
3793 output: 'modinfo-' + target + '.c',
3794 input: modinfo_files,
3795 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'],
3798 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
3799 modinfo_dep = declare_dependency(link_with: modinfo_lib)
3801 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH']
3802 hw_arch[arch].add(modinfo_dep)
3806 if emulator_modules.length() > 0
3807 alias_target('modules', emulator_modules)
3811 nm = find_program('nm')
3812 undefsym = find_program('scripts/undefsym.py')
3813 block_syms = custom_target('block.syms', output: 'block.syms',
3814 input: [libqemuutil, block_mods],
3816 command: [undefsym, nm, '@INPUT@'])
3817 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3818 input: [libqemuutil, system_mods],
3820 command: [undefsym, nm, '@INPUT@'])
3822 authz_ss = authz_ss.apply({})
3823 libauthz = static_library('authz', authz_ss.sources() + genh,
3824 dependencies: [authz_ss.dependencies()],
3825 build_by_default: false)
3827 authz = declare_dependency(objects: libauthz.extract_all_objects(recursive: false),
3828 dependencies: [authz_ss.dependencies(), qom])
3830 crypto_ss = crypto_ss.apply({})
3831 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3832 dependencies: [crypto_ss.dependencies()],
3833 build_by_default: false)
3835 crypto = declare_dependency(objects: libcrypto.extract_all_objects(recursive: false),
3836 dependencies: [crypto_ss.dependencies(), authz, qom])
3838 io_ss = io_ss.apply({})
3839 libio = static_library('io', io_ss.sources() + genh,
3840 dependencies: [io_ss.dependencies()],
3841 link_with: libqemuutil,
3842 build_by_default: false)
3844 io = declare_dependency(objects: libio.extract_all_objects(recursive: false),
3845 dependencies: [io_ss.dependencies(), crypto, qom])
3847 libmigration = static_library('migration', sources: migration_files + genh,
3848 build_by_default: false)
3849 migration = declare_dependency(objects: libmigration.extract_all_objects(recursive: false),
3850 dependencies: [qom, io])
3851 system_ss.add(migration)
3853 block_ss = block_ss.apply({})
3854 libblock = static_library('block', block_ss.sources() + genh,
3855 dependencies: block_ss.dependencies(),
3856 build_by_default: false)
3858 block = declare_dependency(objects: libblock.extract_all_objects(recursive: false),
3859 dependencies: [block_ss.dependencies(), crypto, io])
3861 blockdev_ss = blockdev_ss.apply({})
3862 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3863 dependencies: blockdev_ss.dependencies(),
3864 build_by_default: false)
3866 blockdev = declare_dependency(objects: libblockdev.extract_all_objects(recursive: false),
3867 dependencies: [blockdev_ss.dependencies(), block, event_loop_base])
3869 qmp_ss = qmp_ss.apply({})
3870 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3871 dependencies: qmp_ss.dependencies(),
3872 build_by_default: false)
3874 qmp = declare_dependency(objects: libqmp.extract_all_objects(recursive: false),
3875 dependencies: qmp_ss.dependencies())
3877 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3878 dependencies: chardev_ss.dependencies(),
3879 build_by_default: false)
3881 chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false),
3882 dependencies: chardev_ss.dependencies())
3884 hwcore_ss = hwcore_ss.apply({})
3885 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3886 build_by_default: false)
3887 hwcore = declare_dependency(objects: libhwcore.extract_all_objects(recursive: false))
3888 common_ss.add(hwcore)
3894 system_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3895 common_ss.add(qom, qemuutil)
3897 common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss])
3898 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3900 # Note that this library is never used directly (only through extract_objects)
3901 # and is not built by default; therefore, source files not used by the build
3902 # configuration will be in build.ninja, but are never built by default.
3903 common_all = static_library('common',
3904 build_by_default: false,
3905 sources: common_ss.all_sources() + genh,
3906 include_directories: common_user_inc,
3907 implicit_include_directories: false,
3908 dependencies: common_ss.all_dependencies())
3910 if have_rust and have_system
3911 rustc_args = run_command(
3912 find_program('scripts/rust/rustc_args.py'),
3913 '--config-headers', meson.project_build_root() / 'config-host.h',
3915 check: true).stdout().strip().split()
3916 rustc_args += ['-D', 'unsafe_op_in_unsafe_fn']
3918 '--disable-header-comment',
3919 '--raw-line', '// @generated',
3920 '--ctypes-prefix', 'core::ffi',
3921 '--formatter', 'rustfmt',
3925 '--merge-extern-blocks',
3926 '--no-doc-comments',
3928 '--with-derive-default',
3929 '--no-size_t-is-usize',
3930 '--no-layout-tests',
3931 '--no-prepend-enum-name',
3932 '--allowlist-file', meson.project_source_root() + '/include/.*',
3933 '--allowlist-file', meson.project_source_root() + '/.*',
3934 '--allowlist-file', meson.project_build_root() + '/.*'
3940 'MemoryDeviceInfoKind',
3942 'MigrationPriority',
3948 foreach enum : c_enums
3949 bindgen_args += ['--rustified-enum', enum]
3955 foreach enum : c_bitfields
3956 bindgen_args += ['--bitfield-enum', enum]
3959 # TODO: Remove this comment when the clang/libclang mismatch issue is solved.
3961 # Rust bindings generation with `bindgen` might fail in some cases where the
3962 # detected `libclang` does not match the expected `clang` version/target. In
3963 # this case you must pass the path to `clang` and `libclang` to your build
3964 # command invocation using the environment variables CLANG_PATH and
3966 bindings_rs = import('rust').bindgen(
3967 input: 'rust/wrapper.h',
3968 dependencies: common_ss.all_dependencies(),
3969 output: 'bindings.rs',
3970 include_directories: include_directories('.', 'include'),
3971 bindgen_version: ['>=0.69.4'],
3978 feature_to_c = find_program('scripts/feature_to_c.py')
3980 if host_os == 'darwin'
3981 entitlement = find_program('scripts/entitlement.sh')
3986 foreach target : target_dirs
3987 config_target = config_target_mak[target]
3988 target_name = config_target['TARGET_NAME']
3989 target_base_arch = config_target['TARGET_BASE_ARCH']
3990 arch_srcs = [config_target_h[target]]
3992 c_args = ['-DCOMPILING_PER_TARGET',
3993 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3994 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3995 link_args = emulator_link_args
3997 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3998 if host_os == 'linux'
3999 target_inc += include_directories('linux-headers', is_system: true)
4001 if target.endswith('-softmmu')
4002 target_type='system'
4003 t = target_system_arch[target_base_arch].apply(config_target, strict: false)
4004 arch_srcs += t.sources()
4005 arch_deps += t.dependencies()
4007 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
4008 if hw_arch.has_key(hw_dir)
4009 hw = hw_arch[hw_dir].apply(config_target, strict: false)
4010 arch_srcs += hw.sources()
4011 arch_deps += hw.dependencies()
4014 arch_srcs += config_devices_h[target]
4015 link_args += ['@block.syms', '@qemu.syms']
4017 abi = config_target['TARGET_ABI_DIR']
4019 target_inc += common_user_inc
4020 if target_base_arch in target_user_arch
4021 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
4022 arch_srcs += t.sources()
4023 arch_deps += t.dependencies()
4025 if 'CONFIG_LINUX_USER' in config_target
4026 base_dir = 'linux-user'
4028 if 'CONFIG_BSD_USER' in config_target
4029 base_dir = 'bsd-user'
4030 target_inc += include_directories('bsd-user/' / host_os)
4031 target_inc += include_directories('bsd-user/host/' / host_arch)
4032 dir = base_dir / abi
4033 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
4035 target_inc += include_directories(
4039 if 'CONFIG_LINUX_USER' in config_target
4040 dir = base_dir / abi
4041 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
4042 if config_target.has_key('TARGET_SYSTBL_ABI')
4044 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
4045 extra_args : config_target['TARGET_SYSTBL_ABI'])
4050 if 'TARGET_XML_FILES' in config_target
4051 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
4052 output: target + '-gdbstub-xml.c',
4053 input: files(config_target['TARGET_XML_FILES'].split()),
4054 command: [feature_to_c, '@INPUT@'],
4056 arch_srcs += gdbstub_xml
4059 t = target_arch[target_base_arch].apply(config_target, strict: false)
4060 arch_srcs += t.sources()
4061 arch_deps += t.dependencies()
4063 target_common = common_ss.apply(config_target, strict: false)
4064 objects = common_all.extract_objects(target_common.sources())
4065 arch_deps += target_common.dependencies()
4067 target_specific = specific_ss.apply(config_target, strict: false)
4068 arch_srcs += target_specific.sources()
4069 arch_deps += target_specific.dependencies()
4071 if have_rust and have_system
4072 target_rust = rust_devices_ss.apply(config_target, strict: false)
4074 foreach dep : target_rust.dependencies()
4075 crates += dep.get_variable('crate')
4077 if crates.length() > 0
4078 rlib_rs = custom_target('rust_' + target.underscorify() + '.rs',
4079 output: 'rust_' + target.underscorify() + '.rs',
4080 command: [find_program('scripts/rust/rust_root_crate.sh')] + crates,
4082 build_by_default: true,
4083 build_always_stale: true)
4084 rlib = static_library('rust_' + target.underscorify(),
4086 dependencies: target_rust.dependencies(),
4087 override_options: ['rust_std=2021', 'build.rust_std=2021'],
4088 rust_args: rustc_args,
4090 arch_deps += declare_dependency(link_whole: [rlib])
4094 # allow using headers from the dependencies but do not include the sources,
4095 # because this emulator only needs those in "objects". For external
4096 # dependencies, the full dependency is included below in the executable.
4098 foreach dep : arch_deps
4099 lib_deps += dep.partial_dependency(compile_args: true, includes: true)
4102 lib = static_library('qemu-' + target,
4103 sources: arch_srcs + genh,
4104 dependencies: lib_deps,
4106 include_directories: target_inc,
4108 build_by_default: false)
4110 if target.endswith('-softmmu')
4112 'name': 'qemu-system-' + target_name,
4113 'win_subsystem': 'console',
4114 'sources': files('system/main.c'),
4117 if host_os == 'windows' and (sdl.found() or gtk.found())
4119 'name': 'qemu-system-' + target_name + 'w',
4120 'win_subsystem': 'windows',
4121 'sources': files('system/main.c'),
4125 if get_option('fuzzing')
4126 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
4128 'name': 'qemu-fuzz-' + target_name,
4129 'win_subsystem': 'console',
4130 'sources': specific_fuzz.sources(),
4131 'dependencies': specific_fuzz.dependencies(),
4136 'name': 'qemu-' + target_name,
4137 'win_subsystem': 'console',
4143 exe_name = exe['name']
4144 if host_os == 'darwin'
4145 exe_name += '-unsigned'
4148 emulator = executable(exe_name, exe['sources'],
4151 dependencies: arch_deps + exe['dependencies'],
4152 objects: lib.extract_all_objects(recursive: true),
4153 link_depends: [block_syms, qemu_syms],
4154 link_args: link_args,
4155 win_subsystem: exe['win_subsystem'])
4157 if host_os == 'darwin'
4158 icon = 'pc-bios/qemu.rsrc'
4159 build_input = [emulator, files(icon)]
4161 get_option('bindir') / exe_name,
4162 meson.current_source_dir() / icon
4164 if 'CONFIG_HVF' in config_target
4165 entitlements = 'accel/hvf/entitlements.plist'
4166 build_input += files(entitlements)
4167 install_input += meson.current_source_dir() / entitlements
4170 emulators += {exe['name'] : custom_target(exe['name'],
4172 output: exe['name'],
4173 command: [entitlement, '@OUTPUT@', '@INPUT@'])
4176 meson.add_install_script(entitlement, '--install',
4177 get_option('bindir') / exe['name'],
4180 emulators += {exe['name']: emulator}
4185 'probe-prefix': 'qemu.' + target_type + '.' + target_name,
4191 # Other build targets
4193 if get_option('plugins')
4194 install_headers('include/qemu/qemu-plugin.h')
4195 if host_os == 'windows'
4196 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer,
4197 # so that plugin authors can compile against it.
4198 install_data(win32_qemu_plugin_api_lib, install_dir: 'lib')
4204 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
4205 # when we don't build tools or system
4206 if xkbcommon.found()
4207 # used for the update-keymaps target, so include rules even if !have_tools
4208 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
4209 dependencies: [qemuutil, xkbcommon], install: have_tools)
4213 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
4214 link_args: '@block.syms', link_depends: block_syms,
4215 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
4216 qemu_io = executable('qemu-io', files('qemu-io.c'),
4217 link_args: '@block.syms', link_depends: block_syms,
4218 dependencies: [block, qemuutil], install: true)
4219 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
4220 link_args: '@block.syms', link_depends: block_syms,
4221 dependencies: [blockdev, qemuutil, selinux],
4224 subdir('storage-daemon')
4226 foreach exe: [ 'qemu-img', 'qemu-io', 'qemu-nbd', 'qemu-storage-daemon']
4229 'probe-prefix': 'qemu.' + exe.substring(5).replace('-', '_')
4233 subdir('contrib/elf2dmp')
4235 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
4236 dependencies: qemuutil,
4240 subdir('contrib/vhost-user-blk')
4241 subdir('contrib/vhost-user-gpu')
4242 subdir('contrib/vhost-user-input')
4243 subdir('contrib/vhost-user-scsi')
4246 if host_os == 'linux'
4247 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
4248 dependencies: [qemuutil, libcap_ng],
4250 install_dir: get_option('libexecdir'))
4252 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
4253 dependencies: [authz, crypto, io, qom, qemuutil,
4254 libcap_ng, mpathpersist],
4257 if cpu in ['x86', 'x86_64']
4258 executable('qemu-vmsr-helper', files('tools/i386/qemu-vmsr-helper.c'),
4259 dependencies: [authz, crypto, io, qom, qemuutil,
4260 libcap_ng, mpathpersist],
4266 subdir('contrib/ivshmem-client')
4267 subdir('contrib/ivshmem-server')
4272 foreach t: traceable
4274 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / t['exe'], 'install': false},
4275 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / t['exe'], 'install': true},
4276 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
4277 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
4280 tracetool, '--group=all', '--format=' + stp['fmt'],
4281 '--binary=' + stp['bin'],
4282 '--probe-prefix=' + t['probe-prefix'],
4283 '@INPUT@', '@OUTPUT@'
4286 custom_target(t['exe'] + stp['ext'],
4287 input: trace_events_all,
4288 output: t['exe'] + stp['ext'],
4289 install: stp['install'],
4290 install_dir: get_option('datadir') / 'systemtap/tapset',
4292 depend_files: tracetool_depends)
4306 if host_machine.system() == 'windows'
4308 find_program('scripts/nsis.py'),
4310 get_option('prefix'),
4311 meson.current_source_dir(),
4312 glib_pc.get_variable('bindir'),
4315 '-DDISPLAYVERSION=' + meson.project_version(),
4318 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
4321 nsis_cmd += '-DCONFIG_GTK=y'
4324 nsis = custom_target('nsis',
4325 output: 'qemu-setup-' + meson.project_version() + '.exe',
4326 input: files('qemu.nsi'),
4327 build_always_stale: true,
4328 command: nsis_cmd + ['@INPUT@'])
4329 alias_target('installer', nsis)
4332 #########################
4333 # Configuration summary #
4334 #########################
4338 summary_info += {'Build directory': meson.current_build_dir()}
4339 summary_info += {'Source path': meson.current_source_dir()}
4340 summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'}
4341 summary(summary_info, bool_yn: true, section: 'Build environment')
4344 summary_info += {'Install prefix': get_option('prefix')}
4345 summary_info += {'BIOS directory': qemu_datadir}
4346 pathsep = host_os == 'windows' ? ';' : ':'
4347 summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))}
4348 summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
4349 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
4350 summary_info += {'module directory': qemu_moddir}
4351 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
4352 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
4353 summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')}
4354 if host_os != 'windows'
4355 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
4356 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')}
4358 summary_info += {'local state directory': 'queried at runtime'}
4360 summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
4361 summary(summary_info, bool_yn: true, section: 'Directories')
4365 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
4366 summary_info += {'sphinx-build': sphinx_build}
4368 # FIXME: the [binaries] section of machine files, which can be probed
4369 # with find_program(), would be great for passing gdb and genisoimage
4370 # paths from configure to Meson. However, there seems to be no way to
4371 # hide a program (for example if gdb is too old).
4372 if config_host.has_key('GDB')
4373 summary_info += {'gdb': config_host['GDB']}
4375 summary_info += {'iasl': iasl}
4376 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
4377 if host_os == 'windows' and have_ga
4378 summary_info += {'wixl': wixl}
4380 if slirp.found() and have_system
4381 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
4383 summary(summary_info, bool_yn: true, section: 'Host binaries')
4385 # Configurable features
4387 summary_info += {'Documentation': build_docs}
4388 summary_info += {'system-mode emulation': have_system}
4389 summary_info += {'user-mode emulation': have_user}
4390 summary_info += {'block layer': have_block}
4391 summary_info += {'Install blobs': get_option('install_blobs')}
4392 summary_info += {'module support': enable_modules}
4394 summary_info += {'alternative module path': get_option('module_upgrades')}
4396 summary_info += {'fuzzing support': get_option('fuzzing')}
4398 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
4400 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
4401 if 'simple' in get_option('trace_backends')
4402 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
4404 summary_info += {'D-Bus display': dbus_display}
4405 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
4406 summary_info += {'Relocatable install': get_option('relocatable')}
4407 summary_info += {'vhost-kernel support': have_vhost_kernel}
4408 summary_info += {'vhost-net support': have_vhost_net}
4409 summary_info += {'vhost-user support': have_vhost_user}
4410 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
4411 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
4412 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
4413 summary_info += {'build guest agent': have_ga}
4414 summary(summary_info, bool_yn: true, section: 'Configurable features')
4416 # Compilation information
4418 summary_info += {'host CPU': cpu}
4419 summary_info += {'host endianness': build_machine.endian()}
4420 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
4421 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
4422 if 'cpp' in all_languages
4423 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
4425 summary_info += {'C++ compiler': false}
4427 if 'objc' in all_languages
4428 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
4430 summary_info += {'Objective-C compiler': false}
4432 summary_info += {'Rust support': have_rust}
4434 summary_info += {'rustc version': rustc.version()}
4435 summary_info += {'rustc': ' '.join(rustc.cmd_array())}
4436 summary_info += {'Rust target': config_host['RUST_TARGET_TRIPLE']}
4438 option_cflags = (get_option('debug') ? ['-g'] : [])
4439 if get_option('optimization') != 'plain'
4440 option_cflags += ['-O' + get_option('optimization')]
4442 summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)}
4443 if 'cpp' in all_languages
4444 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)}
4446 if 'objc' in all_languages
4447 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)}
4449 link_args = get_option('c_link_args')
4450 if link_args.length() > 0
4451 summary_info += {'LDFLAGS': ' '.join(link_args)}
4453 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)}
4454 if 'cpp' in all_languages
4455 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)}
4457 if 'objc' in all_languages
4458 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)}
4460 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
4461 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
4462 summary_info += {'PIE': get_option('b_pie')}
4463 summary_info += {'static build': get_option('prefer_static')}
4464 summary_info += {'malloc trim support': has_malloc_trim}
4465 summary_info += {'membarrier': have_membarrier}
4466 summary_info += {'debug graph lock': get_option('debug_graph_lock')}
4467 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
4468 summary_info += {'mutex debugging': get_option('debug_mutex')}
4469 summary_info += {'memory allocator': get_option('malloc')}
4470 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
4471 summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')}
4472 summary_info += {'gcov': get_option('b_coverage')}
4473 summary_info += {'thread sanitizer': get_option('tsan')}
4474 summary_info += {'CFI support': get_option('cfi')}
4475 if get_option('cfi')
4476 summary_info += {'CFI debug support': get_option('cfi_debug')}
4478 summary_info += {'strip binaries': get_option('strip')}
4479 summary_info += {'sparse': sparse}
4480 summary_info += {'mingw32 support': host_os == 'windows'}
4481 summary(summary_info, bool_yn: true, section: 'Compilation')
4483 # snarf the cross-compilation information for tests
4486 foreach target: target_dirs
4487 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak'
4488 if fs.exists(tcg_mak)
4489 config_cross_tcg = keyval.load(tcg_mak)
4490 if 'CC' in config_cross_tcg
4491 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']}
4497 summary(summary_info, bool_yn: true, section: 'Cross compilers')
4500 # Targets and accelerators
4503 summary_info += {'KVM support': config_all_accel.has_key('CONFIG_KVM')}
4504 summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')}
4505 summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')}
4506 summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')}
4507 summary_info += {'Xen support': xen.found()}
4509 summary_info += {'xen ctrl version': xen.version()}
4511 summary_info += {'Xen emulation': config_all_devices.has_key('CONFIG_XEN_EMU')}
4513 summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')}
4514 if config_all_accel.has_key('CONFIG_TCG')
4515 if get_option('tcg_interpreter')
4516 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
4518 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
4520 summary_info += {'TCG plugins': get_option('plugins')}
4521 summary_info += {'TCG debug enabled': get_option('debug_tcg')}
4522 if have_linux_user or have_bsd_user
4523 summary_info += {'syscall buffer debugging support': get_option('debug_remap')}
4526 summary_info += {'target list': ' '.join(target_dirs)}
4528 summary_info += {'default devices': get_option('default_devices')}
4529 summary_info += {'out of process emulation': multiprocess_allowed}
4530 summary_info += {'vfio-user server': vfio_user_server_allowed}
4532 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
4536 summary_info += {'coroutine backend': coroutine_backend}
4537 summary_info += {'coroutine pool': have_coroutine_pool}
4539 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
4540 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
4541 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
4542 summary_info += {'VirtFS (9P) support': have_virtfs}
4543 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
4544 summary_info += {'bochs support': get_option('bochs').allowed()}
4545 summary_info += {'cloop support': get_option('cloop').allowed()}
4546 summary_info += {'dmg support': get_option('dmg').allowed()}
4547 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
4548 summary_info += {'vdi support': get_option('vdi').allowed()}
4549 summary_info += {'vhdx support': get_option('vhdx').allowed()}
4550 summary_info += {'vmdk support': get_option('vmdk').allowed()}
4551 summary_info += {'vpc support': get_option('vpc').allowed()}
4552 summary_info += {'vvfat support': get_option('vvfat').allowed()}
4553 summary_info += {'qed support': get_option('qed').allowed()}
4554 summary_info += {'parallels support': get_option('parallels').allowed()}
4555 summary_info += {'FUSE exports': fuse}
4556 summary_info += {'VDUSE block exports': have_vduse_blk_export}
4558 summary(summary_info, bool_yn: true, section: 'Block layer support')
4562 summary_info += {'TLS priority': get_option('tls_priority')}
4563 summary_info += {'GNUTLS support': gnutls}
4565 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
4567 summary_info += {'libgcrypt': gcrypt}
4568 summary_info += {'nettle': nettle}
4570 summary_info += {' XTS': xts != 'private'}
4572 summary_info += {'SM4 ALG support': crypto_sm4}
4573 summary_info += {'AF_ALG support': have_afalg}
4574 summary_info += {'rng-none': get_option('rng_none')}
4575 summary_info += {'Linux keyring': have_keyring}
4576 summary_info += {'Linux keyutils': keyutils}
4577 summary(summary_info, bool_yn: true, section: 'Crypto')
4581 if host_os == 'darwin'
4582 summary_info += {'Cocoa support': cocoa}
4584 summary_info += {'SDL support': sdl}
4585 summary_info += {'SDL image support': sdl_image}
4586 summary_info += {'GTK support': gtk}
4587 summary_info += {'pixman': pixman}
4588 summary_info += {'VTE support': vte}
4589 summary_info += {'PNG support': png}
4590 summary_info += {'VNC support': vnc}
4592 summary_info += {'VNC SASL support': sasl}
4593 summary_info += {'VNC JPEG support': jpeg}
4595 summary_info += {'spice protocol support': spice_protocol}
4596 if spice_protocol.found()
4597 summary_info += {' spice server support': spice}
4599 summary_info += {'curses support': curses}
4600 summary_info += {'brlapi support': brlapi}
4601 summary(summary_info, bool_yn: true, section: 'User interface')
4605 summary_info += {'VirGL support': virgl}
4606 summary_info += {'Rutabaga support': rutabaga}
4607 summary(summary_info, bool_yn: true, section: 'Graphics backends')
4611 if host_os not in ['darwin', 'haiku', 'windows']
4612 summary_info += {'OSS support': oss}
4613 summary_info += {'sndio support': sndio}
4614 elif host_os == 'darwin'
4615 summary_info += {'CoreAudio support': coreaudio}
4616 elif host_os == 'windows'
4617 summary_info += {'DirectSound support': dsound}
4619 if host_os == 'linux'
4620 summary_info += {'ALSA support': alsa}
4621 summary_info += {'PulseAudio support': pulse}
4623 summary_info += {'PipeWire support': pipewire}
4624 summary_info += {'JACK support': jack}
4625 summary(summary_info, bool_yn: true, section: 'Audio backends')
4629 if host_os == 'darwin'
4630 summary_info += {'vmnet.framework support': vmnet}
4632 summary_info += {'AF_XDP support': libxdp}
4633 summary_info += {'slirp support': slirp}
4634 summary_info += {'vde support': vde}
4635 summary_info += {'netmap support': have_netmap}
4636 summary_info += {'l2tpv3 support': have_l2tpv3}
4637 summary(summary_info, bool_yn: true, section: 'Network backends')
4641 summary_info += {'libtasn1': tasn1}
4642 summary_info += {'PAM': pam}
4643 summary_info += {'iconv support': iconv}
4644 summary_info += {'blkio support': blkio}
4645 summary_info += {'curl support': curl}
4646 summary_info += {'Multipath support': mpathpersist}
4647 summary_info += {'Linux AIO support': libaio}
4648 summary_info += {'Linux io_uring support': linux_io_uring}
4649 summary_info += {'ATTR/XATTR support': libattr}
4650 summary_info += {'RDMA support': rdma}
4651 summary_info += {'fdt support': fdt_opt == 'internal' ? 'internal' : fdt}
4652 summary_info += {'libcap-ng support': libcap_ng}
4653 summary_info += {'bpf support': libbpf}
4654 summary_info += {'rbd support': rbd}
4655 summary_info += {'smartcard support': cacard}
4656 summary_info += {'U2F support': u2f}
4657 summary_info += {'libusb': libusb}
4658 summary_info += {'usb net redir': usbredir}
4659 summary_info += {'OpenGL support (epoxy)': opengl}
4660 summary_info += {'GBM': gbm}
4661 summary_info += {'libiscsi support': libiscsi}
4662 summary_info += {'libnfs support': libnfs}
4663 if host_os == 'windows'
4665 summary_info += {'QGA VSS support': have_qga_vss}
4668 summary_info += {'seccomp support': seccomp}
4669 summary_info += {'GlusterFS support': glusterfs}
4670 summary_info += {'hv-balloon support': hv_balloon}
4671 summary_info += {'TPM support': have_tpm}
4672 summary_info += {'libssh support': libssh}
4673 summary_info += {'lzo support': lzo}
4674 summary_info += {'snappy support': snappy}
4675 summary_info += {'bzip2 support': libbzip2}
4676 summary_info += {'lzfse support': liblzfse}
4677 summary_info += {'zstd support': zstd}
4678 summary_info += {'Query Processing Library support': qpl}
4679 summary_info += {'UADK Library support': uadk}
4680 summary_info += {'qatzip support': qatzip}
4681 summary_info += {'NUMA host support': numa}
4682 summary_info += {'capstone': capstone}
4683 summary_info += {'libpmem support': libpmem}
4684 summary_info += {'libdaxctl support': libdaxctl}
4685 summary_info += {'libudev': libudev}
4686 # Dummy dependency, keep .found()
4687 summary_info += {'FUSE lseek': fuse_lseek.found()}
4688 summary_info += {'selinux': selinux}
4689 summary_info += {'libdw': libdw}
4690 if host_os == 'freebsd'
4691 summary_info += {'libinotify-kqueue': inotify}
4693 summary(summary_info, bool_yn: true, section: 'Dependencies')
4695 if host_arch == 'unknown'
4697 warning('UNSUPPORTED HOST CPU')
4699 message('Support for CPU host architecture ' + cpu + ' is not currently')
4700 message('maintained. The QEMU project does not guarantee that QEMU will')
4701 message('compile or work on this host CPU. You can help by volunteering')
4702 message('to maintain it and providing a build host for our continuous')
4703 message('integration setup.')
4704 if get_option('tcg').allowed() and target_dirs.length() > 0
4706 message('configure has succeeded and you can continue to build, but')
4707 message('QEMU will use a slow interpreter to emulate the target CPU.')
4711 if not supported_oses.contains(host_os)
4713 warning('UNSUPPORTED HOST OS')
4715 message('Support for host OS ' + host_os + 'is not currently maintained.')
4716 message('configure has succeeded and you can continue to build, but')
4717 message('the QEMU project does not guarantee that QEMU will compile or')
4718 message('work on this operating system. You can help by volunteering')
4719 message('to maintain it and providing a build host for our continuous')
4720 message('integration setup. This will ensure that future versions of QEMU')
4721 message('will keep working on ' + host_os + '.')
4724 if host_arch == 'unknown' or not supported_oses.contains(host_os)
4726 message('If you want to help supporting QEMU on this platform, please')
4727 message('contact the developers at qemu-devel@nongnu.org.')
4730 actually_reloc = get_option('relocatable')
4731 # check if get_relocated_path() is actually able to relocate paths
4732 if get_option('relocatable') and \
4733 not (get_option('prefix') / get_option('bindir')).startswith(get_option('prefix') / '')
4735 warning('bindir not included within prefix, the installation will not be relocatable.')
4736 actually_reloc = false
4738 if not actually_reloc and (host_os == 'windows' or get_option('relocatable'))
4739 if host_os == 'windows'
4741 warning('Windows installs should usually be relocatable.')
4744 message('QEMU will have to be installed under ' + get_option('prefix') + '.')
4745 message('Use --disable-relocatable to remove this warning.')