1 project('qemu', ['c'], meson_version: '>=0.59.3',
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 sh = find_program('sh')
18 cc = meson.get_compiler('c')
19 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
20 enable_modules = 'CONFIG_MODULES' in config_host
21 enable_static = 'CONFIG_STATIC' in config_host
23 # Allow both shared and static libraries unless --enable-static
24 static_kwargs = enable_static ? {'static': true} : {}
26 # Temporary directory used for files created while
27 # configure runs. Since it is in the build directory
28 # we can safely blow away any previous version of it
29 # (and we need not jump through hoops to try to delete
30 # it when configure exits.)
31 tmpdir = meson.current_build_dir() / 'meson-private/temp'
33 if get_option('qemu_suffix').startswith('/')
34 error('qemu_suffix cannot start with a /')
37 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
38 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
39 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
40 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
42 qemu_desktopdir = get_option('datadir') / 'applications'
43 qemu_icondir = get_option('datadir') / 'icons'
45 config_host_data = configuration_data()
47 qapi_trace_events = []
49 bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
50 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
51 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
52 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc', 'sparc64']
54 cpu = host_machine.cpu_family()
56 # Unify riscv* to a single family.
57 if cpu in ['riscv32', 'riscv64']
61 targetos = host_machine.system()
63 target_dirs = config_host['TARGET_DIRS'].split()
64 have_linux_user = false
67 foreach target : target_dirs
68 have_linux_user = have_linux_user or target.endswith('linux-user')
69 have_bsd_user = have_bsd_user or target.endswith('bsd-user')
70 have_system = have_system or target.endswith('-softmmu')
72 have_user = have_linux_user or have_bsd_user
73 have_tools = get_option('tools') \
74 .disable_auto_if(not have_system) \
76 have_ga = get_option('guest_agent') \
77 .disable_auto_if(not have_system and not have_tools) \
78 .require(targetos in ['sunos', 'linux', 'windows'],
79 error_message: 'unsupported OS for QEMU guest agent') \
81 have_block = have_system or have_tools
83 python = import('python').find_installation()
85 if cpu not in supported_cpus
95 if cpu in ['x86', 'x86_64']
96 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
98 kvm_targets = ['aarch64-softmmu']
100 kvm_targets = ['s390x-softmmu']
101 elif cpu in ['ppc', 'ppc64']
102 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
103 elif cpu in ['mips', 'mips64']
104 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
105 elif cpu in ['riscv']
106 kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
112 if get_option('kvm').allowed() and targetos == 'linux'
113 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
115 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
117 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
119 if cpu in ['aarch64']
120 accelerator_targets += {
121 'CONFIG_HVF': ['aarch64-softmmu']
125 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
126 # i386 emulator provides xenpv machine type for multiple architectures
127 accelerator_targets += {
128 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
131 if cpu in ['x86', 'x86_64']
132 accelerator_targets += {
133 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
134 'CONFIG_HVF': ['x86_64-softmmu'],
135 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
136 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
141 # Darwin does not support references to thread-local variables in modules
142 if targetos != 'darwin'
143 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
146 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
147 unpack_edk2_blobs = false
148 foreach target : edk2_targets
149 if target in target_dirs
150 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
151 unpack_edk2_blobs = bzip2.found()
158 if 'dtrace' in get_option('trace_backends')
159 dtrace = find_program('dtrace', required: true)
160 stap = find_program('stap', required: false)
162 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
163 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
164 # instead. QEMU --enable-modules depends on this because the SystemTap
165 # semaphores are linked into the main binary and not the module's shared
167 add_global_arguments('-DSTAP_SDT_V2',
168 native: false, language: ['c', 'cpp', 'objc'])
172 if get_option('iasl') == ''
173 iasl = find_program('iasl', required: false)
175 iasl = find_program(get_option('iasl'), required: true)
182 qemu_cflags = config_host['QEMU_CFLAGS'].split()
183 qemu_cxxflags = config_host['QEMU_CXXFLAGS'].split()
184 qemu_objcflags = config_host['QEMU_OBJCFLAGS'].split()
185 qemu_ldflags = config_host['QEMU_LDFLAGS'].split()
187 if targetos == 'windows'
188 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat')
189 # Disable ASLR for debug builds to allow debugging with gdb
190 if get_option('optimization') == '0'
191 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase')
195 if get_option('gprof')
196 qemu_cflags += ['-p']
197 qemu_cxxflags += ['-p']
198 qemu_objcflags += ['-p']
199 qemu_ldflags += ['-p']
202 # Specify linker-script with add_project_link_arguments so that it is not placed
203 # within a linker --start-group/--end-group pair
204 if get_option('fuzzing')
205 add_project_link_arguments(['-Wl,-T,',
206 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
207 native: false, language: ['c', 'cpp', 'objc'])
209 # Specify a filter to only instrument code that is directly related to
211 configure_file(output: 'instrumentation-filter',
212 input: 'scripts/oss-fuzz/instrumentation-filter-template',
215 if cc.compiles('int main () { return 0; }',
216 name: '-fsanitize-coverage-allowlist=/dev/null',
217 args: ['-fsanitize-coverage-allowlist=/dev/null',
218 '-fsanitize-coverage=trace-pc'] )
219 add_global_arguments('-fsanitize-coverage-allowlist=instrumentation-filter',
220 native: false, language: ['c', 'cpp', 'objc'])
223 if get_option('fuzzing_engine') == ''
224 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
225 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
226 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
227 # unable to bind the fuzzer-related callbacks added by instrumentation.
228 add_global_arguments('-fsanitize=fuzzer-no-link',
229 native: false, language: ['c', 'cpp', 'objc'])
230 add_global_link_arguments('-fsanitize=fuzzer-no-link',
231 native: false, language: ['c', 'cpp', 'objc'])
232 # For the actual fuzzer binaries, we need to link against the libfuzzer
233 # library. They need to be configurable, to support OSS-Fuzz
234 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
236 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
237 # the needed CFLAGS have already been provided
238 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
242 add_global_arguments(qemu_cflags, native: false, language: ['c'])
243 add_global_arguments(qemu_cxxflags, native: false, language: ['cpp'])
244 add_global_arguments(qemu_objcflags, native: false, language: ['objc'])
245 add_global_link_arguments(qemu_ldflags, native: false, language: ['c', 'cpp', 'objc'])
247 if targetos == 'linux'
248 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
249 '-isystem', 'linux-headers',
250 language: ['c', 'cpp'])
253 add_project_arguments('-iquote', '.',
254 '-iquote', meson.current_source_dir(),
255 '-iquote', meson.current_source_dir() / 'include',
256 language: ['c', 'cpp', 'objc'])
258 link_language = meson.get_external_property('link_language', 'cpp')
259 if link_language == 'cpp'
260 add_languages('cpp', required: true, native: false)
261 cxx = meson.get_compiler('cpp')
266 if host_machine.system() == 'darwin'
267 add_languages('objc', required: false, native: false)
270 sparse = find_program('cgcc', required: get_option('sparse'))
273 command: [find_program('scripts/check_sparse.py'),
274 'compile_commands.json', sparse.full_path(), '-Wbitwise',
275 '-Wno-transparent-union', '-Wno-old-initializer',
276 '-Wno-non-pointer-null'])
279 ###########################################
280 # Target-specific checks and dependencies #
281 ###########################################
284 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
287 #include <sys/types.h>
288 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
289 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
291 args: ['-Werror', '-fsanitize=fuzzer'])
292 error('Your compiler does not support -fsanitize=fuzzer')
296 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
297 error('ftrace is supported only on Linux')
299 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
302 openlog("qemu", LOG_PID, LOG_DAEMON);
303 syslog(LOG_INFO, "configure");
306 error('syslog is not supported on this system')
309 # Miscellaneous Linux-only features
310 get_option('mpath') \
311 .require(targetos == 'linux', error_message: 'Multipath is supported only on Linux')
313 multiprocess_allowed = get_option('multiprocess') \
314 .require(targetos == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
317 vfio_user_server_allowed = get_option('vfio_user_server') \
318 .require(targetos == 'linux', error_message: 'vfio-user server is supported only on Linux') \
321 have_tpm = get_option('tpm') \
322 .require(targetos != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
326 have_vhost_user = get_option('vhost_user') \
327 .disable_auto_if(targetos != 'linux') \
328 .require(targetos != 'windows',
329 error_message: 'vhost-user is not available on Windows').allowed()
330 have_vhost_vdpa = get_option('vhost_vdpa') \
331 .require(targetos == 'linux',
332 error_message: 'vhost-vdpa is only available on Linux').allowed()
333 have_vhost_kernel = get_option('vhost_kernel') \
334 .require(targetos == 'linux',
335 error_message: 'vhost-kernel is only available on Linux').allowed()
336 have_vhost_user_crypto = get_option('vhost_crypto') \
337 .require(have_vhost_user,
338 error_message: 'vhost-crypto requires vhost-user to be enabled').allowed()
340 have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel
342 have_vhost_net_user = have_vhost_user and get_option('vhost_net').allowed()
343 have_vhost_net_vdpa = have_vhost_vdpa and get_option('vhost_net').allowed()
344 have_vhost_net_kernel = have_vhost_kernel and get_option('vhost_net').allowed()
345 have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_vdpa
347 # Target-specific libraries and flags
348 libm = cc.find_library('m', required: false)
349 threads = dependency('threads')
350 util = cc.find_library('util', required: false)
356 emulator_link_args = []
363 if targetos == 'windows'
364 midl = find_program('midl', required: false)
365 widl = find_program('widl', required: false)
366 pathcch = cc.find_library('pathcch')
367 socket = cc.find_library('ws2_32')
368 winmm = cc.find_library('winmm')
370 win = import('windows')
371 version_res = win.compile_resources('version.rc',
372 depend_files: files('pc-bios/qemu-nsis.ico'),
373 include_directories: include_directories('.'))
375 elif targetos == 'darwin'
376 coref = dependency('appleframeworks', modules: 'CoreFoundation')
377 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
378 host_dsosuf = '.dylib'
379 elif targetos == 'sunos'
380 socket = [cc.find_library('socket'),
381 cc.find_library('nsl'),
382 cc.find_library('resolv')]
383 elif targetos == 'haiku'
384 socket = [cc.find_library('posix_error_mapper'),
385 cc.find_library('network'),
386 cc.find_library('bsd')]
387 elif targetos == 'openbsd'
388 if get_option('tcg').allowed() and target_dirs.length() > 0
389 # Disable OpenBSD W^X if available
390 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
394 # Target-specific configuration of accelerators
396 if get_option('kvm').allowed() and targetos == 'linux'
397 accelerators += 'CONFIG_KVM'
399 if get_option('whpx').allowed() and targetos == 'windows'
400 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
401 error('WHPX requires 64-bit host')
402 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
403 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
404 accelerators += 'CONFIG_WHPX'
407 if get_option('hvf').allowed()
408 hvf = dependency('appleframeworks', modules: 'Hypervisor',
409 required: get_option('hvf'))
411 accelerators += 'CONFIG_HVF'
414 if get_option('hax').allowed()
415 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
416 accelerators += 'CONFIG_HAX'
419 if targetos == 'netbsd'
420 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
422 accelerators += 'CONFIG_NVMM'
427 if get_option('tcg').allowed()
428 if host_arch == 'unknown'
429 if get_option('tcg_interpreter')
430 warning('Unsupported CPU @0@, will use TCG with TCI (slow)'.format(cpu))
432 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
434 elif get_option('tcg_interpreter')
435 warning('Use of the TCG interpreter is not recommended on this host')
436 warning('architecture. There is a native TCG execution backend available')
437 warning('which provides substantially better performance and reliability.')
438 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
439 warning('configuration option on this architecture to use the native')
442 if get_option('tcg_interpreter')
444 elif host_arch == 'sparc64'
446 elif host_arch == 'x86_64'
448 elif host_arch == 'ppc64'
451 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
452 language: ['c', 'cpp', 'objc'])
454 accelerators += 'CONFIG_TCG'
455 config_host += { 'CONFIG_TCG': 'y' }
458 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
459 error('KVM not available on this platform')
461 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
462 error('HVF not available on this platform')
464 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
465 error('NVMM not available on this platform')
467 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
468 error('WHPX not available on this platform')
475 # The path to glib.h is added to all compilation commands. This was
476 # grandfathered in from the QEMU Makefiles.
477 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
478 native: false, language: ['c', 'cpp', 'objc'])
479 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
480 link_args: config_host['GLIB_LIBS'].split(),
481 version: config_host['GLIB_VERSION'],
483 'bindir': config_host['GLIB_BINDIR'],
485 # override glib dep with the configure results (for subprojects)
486 meson.override_dependency('glib-2.0', glib)
489 gdbus_codegen = not_found
490 if not get_option('gio').auto() or have_system
491 gio = dependency('gio-2.0', required: get_option('gio'),
492 method: 'pkg-config', kwargs: static_kwargs)
493 if gio.found() and not cc.links('''
497 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
499 }''', dependencies: [glib, gio])
500 if get_option('gio').enabled()
501 error('The installed libgio is broken for static linking')
506 gdbus_codegen = find_program(gio.get_variable('gdbus_codegen'),
507 required: get_option('gio'))
508 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
509 method: 'pkg-config', kwargs: static_kwargs)
510 gio = declare_dependency(dependencies: [gio, gio_unix],
511 version: gio.version())
516 if 'ust' in get_option('trace_backends')
517 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
518 method: 'pkg-config', kwargs: static_kwargs)
521 if have_system or have_tools
522 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
523 method: 'pkg-config', kwargs: static_kwargs)
525 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
528 if not get_option('linux_aio').auto() or have_block
529 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
530 required: get_option('linux_aio'),
531 kwargs: static_kwargs)
534 linux_io_uring_test = '''
535 #include <liburing.h>
536 #include <linux/errqueue.h>
538 int main(void) { return 0; }'''
540 linux_io_uring = not_found
541 if not get_option('linux_io_uring').auto() or have_block
542 linux_io_uring = dependency('liburing', version: '>=0.3',
543 required: get_option('linux_io_uring'),
544 method: 'pkg-config', kwargs: static_kwargs)
545 if not cc.links(linux_io_uring_test)
546 linux_io_uring = not_found
551 if not get_option('libnfs').auto() or have_block
552 libnfs = dependency('libnfs', version: '>=1.9.3',
553 required: get_option('libnfs'),
554 method: 'pkg-config', kwargs: static_kwargs)
559 #include <sys/types.h>
560 #ifdef CONFIG_LIBATTR
561 #include <attr/xattr.h>
563 #include <sys/xattr.h>
565 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
568 have_old_libattr = false
569 if get_option('attr').allowed()
570 if cc.links(libattr_test)
571 libattr = declare_dependency()
573 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
574 required: get_option('attr'),
575 kwargs: static_kwargs)
576 if libattr.found() and not \
577 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
579 if get_option('attr').enabled()
580 error('could not link libattr')
582 warning('could not link libattr, disabling')
585 have_old_libattr = libattr.found()
590 cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
591 required: get_option('cocoa'))
593 vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
594 if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
595 'VMNET_BRIDGED_MODE',
598 if get_option('vmnet').enabled()
599 error('vmnet.framework API is outdated')
601 warning('vmnet.framework API is outdated, disabling')
606 if not get_option('seccomp').auto() or have_system or have_tools
607 seccomp = dependency('libseccomp', version: '>=2.3.0',
608 required: get_option('seccomp'),
609 method: 'pkg-config', kwargs: static_kwargs)
612 libcap_ng = not_found
613 if not get_option('cap_ng').auto() or have_system or have_tools
614 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
615 required: get_option('cap_ng'),
616 kwargs: static_kwargs)
618 if libcap_ng.found() and not cc.links('''
622 capng_capability_to_name(CAPNG_EFFECTIVE);
624 }''', dependencies: libcap_ng)
625 libcap_ng = not_found
626 if get_option('cap_ng').enabled()
627 error('could not link libcap-ng')
629 warning('could not link libcap-ng, disabling')
633 if get_option('xkbcommon').auto() and not have_system and not have_tools
634 xkbcommon = not_found
636 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
637 method: 'pkg-config', kwargs: static_kwargs)
641 if not get_option('vde').auto() or have_system or have_tools
642 vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
643 required: get_option('vde'),
644 kwargs: static_kwargs)
646 if vde.found() and not cc.links('''
647 #include <libvdeplug.h>
650 struct vde_open_args a = {0, 0, 0};
654 }''', dependencies: vde)
656 if get_option('cap_ng').enabled()
657 error('could not link libvdeplug')
659 warning('could not link libvdeplug, disabling')
664 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
665 pulse = dependency('libpulse', required: get_option('pa'),
666 method: 'pkg-config', kwargs: static_kwargs)
669 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
670 alsa = dependency('alsa', required: get_option('alsa'),
671 method: 'pkg-config', kwargs: static_kwargs)
674 if not get_option('jack').auto() or have_system
675 jack = dependency('jack', required: get_option('jack'),
676 method: 'pkg-config', kwargs: static_kwargs)
679 spice_protocol = not_found
680 if not get_option('spice_protocol').auto() or have_system
681 spice_protocol = dependency('spice-protocol', version: '>=0.12.3',
682 required: get_option('spice_protocol'),
683 method: 'pkg-config', kwargs: static_kwargs)
686 if not get_option('spice').auto() or have_system
687 spice = dependency('spice-server', version: '>=0.12.5',
688 required: get_option('spice'),
689 method: 'pkg-config', kwargs: static_kwargs)
691 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
693 rt = cc.find_library('rt', required: false)
696 if not get_option('libiscsi').auto() or have_block
697 libiscsi = dependency('libiscsi', version: '>=1.9.0',
698 required: get_option('libiscsi'),
699 method: 'pkg-config', kwargs: static_kwargs)
702 if not get_option('zstd').auto() or have_block
703 zstd = dependency('libzstd', version: '>=1.4.0',
704 required: get_option('zstd'),
705 method: 'pkg-config', kwargs: static_kwargs)
709 have_vhost_user_gpu = have_tools and targetos == 'linux' and pixman.found()
710 if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
711 virgl = dependency('virglrenderer',
712 method: 'pkg-config',
713 required: get_option('virglrenderer'),
714 kwargs: static_kwargs)
717 if not get_option('curl').auto() or have_block
718 curl = dependency('libcurl', version: '>=7.29.0',
719 method: 'pkg-config',
720 required: get_option('curl'),
721 kwargs: static_kwargs)
724 if targetos == 'linux' and (have_system or have_tools)
725 libudev = dependency('libudev',
726 method: 'pkg-config',
727 required: get_option('libudev'),
728 kwargs: static_kwargs)
731 mpathlibs = [libudev]
732 mpathpersist = not_found
733 mpathpersist_new_api = false
734 if targetos == 'linux' and have_tools and get_option('mpath').allowed()
735 mpath_test_source_new = '''
737 #include <mpath_persist.h>
738 unsigned mpath_mx_alloc_len = 1024;
740 static struct config *multipath_conf;
741 extern struct udev *udev;
742 extern struct config *get_multipath_config(void);
743 extern void put_multipath_config(struct config *conf);
745 struct config *get_multipath_config(void) { return multipath_conf; }
746 void put_multipath_config(struct config *conf) { }
749 multipath_conf = mpath_lib_init();
752 mpath_test_source_old = '''
754 #include <mpath_persist.h>
755 unsigned mpath_mx_alloc_len = 1024;
758 struct udev *udev = udev_new();
759 mpath_lib_init(udev);
762 libmpathpersist = cc.find_library('mpathpersist',
763 required: get_option('mpath'),
764 kwargs: static_kwargs)
765 if libmpathpersist.found()
766 mpathlibs += libmpathpersist
768 mpathlibs += cc.find_library('devmapper',
769 required: get_option('mpath'),
770 kwargs: static_kwargs)
772 mpathlibs += cc.find_library('multipath',
773 required: get_option('mpath'),
774 kwargs: static_kwargs)
775 foreach lib: mpathlibs
781 if mpathlibs.length() == 0
782 msg = 'Dependencies missing for libmpathpersist'
783 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
784 mpathpersist = declare_dependency(dependencies: mpathlibs)
785 mpathpersist_new_api = true
786 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
787 mpathpersist = declare_dependency(dependencies: mpathlibs)
789 msg = 'Cannot detect libmpathpersist API'
791 if not mpathpersist.found()
792 if get_option('mpath').enabled()
795 warning(msg + ', disabling')
803 if have_system and get_option('curses').allowed()
805 #if defined(__APPLE__) || defined(__OpenBSD__)
806 #define _XOPEN_SOURCE_EXTENDED 1
813 setlocale(LC_ALL, "");
815 addwstr(L"wide chars\n");
817 add_wch(WACS_DEGREE);
821 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
822 foreach curses_dep : curses_dep_list
823 if not curses.found()
824 curses = dependency(curses_dep,
826 method: 'pkg-config',
827 kwargs: static_kwargs)
830 msg = get_option('curses').enabled() ? 'curses library not found' : ''
831 curses_compile_args = ['-DNCURSES_WIDECHAR=1']
833 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
834 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
836 msg = 'curses package not usable'
840 if not curses.found()
841 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
842 if targetos != 'windows' and not has_curses_h
843 message('Trying with /usr/include/ncursesw')
844 curses_compile_args += ['-I/usr/include/ncursesw']
845 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
848 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
849 foreach curses_libname : curses_libname_list
850 libcurses = cc.find_library(curses_libname,
852 kwargs: static_kwargs)
854 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
855 curses = declare_dependency(compile_args: curses_compile_args,
856 dependencies: [libcurses])
859 msg = 'curses library not usable'
865 if get_option('iconv').allowed()
866 foreach link_args : [ ['-liconv'], [] ]
867 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
868 # We need to use libiconv if available because mixing libiconv's headers with
869 # the system libc does not work.
870 # However, without adding glib to the dependencies -L/usr/local/lib will not be
871 # included in the command line and libiconv will not be found.
875 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
876 return conv != (iconv_t) -1;
877 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
878 iconv = declare_dependency(link_args: link_args, dependencies: glib)
883 if curses.found() and not iconv.found()
884 if get_option('iconv').enabled()
885 error('iconv not available')
887 msg = 'iconv required for curses UI but not available'
890 if not curses.found() and msg != ''
891 if get_option('curses').enabled()
894 warning(msg + ', disabling')
900 if not get_option('brlapi').auto() or have_system
901 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
902 required: get_option('brlapi'),
903 kwargs: static_kwargs)
904 if brlapi.found() and not cc.links('''
907 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
909 if get_option('brlapi').enabled()
910 error('could not link brlapi')
912 warning('could not link brlapi, disabling')
918 if not get_option('sdl').auto() or have_system
919 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
920 sdl_image = not_found
923 # work around 2.0.8 bug
924 sdl = declare_dependency(compile_args: '-Wno-undef',
926 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
927 method: 'pkg-config', kwargs: static_kwargs)
929 if get_option('sdl_image').enabled()
930 error('sdl-image required, but SDL was @0@'.format(
931 get_option('sdl').disabled() ? 'disabled' : 'not found'))
933 sdl_image = not_found
937 if not get_option('rbd').auto() or have_block
938 librados = cc.find_library('rados', required: get_option('rbd'),
939 kwargs: static_kwargs)
940 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
941 required: get_option('rbd'),
942 kwargs: static_kwargs)
943 if librados.found() and librbd.found()
946 #include <rbd/librbd.h>
949 rados_create(&cluster, NULL);
950 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
954 }''', dependencies: [librbd, librados])
955 rbd = declare_dependency(dependencies: [librbd, librados])
956 elif get_option('rbd').enabled()
957 error('librbd >= 1.12.0 required')
959 warning('librbd >= 1.12.0 not found, disabling')
964 glusterfs = not_found
965 glusterfs_ftruncate_has_stat = false
966 glusterfs_iocb_has_stat = false
967 if not get_option('glusterfs').auto() or have_block
968 glusterfs = dependency('glusterfs-api', version: '>=3',
969 required: get_option('glusterfs'),
970 method: 'pkg-config', kwargs: static_kwargs)
972 glusterfs_ftruncate_has_stat = cc.links('''
973 #include <glusterfs/api/glfs.h>
978 /* new glfs_ftruncate() passes two additional args */
979 return glfs_ftruncate(NULL, 0, NULL, NULL);
981 ''', dependencies: glusterfs)
982 glusterfs_iocb_has_stat = cc.links('''
983 #include <glusterfs/api/glfs.h>
985 /* new glfs_io_cbk() passes two additional glfs_stat structs */
987 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
993 glfs_io_cbk iocb = &glusterfs_iocb;
994 iocb(NULL, 0 , NULL, NULL, NULL);
997 ''', dependencies: glusterfs)
1002 if not get_option('libssh').auto() or have_block
1003 libssh = dependency('libssh', version: '>=0.8.7',
1004 method: 'pkg-config',
1005 required: get_option('libssh'),
1006 kwargs: static_kwargs)
1009 libbzip2 = not_found
1010 if not get_option('bzip2').auto() or have_block
1011 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
1012 required: get_option('bzip2'),
1013 kwargs: static_kwargs)
1014 if libbzip2.found() and not cc.links('''
1016 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
1017 libbzip2 = not_found
1018 if get_option('bzip2').enabled()
1019 error('could not link libbzip2')
1021 warning('could not link libbzip2, disabling')
1026 liblzfse = not_found
1027 if not get_option('lzfse').auto() or have_block
1028 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
1029 required: get_option('lzfse'),
1030 kwargs: static_kwargs)
1032 if liblzfse.found() and not cc.links('''
1034 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
1035 liblzfse = not_found
1036 if get_option('lzfse').enabled()
1037 error('could not link liblzfse')
1039 warning('could not link liblzfse, disabling')
1044 if get_option('oss').allowed() and have_system
1045 if not cc.has_header('sys/soundcard.h')
1047 elif targetos == 'netbsd'
1048 oss = cc.find_library('ossaudio', required: get_option('oss'),
1049 kwargs: static_kwargs)
1051 oss = declare_dependency()
1055 if get_option('oss').enabled()
1056 error('OSS not found')
1061 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
1062 if cc.has_header('dsound.h')
1063 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
1066 if not dsound.found()
1067 if get_option('dsound').enabled()
1068 error('DirectSound not found')
1073 coreaudio = not_found
1074 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
1075 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
1076 required: get_option('coreaudio'))
1080 if not get_option('opengl').auto() or have_system or have_vhost_user_gpu
1081 epoxy = dependency('epoxy', method: 'pkg-config',
1082 required: get_option('opengl'), kwargs: static_kwargs)
1083 if cc.has_header('epoxy/egl.h', dependencies: epoxy)
1085 elif get_option('opengl').enabled()
1086 error('epoxy/egl.h not found')
1090 if (have_system or have_tools) and (virgl.found() or opengl.found())
1091 gbm = dependency('gbm', method: 'pkg-config', required: false,
1092 kwargs: static_kwargs)
1094 have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and opengl.found() and gbm.found()
1097 gnutls_crypto = not_found
1098 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
1099 # For general TLS support our min gnutls matches
1100 # that implied by our platform support matrix
1102 # For the crypto backends, we look for a newer
1105 # Version 3.6.8 is needed to get XTS
1106 # Version 3.6.13 is needed to get PBKDF
1107 # Version 3.6.14 is needed to get HW accelerated XTS
1109 # If newer enough gnutls isn't available, we can
1110 # still use a different crypto backend to satisfy
1111 # the platform support requirements
1112 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
1113 method: 'pkg-config',
1115 kwargs: static_kwargs)
1116 if gnutls_crypto.found()
1117 gnutls = gnutls_crypto
1119 # Our min version if all we need is TLS
1120 gnutls = dependency('gnutls', version: '>=3.5.18',
1121 method: 'pkg-config',
1122 required: get_option('gnutls'),
1123 kwargs: static_kwargs)
1127 # We prefer use of gnutls for crypto, unless the options
1128 # explicitly asked for nettle or gcrypt.
1130 # If gnutls isn't available for crypto, then we'll prefer
1131 # gcrypt over nettle for performance reasons.
1137 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1138 error('Only one of gcrypt & nettle can be enabled')
1141 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1142 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1143 gnutls_crypto = not_found
1146 if not gnutls_crypto.found()
1147 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1148 gcrypt = dependency('libgcrypt', version: '>=1.8',
1149 method: 'config-tool',
1150 required: get_option('gcrypt'),
1151 kwargs: static_kwargs)
1152 # Debian has removed -lgpg-error from libgcrypt-config
1153 # as it "spreads unnecessary dependencies" which in
1154 # turn breaks static builds...
1155 if gcrypt.found() and enable_static
1156 gcrypt = declare_dependency(dependencies: [
1158 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
1161 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1162 nettle = dependency('nettle', version: '>=3.4',
1163 method: 'pkg-config',
1164 required: get_option('nettle'),
1165 kwargs: static_kwargs)
1166 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1172 gmp = dependency('gmp', required: false, method: 'pkg-config', kwargs: static_kwargs)
1173 if nettle.found() and gmp.found()
1174 hogweed = dependency('hogweed', version: '>=3.4',
1175 method: 'pkg-config',
1176 required: get_option('nettle'),
1177 kwargs: static_kwargs)
1184 if not get_option('gtk').auto() or have_system
1185 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1186 method: 'pkg-config',
1187 required: get_option('gtk'),
1188 kwargs: static_kwargs)
1190 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1191 method: 'pkg-config',
1193 kwargs: static_kwargs)
1194 gtk = declare_dependency(dependencies: [gtk, gtkx11])
1196 if not get_option('vte').auto() or have_system
1197 vte = dependency('vte-2.91',
1198 method: 'pkg-config',
1199 required: get_option('vte'),
1200 kwargs: static_kwargs)
1207 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
1208 kwargs: static_kwargs)
1211 if get_option('png').allowed() and have_system
1212 png = dependency('libpng', version: '>=1.6.34', required: get_option('png'),
1213 method: 'pkg-config', kwargs: static_kwargs)
1218 if get_option('vnc').allowed() and have_system
1219 vnc = declare_dependency() # dummy dependency
1220 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1221 method: 'pkg-config', kwargs: static_kwargs)
1222 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1223 required: get_option('vnc_sasl'),
1224 kwargs: static_kwargs)
1226 sasl = declare_dependency(dependencies: sasl,
1227 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1232 if not get_option('auth_pam').auto() or have_system
1233 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1234 required: get_option('auth_pam'),
1235 kwargs: static_kwargs)
1237 if pam.found() and not cc.links('''
1239 #include <security/pam_appl.h>
1241 const char *service_name = "qemu";
1242 const char *user = "frank";
1243 const struct pam_conv pam_conv = { 0 };
1244 pam_handle_t *pamh = NULL;
1245 pam_start(service_name, user, &pam_conv, &pamh);
1247 }''', dependencies: pam)
1249 if get_option('auth_pam').enabled()
1250 error('could not link libpam')
1252 warning('could not link libpam, disabling')
1257 if not get_option('snappy').auto() or have_system
1258 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1259 required: get_option('snappy'),
1260 kwargs: static_kwargs)
1262 if snappy.found() and not linker.links('''
1263 #include <snappy-c.h>
1264 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1266 if get_option('snappy').enabled()
1267 error('could not link libsnappy')
1269 warning('could not link libsnappy, disabling')
1274 if not get_option('lzo').auto() or have_system
1275 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1276 required: get_option('lzo'),
1277 kwargs: static_kwargs)
1279 if lzo.found() and not cc.links('''
1280 #include <lzo/lzo1x.h>
1281 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1283 if get_option('lzo').enabled()
1284 error('could not link liblzo2')
1286 warning('could not link liblzo2, disabling')
1291 if not get_option('numa').auto() or have_system or have_tools
1292 numa = cc.find_library('numa', has_headers: ['numa.h'],
1293 required: get_option('numa'),
1294 kwargs: static_kwargs)
1296 if numa.found() and not cc.links('''
1298 int main(void) { return numa_available(); }
1299 ''', dependencies: numa)
1301 if get_option('numa').enabled()
1302 error('could not link numa')
1304 warning('could not link numa, disabling')
1309 if not get_option('rdma').auto() or have_system
1310 libumad = cc.find_library('ibumad', required: get_option('rdma'))
1311 rdma_libs = [cc.find_library('rdmacm', has_headers: ['rdma/rdma_cma.h'],
1312 required: get_option('rdma'),
1313 kwargs: static_kwargs),
1314 cc.find_library('ibverbs', required: get_option('rdma'),
1315 kwargs: static_kwargs),
1317 rdma = declare_dependency(dependencies: rdma_libs)
1318 foreach lib: rdma_libs
1326 if get_option('xen').enabled() or (get_option('xen').auto() and have_system)
1327 xencontrol = dependency('xencontrol', required: false,
1328 method: 'pkg-config', kwargs: static_kwargs)
1329 if xencontrol.found()
1330 xen_pc = declare_dependency(version: xencontrol.version(),
1333 # disabler: true makes xen_pc.found() return false if any is not found
1334 dependency('xenstore', required: false,
1335 method: 'pkg-config', kwargs: static_kwargs,
1337 dependency('xenforeignmemory', required: false,
1338 method: 'pkg-config', kwargs: static_kwargs,
1340 dependency('xengnttab', required: false,
1341 method: 'pkg-config', kwargs: static_kwargs,
1343 dependency('xenevtchn', required: false,
1344 method: 'pkg-config', kwargs: static_kwargs,
1346 dependency('xendevicemodel', required: false,
1347 method: 'pkg-config', kwargs: static_kwargs,
1349 # optional, no "disabler: true"
1350 dependency('xentoolcore', required: false,
1351 method: 'pkg-config', kwargs: static_kwargs)])
1357 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' ]
1359 '4.11.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
1360 '4.10.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn', 'xentoolcore' ],
1361 '4.9.0': [ 'xenstore', 'xenctrl', 'xendevicemodel', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1362 '4.8.0': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1363 '4.7.1': [ 'xenstore', 'xenctrl', 'xenforeignmemory', 'xengnttab', 'xenevtchn' ],
1364 '4.6.0': [ 'xenstore', 'xenctrl' ],
1365 '4.5.0': [ 'xenstore', 'xenctrl' ],
1366 '4.2.0': [ 'xenstore', 'xenctrl' ],
1369 foreach ver: xen_tests
1370 # cache the various library tests to avoid polluting the logs
1372 foreach l: xen_libs[ver]
1373 if l not in xen_deps
1374 xen_deps += { l: cc.find_library(l, required: false) }
1376 xen_test_deps += xen_deps[l]
1379 # Use -D to pick just one of the test programs in scripts/xen-detect.c
1380 xen_version = ver.split('.')
1381 xen_ctrl_version = xen_version[0] + \
1382 ('0' + xen_version[1]).substring(-2) + \
1383 ('0' + xen_version[2]).substring(-2)
1384 if cc.links(files('scripts/xen-detect.c'),
1385 args: '-DCONFIG_XEN_CTRL_INTERFACE_VERSION=' + xen_ctrl_version,
1386 dependencies: xen_test_deps)
1387 xen = declare_dependency(version: ver, dependencies: xen_test_deps)
1393 accelerators += 'CONFIG_XEN'
1394 elif get_option('xen').enabled()
1395 error('could not compile and link Xen test program')
1398 have_xen_pci_passthrough = get_option('xen_pci_passthrough') \
1399 .require(xen.found(),
1400 error_message: 'Xen PCI passthrough requested but Xen not enabled') \
1401 .require(targetos == 'linux',
1402 error_message: 'Xen PCI passthrough not available on this platform') \
1407 if not get_option('smartcard').auto() or have_system
1408 cacard = dependency('libcacard', required: get_option('smartcard'),
1409 version: '>=2.5.1', method: 'pkg-config',
1410 kwargs: static_kwargs)
1414 u2f = dependency('u2f-emu', required: get_option('u2f'),
1415 method: 'pkg-config',
1416 kwargs: static_kwargs)
1420 canokey = dependency('canokey-qemu', required: get_option('canokey'),
1421 method: 'pkg-config',
1422 kwargs: static_kwargs)
1424 usbredir = not_found
1425 if not get_option('usb_redir').auto() or have_system
1426 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1427 version: '>=0.6', method: 'pkg-config',
1428 kwargs: static_kwargs)
1431 if not get_option('libusb').auto() or have_system
1432 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1433 version: '>=1.0.13', method: 'pkg-config',
1434 kwargs: static_kwargs)
1438 if not get_option('libpmem').auto() or have_system
1439 libpmem = dependency('libpmem', required: get_option('libpmem'),
1440 method: 'pkg-config', kwargs: static_kwargs)
1442 libdaxctl = not_found
1443 if not get_option('libdaxctl').auto() or have_system
1444 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1445 version: '>=57', method: 'pkg-config',
1446 kwargs: static_kwargs)
1450 tasn1 = dependency('libtasn1',
1451 method: 'pkg-config',
1452 kwargs: static_kwargs)
1454 keyutils = dependency('libkeyutils', required: false,
1455 method: 'pkg-config', kwargs: static_kwargs)
1457 has_gettid = cc.has_function('gettid')
1460 selinux = dependency('libselinux',
1461 required: get_option('selinux'),
1462 method: 'pkg-config', kwargs: static_kwargs)
1467 if get_option('malloc') == 'system'
1469 get_option('malloc_trim').allowed() and \
1470 cc.links('''#include <malloc.h>
1471 int main(void) { malloc_trim(0); return 0; }''')
1473 has_malloc_trim = false
1474 malloc = cc.find_library(get_option('malloc'), required: true)
1476 if not has_malloc_trim and get_option('malloc_trim').enabled()
1477 if get_option('malloc') == 'system'
1478 error('malloc_trim not available on this platform.')
1480 error('malloc_trim not available with non-libc memory allocator')
1484 # Check whether the glibc provides statx()
1486 gnu_source_prefix = '''
1491 statx_test = gnu_source_prefix + '''
1492 #include <sys/stat.h>
1494 struct statx statxbuf;
1495 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1499 has_statx = cc.links(statx_test)
1501 # Check whether statx() provides mount ID information
1503 statx_mnt_id_test = gnu_source_prefix + '''
1504 #include <sys/stat.h>
1506 struct statx statxbuf;
1507 statx(0, "", 0, STATX_BASIC_STATS | STATX_MNT_ID, &statxbuf);
1508 return statxbuf.stx_mnt_id;
1511 has_statx_mnt_id = cc.links(statx_mnt_id_test)
1513 have_vhost_user_blk_server = get_option('vhost_user_blk_server') \
1514 .require(targetos == 'linux',
1515 error_message: 'vhost_user_blk_server requires linux') \
1516 .require(have_vhost_user,
1517 error_message: 'vhost_user_blk_server requires vhost-user support') \
1518 .disable_auto_if(not have_tools and not have_system) \
1521 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1522 error('Cannot enable fuse-lseek while fuse is disabled')
1525 fuse = dependency('fuse3', required: get_option('fuse'),
1526 version: '>=3.1', method: 'pkg-config',
1527 kwargs: static_kwargs)
1529 fuse_lseek = not_found
1530 if get_option('fuse_lseek').allowed()
1531 if fuse.version().version_compare('>=3.8')
1533 fuse_lseek = declare_dependency()
1534 elif get_option('fuse_lseek').enabled()
1536 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1538 error('fuse-lseek requires libfuse, which was not found')
1543 have_libvduse = (targetos == 'linux')
1544 if get_option('libvduse').enabled()
1545 if targetos != 'linux'
1546 error('libvduse requires linux')
1548 elif get_option('libvduse').disabled()
1549 have_libvduse = false
1552 have_vduse_blk_export = (have_libvduse and targetos == 'linux')
1553 if get_option('vduse_blk_export').enabled()
1554 if targetos != 'linux'
1555 error('vduse_blk_export requires linux')
1556 elif not have_libvduse
1557 error('vduse_blk_export requires libvduse support')
1559 elif get_option('vduse_blk_export').disabled()
1560 have_vduse_blk_export = false
1564 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1565 if libbpf.found() and not cc.links('''
1566 #include <bpf/libbpf.h>
1569 bpf_object__destroy_skeleton(NULL);
1571 }''', dependencies: libbpf)
1573 if get_option('bpf').enabled()
1574 error('libbpf skeleton test failed')
1576 warning('libbpf skeleton test failed, disabling')
1584 audio_drivers_selected = []
1586 audio_drivers_available = {
1587 'alsa': alsa.found(),
1588 'coreaudio': coreaudio.found(),
1589 'dsound': dsound.found(),
1590 'jack': jack.found(),
1592 'pa': pulse.found(),
1595 foreach k, v: audio_drivers_available
1596 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1599 # Default to native drivers first, OSS second, SDL third
1600 audio_drivers_priority = \
1601 [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
1602 (targetos == 'linux' ? [] : [ 'sdl' ])
1603 audio_drivers_default = []
1604 foreach k: audio_drivers_priority
1605 if audio_drivers_available[k]
1606 audio_drivers_default += k
1610 foreach k: get_option('audio_drv_list')
1612 audio_drivers_selected += audio_drivers_default
1613 elif not audio_drivers_available[k]
1614 error('Audio driver "@0@" not available.'.format(k))
1616 audio_drivers_selected += k
1620 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1621 '"' + '", "'.join(audio_drivers_selected) + '", ')
1623 if get_option('cfi')
1625 # Check for dependency on LTO
1626 if not get_option('b_lto')
1627 error('Selected Control-Flow Integrity but LTO is disabled')
1629 if config_host.has_key('CONFIG_MODULES')
1630 error('Selected Control-Flow Integrity is not compatible with modules')
1632 # Check for cfi flags. CFI requires LTO so we can't use
1633 # get_supported_arguments, but need a more complex "compiles" which allows
1635 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1636 args: ['-flto', '-fsanitize=cfi-icall'] )
1637 cfi_flags += '-fsanitize=cfi-icall'
1639 error('-fsanitize=cfi-icall is not supported by the compiler')
1641 if cc.compiles('int main () { return 0; }',
1642 name: '-fsanitize-cfi-icall-generalize-pointers',
1643 args: ['-flto', '-fsanitize=cfi-icall',
1644 '-fsanitize-cfi-icall-generalize-pointers'] )
1645 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1647 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1649 if get_option('cfi_debug')
1650 if cc.compiles('int main () { return 0; }',
1651 name: '-fno-sanitize-trap=cfi-icall',
1652 args: ['-flto', '-fsanitize=cfi-icall',
1653 '-fno-sanitize-trap=cfi-icall'] )
1654 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1656 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1659 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1660 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1663 have_host_block_device = (targetos != 'darwin' or
1664 cc.has_header('IOKit/storage/IOMedia.h'))
1666 # FIXME enable_modules shouldn't be necessary, but: https://github.com/mesonbuild/meson/issues/8333
1667 dbus_display = get_option('dbus_display') \
1668 .require(gio.version().version_compare('>=2.64'),
1669 error_message: '-display dbus requires glib>=2.64') \
1670 .require(enable_modules,
1671 error_message: '-display dbus requires --enable-modules') \
1672 .require(gdbus_codegen.found(),
1673 error_message: '-display dbus requires gdbus-codegen') \
1674 .require(opengl.found() and gbm.found(),
1675 error_message: '-display dbus requires epoxy/egl and gbm') \
1678 have_virtfs = get_option('virtfs') \
1679 .require(targetos == 'linux' or targetos == 'darwin',
1680 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
1681 .require(targetos == 'linux' or cc.has_function('pthread_fchdir_np'),
1682 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
1683 .require(targetos == 'darwin' or (libattr.found() and libcap_ng.found()),
1684 error_message: 'virtio-9p (virtfs) on Linux requires libcap-ng-devel and libattr-devel') \
1685 .disable_auto_if(not have_tools and not have_system) \
1688 have_virtfs_proxy_helper = targetos != 'darwin' and have_virtfs and have_tools
1690 if get_option('block_drv_ro_whitelist') == ''
1691 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
1693 config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
1694 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
1696 if get_option('block_drv_rw_whitelist') == ''
1697 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
1699 config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
1700 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
1703 foreach k : get_option('trace_backends')
1704 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1706 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1707 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
1709 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
1711 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1712 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1713 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1714 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1715 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1717 qemu_firmwarepath = ''
1718 foreach k : get_option('qemu_firmwarepath')
1719 qemu_firmwarepath += '"' + get_option('prefix') / k + '", '
1721 config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath)
1723 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1724 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1725 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1726 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1727 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1728 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1730 if config_host.has_key('CONFIG_MODULES')
1731 config_host_data.set('CONFIG_STAMP', run_command(
1732 meson.current_source_dir() / 'scripts/qemu-stamp.py',
1733 meson.project_version(), get_option('pkgversion'), '--',
1734 meson.current_source_dir() / 'configure',
1735 capture: true, check: true).stdout().strip())
1738 have_slirp_smbd = get_option('slirp_smbd') \
1739 .require(targetos != 'windows', error_message: 'Host smbd not supported on this platform.') \
1742 smbd_path = get_option('smbd')
1744 smbd_path = (targetos == 'solaris' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
1746 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
1749 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
1751 if get_option('module_upgrades') and not enable_modules
1752 error('Cannot enable module-upgrades as modules are not enabled')
1754 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
1756 config_host_data.set('CONFIG_ATTR', libattr.found())
1757 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
1758 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1759 config_host_data.set('CONFIG_COCOA', cocoa.found())
1760 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1761 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1762 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1763 config_host_data.set('CONFIG_LZO', lzo.found())
1764 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1765 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1766 config_host_data.set('CONFIG_CURL', curl.found())
1767 config_host_data.set('CONFIG_CURSES', curses.found())
1768 config_host_data.set('CONFIG_GBM', gbm.found())
1769 config_host_data.set('CONFIG_GIO', gio.found())
1770 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1771 if glusterfs.found()
1772 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1773 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1774 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1775 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1776 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1777 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1779 config_host_data.set('CONFIG_GTK', gtk.found())
1780 config_host_data.set('CONFIG_VTE', vte.found())
1781 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1782 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1783 config_host_data.set('CONFIG_EBPF', libbpf.found())
1784 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1785 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1786 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1787 config_host_data.set('CONFIG_LIBSSH', libssh.found())
1788 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1789 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1790 config_host_data.set('CONFIG_LIBURING_REGISTER_RING_FD', cc.has_function('io_uring_register_ring_fd', prefix: '#include <liburing.h>', dependencies:linux_io_uring))
1791 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1792 config_host_data.set('CONFIG_NUMA', numa.found())
1793 config_host_data.set('CONFIG_OPENGL', opengl.found())
1794 config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
1795 config_host_data.set('CONFIG_RBD', rbd.found())
1796 config_host_data.set('CONFIG_RDMA', rdma.found())
1797 config_host_data.set('CONFIG_SDL', sdl.found())
1798 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1799 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1800 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1801 config_host_data.set('CONFIG_TPM', have_tpm)
1802 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1803 config_host_data.set('CONFIG_VDE', vde.found())
1804 config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
1805 config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
1806 config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)
1807 config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
1808 config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
1809 config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
1810 config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
1811 config_host_data.set('CONFIG_VMNET', vmnet.found())
1812 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1813 config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export)
1814 config_host_data.set('CONFIG_PNG', png.found())
1815 config_host_data.set('CONFIG_VNC', vnc.found())
1816 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1817 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1818 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1819 config_host_data.set('CONFIG_VTE', vte.found())
1820 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1821 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1822 config_host_data.set('CONFIG_GETTID', has_gettid)
1823 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1824 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1825 config_host_data.set('CONFIG_TASN1', tasn1.found())
1826 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1827 config_host_data.set('CONFIG_NETTLE', nettle.found())
1828 config_host_data.set('CONFIG_HOGWEED', hogweed.found())
1829 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1830 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1831 config_host_data.set('CONFIG_STATX', has_statx)
1832 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
1833 config_host_data.set('CONFIG_ZSTD', zstd.found())
1834 config_host_data.set('CONFIG_FUSE', fuse.found())
1835 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1836 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1837 if spice_protocol.found()
1838 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
1839 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
1840 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
1842 config_host_data.set('CONFIG_SPICE', spice.found())
1843 config_host_data.set('CONFIG_X11', x11.found())
1844 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
1845 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1846 config_host_data.set('CONFIG_SELINUX', selinux.found())
1847 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
1849 # protect from xen.version() having less than three components
1850 xen_version = xen.version().split('.') + ['0', '0']
1851 xen_ctrl_version = xen_version[0] + \
1852 ('0' + xen_version[1]).substring(-2) + \
1853 ('0' + xen_version[2]).substring(-2)
1854 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
1856 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1857 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1858 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1859 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1861 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1862 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1864 have_coroutine_pool = get_option('coroutine_pool')
1865 if get_option('debug_stack_usage') and have_coroutine_pool
1866 message('Disabling coroutine pool to measure stack usage')
1867 have_coroutine_pool = false
1869 config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool)
1870 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
1871 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
1872 config_host_data.set('CONFIG_GPROF', get_option('gprof'))
1873 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
1874 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
1875 config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
1878 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1879 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1880 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1881 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1882 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1883 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1884 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1885 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1886 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1887 if targetos == 'windows'
1888 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h'))
1892 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1893 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1894 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1895 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1896 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1897 # Note that we need to specify prefix: here to avoid incorrectly
1898 # thinking that Windows has posix_memalign()
1899 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
1900 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
1901 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
1902 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
1903 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1904 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1905 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
1906 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1907 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1908 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1909 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1910 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1911 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1912 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
1913 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1914 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1915 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1917 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
1918 cc.has_function('rbd_namespace_exists',
1920 prefix: '#include <rbd/librbd.h>'))
1923 config_host_data.set('HAVE_IBV_ADVISE_MR',
1924 cc.has_function('ibv_advise_mr',
1926 prefix: '#include <infiniband/verbs.h>'))
1930 config_host_data.set('CONFIG_BYTESWAP_H',
1931 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1932 config_host_data.set('CONFIG_EPOLL_CREATE1',
1933 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1934 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1935 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1936 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1937 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1938 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1939 config_host_data.set('CONFIG_FIEMAP',
1940 cc.has_header('linux/fiemap.h') and
1941 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1942 config_host_data.set('CONFIG_GETRANDOM',
1943 cc.has_function('getrandom') and
1944 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1945 config_host_data.set('CONFIG_INOTIFY',
1946 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1947 config_host_data.set('CONFIG_INOTIFY1',
1948 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1949 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1950 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1951 prefix: '''#include <sys/endian.h>
1952 #include <sys/types.h>'''))
1953 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1954 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1955 config_host_data.set('CONFIG_RTNETLINK',
1956 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1957 config_host_data.set('CONFIG_SYSMACROS',
1958 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1959 config_host_data.set('HAVE_OPTRESET',
1960 cc.has_header_symbol('getopt.h', 'optreset'))
1961 config_host_data.set('HAVE_IPPROTO_MPTCP',
1962 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1963 config_host_data.set('HAVE_SYS_MOUNT_FSCONFIG',
1964 cc.has_header_symbol('sys/mount.h', 'FSCONFIG_SET_FLAG'))
1967 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1968 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1969 prefix: '#include <signal.h>'))
1970 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1971 cc.has_member('struct stat', 'st_atim',
1972 prefix: '#include <sys/stat.h>'))
1975 config_host_data.set('CONFIG_IOVEC',
1976 cc.has_type('struct iovec',
1977 prefix: '#include <sys/uio.h>'))
1978 config_host_data.set('HAVE_UTMPX',
1979 cc.has_type('struct utmpx',
1980 prefix: '#include <utmpx.h>'))
1982 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1983 #include <sys/eventfd.h>
1984 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1985 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1988 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1989 return fdatasync(0);
1991 #error Not supported
1995 has_madvise = cc.links(gnu_source_prefix + '''
1996 #include <sys/types.h>
1997 #include <sys/mman.h>
1999 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
2000 missing_madvise_proto = false
2002 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
2003 # but forget to prototype it. In this case, has_madvise will be true (the
2004 # test program links despite a compile warning). To detect the
2005 # missing-prototype case, we try again with a definitely-bogus prototype.
2006 # This will only compile if the system headers don't provide the prototype;
2007 # otherwise the conflicting prototypes will cause a compiler error.
2008 missing_madvise_proto = cc.links(gnu_source_prefix + '''
2009 #include <sys/types.h>
2010 #include <sys/mman.h>
2012 extern int madvise(int);
2013 int main(void) { return madvise(0); }''')
2015 config_host_data.set('CONFIG_MADVISE', has_madvise)
2016 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
2018 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
2019 #include <sys/mman.h>
2020 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
2021 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
2023 #if !defined(AT_EMPTY_PATH)
2024 # error missing definition
2026 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
2028 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
2029 #include <sys/mman.h>
2031 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
2033 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
2034 #include <pthread.h>
2036 static void *f(void *p) { return NULL; }
2040 pthread_create(&thread, 0, f, 0);
2041 pthread_setname_np(thread, "QEMU");
2043 }''', dependencies: threads))
2044 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
2045 #include <pthread.h>
2047 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
2051 pthread_create(&thread, 0, f, 0);
2053 }''', dependencies: threads))
2054 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
2055 #include <pthread.h>
2060 pthread_condattr_t attr
2061 pthread_condattr_init(&attr);
2062 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
2064 }''', dependencies: threads))
2066 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
2067 #include <sys/signalfd.h>
2069 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
2070 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
2078 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
2079 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
2083 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
2084 #include <sys/mman.h>
2085 int main(int argc, char *argv[]) {
2086 return mlockall(MCL_FUTURE);
2090 if get_option('l2tpv3').allowed() and have_system
2091 have_l2tpv3 = cc.has_type('struct mmsghdr',
2092 prefix: gnu_source_prefix + '''
2093 #include <sys/socket.h>
2094 #include <linux/ip.h>''')
2096 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2099 if get_option('netmap').allowed() and have_system
2100 have_netmap = cc.compiles('''
2101 #include <inttypes.h>
2103 #include <net/netmap.h>
2104 #include <net/netmap_user.h>
2105 #if (NETMAP_API < 11) || (NETMAP_API > 15)
2108 int main(void) { return 0; }''')
2109 if not have_netmap and get_option('netmap').enabled()
2110 error('Netmap headers not available')
2113 config_host_data.set('CONFIG_NETMAP', have_netmap)
2115 # Work around a system header bug with some kernel/XFS header
2116 # versions where they both try to define 'struct fsxattr':
2117 # xfs headers will not try to redefine structs from linux headers
2118 # if this macro is set.
2119 config_host_data.set('HAVE_FSXATTR', cc.links('''
2120 #include <linux/fs.h>
2126 # Some versions of Mac OS X incorrectly define SIZE_MAX
2127 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2130 int main(int argc, char *argv[]) {
2131 return printf("%zu", SIZE_MAX);
2132 }''', args: ['-Werror']))
2139 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2140 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2141 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2142 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2143 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2147 # See if 64-bit atomic operations are supported.
2148 # Note that without __atomic builtins, we can only
2149 # assume atomic loads/stores max at pointer size.
2150 config_host_data.set('CONFIG_ATOMIC64', cc.links(atomic_test.format('uint64_t')))
2152 has_int128 = cc.links('''
2162 config_host_data.set('CONFIG_INT128', has_int128)
2165 # "do we have 128-bit atomics which are handled inline and specifically not
2166 # via libatomic". The reason we can't use libatomic is documented in the
2167 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2168 has_atomic128 = cc.links(atomic_test.format('unsigned __int128'))
2170 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2172 if not has_atomic128
2173 has_cmpxchg128 = cc.links('''
2176 unsigned __int128 x = 0, y = 0;
2177 __sync_val_compare_and_swap_16(&x, y, x);
2182 config_host_data.set('CONFIG_CMPXCHG128', has_cmpxchg128)
2186 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2187 #include <sys/auxv.h>
2189 return getauxval(AT_HWCAP) == 0;
2192 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2193 #include <linux/usbdevice_fs.h>
2195 #ifndef USBDEVFS_GET_CAPABILITIES
2196 #error "USBDEVFS_GET_CAPABILITIES undefined"
2199 #ifndef USBDEVFS_DISCONNECT_CLAIM
2200 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2203 int main(void) { return 0; }'''))
2205 have_keyring = get_option('keyring') \
2206 .require(targetos == 'linux', error_message: 'keyring is only available on Linux') \
2207 .require(cc.compiles('''
2209 #include <asm/unistd.h>
2210 #include <linux/keyctl.h>
2211 #include <sys/syscall.h>
2214 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2215 }'''), error_message: 'keyctl syscall not available on this system').allowed()
2216 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2218 have_cpuid_h = cc.links('''
2221 unsigned a, b, c, d;
2222 unsigned max = __get_cpuid_max(0, 0);
2225 __cpuid(1, a, b, c, d);
2229 __cpuid_count(7, 0, a, b, c, d);
2234 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2236 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2237 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2238 .require(cc.links('''
2239 #pragma GCC push_options
2240 #pragma GCC target("avx2")
2242 #include <immintrin.h>
2243 static int bar(void *a) {
2244 __m256i x = *(__m256i *)a;
2245 return _mm256_testz_si256(x, x);
2247 int main(int argc, char *argv[]) { return bar(argv[0]); }
2248 '''), error_message: 'AVX2 not available').allowed())
2250 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2251 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2252 .require(cc.links('''
2253 #pragma GCC push_options
2254 #pragma GCC target("avx512f")
2256 #include <immintrin.h>
2257 static int bar(void *a) {
2258 __m512i x = *(__m512i *)a;
2259 return _mm512_test_epi64_mask(x, x);
2261 int main(int argc, char *argv[]) { return bar(argv[0]); }
2262 '''), error_message: 'AVX512F not available').allowed())
2264 have_pvrdma = get_option('pvrdma') \
2265 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
2266 .require(cc.compiles(gnu_source_prefix + '''
2267 #include <sys/mman.h>
2272 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2275 }'''), error_message: 'PVRDMA requires mremap').allowed()
2278 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.links('''
2279 #include <infiniband/verbs.h>
2283 struct ibv_pd *pd = NULL;
2289 mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2295 if get_option('membarrier').disabled()
2296 have_membarrier = false
2297 elif targetos == 'windows'
2298 have_membarrier = true
2299 elif targetos == 'linux'
2300 have_membarrier = cc.compiles('''
2301 #include <linux/membarrier.h>
2302 #include <sys/syscall.h>
2306 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2307 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2311 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2312 .require(have_membarrier, error_message: 'membarrier system call not available') \
2315 have_afalg = get_option('crypto_afalg') \
2316 .require(cc.compiles(gnu_source_prefix + '''
2318 #include <sys/types.h>
2319 #include <sys/socket.h>
2320 #include <linux/if_alg.h>
2323 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2326 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2327 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2329 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2330 'linux/vm_sockets.h', 'AF_VSOCK',
2331 prefix: '#include <sys/socket.h>',
2335 have_vss_sdk = false # old xp/2003 SDK
2336 if targetos == 'windows' and link_language == 'cpp'
2337 have_vss = cxx.compiles('''
2338 #define __MIDL_user_allocate_free_DEFINED__
2340 int main(void) { return VSS_CTX_BACKUP; }''')
2341 have_vss_sdk = cxx.has_header('vscoordint.h')
2343 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2345 foreach k, v: config_host
2346 if k.startswith('CONFIG_')
2347 config_host_data.set(k, v == 'y' ? 1 : v)
2351 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2352 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2353 if targetos == 'windows'
2354 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2360 }''', name: '_lock_file and _unlock_file'))
2363 ########################
2364 # Target configuration #
2365 ########################
2367 minikconf = find_program('scripts/minikconf.py')
2369 config_all_devices = {}
2370 config_all_disas = {}
2371 config_devices_mak_list = []
2372 config_devices_h = {}
2373 config_target_h = {}
2374 config_target_mak = {}
2377 'alpha' : ['CONFIG_ALPHA_DIS'],
2378 'avr' : ['CONFIG_AVR_DIS'],
2379 'cris' : ['CONFIG_CRIS_DIS'],
2380 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2381 'hppa' : ['CONFIG_HPPA_DIS'],
2382 'i386' : ['CONFIG_I386_DIS'],
2383 'x86_64' : ['CONFIG_I386_DIS'],
2384 'm68k' : ['CONFIG_M68K_DIS'],
2385 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2386 'mips' : ['CONFIG_MIPS_DIS'],
2387 'nios2' : ['CONFIG_NIOS2_DIS'],
2388 'or1k' : ['CONFIG_OPENRISC_DIS'],
2389 'ppc' : ['CONFIG_PPC_DIS'],
2390 'riscv' : ['CONFIG_RISCV_DIS'],
2391 'rx' : ['CONFIG_RX_DIS'],
2392 's390' : ['CONFIG_S390_DIS'],
2393 'sh4' : ['CONFIG_SH4_DIS'],
2394 'sparc' : ['CONFIG_SPARC_DIS'],
2395 'xtensa' : ['CONFIG_XTENSA_DIS'],
2396 'loongarch' : ['CONFIG_LOONGARCH_DIS'],
2398 if link_language == 'cpp'
2400 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
2404 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2406 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2407 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2408 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2409 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2410 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2411 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2412 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
2413 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2414 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2415 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2416 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
2417 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
2418 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
2419 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : [])
2421 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2423 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2424 actual_target_dirs = []
2426 foreach target : target_dirs
2427 config_target = { 'TARGET_NAME': target.split('-')[0] }
2428 if target.endswith('linux-user')
2429 if targetos != 'linux'
2433 error('Target @0@ is only available on a Linux host'.format(target))
2435 config_target += { 'CONFIG_LINUX_USER': 'y' }
2436 elif target.endswith('bsd-user')
2437 if 'CONFIG_BSD' not in config_host
2441 error('Target @0@ is only available on a BSD host'.format(target))
2443 config_target += { 'CONFIG_BSD_USER': 'y' }
2444 elif target.endswith('softmmu')
2445 config_target += { 'CONFIG_SOFTMMU': 'y' }
2447 if target.endswith('-user')
2449 'CONFIG_USER_ONLY': 'y',
2450 'CONFIG_QEMU_INTERP_PREFIX':
2451 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
2456 foreach sym: accelerators
2457 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2458 config_target += { sym: 'y' }
2459 config_all += { sym: 'y' }
2460 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
2461 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
2463 if target in modular_tcg
2464 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2466 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2468 accel_kconfig += [ sym + '=y' ]
2471 if accel_kconfig.length() == 0
2475 error('No accelerator available for target @0@'.format(target))
2478 actual_target_dirs += target
2479 config_target += keyval.load('configs/targets' / target + '.mak')
2480 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
2482 if 'TARGET_NEED_FDT' in config_target
2483 fdt_required += target
2487 if 'TARGET_BASE_ARCH' not in config_target
2488 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2490 if 'TARGET_ABI_DIR' not in config_target
2491 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2493 if 'TARGET_BIG_ENDIAN' not in config_target
2494 config_target += {'TARGET_BIG_ENDIAN': 'n'}
2497 foreach k, v: disassemblers
2498 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
2500 config_target += { sym: 'y' }
2501 config_all_disas += { sym: 'y' }
2506 config_target_data = configuration_data()
2507 foreach k, v: config_target
2508 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2510 elif ignored.contains(k)
2512 elif k == 'TARGET_BASE_ARCH'
2513 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2514 # not used to select files from sourcesets.
2515 config_target_data.set('TARGET_' + v.to_upper(), 1)
2516 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
2517 config_target_data.set_quoted(k, v)
2519 config_target_data.set(k, 1)
2521 config_target_data.set(k, 0)
2523 config_target_data.set(k, v)
2526 config_target_data.set('QEMU_ARCH',
2527 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
2528 config_target_h += {target: configure_file(output: target + '-config-target.h',
2529 configuration: config_target_data)}
2531 if target.endswith('-softmmu')
2532 config_input = meson.get_external_property(target, 'default')
2533 config_devices_mak = target + '-config-devices.mak'
2534 config_devices_mak = configure_file(
2535 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2536 output: config_devices_mak,
2537 depfile: config_devices_mak + '.d',
2539 command: [minikconf,
2540 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2541 config_devices_mak, '@DEPFILE@', '@INPUT@',
2542 host_kconfig, accel_kconfig,
2543 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
2545 config_devices_data = configuration_data()
2546 config_devices = keyval.load(config_devices_mak)
2547 foreach k, v: config_devices
2548 config_devices_data.set(k, 1)
2550 config_devices_mak_list += config_devices_mak
2551 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2552 configuration: config_devices_data)}
2553 config_target += config_devices
2554 config_all_devices += config_devices
2556 config_target_mak += {target: config_target}
2558 target_dirs = actual_target_dirs
2560 # This configuration is used to build files that are shared by
2561 # multiple binaries, and then extracted out of the "common"
2562 # static_library target.
2564 # We do not use all_sources()/all_dependencies(), because it would
2565 # build literally all source files, including devices only used by
2566 # targets that are not built for this compilation. The CONFIG_ALL
2567 # pseudo symbol replaces it.
2569 config_all += config_all_devices
2570 config_all += config_host
2571 config_all += config_all_disas
2573 'CONFIG_XEN': xen.found(),
2574 'CONFIG_SOFTMMU': have_system,
2575 'CONFIG_USER_ONLY': have_user,
2579 target_configs_h = []
2580 foreach target: target_dirs
2581 target_configs_h += config_target_h[target]
2582 target_configs_h += config_devices_h.get(target, [])
2584 genh += custom_target('config-poison.h',
2585 input: [target_configs_h],
2586 output: 'config-poison.h',
2588 command: [find_program('scripts/make-config-poison.sh'),
2595 capstone = not_found
2596 if not get_option('capstone').auto() or have_system or have_user
2597 capstone = dependency('capstone', version: '>=3.0.5',
2598 kwargs: static_kwargs, method: 'pkg-config',
2599 required: get_option('capstone'))
2601 # Some versions of capstone have broken pkg-config file
2602 # that reports a wrong -I path, causing the #include to
2603 # fail later. If the system has such a broken version
2605 if capstone.found() and not cc.compiles('#include <capstone.h>',
2606 dependencies: [capstone])
2607 capstone = not_found
2608 if get_option('capstone').enabled()
2609 error('capstone requested, but it does not appear to work')
2615 slirp_opt = 'disabled'
2617 slirp_opt = get_option('slirp')
2618 if slirp_opt in ['enabled', 'auto', 'system']
2619 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2620 slirp_dep_required = (slirp_opt == 'system' or
2621 slirp_opt == 'enabled' and not have_internal)
2622 slirp = dependency('slirp', kwargs: static_kwargs,
2623 method: 'pkg-config', version: '>=4.1.0',
2624 required: slirp_dep_required)
2625 # slirp <4.7 is incompatible with CFI support in QEMU. This is because
2626 # it passes function pointers within libslirp as callbacks for timers.
2627 # When using a system-wide shared libslirp, the type information for the
2628 # callback is missing and the timer call produces a false positive with CFI.
2629 # Do not use the "version" keyword argument to produce a better error.
2630 # with control-flow integrity.
2631 if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
2632 if slirp_dep_required
2633 error('Control-Flow Integrity requires libslirp 4.7.')
2635 warning('Control-Flow Integrity requires libslirp 4.7, not using system-wide libslirp.')
2640 slirp_opt = 'system'
2642 slirp_opt = 'internal'
2644 slirp_opt = 'disabled'
2647 if slirp_opt == 'internal'
2649 if targetos == 'windows'
2650 slirp_deps = cc.find_library('iphlpapi')
2651 elif targetos == 'darwin'
2652 slirp_deps = cc.find_library('resolv')
2654 slirp_conf = configuration_data()
2655 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2656 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2657 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2658 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2659 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2661 'slirp/src/arp_table.c',
2662 'slirp/src/bootp.c',
2663 'slirp/src/cksum.c',
2664 'slirp/src/dhcpv6.c',
2665 'slirp/src/dnssearch.c',
2667 'slirp/src/ip6_icmp.c',
2668 'slirp/src/ip6_input.c',
2669 'slirp/src/ip6_output.c',
2670 'slirp/src/ip_icmp.c',
2671 'slirp/src/ip_input.c',
2672 'slirp/src/ip_output.c',
2676 'slirp/src/ndp_table.c',
2678 'slirp/src/slirp.c',
2679 'slirp/src/socket.c',
2680 'slirp/src/state.c',
2681 'slirp/src/stream.c',
2682 'slirp/src/tcp_input.c',
2683 'slirp/src/tcp_output.c',
2684 'slirp/src/tcp_subr.c',
2685 'slirp/src/tcp_timer.c',
2690 'slirp/src/version.c',
2691 'slirp/src/vmstate.c',
2695 input : 'slirp/src/libslirp-version.h.in',
2696 output : 'libslirp-version.h',
2697 configuration: slirp_conf)
2699 slirp_inc = include_directories('slirp', 'slirp/src')
2700 libslirp = static_library('slirp',
2701 build_by_default: false,
2702 sources: slirp_files,
2703 c_args: slirp_cargs,
2704 include_directories: slirp_inc)
2705 slirp = declare_dependency(link_with: libslirp,
2706 dependencies: slirp_deps,
2707 include_directories: slirp_inc)
2711 libvfio_user_dep = not_found
2712 if have_system and vfio_user_server_allowed
2713 have_internal = fs.exists(meson.current_source_dir() / 'subprojects/libvfio-user/meson.build')
2715 if not have_internal
2716 error('libvfio-user source not found - please pull git submodule')
2719 libvfio_user_proj = subproject('libvfio-user')
2721 libvfio_user_lib = libvfio_user_proj.get_variable('libvfio_user_dep')
2723 libvfio_user_dep = declare_dependency(dependencies: [libvfio_user_lib])
2728 fdt_opt = get_option('fdt')
2729 if fdt_opt in ['enabled', 'auto', 'system']
2730 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2731 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2732 required: fdt_opt == 'system' or
2733 fdt_opt == 'enabled' and not have_internal)
2734 if fdt.found() and cc.links('''
2736 #include <libfdt_env.h>
2737 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2740 elif fdt_opt == 'system'
2741 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2743 fdt_opt = 'internal'
2745 fdt_opt = 'disabled'
2749 if fdt_opt == 'internal'
2752 'dtc/libfdt/fdt_ro.c',
2753 'dtc/libfdt/fdt_wip.c',
2754 'dtc/libfdt/fdt_sw.c',
2755 'dtc/libfdt/fdt_rw.c',
2756 'dtc/libfdt/fdt_strerror.c',
2757 'dtc/libfdt/fdt_empty_tree.c',
2758 'dtc/libfdt/fdt_addresses.c',
2759 'dtc/libfdt/fdt_overlay.c',
2760 'dtc/libfdt/fdt_check.c',
2763 fdt_inc = include_directories('dtc/libfdt')
2764 libfdt = static_library('fdt',
2765 build_by_default: false,
2767 include_directories: fdt_inc)
2768 fdt = declare_dependency(link_with: libfdt,
2769 include_directories: fdt_inc)
2772 fdt_opt = 'disabled'
2774 if not fdt.found() and fdt_required.length() > 0
2775 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2778 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2779 config_host_data.set('CONFIG_FDT', fdt.found())
2780 config_host_data.set('CONFIG_SLIRP', slirp.found())
2782 #####################
2783 # Generated sources #
2784 #####################
2786 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2788 hxtool = find_program('scripts/hxtool')
2789 shaderinclude = find_program('scripts/shaderinclude.pl')
2790 qapi_gen = find_program('scripts/qapi-gen.py')
2791 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2792 meson.current_source_dir() / 'scripts/qapi/commands.py',
2793 meson.current_source_dir() / 'scripts/qapi/common.py',
2794 meson.current_source_dir() / 'scripts/qapi/error.py',
2795 meson.current_source_dir() / 'scripts/qapi/events.py',
2796 meson.current_source_dir() / 'scripts/qapi/expr.py',
2797 meson.current_source_dir() / 'scripts/qapi/gen.py',
2798 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2799 meson.current_source_dir() / 'scripts/qapi/parser.py',
2800 meson.current_source_dir() / 'scripts/qapi/schema.py',
2801 meson.current_source_dir() / 'scripts/qapi/source.py',
2802 meson.current_source_dir() / 'scripts/qapi/types.py',
2803 meson.current_source_dir() / 'scripts/qapi/visit.py',
2804 meson.current_source_dir() / 'scripts/qapi/common.py',
2805 meson.current_source_dir() / 'scripts/qapi-gen.py'
2809 python, files('scripts/tracetool.py'),
2810 '--backend=' + ','.join(get_option('trace_backends'))
2812 tracetool_depends = files(
2813 'scripts/tracetool/backend/log.py',
2814 'scripts/tracetool/backend/__init__.py',
2815 'scripts/tracetool/backend/dtrace.py',
2816 'scripts/tracetool/backend/ftrace.py',
2817 'scripts/tracetool/backend/simple.py',
2818 'scripts/tracetool/backend/syslog.py',
2819 'scripts/tracetool/backend/ust.py',
2820 'scripts/tracetool/format/ust_events_c.py',
2821 'scripts/tracetool/format/ust_events_h.py',
2822 'scripts/tracetool/format/__init__.py',
2823 'scripts/tracetool/format/d.py',
2824 'scripts/tracetool/format/simpletrace_stap.py',
2825 'scripts/tracetool/format/c.py',
2826 'scripts/tracetool/format/h.py',
2827 'scripts/tracetool/format/log_stap.py',
2828 'scripts/tracetool/format/stap.py',
2829 'scripts/tracetool/__init__.py',
2830 'scripts/tracetool/transform.py',
2831 'scripts/tracetool/vcpu.py'
2834 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2835 meson.current_source_dir(),
2836 get_option('pkgversion'), meson.project_version()]
2837 qemu_version = custom_target('qemu-version.h',
2838 output: 'qemu-version.h',
2839 command: qemu_version_cmd,
2841 build_by_default: true,
2842 build_always_stale: true)
2843 genh += qemu_version
2847 ['qemu-options.hx', 'qemu-options.def'],
2848 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2852 ['hmp-commands.hx', 'hmp-commands.h'],
2853 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2856 foreach d : hx_headers
2857 hxdep += custom_target(d[1],
2861 build_by_default: true, # to be removed when added to a target
2862 command: [hxtool, '-h', '@INPUT0@'])
2870 authz_ss = ss.source_set()
2871 blockdev_ss = ss.source_set()
2872 block_ss = ss.source_set()
2873 chardev_ss = ss.source_set()
2874 common_ss = ss.source_set()
2875 crypto_ss = ss.source_set()
2876 hwcore_ss = ss.source_set()
2877 io_ss = ss.source_set()
2878 qmp_ss = ss.source_set()
2879 qom_ss = ss.source_set()
2880 softmmu_ss = ss.source_set()
2881 specific_fuzz_ss = ss.source_set()
2882 specific_ss = ss.source_set()
2883 stub_ss = ss.source_set()
2884 trace_ss = ss.source_set()
2885 user_ss = ss.source_set()
2886 util_ss = ss.source_set()
2889 qtest_module_ss = ss.source_set()
2890 tcg_module_ss = ss.source_set()
2896 target_softmmu_arch = {}
2897 target_user_arch = {}
2903 # TODO: add each directory to the subdirs from its own meson.build, once
2905 trace_events_subdirs = [
2913 trace_events_subdirs += [ 'linux-user' ]
2916 trace_events_subdirs += [ 'bsd-user' ]
2919 trace_events_subdirs += [
2928 trace_events_subdirs += [
2942 'hw/block/dataplane',
2991 if have_system or have_user
2992 trace_events_subdirs += [
3010 vhost_user = not_found
3011 if targetos == 'linux' and have_vhost_user
3012 libvhost_user = subproject('libvhost-user')
3013 vhost_user = libvhost_user.get_variable('vhost_user_dep')
3016 libvduse = not_found
3018 libvduse_proj = subproject('libvduse')
3019 libvduse = libvduse_proj.get_variable('libvduse_dep')
3022 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3023 # that is filled in by qapi/.
3037 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3038 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3041 qom_ss = qom_ss.apply(config_host, strict: false)
3042 libqom = static_library('qom', qom_ss.sources() + genh,
3043 dependencies: [qom_ss.dependencies()],
3045 qom = declare_dependency(link_whole: libqom)
3047 event_loop_base = files('event-loop-base.c')
3048 event_loop_base = static_library('event-loop-base', sources: event_loop_base + genh,
3049 build_by_default: true)
3050 event_loop_base = declare_dependency(link_whole: event_loop_base,
3051 dependencies: [qom])
3053 stub_ss = stub_ss.apply(config_all, strict: false)
3055 util_ss.add_all(trace_ss)
3056 util_ss = util_ss.apply(config_all, strict: false)
3057 libqemuutil = static_library('qemuutil',
3058 sources: util_ss.sources() + stub_ss.sources() + genh,
3059 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
3060 qemuutil = declare_dependency(link_with: libqemuutil,
3061 sources: genh + version_res,
3062 dependencies: [event_loop_base])
3064 if have_system or have_user
3065 decodetree = generator(find_program('scripts/decodetree.py'),
3066 output: 'decode-@BASENAME@.c.inc',
3067 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3068 subdir('libdecnumber')
3085 if config_host_data.get('CONFIG_REPLICATION')
3086 block_ss.add(files('replication.c'))
3093 blockdev_ss.add(files(
3100 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3101 # os-win32.c does not
3102 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
3103 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
3106 common_ss.add(files('cpus-common.c'))
3110 common_ss.add(capstone)
3111 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
3113 # Work around a gcc bug/misfeature wherein constant propagation looks
3115 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3116 # to guess that a const variable is always zero. Without lto, this is
3117 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
3118 # without lto, not even the alias is required -- we simply use different
3119 # declarations in different compilation units.
3120 pagevary = files('page-vary-common.c')
3121 if get_option('b_lto')
3122 pagevary_flags = ['-fno-lto']
3123 if get_option('cfi')
3124 pagevary_flags += '-fno-sanitize=cfi-icall'
3126 pagevary = static_library('page-vary-common', sources: pagevary + genh,
3127 c_args: pagevary_flags)
3128 pagevary = declare_dependency(link_with: pagevary)
3130 common_ss.add(pagevary)
3131 specific_ss.add(files('page-vary.c'))
3139 subdir('semihosting')
3146 common_user_inc = []
3148 subdir('common-user')
3150 subdir('linux-user')
3152 # needed for fuzzing binaries
3153 subdir('tests/qtest/libqos')
3154 subdir('tests/qtest/fuzz')
3157 tcg_real_module_ss = ss.source_set()
3158 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3159 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3160 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3161 'tcg': tcg_real_module_ss }}
3163 ########################
3164 # Library dependencies #
3165 ########################
3167 modinfo_collect = find_program('scripts/modinfo-collect.py')
3168 modinfo_generate = find_program('scripts/modinfo-generate.py')
3173 foreach d, list : modules
3174 foreach m, module_ss : list
3175 if enable_modules and targetos != 'windows'
3176 module_ss = module_ss.apply(config_all, strict: false)
3177 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3178 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3184 if module_ss.sources() != []
3185 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3186 # input. Sources can be used multiple times but objects are
3187 # unique when it comes to lookup in compile_commands.json.
3188 # Depnds on a mesion version with
3189 # https://github.com/mesonbuild/meson/pull/8900
3190 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3191 output: d + '-' + m + '.modinfo',
3192 input: module_ss.sources() + genh,
3194 command: [modinfo_collect, module_ss.sources()])
3198 block_ss.add_all(module_ss)
3200 softmmu_ss.add_all(module_ss)
3206 foreach d, list : target_modules
3207 foreach m, module_ss : list
3208 if enable_modules and targetos != 'windows'
3209 foreach target : target_dirs
3210 if target.endswith('-softmmu')
3211 config_target = config_target_mak[target]
3212 config_target += config_host
3213 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3214 c_args = ['-DNEED_CPU_H',
3215 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3216 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3217 target_module_ss = module_ss.apply(config_target, strict: false)
3218 if target_module_ss.sources() != []
3219 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3220 sl = static_library(module_name,
3221 [genh, target_module_ss.sources()],
3222 dependencies: [modulecommon, target_module_ss.dependencies()],
3223 include_directories: target_inc,
3227 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3228 modinfo_files += custom_target(module_name + '.modinfo',
3229 output: module_name + '.modinfo',
3230 input: target_module_ss.sources() + genh,
3232 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3237 specific_ss.add_all(module_ss)
3243 foreach target : target_dirs
3244 if target.endswith('-softmmu')
3245 config_target = config_target_mak[target]
3246 config_devices_mak = target + '-config-devices.mak'
3247 modinfo_src = custom_target('modinfo-' + target + '.c',
3248 output: 'modinfo-' + target + '.c',
3249 input: modinfo_files,
3250 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'],
3253 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
3254 modinfo_dep = declare_dependency(link_with: modinfo_lib)
3256 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH']
3257 hw_arch[arch].add(modinfo_dep)
3262 nm = find_program('nm')
3263 undefsym = find_program('scripts/undefsym.py')
3264 block_syms = custom_target('block.syms', output: 'block.syms',
3265 input: [libqemuutil, block_mods],
3267 command: [undefsym, nm, '@INPUT@'])
3268 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3269 input: [libqemuutil, softmmu_mods],
3271 command: [undefsym, nm, '@INPUT@'])
3273 authz_ss = authz_ss.apply(config_host, strict: false)
3274 libauthz = static_library('authz', authz_ss.sources() + genh,
3275 dependencies: [authz_ss.dependencies()],
3277 build_by_default: false)
3279 authz = declare_dependency(link_whole: libauthz,
3282 crypto_ss = crypto_ss.apply(config_host, strict: false)
3283 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3284 dependencies: [crypto_ss.dependencies()],
3286 build_by_default: false)
3288 crypto = declare_dependency(link_whole: libcrypto,
3289 dependencies: [authz, qom])
3291 io_ss = io_ss.apply(config_host, strict: false)
3292 libio = static_library('io', io_ss.sources() + genh,
3293 dependencies: [io_ss.dependencies()],
3294 link_with: libqemuutil,
3296 build_by_default: false)
3298 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3300 libmigration = static_library('migration', sources: migration_files + genh,
3302 build_by_default: false)
3303 migration = declare_dependency(link_with: libmigration,
3304 dependencies: [zlib, qom, io])
3305 softmmu_ss.add(migration)
3307 block_ss = block_ss.apply(config_host, strict: false)
3308 libblock = static_library('block', block_ss.sources() + genh,
3309 dependencies: block_ss.dependencies(),
3310 link_depends: block_syms,
3312 build_by_default: false)
3314 block = declare_dependency(link_whole: [libblock],
3315 link_args: '@block.syms',
3316 dependencies: [crypto, io])
3318 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
3319 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3320 dependencies: blockdev_ss.dependencies(),
3322 build_by_default: false)
3324 blockdev = declare_dependency(link_whole: [libblockdev],
3325 dependencies: [block, event_loop_base])
3327 qmp_ss = qmp_ss.apply(config_host, strict: false)
3328 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3329 dependencies: qmp_ss.dependencies(),
3331 build_by_default: false)
3333 qmp = declare_dependency(link_whole: [libqmp])
3335 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3337 dependencies: chardev_ss.dependencies(),
3338 build_by_default: false)
3340 chardev = declare_dependency(link_whole: libchardev)
3342 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
3343 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3345 build_by_default: false)
3346 hwcore = declare_dependency(link_whole: libhwcore)
3347 common_ss.add(hwcore)
3353 emulator_modules = []
3354 foreach m : block_mods + softmmu_mods
3355 emulator_modules += shared_module(m.name(),
3356 build_by_default: true,
3360 install_dir: qemu_moddir)
3362 if emulator_modules.length() > 0
3363 alias_target('modules', emulator_modules)
3366 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3367 common_ss.add(qom, qemuutil)
3369 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
3370 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3372 common_all = common_ss.apply(config_all, strict: false)
3373 common_all = static_library('common',
3374 build_by_default: false,
3375 sources: common_all.sources() + genh,
3376 include_directories: common_user_inc,
3377 implicit_include_directories: false,
3378 dependencies: common_all.dependencies(),
3381 feature_to_c = find_program('scripts/feature_to_c.sh')
3383 if targetos == 'darwin'
3384 entitlement = find_program('scripts/entitlement.sh')
3388 foreach target : target_dirs
3389 config_target = config_target_mak[target]
3390 target_name = config_target['TARGET_NAME']
3391 target_base_arch = config_target['TARGET_BASE_ARCH']
3392 arch_srcs = [config_target_h[target]]
3394 c_args = ['-DNEED_CPU_H',
3395 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3396 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3397 link_args = emulator_link_args
3399 config_target += config_host
3400 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3401 if targetos == 'linux'
3402 target_inc += include_directories('linux-headers', is_system: true)
3404 if target.endswith('-softmmu')
3405 target_type='system'
3406 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3407 arch_srcs += t.sources()
3408 arch_deps += t.dependencies()
3410 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3411 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3412 arch_srcs += hw.sources()
3413 arch_deps += hw.dependencies()
3415 arch_srcs += config_devices_h[target]
3416 link_args += ['@block.syms', '@qemu.syms']
3418 abi = config_target['TARGET_ABI_DIR']
3420 target_inc += common_user_inc
3421 if target_base_arch in target_user_arch
3422 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3423 arch_srcs += t.sources()
3424 arch_deps += t.dependencies()
3426 if 'CONFIG_LINUX_USER' in config_target
3427 base_dir = 'linux-user'
3429 if 'CONFIG_BSD_USER' in config_target
3430 base_dir = 'bsd-user'
3431 target_inc += include_directories('bsd-user/' / targetos)
3432 target_inc += include_directories('bsd-user/host/' / host_arch)
3433 dir = base_dir / abi
3434 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3436 target_inc += include_directories(
3440 if 'CONFIG_LINUX_USER' in config_target
3441 dir = base_dir / abi
3442 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3443 if config_target.has_key('TARGET_SYSTBL_ABI')
3445 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3446 extra_args : config_target['TARGET_SYSTBL_ABI'])
3451 if 'TARGET_XML_FILES' in config_target
3452 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3453 output: target + '-gdbstub-xml.c',
3454 input: files(config_target['TARGET_XML_FILES'].split()),
3455 command: [feature_to_c, '@INPUT@'],
3457 arch_srcs += gdbstub_xml
3460 t = target_arch[target_base_arch].apply(config_target, strict: false)
3461 arch_srcs += t.sources()
3462 arch_deps += t.dependencies()
3464 target_common = common_ss.apply(config_target, strict: false)
3465 objects = common_all.extract_objects(target_common.sources())
3466 deps = target_common.dependencies()
3468 target_specific = specific_ss.apply(config_target, strict: false)
3469 arch_srcs += target_specific.sources()
3470 arch_deps += target_specific.dependencies()
3472 lib = static_library('qemu-' + target,
3473 sources: arch_srcs + genh,
3474 dependencies: arch_deps,
3476 include_directories: target_inc,
3478 build_by_default: false,
3481 if target.endswith('-softmmu')
3483 'name': 'qemu-system-' + target_name,
3484 'win_subsystem': 'console',
3485 'sources': files('softmmu/main.c'),
3488 if targetos == 'windows' and (sdl.found() or gtk.found())
3490 'name': 'qemu-system-' + target_name + 'w',
3491 'win_subsystem': 'windows',
3492 'sources': files('softmmu/main.c'),
3496 if get_option('fuzzing')
3497 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3499 'name': 'qemu-fuzz-' + target_name,
3500 'win_subsystem': 'console',
3501 'sources': specific_fuzz.sources(),
3502 'dependencies': specific_fuzz.dependencies(),
3507 'name': 'qemu-' + target_name,
3508 'win_subsystem': 'console',
3514 exe_name = exe['name']
3515 if targetos == 'darwin'
3516 exe_name += '-unsigned'
3519 emulator = executable(exe_name, exe['sources'],
3522 dependencies: arch_deps + deps + exe['dependencies'],
3523 objects: lib.extract_all_objects(recursive: true),
3524 link_language: link_language,
3525 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3526 link_args: link_args,
3527 win_subsystem: exe['win_subsystem'])
3529 if targetos == 'darwin'
3530 icon = 'pc-bios/qemu.rsrc'
3531 build_input = [emulator, files(icon)]
3533 get_option('bindir') / exe_name,
3534 meson.current_source_dir() / icon
3536 if 'CONFIG_HVF' in config_target
3537 entitlements = 'accel/hvf/entitlements.plist'
3538 build_input += files(entitlements)
3539 install_input += meson.current_source_dir() / entitlements
3542 emulators += {exe['name'] : custom_target(exe['name'],
3544 output: exe['name'],
3545 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3548 meson.add_install_script(entitlement, '--install',
3549 get_option('bindir') / exe['name'],
3552 emulators += {exe['name']: emulator}
3557 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3558 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3559 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3560 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3562 custom_target(exe['name'] + stp['ext'],
3563 input: trace_events_all,
3564 output: exe['name'] + stp['ext'],
3565 install: stp['install'],
3566 install_dir: get_option('datadir') / 'systemtap/tapset',
3568 tracetool, '--group=all', '--format=' + stp['fmt'],
3569 '--binary=' + stp['bin'],
3570 '--target-name=' + target_name,
3571 '--target-type=' + target_type,
3572 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3573 '@INPUT@', '@OUTPUT@'
3575 depend_files: tracetool_depends)
3581 # Other build targets
3583 if 'CONFIG_PLUGIN' in config_host
3584 install_headers('include/qemu/qemu-plugin.h')
3589 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3590 # when we don't build tools or system
3591 if xkbcommon.found()
3592 # used for the update-keymaps target, so include rules even if !have_tools
3593 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3594 dependencies: [qemuutil, xkbcommon], install: have_tools)
3598 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3599 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3600 qemu_io = executable('qemu-io', files('qemu-io.c'),
3601 dependencies: [block, qemuutil], install: true)
3602 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3603 dependencies: [blockdev, qemuutil, gnutls, selinux],
3606 subdir('storage-daemon')
3607 subdir('contrib/rdmacm-mux')
3608 subdir('contrib/elf2dmp')
3610 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3611 dependencies: qemuutil,
3615 subdir('contrib/vhost-user-blk')
3616 subdir('contrib/vhost-user-gpu')
3617 subdir('contrib/vhost-user-input')
3618 subdir('contrib/vhost-user-scsi')
3621 if targetos == 'linux'
3622 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3623 dependencies: [qemuutil, libcap_ng],
3625 install_dir: get_option('libexecdir'))
3627 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3628 dependencies: [authz, crypto, io, qom, qemuutil,
3629 libcap_ng, mpathpersist],
3634 subdir('contrib/ivshmem-client')
3635 subdir('contrib/ivshmem-server')
3648 if host_machine.system() == 'windows'
3650 find_program('scripts/nsis.py'),
3652 get_option('prefix'),
3653 meson.current_source_dir(),
3656 '-DDISPLAYVERSION=' + meson.project_version(),
3659 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3662 nsis_cmd += '-DCONFIG_GTK=y'
3665 nsis = custom_target('nsis',
3666 output: 'qemu-setup-' + meson.project_version() + '.exe',
3667 input: files('qemu.nsi'),
3668 build_always_stale: true,
3669 command: nsis_cmd + ['@INPUT@'])
3670 alias_target('installer', nsis)
3673 #########################
3674 # Configuration summary #
3675 #########################
3679 summary_info += {'Install prefix': get_option('prefix')}
3680 summary_info += {'BIOS directory': qemu_datadir}
3681 pathsep = targetos == 'windows' ? ';' : ':'
3682 summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))}
3683 summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
3684 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
3685 summary_info += {'module directory': qemu_moddir}
3686 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
3687 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
3688 summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')}
3689 if targetos != 'windows'
3690 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
3691 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')}
3693 summary_info += {'local state directory': 'queried at runtime'}
3695 summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
3696 summary_info += {'Build directory': meson.current_build_dir()}
3697 summary_info += {'Source path': meson.current_source_dir()}
3698 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3699 summary(summary_info, bool_yn: true, section: 'Directories')
3703 summary_info += {'git': config_host['GIT']}
3704 summary_info += {'make': config_host['MAKE']}
3705 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3706 summary_info += {'sphinx-build': sphinx_build}
3707 if config_host.has_key('HAVE_GDB_BIN')
3708 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3710 summary_info += {'iasl': iasl}
3711 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3712 if targetos == 'windows' and have_ga
3713 summary_info += {'wixl': wixl}
3715 if slirp_opt != 'disabled' and have_system
3716 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
3718 summary(summary_info, bool_yn: true, section: 'Host binaries')
3720 # Configurable features
3722 summary_info += {'Documentation': build_docs}
3723 summary_info += {'system-mode emulation': have_system}
3724 summary_info += {'user-mode emulation': have_user}
3725 summary_info += {'block layer': have_block}
3726 summary_info += {'Install blobs': get_option('install_blobs')}
3727 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3728 if config_host.has_key('CONFIG_MODULES')
3729 summary_info += {'alternative module path': get_option('module_upgrades')}
3731 summary_info += {'fuzzing support': get_option('fuzzing')}
3733 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3735 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3736 if 'simple' in get_option('trace_backends')
3737 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3739 summary_info += {'D-Bus display': dbus_display}
3740 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
3741 summary_info += {'vhost-kernel support': have_vhost_kernel}
3742 summary_info += {'vhost-net support': have_vhost_net}
3743 summary_info += {'vhost-user support': have_vhost_user}
3744 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
3745 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3746 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
3747 summary_info += {'build guest agent': have_ga}
3748 summary(summary_info, bool_yn: true, section: 'Configurable features')
3750 # Compilation information
3752 summary_info += {'host CPU': cpu}
3753 summary_info += {'host endianness': build_machine.endian()}
3754 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3755 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3756 if link_language == 'cpp'
3757 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3759 summary_info += {'C++ compiler': false}
3761 if targetos == 'darwin'
3762 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3764 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3765 + ['-O' + get_option('optimization')]
3766 + (get_option('debug') ? ['-g'] : []))}
3767 if link_language == 'cpp'
3768 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3769 + ['-O' + get_option('optimization')]
3770 + (get_option('debug') ? ['-g'] : []))}
3772 if targetos == 'darwin'
3773 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args')
3774 + ['-O' + get_option('optimization')]
3775 + (get_option('debug') ? ['-g'] : []))}
3777 link_args = get_option(link_language + '_link_args')
3778 if link_args.length() > 0
3779 summary_info += {'LDFLAGS': ' '.join(link_args)}
3781 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_cflags)}
3782 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_cxxflags)}
3783 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_objcflags)}
3784 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
3785 summary_info += {'profiler': get_option('profiler')}
3786 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3787 summary_info += {'PIE': get_option('b_pie')}
3788 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3789 summary_info += {'malloc trim support': has_malloc_trim}
3790 summary_info += {'membarrier': have_membarrier}
3791 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
3792 summary_info += {'mutex debugging': get_option('debug_mutex')}
3793 summary_info += {'memory allocator': get_option('malloc')}
3794 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
3795 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
3796 summary_info += {'gprof enabled': get_option('gprof')}
3797 summary_info += {'gcov': get_option('b_coverage')}
3798 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3799 summary_info += {'CFI support': get_option('cfi')}
3800 if get_option('cfi')
3801 summary_info += {'CFI debug support': get_option('cfi_debug')}
3803 summary_info += {'strip binaries': get_option('strip')}
3804 summary_info += {'sparse': sparse}
3805 summary_info += {'mingw32 support': targetos == 'windows'}
3806 summary(summary_info, bool_yn: true, section: 'Compilation')
3808 # snarf the cross-compilation information for tests
3811 foreach target: target_dirs
3812 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3813 if fs.exists(tcg_mak)
3814 config_cross_tcg = keyval.load(tcg_mak)
3815 if 'CC' in config_cross_tcg
3816 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']}
3822 summary(summary_info, bool_yn: true, section: 'Cross compilers')
3825 # Targets and accelerators
3828 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3829 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3830 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3831 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3832 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3833 summary_info += {'Xen support': xen.found()}
3835 summary_info += {'xen ctrl version': xen.version()}
3838 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3839 if config_all.has_key('CONFIG_TCG')
3840 if get_option('tcg_interpreter')
3841 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
3843 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3845 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3846 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3848 summary_info += {'target list': ' '.join(target_dirs)}
3850 summary_info += {'default devices': get_option('default_devices')}
3851 summary_info += {'out of process emulation': multiprocess_allowed}
3852 summary_info += {'vfio-user server': vfio_user_server_allowed}
3854 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3858 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3859 summary_info += {'coroutine pool': have_coroutine_pool}
3861 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
3862 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
3863 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
3864 summary_info += {'VirtFS support': have_virtfs}
3865 summary_info += {'build virtiofs daemon': have_virtiofsd}
3866 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
3867 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
3868 summary_info += {'bochs support': get_option('bochs').allowed()}
3869 summary_info += {'cloop support': get_option('cloop').allowed()}
3870 summary_info += {'dmg support': get_option('dmg').allowed()}
3871 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
3872 summary_info += {'vdi support': get_option('vdi').allowed()}
3873 summary_info += {'vvfat support': get_option('vvfat').allowed()}
3874 summary_info += {'qed support': get_option('qed').allowed()}
3875 summary_info += {'parallels support': get_option('parallels').allowed()}
3876 summary_info += {'FUSE exports': fuse}
3877 summary_info += {'VDUSE block exports': have_vduse_blk_export}
3879 summary(summary_info, bool_yn: true, section: 'Block layer support')
3883 summary_info += {'TLS priority': get_option('tls_priority')}
3884 summary_info += {'GNUTLS support': gnutls}
3886 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3888 summary_info += {'libgcrypt': gcrypt}
3889 summary_info += {'nettle': nettle}
3891 summary_info += {' XTS': xts != 'private'}
3893 summary_info += {'AF_ALG support': have_afalg}
3894 summary_info += {'rng-none': get_option('rng_none')}
3895 summary_info += {'Linux keyring': have_keyring}
3896 summary(summary_info, bool_yn: true, section: 'Crypto')
3900 if targetos == 'darwin'
3901 summary_info += {'Cocoa support': cocoa}
3902 summary_info += {'vmnet.framework support': vmnet}
3904 summary_info += {'SDL support': sdl}
3905 summary_info += {'SDL image support': sdl_image}
3906 summary_info += {'GTK support': gtk}
3907 summary_info += {'pixman': pixman}
3908 summary_info += {'VTE support': vte}
3909 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3910 summary_info += {'libtasn1': tasn1}
3911 summary_info += {'PAM': pam}
3912 summary_info += {'iconv support': iconv}
3913 summary_info += {'curses support': curses}
3914 summary_info += {'virgl support': virgl}
3915 summary_info += {'curl support': curl}
3916 summary_info += {'Multipath support': mpathpersist}
3917 summary_info += {'PNG support': png}
3918 summary_info += {'VNC support': vnc}
3920 summary_info += {'VNC SASL support': sasl}
3921 summary_info += {'VNC JPEG support': jpeg}
3923 if targetos not in ['darwin', 'haiku', 'windows']
3924 summary_info += {'OSS support': oss}
3925 elif targetos == 'darwin'
3926 summary_info += {'CoreAudio support': coreaudio}
3927 elif targetos == 'windows'
3928 summary_info += {'DirectSound support': dsound}
3930 if targetos == 'linux'
3931 summary_info += {'ALSA support': alsa}
3932 summary_info += {'PulseAudio support': pulse}
3934 summary_info += {'JACK support': jack}
3935 summary_info += {'brlapi support': brlapi}
3936 summary_info += {'vde support': vde}
3937 summary_info += {'netmap support': have_netmap}
3938 summary_info += {'l2tpv3 support': have_l2tpv3}
3939 summary_info += {'Linux AIO support': libaio}
3940 summary_info += {'Linux io_uring support': linux_io_uring}
3941 summary_info += {'ATTR/XATTR support': libattr}
3942 summary_info += {'RDMA support': rdma}
3943 summary_info += {'PVRDMA support': have_pvrdma}
3944 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3945 summary_info += {'libcap-ng support': libcap_ng}
3946 summary_info += {'bpf support': libbpf}
3947 summary_info += {'spice protocol support': spice_protocol}
3948 if spice_protocol.found()
3949 summary_info += {' spice server support': spice}
3951 summary_info += {'rbd support': rbd}
3952 summary_info += {'smartcard support': cacard}
3953 summary_info += {'U2F support': u2f}
3954 summary_info += {'libusb': libusb}
3955 summary_info += {'usb net redir': usbredir}
3956 summary_info += {'OpenGL support (epoxy)': opengl}
3957 summary_info += {'GBM': gbm}
3958 summary_info += {'libiscsi support': libiscsi}
3959 summary_info += {'libnfs support': libnfs}
3960 if targetos == 'windows'
3962 summary_info += {'QGA VSS support': have_qga_vss}
3965 summary_info += {'seccomp support': seccomp}
3966 summary_info += {'GlusterFS support': glusterfs}
3967 summary_info += {'TPM support': have_tpm}
3968 summary_info += {'libssh support': libssh}
3969 summary_info += {'lzo support': lzo}
3970 summary_info += {'snappy support': snappy}
3971 summary_info += {'bzip2 support': libbzip2}
3972 summary_info += {'lzfse support': liblzfse}
3973 summary_info += {'zstd support': zstd}
3974 summary_info += {'NUMA host support': numa}
3975 summary_info += {'capstone': capstone}
3976 summary_info += {'libpmem support': libpmem}
3977 summary_info += {'libdaxctl support': libdaxctl}
3978 summary_info += {'libudev': libudev}
3979 # Dummy dependency, keep .found()
3980 summary_info += {'FUSE lseek': fuse_lseek.found()}
3981 summary_info += {'selinux': selinux}
3982 summary(summary_info, bool_yn: true, section: 'Dependencies')
3984 if not supported_cpus.contains(cpu)
3986 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3988 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3989 message('The QEMU project intends to remove support for this host CPU in')
3990 message('a future release if nobody volunteers to maintain it and to')
3991 message('provide a build host for our continuous integration setup.')
3992 message('configure has succeeded and you can continue to build, but')
3993 message('if you care about QEMU on this platform you should contact')
3994 message('us upstream at qemu-devel@nongnu.org.')
3997 if not supported_oses.contains(targetos)
3999 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
4001 message('Host OS ' + targetos + 'support is not currently maintained.')
4002 message('The QEMU project intends to remove support for this host OS in')
4003 message('a future release if nobody volunteers to maintain it and to')
4004 message('provide a build host for our continuous integration setup.')
4005 message('configure has succeeded and you can continue to build, but')
4006 message('if you care about QEMU on this platform you should contact')
4007 message('us upstream at qemu-devel@nongnu.org.')