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 not_found = dependency('', required: false)
11 keyval = import('keyval')
12 ss = import('sourceset')
15 sh = find_program('sh')
16 cc = meson.get_compiler('c')
17 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
18 enable_modules = 'CONFIG_MODULES' in config_host
19 enable_static = 'CONFIG_STATIC' in config_host
21 # Allow both shared and static libraries unless --enable-static
22 static_kwargs = enable_static ? {'static': true} : {}
24 # Temporary directory used for files created while
25 # configure runs. Since it is in the build directory
26 # we can safely blow away any previous version of it
27 # (and we need not jump through hoops to try to delete
28 # it when configure exits.)
29 tmpdir = meson.current_build_dir() / 'meson-private/temp'
31 if get_option('qemu_suffix').startswith('/')
32 error('qemu_suffix cannot start with a /')
35 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
36 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
37 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
38 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
40 qemu_desktopdir = get_option('datadir') / 'applications'
41 qemu_icondir = get_option('datadir') / 'icons'
43 config_host_data = configuration_data()
45 qapi_trace_events = []
47 bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
48 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
49 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
50 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc', 'sparc64']
52 cpu = host_machine.cpu_family()
54 # Unify riscv* to a single family.
55 if cpu in ['riscv32', 'riscv64']
59 targetos = host_machine.system()
61 target_dirs = config_host['TARGET_DIRS'].split()
62 have_linux_user = false
65 foreach target : target_dirs
66 have_linux_user = have_linux_user or target.endswith('linux-user')
67 have_bsd_user = have_bsd_user or target.endswith('bsd-user')
68 have_system = have_system or target.endswith('-softmmu')
70 have_user = have_linux_user or have_bsd_user
71 have_tools = get_option('tools') \
72 .disable_auto_if(not have_system) \
74 have_ga = get_option('guest_agent') \
75 .disable_auto_if(not have_system and not have_tools) \
76 .require(targetos in ['sunos', 'linux', 'windows'],
77 error_message: 'unsupported OS for QEMU guest agent') \
79 have_block = have_system or have_tools
81 python = import('python').find_installation()
83 if cpu not in supported_cpus
93 if cpu in ['x86', 'x86_64']
94 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
96 kvm_targets = ['aarch64-softmmu']
98 kvm_targets = ['s390x-softmmu']
99 elif cpu in ['ppc', 'ppc64']
100 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
101 elif cpu in ['mips', 'mips64']
102 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
103 elif cpu in ['riscv']
104 kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
110 if get_option('kvm').allowed() and targetos == 'linux'
111 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
113 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
115 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
117 if cpu in ['aarch64']
118 accelerator_targets += {
119 'CONFIG_HVF': ['aarch64-softmmu']
123 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
124 # i386 emulator provides xenpv machine type for multiple architectures
125 accelerator_targets += {
126 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
129 if cpu in ['x86', 'x86_64']
130 accelerator_targets += {
131 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
132 'CONFIG_HVF': ['x86_64-softmmu'],
133 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
134 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
139 # Darwin does not support references to thread-local variables in modules
140 if targetos != 'darwin'
141 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
144 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
145 unpack_edk2_blobs = false
146 foreach target : edk2_targets
147 if target in target_dirs
148 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
149 unpack_edk2_blobs = bzip2.found()
156 if 'dtrace' in get_option('trace_backends')
157 dtrace = find_program('dtrace', required: true)
158 stap = find_program('stap', required: false)
160 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
161 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
162 # instead. QEMU --enable-modules depends on this because the SystemTap
163 # semaphores are linked into the main binary and not the module's shared
165 add_global_arguments('-DSTAP_SDT_V2',
166 native: false, language: ['c', 'cpp', 'objc'])
170 if get_option('iasl') == ''
171 iasl = find_program('iasl', required: false)
173 iasl = find_program(get_option('iasl'), required: true)
180 qemu_cflags = config_host['QEMU_CFLAGS'].split()
181 qemu_cxxflags = config_host['QEMU_CXXFLAGS'].split()
182 qemu_objcflags = config_host['QEMU_OBJCFLAGS'].split()
183 qemu_ldflags = config_host['QEMU_LDFLAGS'].split()
185 if targetos == 'windows'
186 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat')
187 # Disable ASLR for debug builds to allow debugging with gdb
188 if get_option('optimization') == '0'
189 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase')
193 if get_option('gprof')
194 qemu_cflags += ['-p']
195 qemu_cxxflags += ['-p']
196 qemu_objcflags += ['-p']
197 qemu_ldflags += ['-p']
200 # Specify linker-script with add_project_link_arguments so that it is not placed
201 # within a linker --start-group/--end-group pair
202 if get_option('fuzzing')
203 add_project_link_arguments(['-Wl,-T,',
204 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
205 native: false, language: ['c', 'cpp', 'objc'])
207 # Specify a filter to only instrument code that is directly related to
209 configure_file(output: 'instrumentation-filter',
210 input: 'scripts/oss-fuzz/instrumentation-filter-template',
213 if cc.compiles('int main () { return 0; }',
214 name: '-fsanitize-coverage-allowlist=/dev/null',
215 args: ['-fsanitize-coverage-allowlist=/dev/null'] )
216 add_global_arguments('-fsanitize-coverage-allowlist=instrumentation-filter',
217 native: false, language: ['c', 'cpp', 'objc'])
220 if get_option('fuzzing_engine') == ''
221 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
222 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
223 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
224 # unable to bind the fuzzer-related callbacks added by instrumentation.
225 add_global_arguments('-fsanitize=fuzzer-no-link',
226 native: false, language: ['c', 'cpp', 'objc'])
227 add_global_link_arguments('-fsanitize=fuzzer-no-link',
228 native: false, language: ['c', 'cpp', 'objc'])
229 # For the actual fuzzer binaries, we need to link against the libfuzzer
230 # library. They need to be configurable, to support OSS-Fuzz
231 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
233 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
234 # the needed CFLAGS have already been provided
235 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
239 add_global_arguments(qemu_cflags, native: false, language: ['c'])
240 add_global_arguments(qemu_cxxflags, native: false, language: ['cpp'])
241 add_global_arguments(qemu_objcflags, native: false, language: ['objc'])
242 add_global_link_arguments(qemu_ldflags, native: false, language: ['c', 'cpp', 'objc'])
244 if targetos == 'linux'
245 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
246 '-isystem', 'linux-headers',
247 language: ['c', 'cpp'])
250 add_project_arguments('-iquote', '.',
251 '-iquote', meson.current_source_dir(),
252 '-iquote', meson.current_source_dir() / 'include',
253 language: ['c', 'cpp', 'objc'])
255 link_language = meson.get_external_property('link_language', 'cpp')
256 if link_language == 'cpp'
257 add_languages('cpp', required: true, native: false)
258 cxx = meson.get_compiler('cpp')
263 if host_machine.system() == 'darwin'
264 add_languages('objc', required: false, native: false)
267 sparse = find_program('cgcc', required: get_option('sparse'))
270 command: [find_program('scripts/check_sparse.py'),
271 'compile_commands.json', sparse.full_path(), '-Wbitwise',
272 '-Wno-transparent-union', '-Wno-old-initializer',
273 '-Wno-non-pointer-null'])
276 ###########################################
277 # Target-specific checks and dependencies #
278 ###########################################
281 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
284 #include <sys/types.h>
285 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
286 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
288 args: ['-Werror', '-fsanitize=fuzzer'])
289 error('Your compiler does not support -fsanitize=fuzzer')
293 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
294 error('ftrace is supported only on Linux')
296 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
299 openlog("qemu", LOG_PID, LOG_DAEMON);
300 syslog(LOG_INFO, "configure");
303 error('syslog is not supported on this system')
306 # Miscellaneous Linux-only features
307 get_option('mpath') \
308 .require(targetos == 'linux', error_message: 'Multipath is supported only on Linux')
310 multiprocess_allowed = get_option('multiprocess') \
311 .require(targetos == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
314 vfio_user_server_allowed = get_option('vfio_user_server') \
315 .require(targetos == 'linux', error_message: 'vfio-user server is supported only on Linux') \
318 have_tpm = get_option('tpm') \
319 .require(targetos != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
323 have_vhost_user = get_option('vhost_user') \
324 .disable_auto_if(targetos != 'linux') \
325 .require(targetos != 'windows',
326 error_message: 'vhost-user is not available on Windows').allowed()
327 have_vhost_vdpa = get_option('vhost_vdpa') \
328 .require(targetos == 'linux',
329 error_message: 'vhost-vdpa is only available on Linux').allowed()
330 have_vhost_kernel = get_option('vhost_kernel') \
331 .require(targetos == 'linux',
332 error_message: 'vhost-kernel is only available on Linux').allowed()
333 have_vhost_user_crypto = get_option('vhost_crypto') \
334 .require(have_vhost_user,
335 error_message: 'vhost-crypto requires vhost-user to be enabled').allowed()
337 have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel
339 have_vhost_net_user = have_vhost_user and get_option('vhost_net').allowed()
340 have_vhost_net_vdpa = have_vhost_vdpa and get_option('vhost_net').allowed()
341 have_vhost_net_kernel = have_vhost_kernel and get_option('vhost_net').allowed()
342 have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_vdpa
344 # Target-specific libraries and flags
345 libm = cc.find_library('m', required: false)
346 threads = dependency('threads')
347 util = cc.find_library('util', required: false)
353 emulator_link_args = []
359 if targetos == 'windows'
360 midl = find_program('midl', required: false)
361 widl = find_program('widl', required: false)
362 socket = cc.find_library('ws2_32')
363 winmm = cc.find_library('winmm')
365 win = import('windows')
366 version_res = win.compile_resources('version.rc',
367 depend_files: files('pc-bios/qemu-nsis.ico'),
368 include_directories: include_directories('.'))
370 elif targetos == 'darwin'
371 coref = dependency('appleframeworks', modules: 'CoreFoundation')
372 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
373 host_dsosuf = '.dylib'
374 elif targetos == 'sunos'
375 socket = [cc.find_library('socket'),
376 cc.find_library('nsl'),
377 cc.find_library('resolv')]
378 elif targetos == 'haiku'
379 socket = [cc.find_library('posix_error_mapper'),
380 cc.find_library('network'),
381 cc.find_library('bsd')]
382 elif targetos == 'openbsd'
383 if get_option('tcg').allowed() and target_dirs.length() > 0
384 # Disable OpenBSD W^X if available
385 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
389 # Target-specific configuration of accelerators
391 if get_option('kvm').allowed() and targetos == 'linux'
392 accelerators += 'CONFIG_KVM'
394 if get_option('whpx').allowed() and targetos == 'windows'
395 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
396 error('WHPX requires 64-bit host')
397 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
398 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
399 accelerators += 'CONFIG_WHPX'
402 if get_option('hvf').allowed()
403 hvf = dependency('appleframeworks', modules: 'Hypervisor',
404 required: get_option('hvf'))
406 accelerators += 'CONFIG_HVF'
409 if get_option('hax').allowed()
410 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
411 accelerators += 'CONFIG_HAX'
414 if targetos == 'netbsd'
415 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
417 accelerators += 'CONFIG_NVMM'
422 if get_option('tcg').allowed()
423 if host_arch == 'unknown'
424 if get_option('tcg_interpreter')
425 warning('Unsupported CPU @0@, will use TCG with TCI (slow)'.format(cpu))
427 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
429 elif get_option('tcg_interpreter')
430 warning('Use of the TCG interpreter is not recommended on this host')
431 warning('architecture. There is a native TCG execution backend available')
432 warning('which provides substantially better performance and reliability.')
433 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
434 warning('configuration option on this architecture to use the native')
437 if get_option('tcg_interpreter')
439 elif host_arch == 'sparc64'
441 elif host_arch == 'x86_64'
443 elif host_arch == 'ppc64'
446 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
447 language: ['c', 'cpp', 'objc'])
449 accelerators += 'CONFIG_TCG'
450 config_host += { 'CONFIG_TCG': 'y' }
453 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
454 error('KVM not available on this platform')
456 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
457 error('HVF not available on this platform')
459 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
460 error('NVMM not available on this platform')
462 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
463 error('WHPX not available on this platform')
470 # The path to glib.h is added to all compilation commands. This was
471 # grandfathered in from the QEMU Makefiles.
472 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
473 native: false, language: ['c', 'cpp', 'objc'])
474 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
475 link_args: config_host['GLIB_LIBS'].split(),
476 version: config_host['GLIB_VERSION'],
478 'bindir': config_host['GLIB_BINDIR'],
480 # override glib dep with the configure results (for subprojects)
481 meson.override_dependency('glib-2.0', glib)
484 gdbus_codegen = not_found
485 if not get_option('gio').auto() or have_system
486 gio = dependency('gio-2.0', required: get_option('gio'),
487 method: 'pkg-config', kwargs: static_kwargs)
488 if gio.found() and not cc.links('''
492 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
494 }''', dependencies: [glib, gio])
495 if get_option('gio').enabled()
496 error('The installed libgio is broken for static linking')
501 gdbus_codegen = find_program(gio.get_variable('gdbus_codegen'),
502 required: get_option('gio'))
503 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
504 method: 'pkg-config', kwargs: static_kwargs)
505 gio = declare_dependency(dependencies: [gio, gio_unix],
506 version: gio.version())
511 if 'ust' in get_option('trace_backends')
512 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
513 method: 'pkg-config', kwargs: static_kwargs)
516 if have_system or have_tools
517 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
518 method: 'pkg-config', kwargs: static_kwargs)
520 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
523 if not get_option('linux_aio').auto() or have_block
524 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
525 required: get_option('linux_aio'),
526 kwargs: static_kwargs)
529 linux_io_uring_test = '''
530 #include <liburing.h>
531 #include <linux/errqueue.h>
533 int main(void) { return 0; }'''
535 linux_io_uring = not_found
536 if not get_option('linux_io_uring').auto() or have_block
537 linux_io_uring = dependency('liburing', version: '>=0.3',
538 required: get_option('linux_io_uring'),
539 method: 'pkg-config', kwargs: static_kwargs)
540 if not cc.links(linux_io_uring_test)
541 linux_io_uring = not_found
546 if not get_option('libnfs').auto() or have_block
547 libnfs = dependency('libnfs', version: '>=1.9.3',
548 required: get_option('libnfs'),
549 method: 'pkg-config', kwargs: static_kwargs)
554 #include <sys/types.h>
555 #ifdef CONFIG_LIBATTR
556 #include <attr/xattr.h>
558 #include <sys/xattr.h>
560 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
563 have_old_libattr = false
564 if get_option('attr').allowed()
565 if cc.links(libattr_test)
566 libattr = declare_dependency()
568 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
569 required: get_option('attr'),
570 kwargs: static_kwargs)
571 if libattr.found() and not \
572 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
574 if get_option('attr').enabled()
575 error('could not link libattr')
577 warning('could not link libattr, disabling')
580 have_old_libattr = libattr.found()
585 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
586 if cocoa.found() and get_option('sdl').enabled()
587 error('Cocoa and SDL cannot be enabled at the same time')
589 if cocoa.found() and get_option('gtk').enabled()
590 error('Cocoa and GTK+ cannot be enabled at the same time')
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 and not cocoa.found())
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 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 and not cocoa.found())
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') \
1676 have_virtfs = get_option('virtfs') \
1677 .require(targetos == 'linux' or targetos == 'darwin',
1678 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
1679 .require(targetos == 'linux' or cc.has_function('pthread_fchdir_np'),
1680 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
1681 .require(targetos == 'darwin' or (libattr.found() and libcap_ng.found()),
1682 error_message: 'virtio-9p (virtfs) on Linux requires libcap-ng-devel and libattr-devel') \
1683 .disable_auto_if(not have_tools and not have_system) \
1686 have_virtfs_proxy_helper = targetos != 'darwin' and have_virtfs and have_tools
1688 if get_option('block_drv_ro_whitelist') == ''
1689 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
1691 config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
1692 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
1694 if get_option('block_drv_rw_whitelist') == ''
1695 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
1697 config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
1698 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
1701 foreach k : get_option('trace_backends')
1702 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1704 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1705 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
1707 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
1709 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1710 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1711 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1712 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1713 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1714 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('prefix') / get_option('qemu_firmwarepath'))
1715 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1716 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1717 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1718 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1719 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1720 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1722 if config_host.has_key('CONFIG_MODULES')
1723 config_host_data.set('CONFIG_STAMP', run_command(
1724 meson.current_source_dir() / 'scripts/qemu-stamp.py',
1725 meson.project_version(), get_option('pkgversion'), '--',
1726 meson.current_source_dir() / 'configure',
1727 capture: true, check: true).stdout().strip())
1730 have_slirp_smbd = get_option('slirp_smbd') \
1731 .require(targetos != 'windows', error_message: 'Host smbd not supported on this platform.') \
1734 smbd_path = get_option('smbd')
1736 smbd_path = (targetos == 'solaris' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
1738 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
1741 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
1743 if get_option('module_upgrades') and not enable_modules
1744 error('Cannot enable module-upgrades as modules are not enabled')
1746 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
1748 config_host_data.set('CONFIG_ATTR', libattr.found())
1749 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
1750 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1751 config_host_data.set('CONFIG_COCOA', cocoa.found())
1752 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1753 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1754 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1755 config_host_data.set('CONFIG_LZO', lzo.found())
1756 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1757 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1758 config_host_data.set('CONFIG_CURL', curl.found())
1759 config_host_data.set('CONFIG_CURSES', curses.found())
1760 config_host_data.set('CONFIG_GBM', gbm.found())
1761 config_host_data.set('CONFIG_GIO', gio.found())
1762 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1763 if glusterfs.found()
1764 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1765 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1766 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1767 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1768 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1769 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1771 config_host_data.set('CONFIG_GTK', gtk.found())
1772 config_host_data.set('CONFIG_VTE', vte.found())
1773 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1774 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1775 config_host_data.set('CONFIG_EBPF', libbpf.found())
1776 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1777 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1778 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1779 config_host_data.set('CONFIG_LIBSSH', libssh.found())
1780 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1781 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1782 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))
1783 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1784 config_host_data.set('CONFIG_NUMA', numa.found())
1785 config_host_data.set('CONFIG_OPENGL', opengl.found())
1786 config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
1787 config_host_data.set('CONFIG_RBD', rbd.found())
1788 config_host_data.set('CONFIG_RDMA', rdma.found())
1789 config_host_data.set('CONFIG_SDL', sdl.found())
1790 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1791 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1792 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1793 config_host_data.set('CONFIG_TPM', have_tpm)
1794 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1795 config_host_data.set('CONFIG_VDE', vde.found())
1796 config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
1797 config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
1798 config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)
1799 config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
1800 config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
1801 config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
1802 config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
1803 config_host_data.set('CONFIG_VMNET', vmnet.found())
1804 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1805 config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export)
1806 config_host_data.set('CONFIG_PNG', png.found())
1807 config_host_data.set('CONFIG_VNC', vnc.found())
1808 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1809 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1810 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1811 config_host_data.set('CONFIG_VTE', vte.found())
1812 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1813 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1814 config_host_data.set('CONFIG_GETTID', has_gettid)
1815 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1816 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1817 config_host_data.set('CONFIG_TASN1', tasn1.found())
1818 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1819 config_host_data.set('CONFIG_NETTLE', nettle.found())
1820 config_host_data.set('CONFIG_HOGWEED', hogweed.found())
1821 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1822 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1823 config_host_data.set('CONFIG_STATX', has_statx)
1824 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
1825 config_host_data.set('CONFIG_ZSTD', zstd.found())
1826 config_host_data.set('CONFIG_FUSE', fuse.found())
1827 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1828 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1829 if spice_protocol.found()
1830 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
1831 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
1832 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
1834 config_host_data.set('CONFIG_SPICE', spice.found())
1835 config_host_data.set('CONFIG_X11', x11.found())
1836 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
1837 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1838 config_host_data.set('CONFIG_SELINUX', selinux.found())
1839 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
1841 # protect from xen.version() having less than three components
1842 xen_version = xen.version().split('.') + ['0', '0']
1843 xen_ctrl_version = xen_version[0] + \
1844 ('0' + xen_version[1]).substring(-2) + \
1845 ('0' + xen_version[2]).substring(-2)
1846 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
1848 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1849 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1850 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1851 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1853 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1854 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1856 have_coroutine_pool = get_option('coroutine_pool')
1857 if get_option('debug_stack_usage') and have_coroutine_pool
1858 message('Disabling coroutine pool to measure stack usage')
1859 have_coroutine_pool = false
1861 config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool)
1862 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
1863 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
1864 config_host_data.set('CONFIG_GPROF', get_option('gprof'))
1865 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
1866 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
1867 config_host_data.set('CONFIG_REPLICATION', get_option('live_block_migration').allowed())
1870 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1871 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1872 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1873 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1874 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1875 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1876 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1877 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1878 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1881 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1882 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1883 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1884 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1885 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1886 # Note that we need to specify prefix: here to avoid incorrectly
1887 # thinking that Windows has posix_memalign()
1888 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
1889 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
1890 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
1891 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
1892 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1893 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1894 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
1895 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1896 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1897 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1898 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1899 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1900 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1901 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
1902 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1903 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1904 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1906 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
1907 cc.has_function('rbd_namespace_exists',
1909 prefix: '#include <rbd/librbd.h>'))
1912 config_host_data.set('HAVE_IBV_ADVISE_MR',
1913 cc.has_function('ibv_advise_mr',
1915 prefix: '#include <infiniband/verbs.h>'))
1919 config_host_data.set('CONFIG_BYTESWAP_H',
1920 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1921 config_host_data.set('CONFIG_EPOLL_CREATE1',
1922 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1923 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1924 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1925 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1926 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1927 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1928 config_host_data.set('CONFIG_FIEMAP',
1929 cc.has_header('linux/fiemap.h') and
1930 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1931 config_host_data.set('CONFIG_GETRANDOM',
1932 cc.has_function('getrandom') and
1933 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1934 config_host_data.set('CONFIG_INOTIFY',
1935 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1936 config_host_data.set('CONFIG_INOTIFY1',
1937 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1938 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1939 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1940 prefix: '''#include <sys/endian.h>
1941 #include <sys/types.h>'''))
1942 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1943 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1944 config_host_data.set('CONFIG_RTNETLINK',
1945 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1946 config_host_data.set('CONFIG_SYSMACROS',
1947 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1948 config_host_data.set('HAVE_OPTRESET',
1949 cc.has_header_symbol('getopt.h', 'optreset'))
1950 config_host_data.set('HAVE_IPPROTO_MPTCP',
1951 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1954 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1955 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1956 prefix: '#include <signal.h>'))
1957 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1958 cc.has_member('struct stat', 'st_atim',
1959 prefix: '#include <sys/stat.h>'))
1962 config_host_data.set('CONFIG_IOVEC',
1963 cc.has_type('struct iovec',
1964 prefix: '#include <sys/uio.h>'))
1965 config_host_data.set('HAVE_UTMPX',
1966 cc.has_type('struct utmpx',
1967 prefix: '#include <utmpx.h>'))
1969 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1970 #include <sys/eventfd.h>
1971 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1972 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1975 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1976 return fdatasync(0);
1978 #error Not supported
1982 has_madvise = cc.links(gnu_source_prefix + '''
1983 #include <sys/types.h>
1984 #include <sys/mman.h>
1986 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
1987 missing_madvise_proto = false
1989 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
1990 # but forget to prototype it. In this case, has_madvise will be true (the
1991 # test program links despite a compile warning). To detect the
1992 # missing-prototype case, we try again with a definitely-bogus prototype.
1993 # This will only compile if the system headers don't provide the prototype;
1994 # otherwise the conflicting prototypes will cause a compiler error.
1995 missing_madvise_proto = cc.links(gnu_source_prefix + '''
1996 #include <sys/types.h>
1997 #include <sys/mman.h>
1999 extern int madvise(int);
2000 int main(void) { return madvise(0); }''')
2002 config_host_data.set('CONFIG_MADVISE', has_madvise)
2003 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
2005 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
2006 #include <sys/mman.h>
2007 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
2008 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
2010 #if !defined(AT_EMPTY_PATH)
2011 # error missing definition
2013 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
2015 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
2022 return pipe2(pipefd, O_CLOEXEC);
2024 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
2025 #include <sys/mman.h>
2027 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
2029 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
2030 #include <pthread.h>
2032 static void *f(void *p) { return NULL; }
2036 pthread_create(&thread, 0, f, 0);
2037 pthread_setname_np(thread, "QEMU");
2039 }''', dependencies: threads))
2040 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
2041 #include <pthread.h>
2043 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
2047 pthread_create(&thread, 0, f, 0);
2049 }''', dependencies: threads))
2050 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
2051 #include <pthread.h>
2056 pthread_condattr_t attr
2057 pthread_condattr_init(&attr);
2058 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
2060 }''', dependencies: threads))
2062 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
2063 #include <sys/signalfd.h>
2065 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
2066 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
2074 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
2075 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
2079 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
2080 #include <sys/mman.h>
2081 int main(int argc, char *argv[]) {
2082 return mlockall(MCL_FUTURE);
2086 if get_option('l2tpv3').allowed() and have_system
2087 have_l2tpv3 = cc.has_type('struct mmsghdr',
2088 prefix: gnu_source_prefix + '''
2089 #include <sys/socket.h>
2090 #include <linux/ip.h>''')
2092 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2095 if get_option('netmap').allowed() and have_system
2096 have_netmap = cc.compiles('''
2097 #include <inttypes.h>
2099 #include <net/netmap.h>
2100 #include <net/netmap_user.h>
2101 #if (NETMAP_API < 11) || (NETMAP_API > 15)
2104 int main(void) { return 0; }''')
2105 if not have_netmap and get_option('netmap').enabled()
2106 error('Netmap headers not available')
2109 config_host_data.set('CONFIG_NETMAP', have_netmap)
2111 # Work around a system header bug with some kernel/XFS header
2112 # versions where they both try to define 'struct fsxattr':
2113 # xfs headers will not try to redefine structs from linux headers
2114 # if this macro is set.
2115 config_host_data.set('HAVE_FSXATTR', cc.links('''
2116 #include <linux/fs.h>
2122 # Some versions of Mac OS X incorrectly define SIZE_MAX
2123 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2126 int main(int argc, char *argv[]) {
2127 return printf("%zu", SIZE_MAX);
2128 }''', args: ['-Werror']))
2135 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2136 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2137 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2138 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2139 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2143 # See if 64-bit atomic operations are supported.
2144 # Note that without __atomic builtins, we can only
2145 # assume atomic loads/stores max at pointer size.
2146 config_host_data.set('CONFIG_ATOMIC64', cc.links(atomic_test.format('uint64_t')))
2148 has_int128 = cc.links('''
2158 config_host_data.set('CONFIG_INT128', has_int128)
2161 # "do we have 128-bit atomics which are handled inline and specifically not
2162 # via libatomic". The reason we can't use libatomic is documented in the
2163 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2164 has_atomic128 = cc.links(atomic_test.format('unsigned __int128'))
2166 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2168 if not has_atomic128
2169 has_cmpxchg128 = cc.links('''
2172 unsigned __int128 x = 0, y = 0;
2173 __sync_val_compare_and_swap_16(&x, y, x);
2178 config_host_data.set('CONFIG_CMPXCHG128', has_cmpxchg128)
2182 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2183 #include <sys/auxv.h>
2185 return getauxval(AT_HWCAP) == 0;
2188 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2189 #include <linux/usbdevice_fs.h>
2191 #ifndef USBDEVFS_GET_CAPABILITIES
2192 #error "USBDEVFS_GET_CAPABILITIES undefined"
2195 #ifndef USBDEVFS_DISCONNECT_CLAIM
2196 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2199 int main(void) { return 0; }'''))
2201 have_keyring = get_option('keyring') \
2202 .require(targetos == 'linux', error_message: 'keyring is only available on Linux') \
2203 .require(cc.compiles('''
2205 #include <asm/unistd.h>
2206 #include <linux/keyctl.h>
2207 #include <sys/syscall.h>
2210 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2211 }'''), error_message: 'keyctl syscall not available on this system').allowed()
2212 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2214 have_cpuid_h = cc.links('''
2217 unsigned a, b, c, d;
2218 unsigned max = __get_cpuid_max(0, 0);
2221 __cpuid(1, a, b, c, d);
2225 __cpuid_count(7, 0, a, b, c, d);
2230 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2232 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2233 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2234 .require(cc.links('''
2235 #pragma GCC push_options
2236 #pragma GCC target("avx2")
2238 #include <immintrin.h>
2239 static int bar(void *a) {
2240 __m256i x = *(__m256i *)a;
2241 return _mm256_testz_si256(x, x);
2243 int main(int argc, char *argv[]) { return bar(argv[0]); }
2244 '''), error_message: 'AVX2 not available').allowed())
2246 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2247 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2248 .require(cc.links('''
2249 #pragma GCC push_options
2250 #pragma GCC target("avx512f")
2252 #include <immintrin.h>
2253 static int bar(void *a) {
2254 __m512i x = *(__m512i *)a;
2255 return _mm512_test_epi64_mask(x, x);
2257 int main(int argc, char *argv[]) { return bar(argv[0]); }
2258 '''), error_message: 'AVX512F not available').allowed())
2260 have_pvrdma = get_option('pvrdma') \
2261 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
2262 .require(cc.compiles(gnu_source_prefix + '''
2263 #include <sys/mman.h>
2268 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2271 }'''), error_message: 'PVRDMA requires mremap').allowed()
2274 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.links('''
2275 #include <infiniband/verbs.h>
2279 struct ibv_pd *pd = NULL;
2285 mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2291 if get_option('membarrier').disabled()
2292 have_membarrier = false
2293 elif targetos == 'windows'
2294 have_membarrier = true
2295 elif targetos == 'linux'
2296 have_membarrier = cc.compiles('''
2297 #include <linux/membarrier.h>
2298 #include <sys/syscall.h>
2302 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2303 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2307 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2308 .require(have_membarrier, error_message: 'membarrier system call not available') \
2311 have_afalg = get_option('crypto_afalg') \
2312 .require(cc.compiles(gnu_source_prefix + '''
2314 #include <sys/types.h>
2315 #include <sys/socket.h>
2316 #include <linux/if_alg.h>
2319 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2322 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2323 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2325 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2326 'linux/vm_sockets.h', 'AF_VSOCK',
2327 prefix: '#include <sys/socket.h>',
2331 have_vss_sdk = false # old xp/2003 SDK
2332 if targetos == 'windows' and link_language == 'cpp'
2333 have_vss = cxx.compiles('''
2334 #define __MIDL_user_allocate_free_DEFINED__
2336 int main(void) { return VSS_CTX_BACKUP; }''')
2337 have_vss_sdk = cxx.has_header('vscoordint.h')
2339 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2341 foreach k, v: config_host
2342 if k.startswith('CONFIG_')
2343 config_host_data.set(k, v == 'y' ? 1 : v)
2347 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2348 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2349 if targetos == 'windows'
2350 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2356 }''', name: '_lock_file and _unlock_file'))
2359 ########################
2360 # Target configuration #
2361 ########################
2363 minikconf = find_program('scripts/minikconf.py')
2365 config_all_devices = {}
2366 config_all_disas = {}
2367 config_devices_mak_list = []
2368 config_devices_h = {}
2369 config_target_h = {}
2370 config_target_mak = {}
2373 'alpha' : ['CONFIG_ALPHA_DIS'],
2374 'avr' : ['CONFIG_AVR_DIS'],
2375 'cris' : ['CONFIG_CRIS_DIS'],
2376 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2377 'hppa' : ['CONFIG_HPPA_DIS'],
2378 'i386' : ['CONFIG_I386_DIS'],
2379 'x86_64' : ['CONFIG_I386_DIS'],
2380 'm68k' : ['CONFIG_M68K_DIS'],
2381 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2382 'mips' : ['CONFIG_MIPS_DIS'],
2383 'nios2' : ['CONFIG_NIOS2_DIS'],
2384 'or1k' : ['CONFIG_OPENRISC_DIS'],
2385 'ppc' : ['CONFIG_PPC_DIS'],
2386 'riscv' : ['CONFIG_RISCV_DIS'],
2387 'rx' : ['CONFIG_RX_DIS'],
2388 's390' : ['CONFIG_S390_DIS'],
2389 'sh4' : ['CONFIG_SH4_DIS'],
2390 'sparc' : ['CONFIG_SPARC_DIS'],
2391 'xtensa' : ['CONFIG_XTENSA_DIS'],
2392 'loongarch' : ['CONFIG_LOONGARCH_DIS'],
2394 if link_language == 'cpp'
2396 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
2400 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2402 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2403 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2404 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2405 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2406 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2407 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2408 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
2409 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2410 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2411 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2412 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
2413 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
2414 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
2415 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : [])
2417 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2419 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2420 actual_target_dirs = []
2422 foreach target : target_dirs
2423 config_target = { 'TARGET_NAME': target.split('-')[0] }
2424 if target.endswith('linux-user')
2425 if targetos != 'linux'
2429 error('Target @0@ is only available on a Linux host'.format(target))
2431 config_target += { 'CONFIG_LINUX_USER': 'y' }
2432 elif target.endswith('bsd-user')
2433 if 'CONFIG_BSD' not in config_host
2437 error('Target @0@ is only available on a BSD host'.format(target))
2439 config_target += { 'CONFIG_BSD_USER': 'y' }
2440 elif target.endswith('softmmu')
2441 config_target += { 'CONFIG_SOFTMMU': 'y' }
2443 if target.endswith('-user')
2445 'CONFIG_USER_ONLY': 'y',
2446 'CONFIG_QEMU_INTERP_PREFIX':
2447 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
2452 foreach sym: accelerators
2453 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2454 config_target += { sym: 'y' }
2455 config_all += { sym: 'y' }
2456 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
2457 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
2459 if target in modular_tcg
2460 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2462 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2464 accel_kconfig += [ sym + '=y' ]
2467 if accel_kconfig.length() == 0
2471 error('No accelerator available for target @0@'.format(target))
2474 actual_target_dirs += target
2475 config_target += keyval.load('configs/targets' / target + '.mak')
2476 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
2478 if 'TARGET_NEED_FDT' in config_target
2479 fdt_required += target
2483 if 'TARGET_BASE_ARCH' not in config_target
2484 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2486 if 'TARGET_ABI_DIR' not in config_target
2487 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2489 if 'TARGET_BIG_ENDIAN' not in config_target
2490 config_target += {'TARGET_BIG_ENDIAN': 'n'}
2493 foreach k, v: disassemblers
2494 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
2496 config_target += { sym: 'y' }
2497 config_all_disas += { sym: 'y' }
2502 config_target_data = configuration_data()
2503 foreach k, v: config_target
2504 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2506 elif ignored.contains(k)
2508 elif k == 'TARGET_BASE_ARCH'
2509 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2510 # not used to select files from sourcesets.
2511 config_target_data.set('TARGET_' + v.to_upper(), 1)
2512 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
2513 config_target_data.set_quoted(k, v)
2515 config_target_data.set(k, 1)
2517 config_target_data.set(k, 0)
2519 config_target_data.set(k, v)
2522 config_target_data.set('QEMU_ARCH',
2523 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
2524 config_target_h += {target: configure_file(output: target + '-config-target.h',
2525 configuration: config_target_data)}
2527 if target.endswith('-softmmu')
2528 config_input = meson.get_external_property(target, 'default')
2529 config_devices_mak = target + '-config-devices.mak'
2530 config_devices_mak = configure_file(
2531 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2532 output: config_devices_mak,
2533 depfile: config_devices_mak + '.d',
2535 command: [minikconf,
2536 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2537 config_devices_mak, '@DEPFILE@', '@INPUT@',
2538 host_kconfig, accel_kconfig,
2539 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
2541 config_devices_data = configuration_data()
2542 config_devices = keyval.load(config_devices_mak)
2543 foreach k, v: config_devices
2544 config_devices_data.set(k, 1)
2546 config_devices_mak_list += config_devices_mak
2547 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2548 configuration: config_devices_data)}
2549 config_target += config_devices
2550 config_all_devices += config_devices
2552 config_target_mak += {target: config_target}
2554 target_dirs = actual_target_dirs
2556 # This configuration is used to build files that are shared by
2557 # multiple binaries, and then extracted out of the "common"
2558 # static_library target.
2560 # We do not use all_sources()/all_dependencies(), because it would
2561 # build literally all source files, including devices only used by
2562 # targets that are not built for this compilation. The CONFIG_ALL
2563 # pseudo symbol replaces it.
2565 config_all += config_all_devices
2566 config_all += config_host
2567 config_all += config_all_disas
2569 'CONFIG_XEN': xen.found(),
2570 'CONFIG_SOFTMMU': have_system,
2571 'CONFIG_USER_ONLY': have_user,
2575 target_configs_h = []
2576 foreach target: target_dirs
2577 target_configs_h += config_target_h[target]
2578 target_configs_h += config_devices_h.get(target, [])
2580 genh += custom_target('config-poison.h',
2581 input: [target_configs_h],
2582 output: 'config-poison.h',
2584 command: [find_program('scripts/make-config-poison.sh'),
2591 capstone = not_found
2592 if not get_option('capstone').auto() or have_system or have_user
2593 capstone = dependency('capstone', version: '>=3.0.5',
2594 kwargs: static_kwargs, method: 'pkg-config',
2595 required: get_option('capstone'))
2597 # Some versions of capstone have broken pkg-config file
2598 # that reports a wrong -I path, causing the #include to
2599 # fail later. If the system has such a broken version
2601 if capstone.found() and not cc.compiles('#include <capstone.h>',
2602 dependencies: [capstone])
2603 capstone = not_found
2604 if get_option('capstone').enabled()
2605 error('capstone requested, but it does not appear to work')
2611 slirp_opt = 'disabled'
2613 slirp_opt = get_option('slirp')
2614 if slirp_opt in ['enabled', 'auto', 'system']
2615 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2616 slirp_dep_required = (slirp_opt == 'system' or
2617 slirp_opt == 'enabled' and not have_internal)
2618 slirp = dependency('slirp', kwargs: static_kwargs,
2619 method: 'pkg-config', version: '>=4.1.0',
2620 required: slirp_dep_required)
2621 # slirp <4.7 is incompatible with CFI support in QEMU. This is because
2622 # it passes function pointers within libslirp as callbacks for timers.
2623 # When using a system-wide shared libslirp, the type information for the
2624 # callback is missing and the timer call produces a false positive with CFI.
2625 # Do not use the "version" keyword argument to produce a better error.
2626 # with control-flow integrity.
2627 if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
2628 if slirp_dep_required
2629 error('Control-Flow Integrity requires libslirp 4.7.')
2631 warning('Control-Flow Integrity requires libslirp 4.7, not using system-wide libslirp.')
2636 slirp_opt = 'system'
2638 slirp_opt = 'internal'
2640 slirp_opt = 'disabled'
2643 if slirp_opt == 'internal'
2645 if targetos == 'windows'
2646 slirp_deps = cc.find_library('iphlpapi')
2647 elif targetos == 'darwin'
2648 slirp_deps = cc.find_library('resolv')
2650 slirp_conf = configuration_data()
2651 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2652 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2653 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2654 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2655 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2657 'slirp/src/arp_table.c',
2658 'slirp/src/bootp.c',
2659 'slirp/src/cksum.c',
2660 'slirp/src/dhcpv6.c',
2661 'slirp/src/dnssearch.c',
2663 'slirp/src/ip6_icmp.c',
2664 'slirp/src/ip6_input.c',
2665 'slirp/src/ip6_output.c',
2666 'slirp/src/ip_icmp.c',
2667 'slirp/src/ip_input.c',
2668 'slirp/src/ip_output.c',
2672 'slirp/src/ndp_table.c',
2674 'slirp/src/slirp.c',
2675 'slirp/src/socket.c',
2676 'slirp/src/state.c',
2677 'slirp/src/stream.c',
2678 'slirp/src/tcp_input.c',
2679 'slirp/src/tcp_output.c',
2680 'slirp/src/tcp_subr.c',
2681 'slirp/src/tcp_timer.c',
2686 'slirp/src/version.c',
2687 'slirp/src/vmstate.c',
2691 input : 'slirp/src/libslirp-version.h.in',
2692 output : 'libslirp-version.h',
2693 configuration: slirp_conf)
2695 slirp_inc = include_directories('slirp', 'slirp/src')
2696 libslirp = static_library('slirp',
2697 build_by_default: false,
2698 sources: slirp_files,
2699 c_args: slirp_cargs,
2700 include_directories: slirp_inc)
2701 slirp = declare_dependency(link_with: libslirp,
2702 dependencies: slirp_deps,
2703 include_directories: slirp_inc)
2707 libvfio_user_dep = not_found
2708 if have_system and vfio_user_server_allowed
2709 have_internal = fs.exists(meson.current_source_dir() / 'subprojects/libvfio-user/meson.build')
2711 if not have_internal
2712 error('libvfio-user source not found - please pull git submodule')
2715 libvfio_user_proj = subproject('libvfio-user')
2717 libvfio_user_lib = libvfio_user_proj.get_variable('libvfio_user_dep')
2719 libvfio_user_dep = declare_dependency(dependencies: [libvfio_user_lib])
2724 fdt_opt = get_option('fdt')
2725 if fdt_opt in ['enabled', 'auto', 'system']
2726 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2727 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2728 required: fdt_opt == 'system' or
2729 fdt_opt == 'enabled' and not have_internal)
2730 if fdt.found() and cc.links('''
2732 #include <libfdt_env.h>
2733 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2736 elif fdt_opt == 'system'
2737 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2739 fdt_opt = 'internal'
2741 fdt_opt = 'disabled'
2745 if fdt_opt == 'internal'
2748 'dtc/libfdt/fdt_ro.c',
2749 'dtc/libfdt/fdt_wip.c',
2750 'dtc/libfdt/fdt_sw.c',
2751 'dtc/libfdt/fdt_rw.c',
2752 'dtc/libfdt/fdt_strerror.c',
2753 'dtc/libfdt/fdt_empty_tree.c',
2754 'dtc/libfdt/fdt_addresses.c',
2755 'dtc/libfdt/fdt_overlay.c',
2756 'dtc/libfdt/fdt_check.c',
2759 fdt_inc = include_directories('dtc/libfdt')
2760 libfdt = static_library('fdt',
2761 build_by_default: false,
2763 include_directories: fdt_inc)
2764 fdt = declare_dependency(link_with: libfdt,
2765 include_directories: fdt_inc)
2768 fdt_opt = 'disabled'
2770 if not fdt.found() and fdt_required.length() > 0
2771 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2774 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2775 config_host_data.set('CONFIG_FDT', fdt.found())
2776 config_host_data.set('CONFIG_SLIRP', slirp.found())
2778 #####################
2779 # Generated sources #
2780 #####################
2782 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2784 hxtool = find_program('scripts/hxtool')
2785 shaderinclude = find_program('scripts/shaderinclude.pl')
2786 qapi_gen = find_program('scripts/qapi-gen.py')
2787 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2788 meson.current_source_dir() / 'scripts/qapi/commands.py',
2789 meson.current_source_dir() / 'scripts/qapi/common.py',
2790 meson.current_source_dir() / 'scripts/qapi/error.py',
2791 meson.current_source_dir() / 'scripts/qapi/events.py',
2792 meson.current_source_dir() / 'scripts/qapi/expr.py',
2793 meson.current_source_dir() / 'scripts/qapi/gen.py',
2794 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2795 meson.current_source_dir() / 'scripts/qapi/parser.py',
2796 meson.current_source_dir() / 'scripts/qapi/schema.py',
2797 meson.current_source_dir() / 'scripts/qapi/source.py',
2798 meson.current_source_dir() / 'scripts/qapi/types.py',
2799 meson.current_source_dir() / 'scripts/qapi/visit.py',
2800 meson.current_source_dir() / 'scripts/qapi/common.py',
2801 meson.current_source_dir() / 'scripts/qapi-gen.py'
2805 python, files('scripts/tracetool.py'),
2806 '--backend=' + ','.join(get_option('trace_backends'))
2808 tracetool_depends = files(
2809 'scripts/tracetool/backend/log.py',
2810 'scripts/tracetool/backend/__init__.py',
2811 'scripts/tracetool/backend/dtrace.py',
2812 'scripts/tracetool/backend/ftrace.py',
2813 'scripts/tracetool/backend/simple.py',
2814 'scripts/tracetool/backend/syslog.py',
2815 'scripts/tracetool/backend/ust.py',
2816 'scripts/tracetool/format/ust_events_c.py',
2817 'scripts/tracetool/format/ust_events_h.py',
2818 'scripts/tracetool/format/__init__.py',
2819 'scripts/tracetool/format/d.py',
2820 'scripts/tracetool/format/simpletrace_stap.py',
2821 'scripts/tracetool/format/c.py',
2822 'scripts/tracetool/format/h.py',
2823 'scripts/tracetool/format/log_stap.py',
2824 'scripts/tracetool/format/stap.py',
2825 'scripts/tracetool/__init__.py',
2826 'scripts/tracetool/transform.py',
2827 'scripts/tracetool/vcpu.py'
2830 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2831 meson.current_source_dir(),
2832 get_option('pkgversion'), meson.project_version()]
2833 qemu_version = custom_target('qemu-version.h',
2834 output: 'qemu-version.h',
2835 command: qemu_version_cmd,
2837 build_by_default: true,
2838 build_always_stale: true)
2839 genh += qemu_version
2843 ['qemu-options.hx', 'qemu-options.def'],
2844 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2848 ['hmp-commands.hx', 'hmp-commands.h'],
2849 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2852 foreach d : hx_headers
2853 hxdep += custom_target(d[1],
2857 build_by_default: true, # to be removed when added to a target
2858 command: [hxtool, '-h', '@INPUT0@'])
2866 authz_ss = ss.source_set()
2867 blockdev_ss = ss.source_set()
2868 block_ss = ss.source_set()
2869 chardev_ss = ss.source_set()
2870 common_ss = ss.source_set()
2871 crypto_ss = ss.source_set()
2872 hwcore_ss = ss.source_set()
2873 io_ss = ss.source_set()
2874 qmp_ss = ss.source_set()
2875 qom_ss = ss.source_set()
2876 softmmu_ss = ss.source_set()
2877 specific_fuzz_ss = ss.source_set()
2878 specific_ss = ss.source_set()
2879 stub_ss = ss.source_set()
2880 trace_ss = ss.source_set()
2881 user_ss = ss.source_set()
2882 util_ss = ss.source_set()
2885 qtest_module_ss = ss.source_set()
2886 tcg_module_ss = ss.source_set()
2892 target_softmmu_arch = {}
2893 target_user_arch = {}
2899 # TODO: add each directory to the subdirs from its own meson.build, once
2901 trace_events_subdirs = [
2909 trace_events_subdirs += [ 'linux-user' ]
2912 trace_events_subdirs += [ 'bsd-user' ]
2915 trace_events_subdirs += [
2924 trace_events_subdirs += [
2938 'hw/block/dataplane',
2987 if have_system or have_user
2988 trace_events_subdirs += [
3006 vhost_user = not_found
3007 if targetos == 'linux' and have_vhost_user
3008 libvhost_user = subproject('libvhost-user')
3009 vhost_user = libvhost_user.get_variable('vhost_user_dep')
3012 libvduse = not_found
3014 libvduse_proj = subproject('libvduse')
3015 libvduse = libvduse_proj.get_variable('libvduse_dep')
3018 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3019 # that is filled in by qapi/.
3033 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3034 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3037 qom_ss = qom_ss.apply(config_host, strict: false)
3038 libqom = static_library('qom', qom_ss.sources() + genh,
3039 dependencies: [qom_ss.dependencies()],
3041 qom = declare_dependency(link_whole: libqom)
3043 event_loop_base = files('event-loop-base.c')
3044 event_loop_base = static_library('event-loop-base', sources: event_loop_base + genh,
3045 build_by_default: true)
3046 event_loop_base = declare_dependency(link_whole: event_loop_base,
3047 dependencies: [qom])
3049 stub_ss = stub_ss.apply(config_all, strict: false)
3051 util_ss.add_all(trace_ss)
3052 util_ss = util_ss.apply(config_all, strict: false)
3053 libqemuutil = static_library('qemuutil',
3054 sources: util_ss.sources() + stub_ss.sources() + genh,
3055 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
3056 qemuutil = declare_dependency(link_with: libqemuutil,
3057 sources: genh + version_res,
3058 dependencies: [event_loop_base])
3060 if have_system or have_user
3061 decodetree = generator(find_program('scripts/decodetree.py'),
3062 output: 'decode-@BASENAME@.c.inc',
3063 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3064 subdir('libdecnumber')
3081 if config_host_data.get('CONFIG_REPLICATION')
3082 block_ss.add(files('replication.c'))
3089 blockdev_ss.add(files(
3096 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3097 # os-win32.c does not
3098 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
3099 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
3102 common_ss.add(files('cpus-common.c'))
3106 common_ss.add(capstone)
3107 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
3109 # Work around a gcc bug/misfeature wherein constant propagation looks
3111 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3112 # to guess that a const variable is always zero. Without lto, this is
3113 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
3114 # without lto, not even the alias is required -- we simply use different
3115 # declarations in different compilation units.
3116 pagevary = files('page-vary-common.c')
3117 if get_option('b_lto')
3118 pagevary_flags = ['-fno-lto']
3119 if get_option('cfi')
3120 pagevary_flags += '-fno-sanitize=cfi-icall'
3122 pagevary = static_library('page-vary-common', sources: pagevary + genh,
3123 c_args: pagevary_flags)
3124 pagevary = declare_dependency(link_with: pagevary)
3126 common_ss.add(pagevary)
3127 specific_ss.add(files('page-vary.c'))
3135 subdir('semihosting')
3142 common_user_inc = []
3144 subdir('common-user')
3146 subdir('linux-user')
3148 # needed for fuzzing binaries
3149 subdir('tests/qtest/libqos')
3150 subdir('tests/qtest/fuzz')
3153 tcg_real_module_ss = ss.source_set()
3154 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3155 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3156 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3157 'tcg': tcg_real_module_ss }}
3159 ########################
3160 # Library dependencies #
3161 ########################
3163 modinfo_collect = find_program('scripts/modinfo-collect.py')
3164 modinfo_generate = find_program('scripts/modinfo-generate.py')
3169 foreach d, list : modules
3170 foreach m, module_ss : list
3171 if enable_modules and targetos != 'windows'
3172 module_ss = module_ss.apply(config_all, strict: false)
3173 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3174 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3180 if module_ss.sources() != []
3181 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3182 # input. Sources can be used multiple times but objects are
3183 # unique when it comes to lookup in compile_commands.json.
3184 # Depnds on a mesion version with
3185 # https://github.com/mesonbuild/meson/pull/8900
3186 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3187 output: d + '-' + m + '.modinfo',
3188 input: module_ss.sources() + genh,
3190 command: [modinfo_collect, module_ss.sources()])
3194 block_ss.add_all(module_ss)
3196 softmmu_ss.add_all(module_ss)
3202 foreach d, list : target_modules
3203 foreach m, module_ss : list
3204 if enable_modules and targetos != 'windows'
3205 foreach target : target_dirs
3206 if target.endswith('-softmmu')
3207 config_target = config_target_mak[target]
3208 config_target += config_host
3209 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3210 c_args = ['-DNEED_CPU_H',
3211 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3212 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3213 target_module_ss = module_ss.apply(config_target, strict: false)
3214 if target_module_ss.sources() != []
3215 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3216 sl = static_library(module_name,
3217 [genh, target_module_ss.sources()],
3218 dependencies: [modulecommon, target_module_ss.dependencies()],
3219 include_directories: target_inc,
3223 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3224 modinfo_files += custom_target(module_name + '.modinfo',
3225 output: module_name + '.modinfo',
3226 input: target_module_ss.sources() + genh,
3228 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3233 specific_ss.add_all(module_ss)
3239 foreach target : target_dirs
3240 if target.endswith('-softmmu')
3241 config_target = config_target_mak[target]
3242 config_devices_mak = target + '-config-devices.mak'
3243 modinfo_src = custom_target('modinfo-' + target + '.c',
3244 output: 'modinfo-' + target + '.c',
3245 input: modinfo_files,
3246 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'],
3249 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
3250 modinfo_dep = declare_dependency(link_with: modinfo_lib)
3252 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH']
3253 hw_arch[arch].add(modinfo_dep)
3258 nm = find_program('nm')
3259 undefsym = find_program('scripts/undefsym.py')
3260 block_syms = custom_target('block.syms', output: 'block.syms',
3261 input: [libqemuutil, block_mods],
3263 command: [undefsym, nm, '@INPUT@'])
3264 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3265 input: [libqemuutil, softmmu_mods],
3267 command: [undefsym, nm, '@INPUT@'])
3269 authz_ss = authz_ss.apply(config_host, strict: false)
3270 libauthz = static_library('authz', authz_ss.sources() + genh,
3271 dependencies: [authz_ss.dependencies()],
3273 build_by_default: false)
3275 authz = declare_dependency(link_whole: libauthz,
3278 crypto_ss = crypto_ss.apply(config_host, strict: false)
3279 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3280 dependencies: [crypto_ss.dependencies()],
3282 build_by_default: false)
3284 crypto = declare_dependency(link_whole: libcrypto,
3285 dependencies: [authz, qom])
3287 io_ss = io_ss.apply(config_host, strict: false)
3288 libio = static_library('io', io_ss.sources() + genh,
3289 dependencies: [io_ss.dependencies()],
3290 link_with: libqemuutil,
3292 build_by_default: false)
3294 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3296 libmigration = static_library('migration', sources: migration_files + genh,
3298 build_by_default: false)
3299 migration = declare_dependency(link_with: libmigration,
3300 dependencies: [zlib, qom, io])
3301 softmmu_ss.add(migration)
3303 block_ss = block_ss.apply(config_host, strict: false)
3304 libblock = static_library('block', block_ss.sources() + genh,
3305 dependencies: block_ss.dependencies(),
3306 link_depends: block_syms,
3308 build_by_default: false)
3310 block = declare_dependency(link_whole: [libblock],
3311 link_args: '@block.syms',
3312 dependencies: [crypto, io])
3314 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
3315 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3316 dependencies: blockdev_ss.dependencies(),
3318 build_by_default: false)
3320 blockdev = declare_dependency(link_whole: [libblockdev],
3321 dependencies: [block, event_loop_base])
3323 qmp_ss = qmp_ss.apply(config_host, strict: false)
3324 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3325 dependencies: qmp_ss.dependencies(),
3327 build_by_default: false)
3329 qmp = declare_dependency(link_whole: [libqmp])
3331 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3333 dependencies: chardev_ss.dependencies(),
3334 build_by_default: false)
3336 chardev = declare_dependency(link_whole: libchardev)
3338 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
3339 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3341 build_by_default: false)
3342 hwcore = declare_dependency(link_whole: libhwcore)
3343 common_ss.add(hwcore)
3349 emulator_modules = []
3350 foreach m : block_mods + softmmu_mods
3351 emulator_modules += shared_module(m.name(),
3352 build_by_default: true,
3356 install_dir: qemu_moddir)
3358 if emulator_modules.length() > 0
3359 alias_target('modules', emulator_modules)
3362 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3363 common_ss.add(qom, qemuutil)
3365 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
3366 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3368 common_all = common_ss.apply(config_all, strict: false)
3369 common_all = static_library('common',
3370 build_by_default: false,
3371 sources: common_all.sources() + genh,
3372 include_directories: common_user_inc,
3373 implicit_include_directories: false,
3374 dependencies: common_all.dependencies(),
3377 feature_to_c = find_program('scripts/feature_to_c.sh')
3379 if targetos == 'darwin'
3380 entitlement = find_program('scripts/entitlement.sh')
3384 foreach target : target_dirs
3385 config_target = config_target_mak[target]
3386 target_name = config_target['TARGET_NAME']
3387 target_base_arch = config_target['TARGET_BASE_ARCH']
3388 arch_srcs = [config_target_h[target]]
3390 c_args = ['-DNEED_CPU_H',
3391 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3392 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3393 link_args = emulator_link_args
3395 config_target += config_host
3396 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3397 if targetos == 'linux'
3398 target_inc += include_directories('linux-headers', is_system: true)
3400 if target.endswith('-softmmu')
3401 qemu_target_name = 'qemu-system-' + target_name
3402 target_type='system'
3403 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3404 arch_srcs += t.sources()
3405 arch_deps += t.dependencies()
3407 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3408 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3409 arch_srcs += hw.sources()
3410 arch_deps += hw.dependencies()
3412 arch_srcs += config_devices_h[target]
3413 link_args += ['@block.syms', '@qemu.syms']
3415 abi = config_target['TARGET_ABI_DIR']
3417 target_inc += common_user_inc
3418 qemu_target_name = 'qemu-' + target_name
3419 if target_base_arch in target_user_arch
3420 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3421 arch_srcs += t.sources()
3422 arch_deps += t.dependencies()
3424 if 'CONFIG_LINUX_USER' in config_target
3425 base_dir = 'linux-user'
3427 if 'CONFIG_BSD_USER' in config_target
3428 base_dir = 'bsd-user'
3429 target_inc += include_directories('bsd-user/' / targetos)
3430 target_inc += include_directories('bsd-user/host/' / host_arch)
3431 dir = base_dir / abi
3432 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3434 target_inc += include_directories(
3438 if 'CONFIG_LINUX_USER' in config_target
3439 dir = base_dir / abi
3440 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3441 if config_target.has_key('TARGET_SYSTBL_ABI')
3443 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3444 extra_args : config_target['TARGET_SYSTBL_ABI'])
3449 if 'TARGET_XML_FILES' in config_target
3450 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3451 output: target + '-gdbstub-xml.c',
3452 input: files(config_target['TARGET_XML_FILES'].split()),
3453 command: [feature_to_c, '@INPUT@'],
3455 arch_srcs += gdbstub_xml
3458 t = target_arch[target_base_arch].apply(config_target, strict: false)
3459 arch_srcs += t.sources()
3460 arch_deps += t.dependencies()
3462 target_common = common_ss.apply(config_target, strict: false)
3463 objects = common_all.extract_objects(target_common.sources())
3464 deps = target_common.dependencies()
3466 target_specific = specific_ss.apply(config_target, strict: false)
3467 arch_srcs += target_specific.sources()
3468 arch_deps += target_specific.dependencies()
3470 lib = static_library('qemu-' + target,
3471 sources: arch_srcs + genh,
3472 dependencies: arch_deps,
3474 include_directories: target_inc,
3476 build_by_default: false,
3479 if target.endswith('-softmmu')
3481 'name': 'qemu-system-' + target_name,
3482 'win_subsystem': 'console',
3483 'sources': files('softmmu/main.c'),
3486 if targetos == 'windows' and (sdl.found() or gtk.found())
3488 'name': 'qemu-system-' + target_name + 'w',
3489 'win_subsystem': 'windows',
3490 'sources': files('softmmu/main.c'),
3494 if get_option('fuzzing')
3495 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3497 'name': 'qemu-fuzz-' + target_name,
3498 'win_subsystem': 'console',
3499 'sources': specific_fuzz.sources(),
3500 'dependencies': specific_fuzz.dependencies(),
3505 'name': 'qemu-' + target_name,
3506 'win_subsystem': 'console',
3512 exe_name = exe['name']
3513 if targetos == 'darwin'
3514 exe_name += '-unsigned'
3517 emulator = executable(exe_name, exe['sources'],
3520 dependencies: arch_deps + deps + exe['dependencies'],
3521 objects: lib.extract_all_objects(recursive: true),
3522 link_language: link_language,
3523 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3524 link_args: link_args,
3525 win_subsystem: exe['win_subsystem'])
3527 if targetos == 'darwin'
3528 icon = 'pc-bios/qemu.rsrc'
3529 build_input = [emulator, files(icon)]
3531 get_option('bindir') / exe_name,
3532 meson.current_source_dir() / icon
3534 if 'CONFIG_HVF' in config_target
3535 entitlements = 'accel/hvf/entitlements.plist'
3536 build_input += files(entitlements)
3537 install_input += meson.current_source_dir() / entitlements
3540 emulators += {exe['name'] : custom_target(exe['name'],
3542 output: exe['name'],
3543 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3546 meson.add_install_script(entitlement, '--install',
3547 get_option('bindir') / exe['name'],
3550 emulators += {exe['name']: emulator}
3555 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3556 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3557 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3558 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3560 custom_target(exe['name'] + stp['ext'],
3561 input: trace_events_all,
3562 output: exe['name'] + stp['ext'],
3563 install: stp['install'],
3564 install_dir: get_option('datadir') / 'systemtap/tapset',
3566 tracetool, '--group=all', '--format=' + stp['fmt'],
3567 '--binary=' + stp['bin'],
3568 '--target-name=' + target_name,
3569 '--target-type=' + target_type,
3570 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3571 '@INPUT@', '@OUTPUT@'
3573 depend_files: tracetool_depends)
3579 # Other build targets
3581 if 'CONFIG_PLUGIN' in config_host
3582 install_headers('include/qemu/qemu-plugin.h')
3587 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3588 # when we don't build tools or system
3589 if xkbcommon.found()
3590 # used for the update-keymaps target, so include rules even if !have_tools
3591 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3592 dependencies: [qemuutil, xkbcommon], install: have_tools)
3596 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3597 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3598 qemu_io = executable('qemu-io', files('qemu-io.c'),
3599 dependencies: [block, qemuutil], install: true)
3600 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3601 dependencies: [blockdev, qemuutil, gnutls, selinux],
3604 subdir('storage-daemon')
3605 subdir('contrib/rdmacm-mux')
3606 subdir('contrib/elf2dmp')
3608 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3609 dependencies: qemuutil,
3613 subdir('contrib/vhost-user-blk')
3614 subdir('contrib/vhost-user-gpu')
3615 subdir('contrib/vhost-user-input')
3616 subdir('contrib/vhost-user-scsi')
3619 if targetos == 'linux'
3620 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3621 dependencies: [qemuutil, libcap_ng],
3623 install_dir: get_option('libexecdir'))
3625 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3626 dependencies: [authz, crypto, io, qom, qemuutil,
3627 libcap_ng, mpathpersist],
3632 subdir('contrib/ivshmem-client')
3633 subdir('contrib/ivshmem-server')
3646 if host_machine.system() == 'windows'
3648 find_program('scripts/nsis.py'),
3650 get_option('prefix'),
3651 meson.current_source_dir(),
3654 '-DDISPLAYVERSION=' + meson.project_version(),
3657 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3660 nsis_cmd += '-DCONFIG_GTK=y'
3663 nsis = custom_target('nsis',
3664 output: 'qemu-setup-' + meson.project_version() + '.exe',
3665 input: files('qemu.nsi'),
3666 build_always_stale: true,
3667 command: nsis_cmd + ['@INPUT@'])
3668 alias_target('installer', nsis)
3671 #########################
3672 # Configuration summary #
3673 #########################
3677 summary_info += {'Install prefix': get_option('prefix')}
3678 summary_info += {'BIOS directory': qemu_datadir}
3679 summary_info += {'firmware path': get_option('prefix') / get_option('qemu_firmwarepath')}
3680 summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
3681 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
3682 summary_info += {'module directory': qemu_moddir}
3683 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
3684 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
3685 summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')}
3686 if targetos != 'windows'
3687 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
3688 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')}
3690 summary_info += {'local state directory': 'queried at runtime'}
3692 summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
3693 summary_info += {'Build directory': meson.current_build_dir()}
3694 summary_info += {'Source path': meson.current_source_dir()}
3695 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3696 summary(summary_info, bool_yn: true, section: 'Directories')
3700 summary_info += {'git': config_host['GIT']}
3701 summary_info += {'make': config_host['MAKE']}
3702 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3703 summary_info += {'sphinx-build': sphinx_build}
3704 if config_host.has_key('HAVE_GDB_BIN')
3705 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3707 summary_info += {'iasl': iasl}
3708 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3709 if targetos == 'windows' and have_ga
3710 summary_info += {'wixl': wixl}
3712 if slirp_opt != 'disabled' and have_system
3713 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
3715 summary(summary_info, bool_yn: true, section: 'Host binaries')
3717 # Configurable features
3719 summary_info += {'Documentation': build_docs}
3720 summary_info += {'system-mode emulation': have_system}
3721 summary_info += {'user-mode emulation': have_user}
3722 summary_info += {'block layer': have_block}
3723 summary_info += {'Install blobs': get_option('install_blobs')}
3724 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3725 if config_host.has_key('CONFIG_MODULES')
3726 summary_info += {'alternative module path': get_option('module_upgrades')}
3728 summary_info += {'fuzzing support': get_option('fuzzing')}
3730 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3732 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3733 if 'simple' in get_option('trace_backends')
3734 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3736 summary_info += {'D-Bus display': dbus_display}
3737 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
3738 summary_info += {'vhost-kernel support': have_vhost_kernel}
3739 summary_info += {'vhost-net support': have_vhost_net}
3740 summary_info += {'vhost-user support': have_vhost_user}
3741 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
3742 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3743 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
3744 summary_info += {'build guest agent': have_ga}
3745 summary(summary_info, bool_yn: true, section: 'Configurable features')
3747 # Compilation information
3749 summary_info += {'host CPU': cpu}
3750 summary_info += {'host endianness': build_machine.endian()}
3751 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3752 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3753 if link_language == 'cpp'
3754 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3756 summary_info += {'C++ compiler': false}
3758 if targetos == 'darwin'
3759 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3761 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3762 + ['-O' + get_option('optimization')]
3763 + (get_option('debug') ? ['-g'] : []))}
3764 if link_language == 'cpp'
3765 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3766 + ['-O' + get_option('optimization')]
3767 + (get_option('debug') ? ['-g'] : []))}
3769 if targetos == 'darwin'
3770 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args')
3771 + ['-O' + get_option('optimization')]
3772 + (get_option('debug') ? ['-g'] : []))}
3774 link_args = get_option(link_language + '_link_args')
3775 if link_args.length() > 0
3776 summary_info += {'LDFLAGS': ' '.join(link_args)}
3778 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_cflags)}
3779 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_cxxflags)}
3780 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_objcflags)}
3781 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
3782 summary_info += {'profiler': get_option('profiler')}
3783 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3784 summary_info += {'PIE': get_option('b_pie')}
3785 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3786 summary_info += {'malloc trim support': has_malloc_trim}
3787 summary_info += {'membarrier': have_membarrier}
3788 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
3789 summary_info += {'mutex debugging': get_option('debug_mutex')}
3790 summary_info += {'memory allocator': get_option('malloc')}
3791 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
3792 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
3793 summary_info += {'gprof enabled': get_option('gprof')}
3794 summary_info += {'gcov': get_option('b_coverage')}
3795 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3796 summary_info += {'CFI support': get_option('cfi')}
3797 if get_option('cfi')
3798 summary_info += {'CFI debug support': get_option('cfi_debug')}
3800 summary_info += {'strip binaries': get_option('strip')}
3801 summary_info += {'sparse': sparse}
3802 summary_info += {'mingw32 support': targetos == 'windows'}
3803 summary(summary_info, bool_yn: true, section: 'Compilation')
3805 # snarf the cross-compilation information for tests
3808 foreach target: target_dirs
3809 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3810 if fs.exists(tcg_mak)
3811 config_cross_tcg = keyval.load(tcg_mak)
3812 if 'CC' in config_cross_tcg
3813 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']}
3819 summary(summary_info, bool_yn: true, section: 'Cross compilers')
3822 # Targets and accelerators
3825 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3826 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3827 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3828 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3829 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3830 summary_info += {'Xen support': xen.found()}
3832 summary_info += {'xen ctrl version': xen.version()}
3835 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3836 if config_all.has_key('CONFIG_TCG')
3837 if get_option('tcg_interpreter')
3838 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
3840 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3842 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3843 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3845 summary_info += {'target list': ' '.join(target_dirs)}
3847 summary_info += {'default devices': get_option('default_devices')}
3848 summary_info += {'out of process emulation': multiprocess_allowed}
3849 summary_info += {'vfio-user server': vfio_user_server_allowed}
3851 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3855 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3856 summary_info += {'coroutine pool': have_coroutine_pool}
3858 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
3859 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
3860 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
3861 summary_info += {'VirtFS support': have_virtfs}
3862 summary_info += {'build virtiofs daemon': have_virtiofsd}
3863 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
3864 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
3865 summary_info += {'bochs support': get_option('bochs').allowed()}
3866 summary_info += {'cloop support': get_option('cloop').allowed()}
3867 summary_info += {'dmg support': get_option('dmg').allowed()}
3868 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
3869 summary_info += {'vdi support': get_option('vdi').allowed()}
3870 summary_info += {'vvfat support': get_option('vvfat').allowed()}
3871 summary_info += {'qed support': get_option('qed').allowed()}
3872 summary_info += {'parallels support': get_option('parallels').allowed()}
3873 summary_info += {'FUSE exports': fuse}
3874 summary_info += {'VDUSE block exports': have_vduse_blk_export}
3876 summary(summary_info, bool_yn: true, section: 'Block layer support')
3880 summary_info += {'TLS priority': get_option('tls_priority')}
3881 summary_info += {'GNUTLS support': gnutls}
3883 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3885 summary_info += {'libgcrypt': gcrypt}
3886 summary_info += {'nettle': nettle}
3888 summary_info += {' XTS': xts != 'private'}
3890 summary_info += {'AF_ALG support': have_afalg}
3891 summary_info += {'rng-none': get_option('rng_none')}
3892 summary_info += {'Linux keyring': have_keyring}
3893 summary(summary_info, bool_yn: true, section: 'Crypto')
3897 if targetos == 'darwin'
3898 summary_info += {'Cocoa support': cocoa}
3899 summary_info += {'vmnet.framework support': vmnet}
3901 summary_info += {'SDL support': sdl}
3902 summary_info += {'SDL image support': sdl_image}
3903 summary_info += {'GTK support': gtk}
3904 summary_info += {'pixman': pixman}
3905 summary_info += {'VTE support': vte}
3906 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3907 summary_info += {'libtasn1': tasn1}
3908 summary_info += {'PAM': pam}
3909 summary_info += {'iconv support': iconv}
3910 summary_info += {'curses support': curses}
3911 summary_info += {'virgl support': virgl}
3912 summary_info += {'curl support': curl}
3913 summary_info += {'Multipath support': mpathpersist}
3914 summary_info += {'PNG support': png}
3915 summary_info += {'VNC support': vnc}
3917 summary_info += {'VNC SASL support': sasl}
3918 summary_info += {'VNC JPEG support': jpeg}
3920 if targetos not in ['darwin', 'haiku', 'windows']
3921 summary_info += {'OSS support': oss}
3922 elif targetos == 'darwin'
3923 summary_info += {'CoreAudio support': coreaudio}
3924 elif targetos == 'windows'
3925 summary_info += {'DirectSound support': dsound}
3927 if targetos == 'linux'
3928 summary_info += {'ALSA support': alsa}
3929 summary_info += {'PulseAudio support': pulse}
3931 summary_info += {'JACK support': jack}
3932 summary_info += {'brlapi support': brlapi}
3933 summary_info += {'vde support': vde}
3934 summary_info += {'netmap support': have_netmap}
3935 summary_info += {'l2tpv3 support': have_l2tpv3}
3936 summary_info += {'Linux AIO support': libaio}
3937 summary_info += {'Linux io_uring support': linux_io_uring}
3938 summary_info += {'ATTR/XATTR support': libattr}
3939 summary_info += {'RDMA support': rdma}
3940 summary_info += {'PVRDMA support': have_pvrdma}
3941 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3942 summary_info += {'libcap-ng support': libcap_ng}
3943 summary_info += {'bpf support': libbpf}
3944 summary_info += {'spice protocol support': spice_protocol}
3945 if spice_protocol.found()
3946 summary_info += {' spice server support': spice}
3948 summary_info += {'rbd support': rbd}
3949 summary_info += {'smartcard support': cacard}
3950 summary_info += {'U2F support': u2f}
3951 summary_info += {'libusb': libusb}
3952 summary_info += {'usb net redir': usbredir}
3953 summary_info += {'OpenGL support (epoxy)': opengl}
3954 summary_info += {'GBM': gbm}
3955 summary_info += {'libiscsi support': libiscsi}
3956 summary_info += {'libnfs support': libnfs}
3957 if targetos == 'windows'
3959 summary_info += {'QGA VSS support': have_qga_vss}
3962 summary_info += {'seccomp support': seccomp}
3963 summary_info += {'GlusterFS support': glusterfs}
3964 summary_info += {'TPM support': have_tpm}
3965 summary_info += {'libssh support': libssh}
3966 summary_info += {'lzo support': lzo}
3967 summary_info += {'snappy support': snappy}
3968 summary_info += {'bzip2 support': libbzip2}
3969 summary_info += {'lzfse support': liblzfse}
3970 summary_info += {'zstd support': zstd}
3971 summary_info += {'NUMA host support': numa}
3972 summary_info += {'capstone': capstone}
3973 summary_info += {'libpmem support': libpmem}
3974 summary_info += {'libdaxctl support': libdaxctl}
3975 summary_info += {'libudev': libudev}
3976 # Dummy dependency, keep .found()
3977 summary_info += {'FUSE lseek': fuse_lseek.found()}
3978 summary_info += {'selinux': selinux}
3979 summary(summary_info, bool_yn: true, section: 'Dependencies')
3981 if not supported_cpus.contains(cpu)
3983 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3985 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3986 message('The QEMU project intends to remove support for this host CPU in')
3987 message('a future release if nobody volunteers to maintain it and to')
3988 message('provide a build host for our continuous integration setup.')
3989 message('configure has succeeded and you can continue to build, but')
3990 message('if you care about QEMU on this platform you should contact')
3991 message('us upstream at qemu-devel@nongnu.org.')
3994 if not supported_oses.contains(targetos)
3996 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3998 message('Host OS ' + targetos + 'support is not currently maintained.')
3999 message('The QEMU project intends to remove support for this host OS in')
4000 message('a future release if nobody volunteers to maintain it and to')
4001 message('provide a build host for our continuous integration setup.')
4002 message('configure has succeeded and you can continue to build, but')
4003 message('if you care about QEMU on this platform you should contact')
4004 message('us upstream at qemu-devel@nongnu.org.')