1 project('qemu', ['c'], meson_version: '>=0.63.0',
2 default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
3 'b_staticpic=false', 'stdsplit=false', 'optimization=2', 'b_pie=true'],
4 version: files('VERSION'))
6 add_test_setup('quick', exclude_suites: ['slow', 'thorough'], is_default: true)
7 add_test_setup('slow', exclude_suites: ['thorough'], env: ['G_TEST_SLOW=1', 'SPEED=slow'])
8 add_test_setup('thorough', env: ['G_TEST_SLOW=1', 'SPEED=thorough'])
10 meson.add_postconf_script(find_program('scripts/symlink-install-tree.py'))
12 not_found = dependency('', required: false)
13 keyval = import('keyval')
14 ss = import('sourceset')
17 targetos = host_machine.system()
18 sh = find_program('sh')
19 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
20 enable_modules = 'CONFIG_MODULES' in config_host
22 cc = meson.get_compiler('c')
24 if add_languages('cpp', required: false, native: false)
25 all_languages += ['cpp']
26 cxx = meson.get_compiler('cpp')
28 if targetos == 'darwin' and \
29 add_languages('objc', required: get_option('cocoa'), native: false)
30 all_languages += ['objc']
31 objc = meson.get_compiler('objc')
34 # Temporary directory used for files created while
35 # configure runs. Since it is in the build directory
36 # we can safely blow away any previous version of it
37 # (and we need not jump through hoops to try to delete
38 # it when configure exits.)
39 tmpdir = meson.current_build_dir() / 'meson-private/temp'
41 if get_option('qemu_suffix').startswith('/')
42 error('qemu_suffix cannot start with a /')
45 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
46 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
47 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
48 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
50 qemu_desktopdir = get_option('datadir') / 'applications'
51 qemu_icondir = get_option('datadir') / 'icons'
53 config_host_data = configuration_data()
55 qapi_trace_events = []
57 bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
58 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
59 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
60 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64']
62 cpu = host_machine.cpu_family()
64 # Unify riscv* to a single family.
65 if cpu in ['riscv32', 'riscv64']
69 target_dirs = config_host['TARGET_DIRS'].split()
70 have_linux_user = false
73 foreach target : target_dirs
74 have_linux_user = have_linux_user or target.endswith('linux-user')
75 have_bsd_user = have_bsd_user or target.endswith('bsd-user')
76 have_system = have_system or target.endswith('-softmmu')
78 have_user = have_linux_user or have_bsd_user
79 have_tools = get_option('tools') \
80 .disable_auto_if(not have_system) \
82 have_ga = get_option('guest_agent') \
83 .disable_auto_if(not have_system and not have_tools) \
84 .require(targetos in ['sunos', 'linux', 'windows', 'freebsd', 'netbsd', 'openbsd'],
85 error_message: 'unsupported OS for QEMU guest agent') \
87 have_block = have_system or have_tools
89 python = import('python').find_installation()
91 if cpu not in supported_cpus
101 if cpu in ['x86', 'x86_64']
102 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
103 elif cpu == 'aarch64'
104 kvm_targets = ['aarch64-softmmu']
106 kvm_targets = ['s390x-softmmu']
107 elif cpu in ['ppc', 'ppc64']
108 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
109 elif cpu in ['mips', 'mips64']
110 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
111 elif cpu in ['riscv']
112 kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
118 if get_option('kvm').allowed() and targetos == 'linux'
119 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
121 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
123 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
125 if cpu in ['aarch64']
126 accelerator_targets += {
127 'CONFIG_HVF': ['aarch64-softmmu']
131 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
132 # i386 emulator provides xenpv machine type for multiple architectures
133 accelerator_targets += {
134 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
137 if cpu in ['x86', 'x86_64']
138 accelerator_targets += {
139 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
140 'CONFIG_HVF': ['x86_64-softmmu'],
141 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
142 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
147 # Darwin does not support references to thread-local variables in modules
148 if targetos != 'darwin'
149 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
152 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
153 unpack_edk2_blobs = false
154 foreach target : edk2_targets
155 if target in target_dirs
156 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
157 unpack_edk2_blobs = bzip2.found()
164 if 'dtrace' in get_option('trace_backends')
165 dtrace = find_program('dtrace', required: true)
166 stap = find_program('stap', required: false)
168 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
169 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
170 # instead. QEMU --enable-modules depends on this because the SystemTap
171 # semaphores are linked into the main binary and not the module's shared
173 add_global_arguments('-DSTAP_SDT_V2',
174 native: false, language: all_languages)
178 if get_option('iasl') == ''
179 iasl = find_program('iasl', required: false)
181 iasl = find_program(get_option('iasl'), required: true)
188 qemu_cflags = config_host['QEMU_CFLAGS'].split()
189 qemu_objcflags = config_host['QEMU_OBJCFLAGS'].split()
190 qemu_ldflags = config_host['QEMU_LDFLAGS'].split()
192 if get_option('prefer_static')
193 qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static'
196 # Detect support for PT_GNU_RELRO + DT_BIND_NOW.
197 # The combination is known as "full relro", because .got.plt is read-only too.
198 qemu_ldflags += cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now')
200 if targetos == 'windows'
201 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat')
202 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase', '-Wl,--high-entropy-va')
205 if get_option('gprof')
206 qemu_cflags += ['-p']
207 qemu_objcflags += ['-p']
208 qemu_ldflags += ['-p']
211 # Specify linker-script with add_project_link_arguments so that it is not placed
212 # within a linker --start-group/--end-group pair
213 if get_option('fuzzing')
214 # Specify a filter to only instrument code that is directly related to
216 configure_file(output: 'instrumentation-filter',
217 input: 'scripts/oss-fuzz/instrumentation-filter-template',
220 if cc.compiles('int main () { return 0; }',
221 name: '-fsanitize-coverage-allowlist=/dev/null',
222 args: ['-fsanitize-coverage-allowlist=/dev/null',
223 '-fsanitize-coverage=trace-pc'] )
224 add_global_arguments('-fsanitize-coverage-allowlist=instrumentation-filter',
225 native: false, language: all_languages)
228 if get_option('fuzzing_engine') == ''
229 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
230 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
231 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
232 # unable to bind the fuzzer-related callbacks added by instrumentation.
233 add_global_arguments('-fsanitize=fuzzer-no-link',
234 native: false, language: all_languages)
235 add_global_link_arguments('-fsanitize=fuzzer-no-link',
236 native: false, language: all_languages)
237 # For the actual fuzzer binaries, we need to link against the libfuzzer
238 # library. They need to be configurable, to support OSS-Fuzz
239 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
241 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
242 # the needed CFLAGS have already been provided
243 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
247 # Check that the C++ compiler exists and works with the C compiler.
251 if 'cpp' in all_languages
252 add_global_arguments(['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'],
253 native: false, language: 'cpp')
254 foreach k: qemu_cflags
255 if k not in ['-Wstrict-prototypes', '-Wmissing-prototypes', '-Wnested-externs',
256 '-Wold-style-declaration', '-Wold-style-definition', '-Wredundant-decls']
261 if cxx.links(files('scripts/main.c'), args: qemu_cflags)
262 link_language = 'cpp'
265 message('C++ compiler does not work with C compiler')
266 message('Disabling C++-specific optional code')
270 # Exclude --warn-common with TSan to suppress warnings from the TSan libraries.
271 if targetos != 'sunos' and not config_host.has_key('CONFIG_TSAN')
272 qemu_ldflags += linker.get_supported_link_arguments('-Wl,--warn-common')
275 add_global_link_arguments(qemu_ldflags, native: false, language: all_languages)
277 add_global_arguments(qemu_cflags, native: false, language: 'c')
278 add_global_arguments(qemu_cxxflags, native: false, language: 'cpp')
279 add_global_arguments(qemu_objcflags, native: false, language: 'objc')
280 if targetos == 'linux'
281 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
282 '-isystem', 'linux-headers',
283 language: all_languages)
286 add_project_arguments('-iquote', '.',
287 '-iquote', meson.current_source_dir(),
288 '-iquote', meson.current_source_dir() / 'include',
289 language: all_languages)
291 sparse = find_program('cgcc', required: get_option('sparse'))
294 command: [find_program('scripts/check_sparse.py'),
295 'compile_commands.json', sparse.full_path(), '-Wbitwise',
296 '-Wno-transparent-union', '-Wno-old-initializer',
297 '-Wno-non-pointer-null'])
300 ###########################################
301 # Target-specific checks and dependencies #
302 ###########################################
305 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
308 #include <sys/types.h>
309 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
310 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
312 args: ['-Werror', '-fsanitize=fuzzer'])
313 error('Your compiler does not support -fsanitize=fuzzer')
317 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
318 error('ftrace is supported only on Linux')
320 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
323 openlog("qemu", LOG_PID, LOG_DAEMON);
324 syslog(LOG_INFO, "configure");
327 error('syslog is not supported on this system')
330 # Miscellaneous Linux-only features
331 get_option('mpath') \
332 .require(targetos == 'linux', error_message: 'Multipath is supported only on Linux')
334 multiprocess_allowed = get_option('multiprocess') \
335 .require(targetos == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
338 vfio_user_server_allowed = get_option('vfio_user_server') \
339 .require(targetos == 'linux', error_message: 'vfio-user server is supported only on Linux') \
342 have_tpm = get_option('tpm') \
343 .require(targetos != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
347 have_vhost_user = get_option('vhost_user') \
348 .disable_auto_if(targetos != 'linux') \
349 .require(targetos != 'windows',
350 error_message: 'vhost-user is not available on Windows').allowed()
351 have_vhost_vdpa = get_option('vhost_vdpa') \
352 .require(targetos == 'linux',
353 error_message: 'vhost-vdpa is only available on Linux').allowed()
354 have_vhost_kernel = get_option('vhost_kernel') \
355 .require(targetos == 'linux',
356 error_message: 'vhost-kernel is only available on Linux').allowed()
357 have_vhost_user_crypto = get_option('vhost_crypto') \
358 .require(have_vhost_user,
359 error_message: 'vhost-crypto requires vhost-user to be enabled').allowed()
361 have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel
363 have_vhost_net_user = have_vhost_user and get_option('vhost_net').allowed()
364 have_vhost_net_vdpa = have_vhost_vdpa and get_option('vhost_net').allowed()
365 have_vhost_net_kernel = have_vhost_kernel and get_option('vhost_net').allowed()
366 have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_vdpa
368 # Target-specific libraries and flags
369 libm = cc.find_library('m', required: false)
370 threads = dependency('threads')
371 util = cc.find_library('util', required: false)
377 emulator_link_args = []
384 if targetos == 'windows'
385 midl = find_program('midl', required: false)
386 widl = find_program('widl', required: false)
387 pathcch = cc.find_library('pathcch')
388 socket = cc.find_library('ws2_32')
389 winmm = cc.find_library('winmm')
391 win = import('windows')
392 version_res = win.compile_resources('version.rc',
393 depend_files: files('pc-bios/qemu-nsis.ico'),
394 include_directories: include_directories('.'))
396 elif targetos == 'darwin'
397 coref = dependency('appleframeworks', modules: 'CoreFoundation')
398 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
399 host_dsosuf = '.dylib'
400 elif targetos == 'sunos'
401 socket = [cc.find_library('socket'),
402 cc.find_library('nsl'),
403 cc.find_library('resolv')]
404 elif targetos == 'haiku'
405 socket = [cc.find_library('posix_error_mapper'),
406 cc.find_library('network'),
407 cc.find_library('bsd')]
408 elif targetos == 'openbsd'
409 if get_option('tcg').allowed() and target_dirs.length() > 0
410 # Disable OpenBSD W^X if available
411 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
415 # Target-specific configuration of accelerators
417 if get_option('kvm').allowed() and targetos == 'linux'
418 accelerators += 'CONFIG_KVM'
420 if get_option('whpx').allowed() and targetos == 'windows'
421 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
422 error('WHPX requires 64-bit host')
423 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
424 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
425 accelerators += 'CONFIG_WHPX'
428 if get_option('hvf').allowed()
429 hvf = dependency('appleframeworks', modules: 'Hypervisor',
430 required: get_option('hvf'))
432 accelerators += 'CONFIG_HVF'
435 if get_option('hax').allowed()
436 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
437 accelerators += 'CONFIG_HAX'
440 if targetos == 'netbsd'
441 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
443 accelerators += 'CONFIG_NVMM'
448 if get_option('tcg').allowed()
449 if host_arch == 'unknown'
450 if get_option('tcg_interpreter')
451 warning('Unsupported CPU @0@, will use TCG with TCI (slow)'.format(cpu))
453 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
455 elif get_option('tcg_interpreter')
456 warning('Use of the TCG interpreter is not recommended on this host')
457 warning('architecture. There is a native TCG execution backend available')
458 warning('which provides substantially better performance and reliability.')
459 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
460 warning('configuration option on this architecture to use the native')
463 if get_option('tcg_interpreter')
465 config_host += { 'CONFIG_TCG_INTERPRETER': 'y' }
466 elif host_arch == 'x86_64'
468 elif host_arch == 'ppc64'
471 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
472 language: all_languages)
474 accelerators += 'CONFIG_TCG'
475 config_host += { 'CONFIG_TCG': 'y' }
478 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
479 error('KVM not available on this platform')
481 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
482 error('HVF not available on this platform')
484 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
485 error('NVMM not available on this platform')
487 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
488 error('WHPX not available on this platform')
495 # The path to glib.h is added to all compilation commands. This was
496 # grandfathered in from the QEMU Makefiles.
497 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
498 native: false, language: all_languages)
499 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
500 link_args: config_host['GLIB_LIBS'].split(),
501 version: config_host['GLIB_VERSION'],
503 'bindir': config_host['GLIB_BINDIR'],
505 # override glib dep with the configure results (for subprojects)
506 meson.override_dependency('glib-2.0', glib)
507 # pass down whether Glib has the slice allocator
508 if config_host.has_key('HAVE_GLIB_WITH_SLICE_ALLOCATOR')
509 config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', true)
513 gdbus_codegen = not_found
514 gdbus_codegen_error = '@0@ requires gdbus-codegen, please install libgio'
515 if not get_option('gio').auto() or have_system
516 gio = dependency('gio-2.0', required: get_option('gio'),
517 method: 'pkg-config')
518 if gio.found() and not cc.links('''
522 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
524 }''', dependencies: [glib, gio])
525 if get_option('gio').enabled()
526 error('The installed libgio is broken for static linking')
531 gdbus_codegen = find_program(gio.get_variable('gdbus_codegen'),
532 required: get_option('gio'))
533 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
534 method: 'pkg-config')
535 gio = declare_dependency(dependencies: [gio, gio_unix],
536 version: gio.version())
539 if gdbus_codegen.found() and get_option('cfi')
540 gdbus_codegen = not_found
541 gdbus_codegen_error = '@0@ uses gdbus-codegen, which does not support control flow integrity'
545 if 'ust' in get_option('trace_backends')
546 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
547 method: 'pkg-config')
550 if have_system or have_tools
551 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
552 method: 'pkg-config')
554 zlib = dependency('zlib', required: true)
557 if not get_option('linux_aio').auto() or have_block
558 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
559 required: get_option('linux_aio'))
562 linux_io_uring_test = '''
563 #include <liburing.h>
564 #include <linux/errqueue.h>
566 int main(void) { return 0; }'''
568 linux_io_uring = not_found
569 if not get_option('linux_io_uring').auto() or have_block
570 linux_io_uring = dependency('liburing', version: '>=0.3',
571 required: get_option('linux_io_uring'),
572 method: 'pkg-config')
573 if not cc.links(linux_io_uring_test)
574 linux_io_uring = not_found
579 if not get_option('libnfs').auto() or have_block
580 libnfs = dependency('libnfs', version: '>=1.9.3',
581 required: get_option('libnfs'),
582 method: 'pkg-config')
587 #include <sys/types.h>
588 #ifdef CONFIG_LIBATTR
589 #include <attr/xattr.h>
591 #include <sys/xattr.h>
593 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
596 have_old_libattr = false
597 if get_option('attr').allowed()
598 if cc.links(libattr_test)
599 libattr = declare_dependency()
601 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
602 required: get_option('attr'))
603 if libattr.found() and not \
604 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
606 if get_option('attr').enabled()
607 error('could not link libattr')
609 warning('could not link libattr, disabling')
612 have_old_libattr = libattr.found()
617 cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
618 required: get_option('cocoa'))
620 vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
621 if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
622 'VMNET_BRIDGED_MODE',
625 if get_option('vmnet').enabled()
626 error('vmnet.framework API is outdated')
628 warning('vmnet.framework API is outdated, disabling')
633 seccomp_has_sysrawrc = false
634 if not get_option('seccomp').auto() or have_system or have_tools
635 seccomp = dependency('libseccomp', version: '>=2.3.0',
636 required: get_option('seccomp'),
637 method: 'pkg-config')
639 seccomp_has_sysrawrc = cc.has_header_symbol('seccomp.h',
640 'SCMP_FLTATR_API_SYSRAWRC',
641 dependencies: seccomp)
645 libcap_ng = not_found
646 if not get_option('cap_ng').auto() or have_system or have_tools
647 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
648 required: get_option('cap_ng'))
650 if libcap_ng.found() and not cc.links('''
654 capng_capability_to_name(CAPNG_EFFECTIVE);
656 }''', dependencies: libcap_ng)
657 libcap_ng = not_found
658 if get_option('cap_ng').enabled()
659 error('could not link libcap-ng')
661 warning('could not link libcap-ng, disabling')
665 if get_option('xkbcommon').auto() and not have_system and not have_tools
666 xkbcommon = not_found
668 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
669 method: 'pkg-config')
673 if not get_option('slirp').auto() or have_system
674 slirp = dependency('slirp', required: get_option('slirp'),
675 method: 'pkg-config')
676 # slirp < 4.7 is incompatible with CFI support in QEMU. This is because
677 # it passes function pointers within libslirp as callbacks for timers.
678 # When using a system-wide shared libslirp, the type information for the
679 # callback is missing and the timer call produces a false positive with CFI.
680 # Do not use the "version" keyword argument to produce a better error.
681 # with control-flow integrity.
682 if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
683 if get_option('slirp').enabled()
684 error('Control-Flow Integrity requires libslirp 4.7.')
686 warning('Cannot use libslirp since Control-Flow Integrity requires libslirp >= 4.7.')
693 if not get_option('vde').auto() or have_system or have_tools
694 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
695 required: get_option('vde'))
697 if vde.found() and not cc.links('''
698 #include <libvdeplug.h>
701 struct vde_open_args a = {0, 0, 0};
705 }''', dependencies: vde)
707 if get_option('cap_ng').enabled()
708 error('could not link libvdeplug')
710 warning('could not link libvdeplug, disabling')
715 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
716 pulse = dependency('libpulse', required: get_option('pa'),
717 method: 'pkg-config')
720 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
721 alsa = dependency('alsa', required: get_option('alsa'),
722 method: 'pkg-config')
725 if not get_option('jack').auto() or have_system
726 jack = dependency('jack', required: get_option('jack'),
727 method: 'pkg-config')
730 if not get_option('pipewire').auto() or (targetos == 'linux' and have_system)
731 pipewire = dependency('libpipewire-0.3', version: '>=0.3.60',
732 required: get_option('pipewire'),
733 method: 'pkg-config')
736 if not get_option('sndio').auto() or have_system
737 sndio = dependency('sndio', required: get_option('sndio'),
738 method: 'pkg-config')
741 spice_protocol = not_found
742 if not get_option('spice_protocol').auto() or have_system
743 spice_protocol = dependency('spice-protocol', version: '>=0.14.0',
744 required: get_option('spice_protocol'),
745 method: 'pkg-config')
748 if not get_option('spice').auto() or have_system
749 spice = dependency('spice-server', version: '>=0.14.0',
750 required: get_option('spice'),
751 method: 'pkg-config')
753 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
755 rt = cc.find_library('rt', required: false)
758 if not get_option('libiscsi').auto() or have_block
759 libiscsi = dependency('libiscsi', version: '>=1.9.0',
760 required: get_option('libiscsi'),
761 method: 'pkg-config')
764 if not get_option('zstd').auto() or have_block
765 zstd = dependency('libzstd', version: '>=1.4.0',
766 required: get_option('zstd'),
767 method: 'pkg-config')
771 have_vhost_user_gpu = have_tools and targetos == 'linux' and pixman.found()
772 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
773 virgl = dependency('virglrenderer',
774 method: 'pkg-config',
775 required: get_option('virglrenderer'))
778 if not get_option('blkio').auto() or have_block
779 blkio = dependency('blkio',
780 method: 'pkg-config',
781 required: get_option('blkio'))
784 if not get_option('curl').auto() or have_block
785 curl = dependency('libcurl', version: '>=7.29.0',
786 method: 'pkg-config',
787 required: get_option('curl'))
790 if targetos == 'linux' and (have_system or have_tools)
791 libudev = dependency('libudev',
792 method: 'pkg-config',
793 required: get_option('libudev'))
796 mpathlibs = [libudev]
797 mpathpersist = not_found
798 mpathpersist_new_api = false
799 if targetos == 'linux' and have_tools and get_option('mpath').allowed()
800 mpath_test_source_new = '''
802 #include <mpath_persist.h>
803 unsigned mpath_mx_alloc_len = 1024;
805 static struct config *multipath_conf;
806 extern struct udev *udev;
807 extern struct config *get_multipath_config(void);
808 extern void put_multipath_config(struct config *conf);
810 struct config *get_multipath_config(void) { return multipath_conf; }
811 void put_multipath_config(struct config *conf) { }
814 multipath_conf = mpath_lib_init();
817 mpath_test_source_old = '''
819 #include <mpath_persist.h>
820 unsigned mpath_mx_alloc_len = 1024;
823 struct udev *udev = udev_new();
824 mpath_lib_init(udev);
827 libmpathpersist = cc.find_library('mpathpersist',
828 required: get_option('mpath'))
829 if libmpathpersist.found()
830 mpathlibs += libmpathpersist
831 if get_option('prefer_static')
832 mpathlibs += cc.find_library('devmapper',
833 required: get_option('mpath'))
835 mpathlibs += cc.find_library('multipath',
836 required: get_option('mpath'))
837 foreach lib: mpathlibs
843 if mpathlibs.length() == 0
844 msg = 'Dependencies missing for libmpathpersist'
845 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
846 mpathpersist = declare_dependency(dependencies: mpathlibs)
847 mpathpersist_new_api = true
848 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
849 mpathpersist = declare_dependency(dependencies: mpathlibs)
851 msg = 'Cannot detect libmpathpersist API'
853 if not mpathpersist.found()
854 if get_option('mpath').enabled()
857 warning(msg + ', disabling')
865 if have_system and get_option('curses').allowed()
867 #if defined(__APPLE__) || defined(__OpenBSD__)
868 #define _XOPEN_SOURCE_EXTENDED 1
875 setlocale(LC_ALL, "");
877 addwstr(L"wide chars\n");
879 add_wch(WACS_DEGREE);
883 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
884 curses = dependency(curses_dep_list,
886 method: 'pkg-config')
887 msg = get_option('curses').enabled() ? 'curses library not found' : ''
888 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
890 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
891 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses],
892 version: curses.version())
894 msg = 'curses package not usable'
898 if not curses.found()
899 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
900 if targetos != 'windows' and not has_curses_h
901 message('Trying with /usr/include/ncursesw')
902 curses_compile_args += ['-I/usr/include/ncursesw']
903 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
906 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
907 foreach curses_libname : curses_libname_list
908 libcurses = cc.find_library(curses_libname,
911 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
912 curses = declare_dependency(compile_args: curses_compile_args,
913 dependencies: [libcurses])
916 msg = 'curses library not usable'
922 if get_option('iconv').allowed()
923 foreach link_args : [ ['-liconv'], [] ]
924 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
925 # We need to use libiconv if available because mixing libiconv's headers with
926 # the system libc does not work.
927 # However, without adding glib to the dependencies -L/usr/local/lib will not be
928 # included in the command line and libiconv will not be found.
932 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
933 return conv != (iconv_t) -1;
934 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
935 iconv = declare_dependency(link_args: link_args, dependencies: glib)
940 if curses.found() and not iconv.found()
941 if get_option('iconv').enabled()
942 error('iconv not available')
944 msg = 'iconv required for curses UI but not available'
947 if not curses.found() and msg != ''
948 if get_option('curses').enabled()
951 warning(msg + ', disabling')
957 if not get_option('brlapi').auto() or have_system
958 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
959 required: get_option('brlapi'))
960 if brlapi.found() and not cc.links('''
963 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
965 if get_option('brlapi').enabled()
966 error('could not link brlapi')
968 warning('could not link brlapi, disabling')
974 if not get_option('sdl').auto() or have_system
975 sdl = dependency('sdl2', required: get_option('sdl'))
976 sdl_image = not_found
979 # work around 2.0.8 bug
980 sdl = declare_dependency(compile_args: '-Wno-undef',
982 version: sdl.version())
983 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
984 method: 'pkg-config')
986 if get_option('sdl_image').enabled()
987 error('sdl-image required, but SDL was @0@'.format(
988 get_option('sdl').disabled() ? 'disabled' : 'not found'))
990 sdl_image = not_found
994 if not get_option('rbd').auto() or have_block
995 librados = cc.find_library('rados', required: get_option('rbd'))
996 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
997 required: get_option('rbd'))
998 if librados.found() and librbd.found()
1001 #include <rbd/librbd.h>
1004 rados_create(&cluster, NULL);
1005 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
1009 }''', dependencies: [librbd, librados])
1010 rbd = declare_dependency(dependencies: [librbd, librados])
1011 elif get_option('rbd').enabled()
1012 error('librbd >= 1.12.0 required')
1014 warning('librbd >= 1.12.0 not found, disabling')
1019 glusterfs = not_found
1020 glusterfs_ftruncate_has_stat = false
1021 glusterfs_iocb_has_stat = false
1022 if not get_option('glusterfs').auto() or have_block
1023 glusterfs = dependency('glusterfs-api', version: '>=3',
1024 required: get_option('glusterfs'),
1025 method: 'pkg-config')
1026 if glusterfs.found()
1027 glusterfs_ftruncate_has_stat = cc.links('''
1028 #include <glusterfs/api/glfs.h>
1033 /* new glfs_ftruncate() passes two additional args */
1034 return glfs_ftruncate(NULL, 0, NULL, NULL);
1036 ''', dependencies: glusterfs)
1037 glusterfs_iocb_has_stat = cc.links('''
1038 #include <glusterfs/api/glfs.h>
1040 /* new glfs_io_cbk() passes two additional glfs_stat structs */
1042 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
1048 glfs_io_cbk iocb = &glusterfs_iocb;
1049 iocb(NULL, 0 , NULL, NULL, NULL);
1052 ''', dependencies: glusterfs)
1057 if not get_option('libssh').auto() or have_block
1058 libssh = dependency('libssh', version: '>=0.8.7',
1059 method: 'pkg-config',
1060 required: get_option('libssh'))
1063 libbzip2 = not_found
1064 if not get_option('bzip2').auto() or have_block
1065 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
1066 required: get_option('bzip2'))
1067 if libbzip2.found() and not cc.links('''
1069 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
1070 libbzip2 = not_found
1071 if get_option('bzip2').enabled()
1072 error('could not link libbzip2')
1074 warning('could not link libbzip2, disabling')
1079 liblzfse = not_found
1080 if not get_option('lzfse').auto() or have_block
1081 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
1082 required: get_option('lzfse'))
1084 if liblzfse.found() and not cc.links('''
1086 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
1087 liblzfse = not_found
1088 if get_option('lzfse').enabled()
1089 error('could not link liblzfse')
1091 warning('could not link liblzfse, disabling')
1096 if get_option('oss').allowed() and have_system
1097 if not cc.has_header('sys/soundcard.h')
1099 elif targetos == 'netbsd'
1100 oss = cc.find_library('ossaudio', required: get_option('oss'))
1102 oss = declare_dependency()
1106 if get_option('oss').enabled()
1107 error('OSS not found')
1112 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
1113 if cc.has_header('dsound.h')
1114 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
1117 if not dsound.found()
1118 if get_option('dsound').enabled()
1119 error('DirectSound not found')
1124 coreaudio = not_found
1125 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
1126 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
1127 required: get_option('coreaudio'))
1131 if not get_option('opengl').auto() or have_system or have_vhost_user_gpu
1132 epoxy = dependency('epoxy', method: 'pkg-config',
1133 required: get_option('opengl'))
1134 if cc.has_header('epoxy/egl.h', dependencies: epoxy)
1136 elif get_option('opengl').enabled()
1137 error('epoxy/egl.h not found')
1141 if (have_system or have_tools) and (virgl.found() or opengl.found())
1142 gbm = dependency('gbm', method: 'pkg-config', required: false)
1144 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and opengl.found() and gbm.found()
1147 gnutls_crypto = not_found
1148 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1149 # For general TLS support our min gnutls matches
1150 # that implied by our platform support matrix
1152 # For the crypto backends, we look for a newer
1155 # Version 3.6.8 is needed to get XTS
1156 # Version 3.6.13 is needed to get PBKDF
1157 # Version 3.6.14 is needed to get HW accelerated XTS
1159 # If newer enough gnutls isn't available, we can
1160 # still use a different crypto backend to satisfy
1161 # the platform support requirements
1162 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1163 method: 'pkg-config',
1165 if gnutls_crypto.found()
1166 gnutls = gnutls_crypto
1168 # Our min version if all we need is TLS
1169 gnutls = dependency('gnutls', version: '>=3.5.18',
1170 method: 'pkg-config',
1171 required: get_option('gnutls'))
1175 # We prefer use of gnutls for crypto, unless the options
1176 # explicitly asked for nettle or gcrypt.
1178 # If gnutls isn't available for crypto, then we'll prefer
1179 # gcrypt over nettle for performance reasons.
1185 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1186 error('Only one of gcrypt & nettle can be enabled')
1189 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1190 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1191 gnutls_crypto = not_found
1194 if not gnutls_crypto.found()
1195 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1196 gcrypt = dependency('libgcrypt', version: '>=1.8',
1197 method: 'config-tool',
1198 required: get_option('gcrypt'))
1199 # Debian has removed -lgpg-error from libgcrypt-config
1200 # as it "spreads unnecessary dependencies" which in
1201 # turn breaks static builds...
1202 if gcrypt.found() and get_option('prefer_static')
1203 gcrypt = declare_dependency(dependencies:
1205 cc.find_library('gpg-error', required: true)],
1206 version: gcrypt.version())
1209 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1210 nettle = dependency('nettle', version: '>=3.4',
1211 method: 'pkg-config',
1212 required: get_option('nettle'))
1213 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1219 gmp = dependency('gmp', required: false, method: 'pkg-config')
1220 if nettle.found() and gmp.found()
1221 hogweed = dependency('hogweed', version: '>=3.4',
1222 method: 'pkg-config',
1223 required: get_option('nettle'))
1230 have_gtk_clipboard = get_option('gtk_clipboard').enabled()
1232 if not get_option('gtk').auto() or have_system
1233 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1234 method: 'pkg-config',
1235 required: get_option('gtk'))
1237 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1238 method: 'pkg-config',
1240 gtk = declare_dependency(dependencies: [gtk, gtkx11],
1241 version: gtk.version())
1243 if not get_option('vte').auto() or have_system
1244 vte = dependency('vte-2.91',
1245 method: 'pkg-config',
1246 required: get_option('vte'))
1248 elif have_gtk_clipboard
1249 error('GTK clipboard requested, but GTK not found')
1255 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found())
1258 if get_option('png').allowed() and have_system
1259 png = dependency('libpng', version: '>=1.6.34', required: get_option('png'),
1260 method: 'pkg-config')
1265 if get_option('vnc').allowed() and have_system
1266 vnc = declare_dependency() # dummy dependency
1267 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1268 method: 'pkg-config')
1269 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1270 required: get_option('vnc_sasl'))
1272 sasl = declare_dependency(dependencies: sasl,
1273 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1278 if not get_option('auth_pam').auto() or have_system
1279 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1280 required: get_option('auth_pam'))
1282 if pam.found() and not cc.links('''
1284 #include <security/pam_appl.h>
1286 const char *service_name = "qemu";
1287 const char *user = "frank";
1288 const struct pam_conv pam_conv = { 0 };
1289 pam_handle_t *pamh = NULL;
1290 pam_start(service_name, user, &pam_conv, &pamh);
1292 }''', dependencies: pam)
1294 if get_option('auth_pam').enabled()
1295 error('could not link libpam')
1297 warning('could not link libpam, disabling')
1302 if not get_option('snappy').auto() or have_system
1303 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1304 required: get_option('snappy'))
1306 if snappy.found() and not linker.links('''
1307 #include <snappy-c.h>
1308 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1310 if get_option('snappy').enabled()
1311 error('could not link libsnappy')
1313 warning('could not link libsnappy, disabling')
1318 if not get_option('lzo').auto() or have_system
1319 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1320 required: get_option('lzo'))
1322 if lzo.found() and not cc.links('''
1323 #include <lzo/lzo1x.h>
1324 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1326 if get_option('lzo').enabled()
1327 error('could not link liblzo2')
1329 warning('could not link liblzo2, disabling')
1334 if not get_option('numa').auto() or have_system or have_tools
1335 numa = cc.find_library('numa', has_headers: ['numa.h'],
1336 required: get_option('numa'))
1338 if numa.found() and not cc.links('''
1340 int main(void) { return numa_available(); }
1341 ''', dependencies: numa)
1343 if get_option('numa').enabled()
1344 error('could not link numa')
1346 warning('could not link numa, disabling')
1351 if not get_option('rdma').auto() or have_system
1352 libumad = cc.find_library('ibumad', required: get_option('rdma'))
1353 rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'],
1354 required: get_option('rdma')),
1355 cc.find_library('ibverbs', required: get_option('rdma')),
1357 rdma = declare_dependency(dependencies: rdma_libs)
1358 foreach lib: rdma_libs
1366 if get_option('xen').enabled() or (get_option('xen').auto() and have_system)
1367 xencontrol = dependency('xencontrol', required: false,
1368 method: 'pkg-config')
1369 if xencontrol.found()
1370 xen_pc = declare_dependency(version: xencontrol.version(),
1373 # disabler: true makes xen_pc.found() return false if any is not found
1374 dependency('xenstore', required: false,
1375 method: 'pkg-config',
1377 dependency('xenforeignmemory', required: false,
1378 method: 'pkg-config',
1380 dependency('xengnttab', required: false,
1381 method: 'pkg-config',
1383 dependency('xenevtchn', required: false,
1384 method: 'pkg-config',
1386 dependency('xendevicemodel', required: false,
1387 method: 'pkg-config',
1389 # optional, no "disabler: true"
1390 dependency('xentoolcore', required: false,
1391 method: 'pkg-config')])
1397 xen_tests = [ '4.11.0', '4.10.0', '4.9.0', '4.8.0', '4.7.1', '4.6.0', '4.5.0', '4.2.0' ]
1399 '4.11.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
1400 '4.10.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
1401 '4.9.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1402 '4.8.0': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1403 '4.7.1': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1404 '4.6.0': [ 'xenstore', 'xenctrl' ],
1405 '4.5.0': [ 'xenstore', 'xenctrl' ],
1406 '4.2.0': [ 'xenstore', 'xenctrl' ],
1409 foreach ver: xen_tests
1410 # cache the various library tests to avoid polluting the logs
1412 foreach l: xen_libs[ver]
1413 if l not in xen_deps
1414 xen_deps += { l: cc.find_library(l, required: false) }
1416 xen_test_deps += xen_deps[l]
1419 # Use -D to pick just one of the test programs in scripts/xen-detect.c
1420 xen_version = ver.split('.')
1421 xen_ctrl_version = xen_version[0] + \
1422 ('0' + xen_version[1]).substring(-2) + \
1423 ('0' + xen_version[2]).substring(-2)
1424 if cc.links(files('scripts/xen-detect.c'),
1425 args: '-DCONFIG_XEN_CTRL_INTERFACE_VERSION=' + xen_ctrl_version,
1426 dependencies: xen_test_deps)
1427 xen = declare_dependency(version: ver, dependencies: xen_test_deps)
1433 accelerators += 'CONFIG_XEN'
1434 elif get_option('xen').enabled()
1435 error('could not compile and link Xen test program')
1438 have_xen_pci_passthrough = get_option('xen_pci_passthrough') \
1439 .require(xen.found(),
1440 error_message: 'Xen PCI passthrough requested but Xen not enabled') \
1441 .require(targetos == 'linux',
1442 error_message: 'Xen PCI passthrough not available on this platform') \
1447 if not get_option('smartcard').auto() or have_system
1448 cacard = dependency('libcacard', required: get_option('smartcard'),
1449 version: '>=2.5.1', method: 'pkg-config')
1453 u2f = dependency('u2f-emu', required: get_option('u2f'),
1454 method: 'pkg-config')
1458 canokey = dependency('canokey-qemu', required: get_option('canokey'),
1459 method: 'pkg-config')
1461 usbredir = not_found
1462 if not get_option('usb_redir').auto() or have_system
1463 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1464 version: '>=0.6', method: 'pkg-config')
1467 if not get_option('libusb').auto() or have_system
1468 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1469 version: '>=1.0.13', method: 'pkg-config')
1473 if not get_option('libpmem').auto() or have_system
1474 libpmem = dependency('libpmem', required: get_option('libpmem'),
1475 method: 'pkg-config')
1477 libdaxctl = not_found
1478 if not get_option('libdaxctl').auto() or have_system
1479 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1480 version: '>=57', method: 'pkg-config')
1484 tasn1 = dependency('libtasn1',
1485 method: 'pkg-config')
1487 keyutils = dependency('libkeyutils', required: false,
1488 method: 'pkg-config')
1490 has_gettid = cc.has_function('gettid')
1493 selinux = dependency('libselinux',
1494 required: get_option('selinux'),
1495 method: 'pkg-config')
1500 if get_option('malloc') == 'system'
1502 get_option('malloc_trim').allowed() and \
1503 cc.links('''#include <malloc.h>
1504 int main(void) { malloc_trim(0); return 0; }''')
1506 has_malloc_trim = false
1507 malloc = cc.find_library(get_option('malloc'), required: true)
1509 if not has_malloc_trim and get_option('malloc_trim').enabled()
1510 if get_option('malloc') == 'system'
1511 error('malloc_trim not available on this platform.')
1513 error('malloc_trim not available with non-libc memory allocator')
1517 # Check whether the glibc provides statx()
1519 gnu_source_prefix = '''
1524 statx_test = gnu_source_prefix + '''
1525 #include <sys/stat.h>
1527 struct statx statxbuf;
1528 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1532 has_statx = cc.links(statx_test)
1534 # Check whether statx() provides mount ID information
1536 statx_mnt_id_test = gnu_source_prefix + '''
1537 #include <sys/stat.h>
1539 struct statx statxbuf;
1540 statx(0, "", 0, STATX_BASIC_STATS | STATX_MNT_ID, &statxbuf);
1541 return statxbuf.stx_mnt_id;
1544 has_statx_mnt_id = cc.links(statx_mnt_id_test)
1546 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
1547 .require(targetos == 'linux',
1548 error_message: 'vhost_user_blk_server requires linux') \
1549 .require(have_vhost_user,
1550 error_message: 'vhost_user_blk_server requires vhost-user support') \
1551 .disable_auto_if(not have_tools and not have_system) \
1554 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1555 error('Cannot enable fuse-lseek while fuse is disabled')
1558 fuse = dependency('fuse3', required: get_option('fuse'),
1559 version: '>=3.1', method: 'pkg-config')
1561 fuse_lseek = not_found
1562 if get_option('fuse_lseek').allowed()
1563 if fuse.version().version_compare('>=3.8')
1565 fuse_lseek = declare_dependency()
1566 elif get_option('fuse_lseek').enabled()
1568 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1570 error('fuse-lseek requires libfuse, which was not found')
1575 have_libvduse = (targetos == 'linux')
1576 if get_option('libvduse').enabled()
1577 if targetos != 'linux'
1578 error('libvduse requires linux')
1580 elif get_option('libvduse').disabled()
1581 have_libvduse = false
1584 have_vduse_blk_export = (have_libvduse and targetos == 'linux')
1585 if get_option('vduse_blk_export').enabled()
1586 if targetos != 'linux'
1587 error('vduse_blk_export requires linux')
1588 elif not have_libvduse
1589 error('vduse_blk_export requires libvduse support')
1591 elif get_option('vduse_blk_export').disabled()
1592 have_vduse_blk_export = false
1596 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1597 if libbpf.found() and not cc.links('''
1598 #include <bpf/libbpf.h>
1601 bpf_object__destroy_skeleton(NULL);
1603 }''', dependencies: libbpf)
1605 if get_option('bpf').enabled()
1606 error('libbpf skeleton test failed')
1608 warning('libbpf skeleton test failed, disabling')
1614 if not get_option('libdw').auto() or \
1615 (not get_option('prefer_static') and (have_system or have_user))
1616 libdw = dependency('libdw',
1617 method: 'pkg-config',
1618 required: get_option('libdw'))
1625 audio_drivers_selected = []
1627 audio_drivers_available = {
1628 'alsa': alsa.found(),
1629 'coreaudio': coreaudio.found(),
1630 'dsound': dsound.found(),
1631 'jack': jack.found(),
1633 'pa': pulse.found(),
1634 'pipewire': pipewire.found(),
1636 'sndio': sndio.found(),
1638 foreach k, v: audio_drivers_available
1639 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1642 # Default to native drivers first, OSS second, SDL third
1643 audio_drivers_priority = \
1644 [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \
1645 (targetos == 'linux' ? [] : [ 'sdl' ])
1646 audio_drivers_default = []
1647 foreach k: audio_drivers_priority
1648 if audio_drivers_available[k]
1649 audio_drivers_default += k
1653 foreach k: get_option('audio_drv_list')
1655 audio_drivers_selected += audio_drivers_default
1656 elif not audio_drivers_available[k]
1657 error('Audio driver "@0@" not available.'.format(k))
1659 audio_drivers_selected += k
1663 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1664 '"' + '", "'.join(audio_drivers_selected) + '", ')
1666 if get_option('cfi')
1668 # Check for dependency on LTO
1669 if not get_option('b_lto')
1670 error('Selected Control-Flow Integrity but LTO is disabled')
1672 if config_host.has_key('CONFIG_MODULES')
1673 error('Selected Control-Flow Integrity is not compatible with modules')
1675 # Check for cfi flags. CFI requires LTO so we can't use
1676 # get_supported_arguments, but need a more complex "compiles" which allows
1678 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1679 args: ['-flto', '-fsanitize=cfi-icall'] )
1680 cfi_flags += '-fsanitize=cfi-icall'
1682 error('-fsanitize=cfi-icall is not supported by the compiler')
1684 if cc.compiles('int main () { return 0; }',
1685 name: '-fsanitize-cfi-icall-generalize-pointers',
1686 args: ['-flto', '-fsanitize=cfi-icall',
1687 '-fsanitize-cfi-icall-generalize-pointers'] )
1688 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1690 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1692 if get_option('cfi_debug')
1693 if cc.compiles('int main () { return 0; }',
1694 name: '-fno-sanitize-trap=cfi-icall',
1695 args: ['-flto', '-fsanitize=cfi-icall',
1696 '-fno-sanitize-trap=cfi-icall'] )
1697 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1699 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1702 add_global_arguments(cfi_flags, native: false, language: all_languages)
1703 add_global_link_arguments(cfi_flags, native: false, language: all_languages)
1706 have_host_block_device = (targetos != 'darwin' or
1707 cc.has_header('IOKit/storage/IOMedia.h'))
1709 dbus_display = get_option('dbus_display') \
1710 .require(gio.version().version_compare('>=2.64'),
1711 error_message: '-display dbus requires glib>=2.64') \
1712 .require(gdbus_codegen.found(),
1713 error_message: gdbus_codegen_error.format('-display dbus')) \
1714 .require(targetos != 'windows',
1715 error_message: '-display dbus is not available on Windows') \
1718 have_virtfs = get_option('virtfs') \
1719 .require(targetos == 'linux' or targetos == 'darwin',
1720 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
1721 .require(targetos == 'linux' or cc.has_function('pthread_fchdir_np'),
1722 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
1723 .require(targetos == 'darwin' or libattr.found(),
1724 error_message: 'virtio-9p (virtfs) on Linux requires libattr-devel') \
1725 .disable_auto_if(not have_tools and not have_system) \
1728 have_virtfs_proxy_helper = get_option('virtfs_proxy_helper') \
1729 .require(targetos != 'darwin', error_message: 'the virtfs proxy helper is incompatible with macOS') \
1730 .require(have_virtfs, error_message: 'the virtfs proxy helper requires that virtfs is enabled') \
1731 .disable_auto_if(not have_tools) \
1732 .require(libcap_ng.found(), error_message: 'the virtfs proxy helper requires libcap-ng') \
1735 if get_option('block_drv_ro_whitelist') == ''
1736 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
1738 config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
1739 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
1741 if get_option('block_drv_rw_whitelist') == ''
1742 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
1744 config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
1745 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
1748 foreach k : get_option('trace_backends')
1749 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1751 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1752 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
1754 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
1756 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1757 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1758 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1759 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1760 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1762 qemu_firmwarepath = ''
1763 foreach k : get_option('qemu_firmwarepath')
1764 qemu_firmwarepath += '"' + get_option('prefix') / k + '", '
1766 config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath)
1768 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1769 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1770 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1771 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1772 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1773 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1775 if config_host.has_key('CONFIG_MODULES')
1776 config_host_data.set('CONFIG_STAMP', run_command(
1777 meson.current_source_dir() / 'scripts/qemu-stamp.py',
1778 meson.project_version(), get_option('pkgversion'), '--',
1779 meson.current_source_dir() / 'configure',
1780 capture: true, check: true).stdout().strip())
1783 have_slirp_smbd = get_option('slirp_smbd') \
1784 .require(targetos != 'windows', error_message: 'Host smbd not supported on this platform.') \
1787 smbd_path = get_option('smbd')
1789 smbd_path = (targetos == 'solaris' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
1791 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
1794 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
1796 if get_option('module_upgrades') and not enable_modules
1797 error('Cannot enable module-upgrades as modules are not enabled')
1799 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
1801 config_host_data.set('CONFIG_ATTR', libattr.found())
1802 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
1803 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1804 config_host_data.set('CONFIG_COCOA', cocoa.found())
1805 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1806 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1807 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1808 config_host_data.set('CONFIG_LZO', lzo.found())
1809 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1810 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1811 config_host_data.set('CONFIG_BLKIO', blkio.found())
1812 config_host_data.set('CONFIG_CURL', curl.found())
1813 config_host_data.set('CONFIG_CURSES', curses.found())
1814 config_host_data.set('CONFIG_GBM', gbm.found())
1815 config_host_data.set('CONFIG_GIO', gio.found())
1816 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1817 if glusterfs.found()
1818 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1819 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1820 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1821 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1822 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1823 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1825 config_host_data.set('CONFIG_GTK', gtk.found())
1826 config_host_data.set('CONFIG_VTE', vte.found())
1827 config_host_data.set('CONFIG_GTK_CLIPBOARD', have_gtk_clipboard)
1828 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1829 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1830 config_host_data.set('CONFIG_EBPF', libbpf.found())
1831 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1832 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1833 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1834 config_host_data.set('CONFIG_LIBSSH', libssh.found())
1835 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1836 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1837 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1838 config_host_data.set('CONFIG_NUMA', numa.found())
1840 config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY',
1841 cc.has_function('numa_has_preferred_many',
1842 dependencies: numa))
1844 config_host_data.set('CONFIG_OPENGL', opengl.found())
1845 config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
1846 config_host_data.set('CONFIG_RBD', rbd.found())
1847 config_host_data.set('CONFIG_RDMA', rdma.found())
1848 config_host_data.set('CONFIG_SDL', sdl.found())
1849 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1850 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1852 config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc)
1854 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1855 config_host_data.set('CONFIG_TPM', have_tpm)
1856 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1857 config_host_data.set('CONFIG_VDE', vde.found())
1858 config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
1859 config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
1860 config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)
1861 config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
1862 config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
1863 config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
1864 config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
1865 config_host_data.set('CONFIG_VMNET', vmnet.found())
1866 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1867 config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export)
1868 config_host_data.set('CONFIG_PNG', png.found())
1869 config_host_data.set('CONFIG_VNC', vnc.found())
1870 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1871 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1872 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1873 config_host_data.set('CONFIG_VTE', vte.found())
1874 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1875 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1876 config_host_data.set('CONFIG_GETTID', has_gettid)
1877 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1878 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1879 config_host_data.set('CONFIG_TASN1', tasn1.found())
1880 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1881 config_host_data.set('CONFIG_NETTLE', nettle.found())
1882 config_host_data.set('CONFIG_HOGWEED', hogweed.found())
1883 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1884 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1885 config_host_data.set('CONFIG_STATX', has_statx)
1886 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
1887 config_host_data.set('CONFIG_ZSTD', zstd.found())
1888 config_host_data.set('CONFIG_FUSE', fuse.found())
1889 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1890 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1891 if spice_protocol.found()
1892 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
1893 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
1894 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
1896 config_host_data.set('CONFIG_SPICE', spice.found())
1897 config_host_data.set('CONFIG_X11', x11.found())
1898 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
1899 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1900 config_host_data.set('CONFIG_SELINUX', selinux.found())
1901 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
1902 config_host_data.set('CONFIG_LIBDW', libdw.found())
1904 # protect from xen.version() having less than three components
1905 xen_version = xen.version().split('.') + ['0', '0']
1906 xen_ctrl_version = xen_version[0] + \
1907 ('0' + xen_version[1]).substring(-2) + \
1908 ('0' + xen_version[2]).substring(-2)
1909 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
1911 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1912 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1913 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1914 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1916 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1917 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1919 have_coroutine_pool = get_option('coroutine_pool')
1920 if get_option('debug_stack_usage') and have_coroutine_pool
1921 message('Disabling coroutine pool to measure stack usage')
1922 have_coroutine_pool = false
1924 config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool)
1925 config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock'))
1926 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
1927 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
1928 config_host_data.set('CONFIG_GPROF', get_option('gprof'))
1929 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
1930 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
1931 config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
1934 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1935 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1936 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1937 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1938 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1939 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1940 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1941 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1942 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1943 if targetos == 'windows'
1944 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h'))
1948 config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range'))
1949 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1950 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1951 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1952 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1953 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1954 # Note that we need to specify prefix: here to avoid incorrectly
1955 # thinking that Windows has posix_memalign()
1956 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
1957 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
1958 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
1959 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
1960 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1961 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1962 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
1963 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1964 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1965 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1966 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1967 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1968 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1969 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
1970 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1971 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1972 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1974 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
1975 cc.has_function('rbd_namespace_exists',
1977 prefix: '#include <rbd/librbd.h>'))
1980 config_host_data.set('HAVE_IBV_ADVISE_MR',
1981 cc.has_function('ibv_advise_mr',
1983 prefix: '#include <infiniband/verbs.h>'))
1987 config_host_data.set('CONFIG_BLKZONED',
1988 cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE'))
1989 config_host_data.set('CONFIG_EPOLL_CREATE1',
1990 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1991 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1992 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1993 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1994 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1995 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1996 config_host_data.set('CONFIG_FIEMAP',
1997 cc.has_header('linux/fiemap.h') and
1998 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1999 config_host_data.set('CONFIG_GETRANDOM',
2000 cc.has_function('getrandom') and
2001 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
2002 config_host_data.set('CONFIG_INOTIFY',
2003 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
2004 config_host_data.set('CONFIG_INOTIFY1',
2005 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
2006 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
2007 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
2008 config_host_data.set('CONFIG_RTNETLINK',
2009 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
2010 config_host_data.set('CONFIG_SYSMACROS',
2011 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
2012 config_host_data.set('HAVE_OPTRESET',
2013 cc.has_header_symbol('getopt.h', 'optreset'))
2014 config_host_data.set('HAVE_IPPROTO_MPTCP',
2015 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
2018 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
2019 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
2020 prefix: '#include <signal.h>'))
2021 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
2022 cc.has_member('struct stat', 'st_atim',
2023 prefix: '#include <sys/stat.h>'))
2024 config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY',
2025 cc.has_member('struct blk_zone', 'capacity',
2026 prefix: '#include <linux/blkzoned.h>'))
2029 config_host_data.set('CONFIG_IOVEC',
2030 cc.has_type('struct iovec',
2031 prefix: '#include <sys/uio.h>'))
2032 config_host_data.set('HAVE_UTMPX',
2033 cc.has_type('struct utmpx',
2034 prefix: '#include <utmpx.h>'))
2036 config_host_data.set('CONFIG_EVENTFD', cc.links('''
2037 #include <sys/eventfd.h>
2038 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
2039 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
2042 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
2043 return fdatasync(0);
2045 #error Not supported
2049 has_madvise = cc.links(gnu_source_prefix + '''
2050 #include <sys/types.h>
2051 #include <sys/mman.h>
2053 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
2054 missing_madvise_proto = false
2056 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
2057 # but forget to prototype it. In this case, has_madvise will be true (the
2058 # test program links despite a compile warning). To detect the
2059 # missing-prototype case, we try again with a definitely-bogus prototype.
2060 # This will only compile if the system headers don't provide the prototype;
2061 # otherwise the conflicting prototypes will cause a compiler error.
2062 missing_madvise_proto = cc.links(gnu_source_prefix + '''
2063 #include <sys/types.h>
2064 #include <sys/mman.h>
2066 extern int madvise(int);
2067 int main(void) { return madvise(0); }''')
2069 config_host_data.set('CONFIG_MADVISE', has_madvise)
2070 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
2072 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
2073 #include <sys/mman.h>
2074 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
2075 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
2077 #if !defined(AT_EMPTY_PATH)
2078 # error missing definition
2080 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
2082 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
2083 #include <sys/mman.h>
2085 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
2087 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
2088 #include <pthread.h>
2090 static void *f(void *p) { return NULL; }
2094 pthread_create(&thread, 0, f, 0);
2095 pthread_setname_np(thread, "QEMU");
2097 }''', dependencies: threads))
2098 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
2099 #include <pthread.h>
2101 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
2105 pthread_create(&thread, 0, f, 0);
2107 }''', dependencies: threads))
2108 config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(gnu_source_prefix + '''
2109 #include <pthread.h>
2110 #include <pthread_np.h>
2112 static void *f(void *p) { return NULL; }
2116 pthread_create(&thread, 0, f, 0);
2117 pthread_set_name_np(thread, "QEMU");
2119 }''', dependencies: threads))
2120 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
2121 #include <pthread.h>
2126 pthread_condattr_t attr
2127 pthread_condattr_init(&attr);
2128 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
2130 }''', dependencies: threads))
2131 config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(gnu_source_prefix + '''
2132 #include <pthread.h>
2134 static void *f(void *p) { return NULL; }
2137 int setsize = CPU_ALLOC_SIZE(64);
2140 pthread_create(&thread, 0, f, 0);
2141 cpuset = CPU_ALLOC(64);
2142 CPU_ZERO_S(setsize, cpuset);
2143 pthread_setaffinity_np(thread, setsize, cpuset);
2144 pthread_getaffinity_np(thread, setsize, cpuset);
2147 }''', dependencies: threads))
2148 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
2149 #include <sys/signalfd.h>
2151 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
2152 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
2160 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
2161 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
2165 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
2166 #include <sys/mman.h>
2168 return mlockall(MCL_FUTURE);
2172 if get_option('l2tpv3').allowed() and have_system
2173 have_l2tpv3 = cc.has_type('struct mmsghdr',
2174 prefix: gnu_source_prefix + '''
2175 #include <sys/socket.h>
2176 #include <linux/ip.h>''')
2178 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2181 if get_option('netmap').allowed() and have_system
2182 have_netmap = cc.compiles('''
2183 #include <inttypes.h>
2185 #include <net/netmap.h>
2186 #include <net/netmap_user.h>
2187 #if (NETMAP_API < 11) || (NETMAP_API > 15)
2190 int main(void) { return 0; }''')
2191 if not have_netmap and get_option('netmap').enabled()
2192 error('Netmap headers not available')
2195 config_host_data.set('CONFIG_NETMAP', have_netmap)
2197 # Work around a system header bug with some kernel/XFS header
2198 # versions where they both try to define 'struct fsxattr':
2199 # xfs headers will not try to redefine structs from linux headers
2200 # if this macro is set.
2201 config_host_data.set('HAVE_FSXATTR', cc.links('''
2202 #include <linux/fs.h>
2208 # Some versions of Mac OS X incorrectly define SIZE_MAX
2209 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2213 return printf("%zu", SIZE_MAX);
2214 }''', args: ['-Werror']))
2216 # See if 64-bit atomic operations are supported.
2217 # Note that without __atomic builtins, we can only
2218 # assume atomic loads/stores max at pointer size.
2219 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
2223 uint64_t x = 0, y = 0;
2224 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2225 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2226 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2227 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2228 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2232 has_int128 = cc.links('''
2242 config_host_data.set('CONFIG_INT128', has_int128)
2245 # "do we have 128-bit atomics which are handled inline and specifically not
2246 # via libatomic". The reason we can't use libatomic is documented in the
2247 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2248 # We only care about these operations on 16-byte aligned pointers, so
2249 # force 16-byte alignment of the pointer, which may be greater than
2250 # __alignof(unsigned __int128) for the host.
2251 atomic_test_128 = '''
2252 int main(int ac, char **av) {
2253 unsigned __int128 *p = __builtin_assume_aligned(av[ac - 1], sizeof(16));
2254 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED);
2255 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED);
2256 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2259 has_atomic128 = cc.links(atomic_test_128)
2261 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2263 if not has_atomic128
2264 # Even with __builtin_assume_aligned, the above test may have failed
2265 # without optimization enabled. Try again with optimizations locally
2266 # enabled for the function. See
2267 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389
2268 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128)
2269 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt)
2271 if not has_atomic128_opt
2272 config_host_data.set('CONFIG_CMPXCHG128', cc.links('''
2275 unsigned __int128 x = 0, y = 0;
2276 __sync_val_compare_and_swap_16(&x, y, x);
2284 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2285 #include <sys/auxv.h>
2287 return getauxval(AT_HWCAP) == 0;
2290 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2291 #include <linux/usbdevice_fs.h>
2293 #ifndef USBDEVFS_GET_CAPABILITIES
2294 #error "USBDEVFS_GET_CAPABILITIES undefined"
2297 #ifndef USBDEVFS_DISCONNECT_CLAIM
2298 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2301 int main(void) { return 0; }'''))
2303 have_keyring = get_option('keyring') \
2304 .require(targetos == 'linux', error_message: 'keyring is only available on Linux') \
2305 .require(cc.compiles('''
2307 #include <asm/unistd.h>
2308 #include <linux/keyctl.h>
2309 #include <sys/syscall.h>
2312 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2313 }'''), error_message: 'keyctl syscall not available on this system').allowed()
2314 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2316 have_cpuid_h = cc.links('''
2319 unsigned a, b, c, d;
2320 unsigned max = __get_cpuid_max(0, 0);
2323 __cpuid(1, a, b, c, d);
2327 __cpuid_count(7, 0, a, b, c, d);
2332 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2334 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2335 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2336 .require(cc.links('''
2338 #include <immintrin.h>
2339 static int __attribute__((target("avx2"))) bar(void *a) {
2340 __m256i x = *(__m256i *)a;
2341 return _mm256_testz_si256(x, x);
2343 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2344 '''), error_message: 'AVX2 not available').allowed())
2346 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2347 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2348 .require(cc.links('''
2350 #include <immintrin.h>
2351 static int __attribute__((target("avx512f"))) bar(void *a) {
2352 __m512i x = *(__m512i *)a;
2353 return _mm512_test_epi64_mask(x, x);
2355 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); }
2356 '''), error_message: 'AVX512F not available').allowed())
2358 config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \
2359 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \
2360 .require(cc.links('''
2362 #include <immintrin.h>
2363 static int __attribute__((target("avx512bw"))) bar(void *a) {
2365 __m512i res= _mm512_abs_epi8(*x);
2368 int main(int argc, char *argv[]) { return bar(argv[0]); }
2369 '''), error_message: 'AVX512BW not available').allowed())
2371 have_pvrdma = get_option('pvrdma') \
2372 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
2373 .require(cc.compiles(gnu_source_prefix + '''
2374 #include <sys/mman.h>
2379 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2382 }'''), error_message: 'PVRDMA requires mremap').allowed()
2385 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.links('''
2386 #include <infiniband/verbs.h>
2390 struct ibv_pd *pd = NULL;
2396 mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2402 if get_option('membarrier').disabled()
2403 have_membarrier = false
2404 elif targetos == 'windows'
2405 have_membarrier = true
2406 elif targetos == 'linux'
2407 have_membarrier = cc.compiles('''
2408 #include <linux/membarrier.h>
2409 #include <sys/syscall.h>
2413 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2414 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2418 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2419 .require(have_membarrier, error_message: 'membarrier system call not available') \
2422 have_afalg = get_option('crypto_afalg') \
2423 .require(cc.compiles(gnu_source_prefix + '''
2425 #include <sys/types.h>
2426 #include <sys/socket.h>
2427 #include <linux/if_alg.h>
2430 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2433 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2434 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2436 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2437 'linux/vm_sockets.h', 'AF_VSOCK',
2438 prefix: '#include <sys/socket.h>',
2442 have_vss_sdk = false # old xp/2003 SDK
2443 if targetos == 'windows' and link_language == 'cpp'
2444 have_vss = cxx.compiles('''
2445 #define __MIDL_user_allocate_free_DEFINED__
2447 int main(void) { return VSS_CTX_BACKUP; }''')
2448 have_vss_sdk = cxx.has_header('vscoordint.h')
2450 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2452 foreach k, v: config_host
2453 if k.startswith('CONFIG_')
2454 config_host_data.set(k, v == 'y' ? 1 : v)
2458 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2459 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2460 if targetos == 'windows'
2461 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2467 }''', name: '_lock_file and _unlock_file'))
2470 if targetos == 'windows'
2471 mingw_has_setjmp_longjmp = cc.links('''
2475 * These functions are not available in setjmp header, but may be
2476 * available at link time, from libmingwex.a.
2478 extern int __mingw_setjmp(jmp_buf);
2479 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
2481 __mingw_setjmp(env);
2482 __mingw_longjmp(env, 0);
2484 ''', name: 'mingw setjmp and longjmp')
2486 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp
2487 error('mingw must provide setjmp/longjmp for windows-arm64')
2491 ########################
2492 # Target configuration #
2493 ########################
2495 minikconf = find_program('scripts/minikconf.py')
2497 config_all_devices = {}
2498 config_all_disas = {}
2499 config_devices_mak_list = []
2500 config_devices_h = {}
2501 config_target_h = {}
2502 config_target_mak = {}
2505 'alpha' : ['CONFIG_ALPHA_DIS'],
2506 'avr' : ['CONFIG_AVR_DIS'],
2507 'cris' : ['CONFIG_CRIS_DIS'],
2508 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2509 'hppa' : ['CONFIG_HPPA_DIS'],
2510 'i386' : ['CONFIG_I386_DIS'],
2511 'x86_64' : ['CONFIG_I386_DIS'],
2512 'm68k' : ['CONFIG_M68K_DIS'],
2513 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2514 'mips' : ['CONFIG_MIPS_DIS'],
2515 'nios2' : ['CONFIG_NIOS2_DIS'],
2516 'or1k' : ['CONFIG_OPENRISC_DIS'],
2517 'ppc' : ['CONFIG_PPC_DIS'],
2518 'riscv' : ['CONFIG_RISCV_DIS'],
2519 'rx' : ['CONFIG_RX_DIS'],
2520 's390' : ['CONFIG_S390_DIS'],
2521 'sh4' : ['CONFIG_SH4_DIS'],
2522 'sparc' : ['CONFIG_SPARC_DIS'],
2523 'xtensa' : ['CONFIG_XTENSA_DIS'],
2524 'loongarch' : ['CONFIG_LOONGARCH_DIS'],
2527 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2529 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2530 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2531 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2532 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2533 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2534 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2535 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
2536 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2537 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2538 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2539 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
2540 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
2541 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
2542 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : [])
2544 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2546 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2547 actual_target_dirs = []
2549 foreach target : target_dirs
2550 config_target = { 'TARGET_NAME': target.split('-')[0] }
2551 if target.endswith('linux-user')
2552 if targetos != 'linux'
2556 error('Target @0@ is only available on a Linux host'.format(target))
2558 config_target += { 'CONFIG_LINUX_USER': 'y' }
2559 elif target.endswith('bsd-user')
2560 if 'CONFIG_BSD' not in config_host
2564 error('Target @0@ is only available on a BSD host'.format(target))
2566 config_target += { 'CONFIG_BSD_USER': 'y' }
2567 elif target.endswith('softmmu')
2568 config_target += { 'CONFIG_SOFTMMU': 'y' }
2570 if target.endswith('-user')
2572 'CONFIG_USER_ONLY': 'y',
2573 'CONFIG_QEMU_INTERP_PREFIX':
2574 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
2579 foreach sym: accelerators
2580 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2581 config_target += { sym: 'y' }
2582 config_all += { sym: 'y' }
2583 if target in modular_tcg
2584 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2586 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2588 accel_kconfig += [ sym + '=y' ]
2591 if accel_kconfig.length() == 0
2595 error('No accelerator available for target @0@'.format(target))
2598 actual_target_dirs += target
2599 config_target += keyval.load('configs/targets' / target + '.mak')
2600 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
2602 if 'TARGET_NEED_FDT' in config_target
2603 fdt_required += target
2607 if 'TARGET_BASE_ARCH' not in config_target
2608 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2610 if 'TARGET_ABI_DIR' not in config_target
2611 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2613 if 'TARGET_BIG_ENDIAN' not in config_target
2614 config_target += {'TARGET_BIG_ENDIAN': 'n'}
2617 foreach k, v: disassemblers
2618 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
2620 config_target += { sym: 'y' }
2621 config_all_disas += { sym: 'y' }
2626 config_target_data = configuration_data()
2627 foreach k, v: config_target
2628 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2630 elif ignored.contains(k)
2632 elif k == 'TARGET_BASE_ARCH'
2633 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2634 # not used to select files from sourcesets.
2635 config_target_data.set('TARGET_' + v.to_upper(), 1)
2636 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
2637 config_target_data.set_quoted(k, v)
2639 config_target_data.set(k, 1)
2641 config_target_data.set(k, 0)
2643 config_target_data.set(k, v)
2646 config_target_data.set('QEMU_ARCH',
2647 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
2648 config_target_h += {target: configure_file(output: target + '-config-target.h',
2649 configuration: config_target_data)}
2651 if target.endswith('-softmmu')
2652 config_input = meson.get_external_property(target, 'default')
2653 config_devices_mak = target + '-config-devices.mak'
2654 config_devices_mak = configure_file(
2655 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2656 output: config_devices_mak,
2657 depfile: config_devices_mak + '.d',
2659 command: [minikconf,
2660 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2661 config_devices_mak, '@DEPFILE@', '@INPUT@',
2662 host_kconfig, accel_kconfig,
2663 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
2665 config_devices_data = configuration_data()
2666 config_devices = keyval.load(config_devices_mak)
2667 foreach k, v: config_devices
2668 config_devices_data.set(k, 1)
2670 config_devices_mak_list += config_devices_mak
2671 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2672 configuration: config_devices_data)}
2673 config_target += config_devices
2674 config_all_devices += config_devices
2676 config_target_mak += {target: config_target}
2678 target_dirs = actual_target_dirs
2680 # This configuration is used to build files that are shared by
2681 # multiple binaries, and then extracted out of the "common"
2682 # static_library target.
2684 # We do not use all_sources()/all_dependencies(), because it would
2685 # build literally all source files, including devices only used by
2686 # targets that are not built for this compilation. The CONFIG_ALL
2687 # pseudo symbol replaces it.
2689 config_all += config_all_devices
2690 config_all += config_host
2691 config_all += config_all_disas
2693 'CONFIG_XEN': xen.found(),
2694 'CONFIG_SOFTMMU': have_system,
2695 'CONFIG_USER_ONLY': have_user,
2699 target_configs_h = []
2700 foreach target: target_dirs
2701 target_configs_h += config_target_h[target]
2702 target_configs_h += config_devices_h.get(target, [])
2704 genh += custom_target('config-poison.h',
2705 input: [target_configs_h],
2706 output: 'config-poison.h',
2708 command: [find_program('scripts/make-config-poison.sh'),
2715 capstone = not_found
2716 if not get_option('capstone').auto() or have_system or have_user
2717 capstone = dependency('capstone', version: '>=3.0.5',
2718 method: 'pkg-config',
2719 required: get_option('capstone'))
2721 # Some versions of capstone have broken pkg-config file
2722 # that reports a wrong -I path, causing the #include to
2723 # fail later. If the system has such a broken version
2725 if capstone.found() and not cc.compiles('#include <capstone.h>',
2726 dependencies: [capstone])
2727 capstone = not_found
2728 if get_option('capstone').enabled()
2729 error('capstone requested, but it does not appear to work')
2734 libvfio_user_dep = not_found
2735 if have_system and vfio_user_server_allowed
2736 have_internal = fs.exists(meson.current_source_dir() / 'subprojects/libvfio-user/meson.build')
2738 if not have_internal
2739 error('libvfio-user source not found - please pull git submodule')
2742 libvfio_user_proj = subproject('libvfio-user')
2744 libvfio_user_lib = libvfio_user_proj.get_variable('libvfio_user_dep')
2746 libvfio_user_dep = declare_dependency(dependencies: [libvfio_user_lib])
2751 fdt_opt = get_option('fdt')
2752 if fdt_opt in ['enabled', 'auto', 'system']
2753 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2754 fdt = cc.find_library('fdt',
2755 required: fdt_opt == 'system' or
2756 fdt_opt == 'enabled' and not have_internal)
2757 if fdt.found() and cc.links('''
2759 #include <libfdt_env.h>
2760 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2763 elif fdt_opt == 'system'
2764 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2766 fdt_opt = 'internal'
2768 fdt_opt = 'disabled'
2772 if fdt_opt == 'internal'
2775 'dtc/libfdt/fdt_ro.c',
2776 'dtc/libfdt/fdt_wip.c',
2777 'dtc/libfdt/fdt_sw.c',
2778 'dtc/libfdt/fdt_rw.c',
2779 'dtc/libfdt/fdt_strerror.c',
2780 'dtc/libfdt/fdt_empty_tree.c',
2781 'dtc/libfdt/fdt_addresses.c',
2782 'dtc/libfdt/fdt_overlay.c',
2783 'dtc/libfdt/fdt_check.c',
2786 fdt_inc = include_directories('dtc/libfdt')
2787 libfdt = static_library('fdt',
2788 build_by_default: false,
2790 include_directories: fdt_inc)
2791 fdt = declare_dependency(link_with: libfdt,
2792 include_directories: fdt_inc)
2795 fdt_opt = 'disabled'
2797 if not fdt.found() and fdt_required.length() > 0
2798 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2801 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2802 config_host_data.set('CONFIG_FDT', fdt.found())
2803 config_host_data.set('CONFIG_SLIRP', slirp.found())
2805 #####################
2806 # Generated sources #
2807 #####################
2809 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2811 hxtool = find_program('scripts/hxtool')
2812 shaderinclude = find_program('scripts/shaderinclude.py')
2813 qapi_gen = find_program('scripts/qapi-gen.py')
2814 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2815 meson.current_source_dir() / 'scripts/qapi/commands.py',
2816 meson.current_source_dir() / 'scripts/qapi/common.py',
2817 meson.current_source_dir() / 'scripts/qapi/error.py',
2818 meson.current_source_dir() / 'scripts/qapi/events.py',
2819 meson.current_source_dir() / 'scripts/qapi/expr.py',
2820 meson.current_source_dir() / 'scripts/qapi/gen.py',
2821 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2822 meson.current_source_dir() / 'scripts/qapi/main.py',
2823 meson.current_source_dir() / 'scripts/qapi/parser.py',
2824 meson.current_source_dir() / 'scripts/qapi/schema.py',
2825 meson.current_source_dir() / 'scripts/qapi/source.py',
2826 meson.current_source_dir() / 'scripts/qapi/types.py',
2827 meson.current_source_dir() / 'scripts/qapi/visit.py',
2828 meson.current_source_dir() / 'scripts/qapi-gen.py'
2832 python, files('scripts/tracetool.py'),
2833 '--backend=' + ','.join(get_option('trace_backends'))
2835 tracetool_depends = files(
2836 'scripts/tracetool/backend/log.py',
2837 'scripts/tracetool/backend/__init__.py',
2838 'scripts/tracetool/backend/dtrace.py',
2839 'scripts/tracetool/backend/ftrace.py',
2840 'scripts/tracetool/backend/simple.py',
2841 'scripts/tracetool/backend/syslog.py',
2842 'scripts/tracetool/backend/ust.py',
2843 'scripts/tracetool/format/ust_events_c.py',
2844 'scripts/tracetool/format/ust_events_h.py',
2845 'scripts/tracetool/format/__init__.py',
2846 'scripts/tracetool/format/d.py',
2847 'scripts/tracetool/format/simpletrace_stap.py',
2848 'scripts/tracetool/format/c.py',
2849 'scripts/tracetool/format/h.py',
2850 'scripts/tracetool/format/log_stap.py',
2851 'scripts/tracetool/format/stap.py',
2852 'scripts/tracetool/__init__.py',
2853 'scripts/tracetool/vcpu.py'
2856 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2857 meson.current_source_dir(),
2858 get_option('pkgversion'), meson.project_version()]
2859 qemu_version = custom_target('qemu-version.h',
2860 output: 'qemu-version.h',
2861 command: qemu_version_cmd,
2863 build_by_default: true,
2864 build_always_stale: true)
2865 genh += qemu_version
2869 ['qemu-options.hx', 'qemu-options.def'],
2870 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2874 ['hmp-commands.hx', 'hmp-commands.h'],
2875 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2878 foreach d : hx_headers
2879 hxdep += custom_target(d[1],
2883 build_by_default: true, # to be removed when added to a target
2884 command: [hxtool, '-h', '@INPUT0@'])
2892 authz_ss = ss.source_set()
2893 blockdev_ss = ss.source_set()
2894 block_ss = ss.source_set()
2895 chardev_ss = ss.source_set()
2896 common_ss = ss.source_set()
2897 crypto_ss = ss.source_set()
2898 hwcore_ss = ss.source_set()
2899 io_ss = ss.source_set()
2900 qmp_ss = ss.source_set()
2901 qom_ss = ss.source_set()
2902 softmmu_ss = ss.source_set()
2903 specific_fuzz_ss = ss.source_set()
2904 specific_ss = ss.source_set()
2905 stub_ss = ss.source_set()
2906 trace_ss = ss.source_set()
2907 user_ss = ss.source_set()
2908 util_ss = ss.source_set()
2911 qtest_module_ss = ss.source_set()
2912 tcg_module_ss = ss.source_set()
2918 target_softmmu_arch = {}
2919 target_user_arch = {}
2925 # TODO: add each directory to the subdirs from its own meson.build, once
2927 trace_events_subdirs = [
2936 trace_events_subdirs += [ 'linux-user' ]
2939 trace_events_subdirs += [ 'bsd-user' ]
2942 trace_events_subdirs += [
2951 trace_events_subdirs += [
2965 'hw/block/dataplane',
3015 if have_system or have_user
3016 trace_events_subdirs += [
3034 vhost_user = not_found
3035 if targetos == 'linux' and have_vhost_user
3036 libvhost_user = subproject('libvhost-user')
3037 vhost_user = libvhost_user.get_variable('vhost_user_dep')
3040 libvduse = not_found
3042 libvduse_proj = subproject('libvduse')
3043 libvduse = libvduse_proj.get_variable('libvduse_dep')
3046 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3047 # that is filled in by qapi/.
3062 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3063 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3066 qom_ss = qom_ss.apply(config_host, strict: false)
3067 libqom = static_library('qom', qom_ss.sources() + genh,
3068 dependencies: [qom_ss.dependencies()],
3070 qom = declare_dependency(link_whole: libqom)
3072 event_loop_base = files('event-loop-base.c')
3073 event_loop_base = static_library('event-loop-base', sources: event_loop_base + genh,
3074 build_by_default: true)
3075 event_loop_base = declare_dependency(link_whole: event_loop_base,
3076 dependencies: [qom])
3078 stub_ss = stub_ss.apply(config_all, strict: false)
3080 util_ss.add_all(trace_ss)
3081 util_ss = util_ss.apply(config_all, strict: false)
3082 libqemuutil = static_library('qemuutil',
3083 sources: util_ss.sources() + stub_ss.sources() + genh,
3084 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
3085 qemuutil = declare_dependency(link_with: libqemuutil,
3086 sources: genh + version_res,
3087 dependencies: [event_loop_base])
3089 if have_system or have_user
3090 decodetree = generator(find_program('scripts/decodetree.py'),
3091 output: 'decode-@BASENAME@.c.inc',
3092 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3093 subdir('libdecnumber')
3110 if config_host_data.get('CONFIG_REPLICATION')
3111 block_ss.add(files('replication.c'))
3118 blockdev_ss.add(files(
3125 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3126 # os-win32.c does not
3127 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
3128 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
3131 common_ss.add(files('cpus-common.c'))
3132 specific_ss.add(files('cpu.c'))
3136 # Work around a gcc bug/misfeature wherein constant propagation looks
3138 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3139 # to guess that a const variable is always zero. Without lto, this is
3140 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
3141 # without lto, not even the alias is required -- we simply use different
3142 # declarations in different compilation units.
3143 pagevary = files('page-vary-common.c')
3144 if get_option('b_lto')
3145 pagevary_flags = ['-fno-lto']
3146 if get_option('cfi')
3147 pagevary_flags += '-fno-sanitize=cfi-icall'
3149 pagevary = static_library('page-vary-common', sources: pagevary + genh,
3150 c_args: pagevary_flags)
3151 pagevary = declare_dependency(link_with: pagevary)
3153 common_ss.add(pagevary)
3154 specific_ss.add(files('page-vary.c'))
3162 subdir('semihosting')
3170 common_user_inc = []
3172 subdir('common-user')
3174 subdir('linux-user')
3176 # needed for fuzzing binaries
3177 subdir('tests/qtest/libqos')
3178 subdir('tests/qtest/fuzz')
3181 tcg_real_module_ss = ss.source_set()
3182 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3183 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3184 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3185 'tcg': tcg_real_module_ss }}
3187 ########################
3188 # Library dependencies #
3189 ########################
3191 modinfo_collect = find_program('scripts/modinfo-collect.py')
3192 modinfo_generate = find_program('scripts/modinfo-generate.py')
3197 foreach d, list : modules
3198 if not (d == 'block' ? have_block : have_system)
3202 foreach m, module_ss : list
3203 if enable_modules and targetos != 'windows'
3204 module_ss = module_ss.apply(config_all, strict: false)
3205 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3206 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3212 if module_ss.sources() != []
3213 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3214 # input. Sources can be used multiple times but objects are
3215 # unique when it comes to lookup in compile_commands.json.
3216 # Depnds on a mesion version with
3217 # https://github.com/mesonbuild/meson/pull/8900
3218 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3219 output: d + '-' + m + '.modinfo',
3220 input: module_ss.sources() + genh,
3222 command: [modinfo_collect, module_ss.sources()])
3226 block_ss.add_all(module_ss)
3228 softmmu_ss.add_all(module_ss)
3234 foreach d, list : target_modules
3235 foreach m, module_ss : list
3236 if enable_modules and targetos != 'windows'
3237 foreach target : target_dirs
3238 if target.endswith('-softmmu')
3239 config_target = config_target_mak[target]
3240 config_target += config_host
3241 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3242 c_args = ['-DNEED_CPU_H',
3243 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3244 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3245 target_module_ss = module_ss.apply(config_target, strict: false)
3246 if target_module_ss.sources() != []
3247 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3248 sl = static_library(module_name,
3249 [genh, target_module_ss.sources()],
3250 dependencies: [modulecommon, target_module_ss.dependencies()],
3251 include_directories: target_inc,
3255 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3256 modinfo_files += custom_target(module_name + '.modinfo',
3257 output: module_name + '.modinfo',
3258 input: target_module_ss.sources() + genh,
3260 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3265 specific_ss.add_all(module_ss)
3271 foreach target : target_dirs
3272 if target.endswith('-softmmu')
3273 config_target = config_target_mak[target]
3274 config_devices_mak = target + '-config-devices.mak'
3275 modinfo_src = custom_target('modinfo-' + target + '.c',
3276 output: 'modinfo-' + target + '.c',
3277 input: modinfo_files,
3278 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'],
3281 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
3282 modinfo_dep = declare_dependency(link_with: modinfo_lib)
3284 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH']
3285 hw_arch[arch].add(modinfo_dep)
3290 nm = find_program('nm')
3291 undefsym = find_program('scripts/undefsym.py')
3292 block_syms = custom_target('block.syms', output: 'block.syms',
3293 input: [libqemuutil, block_mods],
3295 command: [undefsym, nm, '@INPUT@'])
3296 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3297 input: [libqemuutil, softmmu_mods],
3299 command: [undefsym, nm, '@INPUT@'])
3301 authz_ss = authz_ss.apply(config_host, strict: false)
3302 libauthz = static_library('authz', authz_ss.sources() + genh,
3303 dependencies: [authz_ss.dependencies()],
3305 build_by_default: false)
3307 authz = declare_dependency(link_whole: libauthz,
3310 crypto_ss = crypto_ss.apply(config_host, strict: false)
3311 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3312 dependencies: [crypto_ss.dependencies()],
3314 build_by_default: false)
3316 crypto = declare_dependency(link_whole: libcrypto,
3317 dependencies: [authz, qom])
3319 io_ss = io_ss.apply(config_host, strict: false)
3320 libio = static_library('io', io_ss.sources() + genh,
3321 dependencies: [io_ss.dependencies()],
3322 link_with: libqemuutil,
3324 build_by_default: false)
3326 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3328 libmigration = static_library('migration', sources: migration_files + genh,
3330 build_by_default: false)
3331 migration = declare_dependency(link_with: libmigration,
3332 dependencies: [zlib, qom, io])
3333 softmmu_ss.add(migration)
3335 block_ss = block_ss.apply(config_host, strict: false)
3336 libblock = static_library('block', block_ss.sources() + genh,
3337 dependencies: block_ss.dependencies(),
3338 link_depends: block_syms,
3340 build_by_default: false)
3342 block = declare_dependency(link_whole: [libblock],
3343 link_args: '@block.syms',
3344 dependencies: [crypto, io])
3346 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
3347 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3348 dependencies: blockdev_ss.dependencies(),
3350 build_by_default: false)
3352 blockdev = declare_dependency(link_whole: [libblockdev],
3353 dependencies: [block, event_loop_base])
3355 qmp_ss = qmp_ss.apply(config_host, strict: false)
3356 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3357 dependencies: qmp_ss.dependencies(),
3359 build_by_default: false)
3361 qmp = declare_dependency(link_whole: [libqmp])
3363 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3365 dependencies: chardev_ss.dependencies(),
3366 build_by_default: false)
3368 chardev = declare_dependency(link_whole: libchardev)
3370 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
3371 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3373 build_by_default: false)
3374 hwcore = declare_dependency(link_whole: libhwcore)
3375 common_ss.add(hwcore)
3381 emulator_modules = []
3382 foreach m : block_mods + softmmu_mods
3383 emulator_modules += shared_module(m.name(),
3384 build_by_default: true,
3388 install_dir: qemu_moddir)
3390 if emulator_modules.length() > 0
3391 alias_target('modules', emulator_modules)
3394 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3395 common_ss.add(qom, qemuutil)
3397 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
3398 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3400 common_all = common_ss.apply(config_all, strict: false)
3401 common_all = static_library('common',
3402 build_by_default: false,
3403 sources: common_all.sources() + genh,
3404 include_directories: common_user_inc,
3405 implicit_include_directories: false,
3406 dependencies: common_all.dependencies(),
3409 feature_to_c = find_program('scripts/feature_to_c.sh')
3411 if targetos == 'darwin'
3412 entitlement = find_program('scripts/entitlement.sh')
3416 foreach target : target_dirs
3417 config_target = config_target_mak[target]
3418 target_name = config_target['TARGET_NAME']
3419 target_base_arch = config_target['TARGET_BASE_ARCH']
3420 arch_srcs = [config_target_h[target]]
3422 c_args = ['-DNEED_CPU_H',
3423 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3424 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3425 link_args = emulator_link_args
3427 config_target += config_host
3428 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3429 if targetos == 'linux'
3430 target_inc += include_directories('linux-headers', is_system: true)
3432 if target.endswith('-softmmu')
3433 target_type='system'
3434 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3435 arch_srcs += t.sources()
3436 arch_deps += t.dependencies()
3438 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3439 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3440 arch_srcs += hw.sources()
3441 arch_deps += hw.dependencies()
3443 arch_srcs += config_devices_h[target]
3444 link_args += ['@block.syms', '@qemu.syms']
3446 abi = config_target['TARGET_ABI_DIR']
3448 target_inc += common_user_inc
3449 if target_base_arch in target_user_arch
3450 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3451 arch_srcs += t.sources()
3452 arch_deps += t.dependencies()
3454 if 'CONFIG_LINUX_USER' in config_target
3455 base_dir = 'linux-user'
3457 if 'CONFIG_BSD_USER' in config_target
3458 base_dir = 'bsd-user'
3459 target_inc += include_directories('bsd-user/' / targetos)
3460 target_inc += include_directories('bsd-user/host/' / host_arch)
3461 dir = base_dir / abi
3462 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3464 target_inc += include_directories(
3468 if 'CONFIG_LINUX_USER' in config_target
3469 dir = base_dir / abi
3470 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3471 if config_target.has_key('TARGET_SYSTBL_ABI')
3473 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3474 extra_args : config_target['TARGET_SYSTBL_ABI'])
3479 if 'TARGET_XML_FILES' in config_target
3480 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3481 output: target + '-gdbstub-xml.c',
3482 input: files(config_target['TARGET_XML_FILES'].split()),
3483 command: [feature_to_c, '@INPUT@'],
3485 arch_srcs += gdbstub_xml
3488 t = target_arch[target_base_arch].apply(config_target, strict: false)
3489 arch_srcs += t.sources()
3490 arch_deps += t.dependencies()
3492 target_common = common_ss.apply(config_target, strict: false)
3493 objects = common_all.extract_objects(target_common.sources())
3494 deps = target_common.dependencies()
3496 target_specific = specific_ss.apply(config_target, strict: false)
3497 arch_srcs += target_specific.sources()
3498 arch_deps += target_specific.dependencies()
3500 lib = static_library('qemu-' + target,
3501 sources: arch_srcs + genh,
3502 dependencies: arch_deps,
3504 include_directories: target_inc,
3506 build_by_default: false,
3509 if target.endswith('-softmmu')
3511 'name': 'qemu-system-' + target_name,
3512 'win_subsystem': 'console',
3513 'sources': files('softmmu/main.c'),
3516 if targetos == 'windows' and (sdl.found() or gtk.found())
3518 'name': 'qemu-system-' + target_name + 'w',
3519 'win_subsystem': 'windows',
3520 'sources': files('softmmu/main.c'),
3524 if get_option('fuzzing')
3525 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3527 'name': 'qemu-fuzz-' + target_name,
3528 'win_subsystem': 'console',
3529 'sources': specific_fuzz.sources(),
3530 'dependencies': specific_fuzz.dependencies(),
3535 'name': 'qemu-' + target_name,
3536 'win_subsystem': 'console',
3542 exe_name = exe['name']
3543 if targetos == 'darwin'
3544 exe_name += '-unsigned'
3547 emulator = executable(exe_name, exe['sources'],
3550 dependencies: arch_deps + deps + exe['dependencies'],
3551 objects: lib.extract_all_objects(recursive: true),
3552 link_language: link_language,
3553 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3554 link_args: link_args,
3555 win_subsystem: exe['win_subsystem'])
3557 if targetos == 'darwin'
3558 icon = 'pc-bios/qemu.rsrc'
3559 build_input = [emulator, files(icon)]
3561 get_option('bindir') / exe_name,
3562 meson.current_source_dir() / icon
3564 if 'CONFIG_HVF' in config_target
3565 entitlements = 'accel/hvf/entitlements.plist'
3566 build_input += files(entitlements)
3567 install_input += meson.current_source_dir() / entitlements
3570 emulators += {exe['name'] : custom_target(exe['name'],
3572 output: exe['name'],
3573 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3576 meson.add_install_script(entitlement, '--install',
3577 get_option('bindir') / exe['name'],
3580 emulators += {exe['name']: emulator}
3585 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3586 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3587 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3588 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3590 custom_target(exe['name'] + stp['ext'],
3591 input: trace_events_all,
3592 output: exe['name'] + stp['ext'],
3593 install: stp['install'],
3594 install_dir: get_option('datadir') / 'systemtap/tapset',
3596 tracetool, '--group=all', '--format=' + stp['fmt'],
3597 '--binary=' + stp['bin'],
3598 '--target-name=' + target_name,
3599 '--target-type=' + target_type,
3600 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3601 '@INPUT@', '@OUTPUT@'
3603 depend_files: tracetool_depends)
3609 # Other build targets
3611 if 'CONFIG_PLUGIN' in config_host
3612 install_headers('include/qemu/qemu-plugin.h')
3617 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3618 # when we don't build tools or system
3619 if xkbcommon.found()
3620 # used for the update-keymaps target, so include rules even if !have_tools
3621 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3622 dependencies: [qemuutil, xkbcommon], install: have_tools)
3626 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3627 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3628 qemu_io = executable('qemu-io', files('qemu-io.c'),
3629 dependencies: [block, qemuutil], install: true)
3630 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3631 dependencies: [blockdev, qemuutil, gnutls, selinux],
3634 subdir('storage-daemon')
3635 subdir('contrib/rdmacm-mux')
3636 subdir('contrib/elf2dmp')
3638 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3639 dependencies: qemuutil,
3643 subdir('contrib/vhost-user-blk')
3644 subdir('contrib/vhost-user-gpu')
3645 subdir('contrib/vhost-user-input')
3646 subdir('contrib/vhost-user-scsi')
3649 if targetos == 'linux'
3650 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3651 dependencies: [qemuutil, libcap_ng],
3653 install_dir: get_option('libexecdir'))
3655 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3656 dependencies: [authz, crypto, io, qom, qemuutil,
3657 libcap_ng, mpathpersist],
3662 subdir('contrib/ivshmem-client')
3663 subdir('contrib/ivshmem-server')
3676 if host_machine.system() == 'windows'
3678 find_program('scripts/nsis.py'),
3680 get_option('prefix'),
3681 meson.current_source_dir(),
3682 config_host['GLIB_BINDIR'],
3685 '-DDISPLAYVERSION=' + meson.project_version(),
3688 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3691 nsis_cmd += '-DCONFIG_GTK=y'
3694 nsis = custom_target('nsis',
3695 output: 'qemu-setup-' + meson.project_version() + '.exe',
3696 input: files('qemu.nsi'),
3697 build_always_stale: true,
3698 command: nsis_cmd + ['@INPUT@'])
3699 alias_target('installer', nsis)
3702 #########################
3703 # Configuration summary #
3704 #########################
3708 summary_info += {'Install prefix': get_option('prefix')}
3709 summary_info += {'BIOS directory': qemu_datadir}
3710 pathsep = targetos == 'windows' ? ';' : ':'
3711 summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))}
3712 summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
3713 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
3714 summary_info += {'module directory': qemu_moddir}
3715 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
3716 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
3717 summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')}
3718 if targetos != 'windows'
3719 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
3720 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')}
3722 summary_info += {'local state directory': 'queried at runtime'}
3724 summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
3725 summary_info += {'Build directory': meson.current_build_dir()}
3726 summary_info += {'Source path': meson.current_source_dir()}
3727 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3728 summary(summary_info, bool_yn: true, section: 'Directories')
3732 summary_info += {'git': config_host['GIT']}
3733 summary_info += {'make': config_host['MAKE']}
3734 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3735 summary_info += {'sphinx-build': sphinx_build}
3736 if config_host.has_key('HAVE_GDB_BIN')
3737 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3739 summary_info += {'iasl': iasl}
3740 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3741 if targetos == 'windows' and have_ga
3742 summary_info += {'wixl': wixl}
3744 if slirp.found() and have_system
3745 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
3747 summary(summary_info, bool_yn: true, section: 'Host binaries')
3749 # Configurable features
3751 summary_info += {'Documentation': build_docs}
3752 summary_info += {'system-mode emulation': have_system}
3753 summary_info += {'user-mode emulation': have_user}
3754 summary_info += {'block layer': have_block}
3755 summary_info += {'Install blobs': get_option('install_blobs')}
3756 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3757 if config_host.has_key('CONFIG_MODULES')
3758 summary_info += {'alternative module path': get_option('module_upgrades')}
3760 summary_info += {'fuzzing support': get_option('fuzzing')}
3762 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3764 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3765 if 'simple' in get_option('trace_backends')
3766 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3768 summary_info += {'D-Bus display': dbus_display}
3769 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
3770 summary_info += {'vhost-kernel support': have_vhost_kernel}
3771 summary_info += {'vhost-net support': have_vhost_net}
3772 summary_info += {'vhost-user support': have_vhost_user}
3773 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
3774 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3775 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
3776 summary_info += {'build guest agent': have_ga}
3777 summary(summary_info, bool_yn: true, section: 'Configurable features')
3779 # Compilation information
3781 summary_info += {'host CPU': cpu}
3782 summary_info += {'host endianness': build_machine.endian()}
3783 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3784 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3785 if link_language == 'cpp'
3786 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3788 summary_info += {'C++ compiler': false}
3790 if targetos == 'darwin'
3791 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3793 option_cflags = (get_option('debug') ? ['-g'] : [])
3794 if get_option('optimization') != 'plain'
3795 option_cflags += ['-O' + get_option('optimization')]
3797 summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)}
3798 if link_language == 'cpp'
3799 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)}
3801 if targetos == 'darwin'
3802 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)}
3804 link_args = get_option(link_language + '_link_args')
3805 if link_args.length() > 0
3806 summary_info += {'LDFLAGS': ' '.join(link_args)}
3808 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_cflags)}
3809 if 'cpp' in all_languages
3810 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_cxxflags)}
3812 if 'objc' in all_languages
3813 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_objcflags)}
3815 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
3816 summary_info += {'profiler': get_option('profiler')}
3817 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3818 summary_info += {'PIE': get_option('b_pie')}
3819 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3820 summary_info += {'malloc trim support': has_malloc_trim}
3821 summary_info += {'membarrier': have_membarrier}
3822 summary_info += {'debug graph lock': get_option('debug_graph_lock')}
3823 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
3824 summary_info += {'mutex debugging': get_option('debug_mutex')}
3825 summary_info += {'memory allocator': get_option('malloc')}
3826 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
3827 summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')}
3828 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
3829 if get_option('gprof')
3830 gprof_info = 'YES (deprecated)'
3832 gprof_info = get_option('gprof')
3834 summary_info += {'gprof': gprof_info}
3835 summary_info += {'gcov': get_option('b_coverage')}
3836 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3837 summary_info += {'CFI support': get_option('cfi')}
3838 if get_option('cfi')
3839 summary_info += {'CFI debug support': get_option('cfi_debug')}
3841 summary_info += {'strip binaries': get_option('strip')}
3842 summary_info += {'sparse': sparse}
3843 summary_info += {'mingw32 support': targetos == 'windows'}
3844 summary(summary_info, bool_yn: true, section: 'Compilation')
3846 # snarf the cross-compilation information for tests
3849 foreach target: target_dirs
3850 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak'
3851 if fs.exists(tcg_mak)
3852 config_cross_tcg = keyval.load(tcg_mak)
3853 if 'CC' in config_cross_tcg
3854 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']}
3860 summary(summary_info, bool_yn: true, section: 'Cross compilers')
3863 # Targets and accelerators
3866 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3867 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3868 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3869 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3870 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3871 summary_info += {'Xen support': xen.found()}
3873 summary_info += {'xen ctrl version': xen.version()}
3875 summary_info += {'Xen emulation': config_all.has_key('CONFIG_XEN_EMU')}
3877 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3878 if config_all.has_key('CONFIG_TCG')
3879 if get_option('tcg_interpreter')
3880 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
3882 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3884 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3885 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3887 summary_info += {'target list': ' '.join(target_dirs)}
3889 summary_info += {'default devices': get_option('default_devices')}
3890 summary_info += {'out of process emulation': multiprocess_allowed}
3891 summary_info += {'vfio-user server': vfio_user_server_allowed}
3893 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3897 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3898 summary_info += {'coroutine pool': have_coroutine_pool}
3900 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
3901 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
3902 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
3903 summary_info += {'VirtFS (9P) support': have_virtfs}
3904 summary_info += {'VirtFS (9P) Proxy Helper support': have_virtfs_proxy_helper}
3905 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
3906 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
3907 summary_info += {'bochs support': get_option('bochs').allowed()}
3908 summary_info += {'cloop support': get_option('cloop').allowed()}
3909 summary_info += {'dmg support': get_option('dmg').allowed()}
3910 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
3911 summary_info += {'vdi support': get_option('vdi').allowed()}
3912 summary_info += {'vhdx support': get_option('vhdx').allowed()}
3913 summary_info += {'vmdk support': get_option('vmdk').allowed()}
3914 summary_info += {'vpc support': get_option('vpc').allowed()}
3915 summary_info += {'vvfat support': get_option('vvfat').allowed()}
3916 summary_info += {'qed support': get_option('qed').allowed()}
3917 summary_info += {'parallels support': get_option('parallels').allowed()}
3918 summary_info += {'FUSE exports': fuse}
3919 summary_info += {'VDUSE block exports': have_vduse_blk_export}
3921 summary(summary_info, bool_yn: true, section: 'Block layer support')
3925 summary_info += {'TLS priority': get_option('tls_priority')}
3926 summary_info += {'GNUTLS support': gnutls}
3928 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3930 summary_info += {'libgcrypt': gcrypt}
3931 summary_info += {'nettle': nettle}
3933 summary_info += {' XTS': xts != 'private'}
3935 summary_info += {'AF_ALG support': have_afalg}
3936 summary_info += {'rng-none': get_option('rng_none')}
3937 summary_info += {'Linux keyring': have_keyring}
3938 summary(summary_info, bool_yn: true, section: 'Crypto')
3942 if targetos == 'darwin'
3943 summary_info += {'Cocoa support': cocoa}
3944 summary_info += {'vmnet.framework support': vmnet}
3946 summary_info += {'SDL support': sdl}
3947 summary_info += {'SDL image support': sdl_image}
3948 summary_info += {'GTK support': gtk}
3949 summary_info += {'pixman': pixman}
3950 summary_info += {'VTE support': vte}
3951 summary_info += {'slirp support': slirp}
3952 summary_info += {'libtasn1': tasn1}
3953 summary_info += {'PAM': pam}
3954 summary_info += {'iconv support': iconv}
3955 summary_info += {'curses support': curses}
3956 summary_info += {'virgl support': virgl}
3957 summary_info += {'blkio support': blkio}
3958 summary_info += {'curl support': curl}
3959 summary_info += {'Multipath support': mpathpersist}
3960 summary_info += {'PNG support': png}
3961 summary_info += {'VNC support': vnc}
3963 summary_info += {'VNC SASL support': sasl}
3964 summary_info += {'VNC JPEG support': jpeg}
3966 if targetos not in ['darwin', 'haiku', 'windows']
3967 summary_info += {'OSS support': oss}
3968 summary_info += {'sndio support': sndio}
3969 elif targetos == 'darwin'
3970 summary_info += {'CoreAudio support': coreaudio}
3971 elif targetos == 'windows'
3972 summary_info += {'DirectSound support': dsound}
3974 if targetos == 'linux'
3975 summary_info += {'ALSA support': alsa}
3976 summary_info += {'PulseAudio support': pulse}
3978 summary_info += {'Pipewire support': pipewire}
3979 summary_info += {'JACK support': jack}
3980 summary_info += {'brlapi support': brlapi}
3981 summary_info += {'vde support': vde}
3982 summary_info += {'netmap support': have_netmap}
3983 summary_info += {'l2tpv3 support': have_l2tpv3}
3984 summary_info += {'Linux AIO support': libaio}
3985 summary_info += {'Linux io_uring support': linux_io_uring}
3986 summary_info += {'ATTR/XATTR support': libattr}
3987 summary_info += {'RDMA support': rdma}
3988 summary_info += {'PVRDMA support': have_pvrdma}
3989 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3990 summary_info += {'libcap-ng support': libcap_ng}
3991 summary_info += {'bpf support': libbpf}
3992 summary_info += {'spice protocol support': spice_protocol}
3993 if spice_protocol.found()
3994 summary_info += {' spice server support': spice}
3996 summary_info += {'rbd support': rbd}
3997 summary_info += {'smartcard support': cacard}
3998 summary_info += {'U2F support': u2f}
3999 summary_info += {'libusb': libusb}
4000 summary_info += {'usb net redir': usbredir}
4001 summary_info += {'OpenGL support (epoxy)': opengl}
4002 summary_info += {'GBM': gbm}
4003 summary_info += {'libiscsi support': libiscsi}
4004 summary_info += {'libnfs support': libnfs}
4005 if targetos == 'windows'
4007 summary_info += {'QGA VSS support': have_qga_vss}
4010 summary_info += {'seccomp support': seccomp}
4011 summary_info += {'GlusterFS support': glusterfs}
4012 summary_info += {'TPM support': have_tpm}
4013 summary_info += {'libssh support': libssh}
4014 summary_info += {'lzo support': lzo}
4015 summary_info += {'snappy support': snappy}
4016 summary_info += {'bzip2 support': libbzip2}
4017 summary_info += {'lzfse support': liblzfse}
4018 summary_info += {'zstd support': zstd}
4019 summary_info += {'NUMA host support': numa}
4020 summary_info += {'capstone': capstone}
4021 summary_info += {'libpmem support': libpmem}
4022 summary_info += {'libdaxctl support': libdaxctl}
4023 summary_info += {'libudev': libudev}
4024 # Dummy dependency, keep .found()
4025 summary_info += {'FUSE lseek': fuse_lseek.found()}
4026 summary_info += {'selinux': selinux}
4027 summary_info += {'libdw': libdw}
4028 summary(summary_info, bool_yn: true, section: 'Dependencies')
4030 if not supported_cpus.contains(cpu)
4032 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
4034 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
4035 message('The QEMU project intends to remove support for this host CPU in')
4036 message('a future release if nobody volunteers to maintain it and to')
4037 message('provide a build host for our continuous integration setup.')
4038 message('configure has succeeded and you can continue to build, but')
4039 message('if you care about QEMU on this platform you should contact')
4040 message('us upstream at qemu-devel@nongnu.org.')
4043 if not supported_oses.contains(targetos)
4045 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
4047 message('Host OS ' + targetos + 'support is not currently maintained.')
4048 message('The QEMU project intends to remove support for this host OS in')
4049 message('a future release if nobody volunteers to maintain it and to')
4050 message('provide a build host for our continuous integration setup.')
4051 message('configure has succeeded and you can continue to build, but')
4052 message('if you care about QEMU on this platform you should contact')
4053 message('us upstream at qemu-devel@nongnu.org.')