1 project('qemu', ['c'], meson_version: '>=0.55.0',
2 default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto'] +
3 (meson.version().version_compare('>=0.56.0') ? [ 'b_staticpic=false' ] : []),
4 version: run_command('head', meson.source_root() / 'VERSION').stdout().strip())
6 not_found = dependency('', required: false)
7 if meson.version().version_compare('>=0.56.0')
8 keyval = import('keyval')
10 keyval = import('unstable-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()
46 target_dirs = config_host['TARGET_DIRS'].split()
49 foreach target : target_dirs
50 have_user = have_user or target.endswith('-user')
51 have_system = have_system or target.endswith('-softmmu')
53 have_tools = 'CONFIG_TOOLS' in config_host
54 have_block = have_system or have_tools
56 python = import('python').find_installation()
58 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
59 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
60 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
62 cpu = host_machine.cpu_family()
63 targetos = host_machine.system()
65 if cpu in ['x86', 'x86_64']
66 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
68 kvm_targets = ['aarch64-softmmu']
70 kvm_targets = ['s390x-softmmu']
71 elif cpu in ['ppc', 'ppc64']
72 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
73 elif cpu in ['mips', 'mips64']
74 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
79 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
80 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
81 # i368 emulator provides xenpv machine type for multiple architectures
82 accelerator_targets += {
83 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
86 if cpu in ['x86', 'x86_64']
87 accelerator_targets += {
88 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
89 'CONFIG_HVF': ['x86_64-softmmu'],
90 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
91 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
95 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
96 install_edk2_blobs = false
97 if get_option('install_blobs')
98 foreach target : target_dirs
99 install_edk2_blobs = install_edk2_blobs or target in edk2_targets
103 bzip2 = find_program('bzip2', required: install_edk2_blobs)
109 # Specify linker-script with add_project_link_arguments so that it is not placed
110 # within a linker --start-group/--end-group pair
111 if 'CONFIG_FUZZ' in config_host
112 add_project_link_arguments(['-Wl,-T,',
113 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
114 native: false, language: ['c', 'cpp', 'objc'])
117 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
118 native: false, language: ['c', 'objc'])
119 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
120 native: false, language: 'cpp')
121 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
122 native: false, language: ['c', 'cpp', 'objc'])
124 if targetos == 'linux'
125 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
126 '-isystem', 'linux-headers',
127 language: ['c', 'cpp'])
130 add_project_arguments('-iquote', '.',
131 '-iquote', meson.current_source_dir(),
132 '-iquote', meson.current_source_dir() / 'include',
133 '-iquote', meson.current_source_dir() / 'disas/libvixl',
134 language: ['c', 'cpp', 'objc'])
136 link_language = meson.get_external_property('link_language', 'cpp')
137 if link_language == 'cpp'
138 add_languages('cpp', required: true, native: false)
140 if host_machine.system() == 'darwin'
141 add_languages('objc', required: false, native: false)
144 sparse = find_program('cgcc', required: get_option('sparse'))
147 command: [find_program('scripts/check_sparse.py'),
148 'compile_commands.json', sparse.full_path(), '-Wbitwise',
149 '-Wno-transparent-union', '-Wno-old-initializer',
150 '-Wno-non-pointer-null'])
153 ###########################################
154 # Target-specific checks and dependencies #
155 ###########################################
157 if targetos != 'linux' and get_option('mpath').enabled()
158 error('Multipath is supported only on Linux')
161 if targetos != 'linux' and get_option('multiprocess').enabled()
162 error('Multiprocess QEMU is supported only on Linux')
164 multiprocess_allowed = targetos == 'linux' and not get_option('multiprocess').disabled()
166 libm = cc.find_library('m', required: false)
167 util = cc.find_library('util', required: false)
173 emulator_link_args = []
176 if targetos == 'windows'
177 socket = cc.find_library('ws2_32')
178 winmm = cc.find_library('winmm')
180 win = import('windows')
181 version_res = win.compile_resources('version.rc',
182 depend_files: files('pc-bios/qemu-nsis.ico'),
183 include_directories: include_directories('.'))
184 elif targetos == 'darwin'
185 coref = dependency('appleframeworks', modules: 'CoreFoundation')
186 iokit = dependency('appleframeworks', modules: 'IOKit')
187 elif targetos == 'sunos'
188 socket = [cc.find_library('socket'),
189 cc.find_library('nsl'),
190 cc.find_library('resolv')]
191 elif targetos == 'haiku'
192 socket = [cc.find_library('posix_error_mapper'),
193 cc.find_library('network'),
194 cc.find_library('bsd')]
195 elif targetos == 'openbsd'
196 if not get_option('tcg').disabled() and target_dirs.length() > 0
197 # Disable OpenBSD W^X if available
198 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
203 if not get_option('kvm').disabled() and targetos == 'linux'
204 accelerators += 'CONFIG_KVM'
206 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
207 accelerators += 'CONFIG_XEN'
208 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
210 have_xen_pci_passthrough = false
212 if not get_option('whpx').disabled() and targetos == 'windows'
213 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
214 error('WHPX requires 64-bit host')
215 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
216 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
217 accelerators += 'CONFIG_WHPX'
220 if not get_option('hvf').disabled()
221 hvf = dependency('appleframeworks', modules: 'Hypervisor',
222 required: get_option('hvf'))
224 accelerators += 'CONFIG_HVF'
227 if not get_option('hax').disabled()
228 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
229 accelerators += 'CONFIG_HAX'
232 if targetos == 'netbsd'
233 if cc.has_header_symbol('nvmm.h', 'nvmm_cpu_stop', required: get_option('nvmm'))
234 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
237 accelerators += 'CONFIG_NVMM'
241 tcg_arch = config_host['ARCH']
242 if not get_option('tcg').disabled()
243 if cpu not in supported_cpus
244 if get_option('tcg_interpreter')
245 warning('Unsupported CPU @0@, will use TCG with TCI (experimental and slow)'.format(cpu))
247 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
249 elif get_option('tcg_interpreter')
250 warning('Use of the TCG interpretor is not recommended on this host')
251 warning('architecture. There is a native TCG execution backend available')
252 warning('which provides substantially better performance and reliability.')
253 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
254 warning('configuration option on this architecture to use the native')
257 if get_option('tcg_interpreter')
259 elif config_host['ARCH'] == 'sparc64'
261 elif config_host['ARCH'] == 's390x'
263 elif config_host['ARCH'] in ['x86_64', 'x32']
265 elif config_host['ARCH'] == 'ppc64'
267 elif config_host['ARCH'] in ['riscv32', 'riscv64']
270 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
271 language: ['c', 'cpp', 'objc'])
273 accelerators += 'CONFIG_TCG'
274 config_host += { 'CONFIG_TCG': 'y' }
277 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
278 error('KVM not available on this platform')
280 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
281 error('HVF not available on this platform')
283 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
284 error('NVMM not available on this platform')
286 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
287 error('WHPX not available on this platform')
289 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
290 if 'CONFIG_XEN' in accelerators
291 error('Xen PCI passthrough not available on this platform')
293 error('Xen PCI passthrough requested but Xen not enabled')
301 # The path to glib.h is added to all compilation commands. This was
302 # grandfathered in from the QEMU Makefiles.
303 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
304 native: false, language: ['c', 'cpp', 'objc'])
305 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
306 link_args: config_host['GLIB_LIBS'].split())
307 # override glib dep with the configure results (for subprojects)
308 meson.override_dependency('glib-2.0', glib)
311 if 'CONFIG_GIO' in config_host
312 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
313 link_args: config_host['GIO_LIBS'].split())
316 if 'CONFIG_TRACE_UST' in config_host
317 lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
320 if 'CONFIG_TRACE_UST' in config_host
321 urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
324 if have_system or have_tools
325 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
326 method: 'pkg-config', kwargs: static_kwargs)
329 if 'CONFIG_AUTH_PAM' in config_host
330 pam = cc.find_library('pam')
332 libaio = cc.find_library('aio', required: false)
333 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
334 linux_io_uring = not_found
335 if 'CONFIG_LINUX_IO_URING' in config_host
336 linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
337 link_args: config_host['LINUX_IO_URING_LIBS'].split())
340 if 'CONFIG_LIBXML2' in config_host
341 libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
342 link_args: config_host['LIBXML2_LIBS'].split())
345 if not get_option('libnfs').auto() or have_block
346 libnfs = dependency('libnfs', version: '>=1.9.3',
347 required: get_option('libnfs'),
348 method: 'pkg-config', kwargs: static_kwargs)
353 #include <sys/types.h>
354 #ifdef CONFIG_LIBATTR
355 #include <attr/xattr.h>
357 #include <sys/xattr.h>
359 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
362 have_old_libattr = false
363 if not get_option('attr').disabled()
364 if cc.links(libattr_test)
365 libattr = declare_dependency()
367 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
368 required: get_option('attr'),
369 kwargs: static_kwargs)
370 if libattr.found() and not \
371 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
373 if get_option('attr').enabled()
374 error('could not link libattr')
376 warning('could not link libattr, disabling')
379 have_old_libattr = libattr.found()
384 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
385 if cocoa.found() and get_option('sdl').enabled()
386 error('Cocoa and SDL cannot be enabled at the same time')
388 if cocoa.found() and get_option('gtk').enabled()
389 error('Cocoa and GTK+ cannot be enabled at the same time')
393 if not get_option('seccomp').auto() or have_system or have_tools
394 seccomp = dependency('libseccomp', version: '>=2.3.0',
395 required: get_option('seccomp'),
396 method: 'pkg-config', kwargs: static_kwargs)
399 libcap_ng = not_found
400 if not get_option('cap_ng').auto() or have_system or have_tools
401 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
402 required: get_option('cap_ng'),
403 kwargs: static_kwargs)
405 if libcap_ng.found() and not cc.links('''
409 capng_capability_to_name(CAPNG_EFFECTIVE);
411 }''', dependencies: libcap_ng)
412 libcap_ng = not_found
413 if get_option('cap_ng').enabled()
414 error('could not link libcap-ng')
416 warning('could not link libcap-ng, disabling')
420 if get_option('xkbcommon').auto() and not have_system and not have_tools
421 xkbcommon = not_found
423 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
424 method: 'pkg-config', kwargs: static_kwargs)
427 if config_host.has_key('CONFIG_VDE')
428 vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
431 if 'CONFIG_LIBPULSE' in config_host
432 pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
433 link_args: config_host['PULSE_LIBS'].split())
436 if 'CONFIG_ALSA' in config_host
437 alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
438 link_args: config_host['ALSA_LIBS'].split())
441 if 'CONFIG_LIBJACK' in config_host
442 jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
445 spice_headers = not_found
446 spice_protocol = not_found
447 if 'CONFIG_SPICE' in config_host
448 spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
449 link_args: config_host['SPICE_LIBS'].split())
450 spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
452 if 'CONFIG_SPICE_PROTOCOL' in config_host
453 spice_protocol = declare_dependency(compile_args: config_host['SPICE_PROTOCOL_CFLAGS'].split())
455 rt = cc.find_library('rt', required: false)
457 if 'CONFIG_PLUGIN' in config_host
458 libdl = cc.find_library('dl', required: true)
461 if not get_option('libiscsi').auto() or have_block
462 libiscsi = dependency('libiscsi', version: '>=1.9.0',
463 required: get_option('libiscsi'),
464 method: 'pkg-config', kwargs: static_kwargs)
467 if not get_option('zstd').auto() or have_block
468 zstd = dependency('libzstd', version: '>=1.4.0',
469 required: get_option('zstd'),
470 method: 'pkg-config', kwargs: static_kwargs)
473 if 'CONFIG_GBM' in config_host
474 gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
475 link_args: config_host['GBM_LIBS'].split())
478 if 'CONFIG_VIRGL' in config_host
479 virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
480 link_args: config_host['VIRGL_LIBS'].split())
483 if not get_option('curl').auto() or have_block
484 curl = dependency('libcurl', version: '>=7.29.0',
485 method: 'pkg-config',
486 required: get_option('curl'),
487 kwargs: static_kwargs)
490 if targetos == 'linux' and (have_system or have_tools)
491 libudev = dependency('libudev',
492 method: 'pkg-config',
493 required: get_option('libudev'),
494 kwargs: static_kwargs)
497 mpathlibs = [libudev]
498 mpathpersist = not_found
499 mpathpersist_new_api = false
500 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
501 mpath_test_source_new = '''
503 #include <mpath_persist.h>
504 unsigned mpath_mx_alloc_len = 1024;
506 static struct config *multipath_conf;
507 extern struct udev *udev;
508 extern struct config *get_multipath_config(void);
509 extern void put_multipath_config(struct config *conf);
511 struct config *get_multipath_config(void) { return multipath_conf; }
512 void put_multipath_config(struct config *conf) { }
515 multipath_conf = mpath_lib_init();
518 mpath_test_source_old = '''
520 #include <mpath_persist.h>
521 unsigned mpath_mx_alloc_len = 1024;
524 struct udev *udev = udev_new();
525 mpath_lib_init(udev);
528 libmpathpersist = cc.find_library('mpathpersist',
529 required: get_option('mpath'),
530 kwargs: static_kwargs)
531 if libmpathpersist.found()
532 mpathlibs += libmpathpersist
534 mpathlibs += cc.find_library('devmapper',
535 required: get_option('mpath'),
536 kwargs: static_kwargs)
538 mpathlibs += cc.find_library('multipath',
539 required: get_option('mpath'),
540 kwargs: static_kwargs)
541 foreach lib: mpathlibs
547 if mpathlibs.length() == 0
548 msg = 'Dependencies missing for libmpathpersist'
549 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
550 mpathpersist = declare_dependency(dependencies: mpathlibs)
551 mpathpersist_new_api = true
552 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
553 mpathpersist = declare_dependency(dependencies: mpathlibs)
555 msg = 'Cannot detect libmpathpersist API'
557 if not mpathpersist.found()
558 if get_option('mpath').enabled()
561 warning(msg + ', disabling')
569 if have_system and not get_option('curses').disabled()
576 setlocale(LC_ALL, "");
578 addwstr(L"wide chars\n");
580 add_wch(WACS_DEGREE);
584 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
585 foreach curses_dep : curses_dep_list
586 if not curses.found()
587 curses = dependency(curses_dep,
589 method: 'pkg-config',
590 kwargs: static_kwargs)
593 msg = get_option('curses').enabled() ? 'curses library not found' : ''
594 curses_compile_args = ['-DNCURSES_WIDECHAR']
596 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
597 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
599 msg = 'curses package not usable'
603 if not curses.found()
604 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
605 if targetos != 'windows' and not has_curses_h
606 message('Trying with /usr/include/ncursesw')
607 curses_compile_args += ['-I/usr/include/ncursesw']
608 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
611 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
612 foreach curses_libname : curses_libname_list
613 libcurses = cc.find_library(curses_libname,
615 kwargs: static_kwargs)
617 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
618 curses = declare_dependency(compile_args: curses_compile_args,
619 dependencies: [libcurses])
622 msg = 'curses library not usable'
628 if not get_option('iconv').disabled()
629 foreach link_args : [ ['-liconv'], [] ]
630 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
631 # We need to use libiconv if available because mixing libiconv's headers with
632 # the system libc does not work.
633 # However, without adding glib to the dependencies -L/usr/local/lib will not be
634 # included in the command line and libiconv will not be found.
638 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
639 return conv != (iconv_t) -1;
640 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
641 iconv = declare_dependency(link_args: link_args, dependencies: glib)
646 if curses.found() and not iconv.found()
647 if get_option('iconv').enabled()
648 error('iconv not available')
650 msg = 'iconv required for curses UI but not available'
653 if not curses.found() and msg != ''
654 if get_option('curses').enabled()
657 warning(msg + ', disabling')
663 if not get_option('brlapi').auto() or have_system
664 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
665 required: get_option('brlapi'),
666 kwargs: static_kwargs)
667 if brlapi.found() and not cc.links('''
670 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
672 if get_option('brlapi').enabled()
673 error('could not link brlapi')
675 warning('could not link brlapi, disabling')
681 if not get_option('sdl').auto() or (have_system and not cocoa.found())
682 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
683 sdl_image = not_found
686 # work around 2.0.8 bug
687 sdl = declare_dependency(compile_args: '-Wno-undef',
689 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
690 method: 'pkg-config', kwargs: static_kwargs)
692 if get_option('sdl_image').enabled()
693 error('sdl-image required, but SDL was @0@'.format(
694 get_option('sdl').disabled() ? 'disabled' : 'not found'))
696 sdl_image = not_found
700 if not get_option('rbd').auto() or have_block
701 librados = cc.find_library('rados', required: get_option('rbd'),
702 kwargs: static_kwargs)
703 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
704 required: get_option('rbd'),
705 kwargs: static_kwargs)
706 if librados.found() and librbd.found()
709 #include <rbd/librbd.h>
712 rados_create(&cluster, NULL);
714 }''', dependencies: [librbd, librados])
715 rbd = declare_dependency(dependencies: [librbd, librados])
716 elif get_option('rbd').enabled()
717 error('could not link librados')
719 warning('could not link librados, disabling')
724 glusterfs = not_found
725 glusterfs_ftruncate_has_stat = false
726 glusterfs_iocb_has_stat = false
727 if not get_option('glusterfs').auto() or have_block
728 glusterfs = dependency('glusterfs-api', version: '>=3',
729 required: get_option('glusterfs'),
730 method: 'pkg-config', kwargs: static_kwargs)
732 glusterfs_ftruncate_has_stat = cc.links('''
733 #include <glusterfs/api/glfs.h>
738 /* new glfs_ftruncate() passes two additional args */
739 return glfs_ftruncate(NULL, 0, NULL, NULL);
741 ''', dependencies: glusterfs)
742 glusterfs_iocb_has_stat = cc.links('''
743 #include <glusterfs/api/glfs.h>
745 /* new glfs_io_cbk() passes two additional glfs_stat structs */
747 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
753 glfs_io_cbk iocb = &glusterfs_iocb;
754 iocb(NULL, 0 , NULL, NULL, NULL);
757 ''', dependencies: glusterfs)
761 if 'CONFIG_LIBSSH' in config_host
762 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
763 link_args: config_host['LIBSSH_LIBS'].split())
766 if not get_option('bzip2').auto() or have_block
767 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
768 required: get_option('bzip2'),
769 kwargs: static_kwargs)
770 if libbzip2.found() and not cc.links('''
772 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
774 if get_option('bzip2').enabled()
775 error('could not link libbzip2')
777 warning('could not link libbzip2, disabling')
783 if not get_option('lzfse').auto() or have_block
784 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
785 required: get_option('lzfse'),
786 kwargs: static_kwargs)
788 if liblzfse.found() and not cc.links('''
790 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
792 if get_option('lzfse').enabled()
793 error('could not link liblzfse')
795 warning('could not link liblzfse, disabling')
800 if 'CONFIG_AUDIO_OSS' in config_host
801 oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
804 if 'CONFIG_AUDIO_DSOUND' in config_host
805 dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
807 coreaudio = not_found
808 if 'CONFIG_AUDIO_COREAUDIO' in config_host
809 coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
812 if 'CONFIG_OPENGL' in config_host
813 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
814 link_args: config_host['OPENGL_LIBS'].split())
818 if not get_option('gnutls').auto() or have_system
819 gnutls = dependency('gnutls', version: '>=3.5.18',
820 method: 'pkg-config',
821 required: get_option('gnutls'),
822 kwargs: static_kwargs)
825 # Nettle has priority over gcrypt
829 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
830 error('Only one of gcrypt & nettle can be enabled')
831 elif (not get_option('nettle').auto() or have_system) and not get_option('gcrypt').enabled()
832 nettle = dependency('nettle', version: '>=3.4',
833 method: 'pkg-config',
834 required: get_option('nettle'),
835 kwargs: static_kwargs)
836 if nettle.found() and cc.has_header('nettle/xts.h', dependencies: nettle)
840 if (not get_option('gcrypt').auto() or have_system) and not nettle.found()
841 gcrypt = dependency('libgcrypt', version: '>=1.5',
842 method: 'config-tool',
843 required: get_option('gcrypt'),
844 kwargs: static_kwargs)
845 if gcrypt.found() and cc.compiles('''
848 gcry_cipher_hd_t handle;
849 gcry_cipher_open(&handle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_XTS, 0);
852 ''', dependencies: gcrypt)
855 # Debian has removed -lgpg-error from libgcrypt-config
856 # as it "spreads unnecessary dependencies" which in
857 # turn breaks static builds...
858 if gcrypt.found() and enable_static
859 gcrypt = declare_dependency(dependencies: [
861 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
867 if not get_option('gtk').auto() or (have_system and not cocoa.found())
868 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
869 method: 'pkg-config',
870 required: get_option('gtk'),
871 kwargs: static_kwargs)
873 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
874 method: 'pkg-config',
876 kwargs: static_kwargs)
877 gtk = declare_dependency(dependencies: [gtk, gtkx11])
882 if 'CONFIG_VTE' in config_host
883 vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
884 link_args: config_host['VTE_LIBS'].split())
888 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
889 kwargs: static_kwargs)
895 if get_option('vnc').enabled()
896 vnc = declare_dependency() # dummy dependency
897 png = dependency('libpng', required: get_option('vnc_png'),
898 method: 'pkg-config', kwargs: static_kwargs)
899 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
900 method: 'pkg-config', kwargs: static_kwargs)
901 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
902 required: get_option('vnc_sasl'),
903 kwargs: static_kwargs)
905 sasl = declare_dependency(dependencies: sasl,
906 compile_args: '-DSTRUCT_IOVEC_DEFINED')
911 if not get_option('snappy').auto() or have_system
912 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
913 required: get_option('snappy'),
914 kwargs: static_kwargs)
916 if snappy.found() and not cc.links('''
917 #include <snappy-c.h>
918 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
920 if get_option('snappy').enabled()
921 error('could not link libsnappy')
923 warning('could not link libsnappy, disabling')
928 if not get_option('lzo').auto() or have_system
929 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
930 required: get_option('lzo'),
931 kwargs: static_kwargs)
933 if lzo.found() and not cc.links('''
934 #include <lzo/lzo1x.h>
935 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
937 if get_option('lzo').enabled()
938 error('could not link liblzo2')
940 warning('could not link liblzo2, disabling')
945 if 'CONFIG_RDMA' in config_host
946 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
949 if 'CONFIG_NUMA' in config_host
950 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
953 if 'CONFIG_XEN_BACKEND' in config_host
954 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
955 link_args: config_host['XEN_LIBS'].split())
958 if 'CONFIG_SMARTCARD' in config_host
959 cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
960 link_args: config_host['SMARTCARD_LIBS'].split())
964 u2f = dependency('u2f-emu', required: get_option('u2f'),
965 method: 'pkg-config',
966 kwargs: static_kwargs)
969 if 'CONFIG_USB_REDIR' in config_host
970 usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
971 link_args: config_host['USB_REDIR_LIBS'].split())
974 if 'CONFIG_USB_LIBUSB' in config_host
975 libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
976 link_args: config_host['LIBUSB_LIBS'].split())
979 if 'CONFIG_LIBPMEM' in config_host
980 libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
981 link_args: config_host['LIBPMEM_LIBS'].split())
983 libdaxctl = not_found
984 if 'CONFIG_LIBDAXCTL' in config_host
985 libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
989 tasn1 = dependency('libtasn1',
990 method: 'pkg-config',
991 kwargs: static_kwargs)
993 keyutils = dependency('libkeyutils', required: false,
994 method: 'pkg-config', kwargs: static_kwargs)
996 has_gettid = cc.has_function('gettid')
1001 if get_option('malloc') == 'system'
1003 not get_option('malloc_trim').disabled() and \
1004 cc.links('''#include <malloc.h>
1005 int main(void) { malloc_trim(0); return 0; }''')
1007 has_malloc_trim = false
1008 malloc = cc.find_library(get_option('malloc'), required: true)
1010 if not has_malloc_trim and get_option('malloc_trim').enabled()
1011 if get_option('malloc') == 'system'
1012 error('malloc_trim not available on this platform.')
1014 error('malloc_trim not available with non-libc memory allocator')
1018 # Check whether the glibc provides statx()
1024 #include <sys/stat.h>
1026 struct statx statxbuf;
1027 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1031 has_statx = cc.links(statx_test)
1033 have_vhost_user_blk_server = (targetos == 'linux' and
1034 'CONFIG_VHOST_USER' in config_host)
1036 if get_option('vhost_user_blk_server').enabled()
1037 if targetos != 'linux'
1038 error('vhost_user_blk_server requires linux')
1039 elif 'CONFIG_VHOST_USER' not in config_host
1040 error('vhost_user_blk_server requires vhost-user support')
1042 elif get_option('vhost_user_blk_server').disabled() or not have_system
1043 have_vhost_user_blk_server = false
1047 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1048 error('Cannot enable fuse-lseek while fuse is disabled')
1051 fuse = dependency('fuse3', required: get_option('fuse'),
1052 version: '>=3.1', method: 'pkg-config',
1053 kwargs: static_kwargs)
1055 fuse_lseek = not_found
1056 if not get_option('fuse_lseek').disabled()
1057 if fuse.version().version_compare('>=3.8')
1059 fuse_lseek = declare_dependency()
1060 elif get_option('fuse_lseek').enabled()
1062 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1064 error('fuse-lseek requires libfuse, which was not found')
1070 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1071 if libbpf.found() and not cc.links('''
1072 #include <bpf/libbpf.h>
1075 bpf_object__destroy_skeleton(NULL);
1077 }''', dependencies: libbpf)
1079 if get_option('bpf').enabled()
1080 error('libbpf skeleton test failed')
1082 warning('libbpf skeleton test failed, disabling')
1086 if get_option('cfi')
1088 # Check for dependency on LTO
1089 if not get_option('b_lto')
1090 error('Selected Control-Flow Integrity but LTO is disabled')
1092 if config_host.has_key('CONFIG_MODULES')
1093 error('Selected Control-Flow Integrity is not compatible with modules')
1095 # Check for cfi flags. CFI requires LTO so we can't use
1096 # get_supported_arguments, but need a more complex "compiles" which allows
1098 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1099 args: ['-flto', '-fsanitize=cfi-icall'] )
1100 cfi_flags += '-fsanitize=cfi-icall'
1102 error('-fsanitize=cfi-icall is not supported by the compiler')
1104 if cc.compiles('int main () { return 0; }',
1105 name: '-fsanitize-cfi-icall-generalize-pointers',
1106 args: ['-flto', '-fsanitize=cfi-icall',
1107 '-fsanitize-cfi-icall-generalize-pointers'] )
1108 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1110 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1112 if get_option('cfi_debug')
1113 if cc.compiles('int main () { return 0; }',
1114 name: '-fno-sanitize-trap=cfi-icall',
1115 args: ['-flto', '-fsanitize=cfi-icall',
1116 '-fno-sanitize-trap=cfi-icall'] )
1117 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1119 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1122 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1123 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1130 have_virtfs = (targetos == 'linux' and
1135 have_virtfs_proxy_helper = have_virtfs and have_tools
1137 if get_option('virtfs').enabled()
1139 if targetos != 'linux'
1140 error('virtio-9p (virtfs) requires Linux')
1141 elif not libcap_ng.found() or not libattr.found()
1142 error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1143 elif not have_system
1144 error('virtio-9p (virtfs) needs system emulation support')
1147 elif get_option('virtfs').disabled()
1151 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1152 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1153 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1154 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1155 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1156 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1157 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1158 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1159 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1160 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1161 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1162 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1164 config_host_data.set('CONFIG_ATTR', libattr.found())
1165 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1166 config_host_data.set('CONFIG_COCOA', cocoa.found())
1167 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1168 config_host_data.set('CONFIG_LZO', lzo.found())
1169 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1170 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1171 config_host_data.set('CONFIG_CURL', curl.found())
1172 config_host_data.set('CONFIG_CURSES', curses.found())
1173 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1174 if glusterfs.found()
1175 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1176 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1177 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1178 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1179 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1180 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1182 config_host_data.set('CONFIG_GTK', gtk.found())
1183 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1184 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1185 config_host_data.set('CONFIG_EBPF', libbpf.found())
1186 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1187 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1188 config_host_data.set('CONFIG_RBD', rbd.found())
1189 config_host_data.set('CONFIG_SDL', sdl.found())
1190 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1191 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1192 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1193 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1194 config_host_data.set('CONFIG_VNC', vnc.found())
1195 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1196 config_host_data.set('CONFIG_VNC_PNG', png.found())
1197 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1198 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1199 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1200 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1201 config_host_data.set('CONFIG_GETTID', has_gettid)
1202 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1203 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1204 config_host_data.set('CONFIG_NETTLE', nettle.found())
1205 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1206 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1207 config_host_data.set('CONFIG_STATX', has_statx)
1208 config_host_data.set('CONFIG_ZSTD', zstd.found())
1209 config_host_data.set('CONFIG_FUSE', fuse.found())
1210 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1211 config_host_data.set('CONFIG_X11', x11.found())
1212 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1213 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1214 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1215 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1216 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1218 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1219 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1220 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1221 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1222 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1223 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1225 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1227 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
1228 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1229 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
1230 foreach k, v: config_host
1231 if ignored.contains(k)
1233 elif arrays.contains(k)
1235 v = '"' + '", "'.join(v.split()) + '", '
1237 config_host_data.set(k, v)
1239 config_host_data.set('HOST_' + v.to_upper(), 1)
1240 elif strings.contains(k)
1241 if not k.startswith('CONFIG_')
1242 k = 'CONFIG_' + k.to_upper()
1244 config_host_data.set_quoted(k, v)
1245 elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1246 config_host_data.set(k, v == 'y' ? 1 : v)
1250 ########################
1251 # Target configuration #
1252 ########################
1254 minikconf = find_program('scripts/minikconf.py')
1256 config_all_devices = {}
1257 config_all_disas = {}
1258 config_devices_mak_list = []
1259 config_devices_h = {}
1260 config_target_h = {}
1261 config_target_mak = {}
1264 'alpha' : ['CONFIG_ALPHA_DIS'],
1265 'arm' : ['CONFIG_ARM_DIS'],
1266 'avr' : ['CONFIG_AVR_DIS'],
1267 'cris' : ['CONFIG_CRIS_DIS'],
1268 'hexagon' : ['CONFIG_HEXAGON_DIS'],
1269 'hppa' : ['CONFIG_HPPA_DIS'],
1270 'i386' : ['CONFIG_I386_DIS'],
1271 'x86_64' : ['CONFIG_I386_DIS'],
1272 'x32' : ['CONFIG_I386_DIS'],
1273 'm68k' : ['CONFIG_M68K_DIS'],
1274 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1275 'mips' : ['CONFIG_MIPS_DIS'],
1276 'nios2' : ['CONFIG_NIOS2_DIS'],
1277 'or1k' : ['CONFIG_OPENRISC_DIS'],
1278 'ppc' : ['CONFIG_PPC_DIS'],
1279 'riscv' : ['CONFIG_RISCV_DIS'],
1280 'rx' : ['CONFIG_RX_DIS'],
1281 's390' : ['CONFIG_S390_DIS'],
1282 'sh4' : ['CONFIG_SH4_DIS'],
1283 'sparc' : ['CONFIG_SPARC_DIS'],
1284 'xtensa' : ['CONFIG_XTENSA_DIS'],
1286 if link_language == 'cpp'
1288 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1289 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1290 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1295 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1296 ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1297 ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \
1298 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1299 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1300 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1301 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1302 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1303 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1304 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1305 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1306 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1308 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1310 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1311 actual_target_dirs = []
1313 foreach target : target_dirs
1314 config_target = { 'TARGET_NAME': target.split('-')[0] }
1315 if target.endswith('linux-user')
1316 if targetos != 'linux'
1320 error('Target @0@ is only available on a Linux host'.format(target))
1322 config_target += { 'CONFIG_LINUX_USER': 'y' }
1323 elif target.endswith('bsd-user')
1324 if 'CONFIG_BSD' not in config_host
1328 error('Target @0@ is only available on a BSD host'.format(target))
1330 config_target += { 'CONFIG_BSD_USER': 'y' }
1331 elif target.endswith('softmmu')
1332 config_target += { 'CONFIG_SOFTMMU': 'y' }
1334 if target.endswith('-user')
1336 'CONFIG_USER_ONLY': 'y',
1337 'CONFIG_QEMU_INTERP_PREFIX':
1338 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1343 foreach sym: accelerators
1344 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1345 config_target += { sym: 'y' }
1346 config_all += { sym: 'y' }
1347 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1348 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1349 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1350 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1352 accel_kconfig += [ sym + '=y' ]
1355 if accel_kconfig.length() == 0
1359 error('No accelerator available for target @0@'.format(target))
1362 actual_target_dirs += target
1363 config_target += keyval.load('default-configs/targets' / target + '.mak')
1364 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1366 if 'TARGET_NEED_FDT' in config_target
1367 fdt_required += target
1371 if 'TARGET_BASE_ARCH' not in config_target
1372 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1374 if 'TARGET_ABI_DIR' not in config_target
1375 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1378 foreach k, v: disassemblers
1379 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1381 config_target += { sym: 'y' }
1382 config_all_disas += { sym: 'y' }
1387 config_target_data = configuration_data()
1388 foreach k, v: config_target
1389 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1391 elif ignored.contains(k)
1393 elif k == 'TARGET_BASE_ARCH'
1394 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1395 # not used to select files from sourcesets.
1396 config_target_data.set('TARGET_' + v.to_upper(), 1)
1397 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1398 config_target_data.set_quoted(k, v)
1400 config_target_data.set(k, 1)
1402 config_target_data.set(k, v)
1405 config_target_h += {target: configure_file(output: target + '-config-target.h',
1406 configuration: config_target_data)}
1408 if target.endswith('-softmmu')
1409 config_devices_mak = target + '-config-devices.mak'
1410 config_devices_mak = configure_file(
1411 input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
1412 output: config_devices_mak,
1413 depfile: config_devices_mak + '.d',
1415 command: [minikconf,
1416 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1417 config_devices_mak, '@DEPFILE@', '@INPUT@',
1418 host_kconfig, accel_kconfig])
1420 config_devices_data = configuration_data()
1421 config_devices = keyval.load(config_devices_mak)
1422 foreach k, v: config_devices
1423 config_devices_data.set(k, 1)
1425 config_devices_mak_list += config_devices_mak
1426 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1427 configuration: config_devices_data)}
1428 config_target += config_devices
1429 config_all_devices += config_devices
1431 config_target_mak += {target: config_target}
1433 target_dirs = actual_target_dirs
1435 # This configuration is used to build files that are shared by
1436 # multiple binaries, and then extracted out of the "common"
1437 # static_library target.
1439 # We do not use all_sources()/all_dependencies(), because it would
1440 # build literally all source files, including devices only used by
1441 # targets that are not built for this compilation. The CONFIG_ALL
1442 # pseudo symbol replaces it.
1444 config_all += config_all_devices
1445 config_all += config_host
1446 config_all += config_all_disas
1448 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1449 'CONFIG_SOFTMMU': have_system,
1450 'CONFIG_USER_ONLY': have_user,
1458 capstone = not_found
1459 capstone_opt = get_option('capstone')
1460 if capstone_opt in ['enabled', 'auto', 'system']
1461 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1462 capstone = dependency('capstone', version: '>=4.0',
1463 kwargs: static_kwargs, method: 'pkg-config',
1464 required: capstone_opt == 'system' or
1465 capstone_opt == 'enabled' and not have_internal)
1467 capstone_opt = 'system'
1469 capstone_opt = 'internal'
1471 capstone_opt = 'disabled'
1474 if capstone_opt == 'internal'
1475 capstone_data = configuration_data()
1476 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1478 capstone_files = files(
1480 'capstone/MCInst.c',
1481 'capstone/MCInstrDesc.c',
1482 'capstone/MCRegisterInfo.c',
1483 'capstone/SStream.c',
1487 if 'CONFIG_ARM_DIS' in config_all_disas
1488 capstone_data.set('CAPSTONE_HAS_ARM', '1')
1489 capstone_files += files(
1490 'capstone/arch/ARM/ARMDisassembler.c',
1491 'capstone/arch/ARM/ARMInstPrinter.c',
1492 'capstone/arch/ARM/ARMMapping.c',
1493 'capstone/arch/ARM/ARMModule.c'
1497 # FIXME: This config entry currently depends on a c++ compiler.
1498 # Which is needed for building libvixl, but not for capstone.
1499 if 'CONFIG_ARM_A64_DIS' in config_all_disas
1500 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1501 capstone_files += files(
1502 'capstone/arch/AArch64/AArch64BaseInfo.c',
1503 'capstone/arch/AArch64/AArch64Disassembler.c',
1504 'capstone/arch/AArch64/AArch64InstPrinter.c',
1505 'capstone/arch/AArch64/AArch64Mapping.c',
1506 'capstone/arch/AArch64/AArch64Module.c'
1510 if 'CONFIG_PPC_DIS' in config_all_disas
1511 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1512 capstone_files += files(
1513 'capstone/arch/PowerPC/PPCDisassembler.c',
1514 'capstone/arch/PowerPC/PPCInstPrinter.c',
1515 'capstone/arch/PowerPC/PPCMapping.c',
1516 'capstone/arch/PowerPC/PPCModule.c'
1520 if 'CONFIG_S390_DIS' in config_all_disas
1521 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1522 capstone_files += files(
1523 'capstone/arch/SystemZ/SystemZDisassembler.c',
1524 'capstone/arch/SystemZ/SystemZInstPrinter.c',
1525 'capstone/arch/SystemZ/SystemZMapping.c',
1526 'capstone/arch/SystemZ/SystemZModule.c',
1527 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1531 if 'CONFIG_I386_DIS' in config_all_disas
1532 capstone_data.set('CAPSTONE_HAS_X86', 1)
1533 capstone_files += files(
1534 'capstone/arch/X86/X86Disassembler.c',
1535 'capstone/arch/X86/X86DisassemblerDecoder.c',
1536 'capstone/arch/X86/X86ATTInstPrinter.c',
1537 'capstone/arch/X86/X86IntelInstPrinter.c',
1538 'capstone/arch/X86/X86InstPrinterCommon.c',
1539 'capstone/arch/X86/X86Mapping.c',
1540 'capstone/arch/X86/X86Module.c'
1544 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1547 # FIXME: There does not seem to be a way to completely replace the c_args
1548 # that come from add_project_arguments() -- we can only add to them.
1549 # So: disable all warnings with a big hammer.
1552 # Include all configuration defines via a header file, which will wind up
1553 # as a dependency on the object file, and thus changes here will result
1555 '-include', 'capstone-defs.h'
1558 libcapstone = static_library('capstone',
1559 build_by_default: false,
1560 sources: capstone_files,
1561 c_args: capstone_cargs,
1562 include_directories: 'capstone/include')
1563 capstone = declare_dependency(link_with: libcapstone,
1564 include_directories: 'capstone/include/capstone')
1568 slirp_opt = 'disabled'
1570 slirp_opt = get_option('slirp')
1571 if slirp_opt in ['enabled', 'auto', 'system']
1572 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1573 slirp = dependency('slirp', kwargs: static_kwargs,
1574 method: 'pkg-config',
1575 required: slirp_opt == 'system' or
1576 slirp_opt == 'enabled' and not have_internal)
1578 slirp_opt = 'system'
1580 slirp_opt = 'internal'
1582 slirp_opt = 'disabled'
1585 if slirp_opt == 'internal'
1587 if targetos == 'windows'
1588 slirp_deps = cc.find_library('iphlpapi')
1590 slirp_conf = configuration_data()
1591 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1592 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1593 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1594 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1595 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1597 'slirp/src/arp_table.c',
1598 'slirp/src/bootp.c',
1599 'slirp/src/cksum.c',
1600 'slirp/src/dhcpv6.c',
1601 'slirp/src/dnssearch.c',
1603 'slirp/src/ip6_icmp.c',
1604 'slirp/src/ip6_input.c',
1605 'slirp/src/ip6_output.c',
1606 'slirp/src/ip_icmp.c',
1607 'slirp/src/ip_input.c',
1608 'slirp/src/ip_output.c',
1612 'slirp/src/ndp_table.c',
1614 'slirp/src/slirp.c',
1615 'slirp/src/socket.c',
1616 'slirp/src/state.c',
1617 'slirp/src/stream.c',
1618 'slirp/src/tcp_input.c',
1619 'slirp/src/tcp_output.c',
1620 'slirp/src/tcp_subr.c',
1621 'slirp/src/tcp_timer.c',
1626 'slirp/src/version.c',
1627 'slirp/src/vmstate.c',
1631 input : 'slirp/src/libslirp-version.h.in',
1632 output : 'libslirp-version.h',
1633 configuration: slirp_conf)
1635 slirp_inc = include_directories('slirp', 'slirp/src')
1636 libslirp = static_library('slirp',
1637 build_by_default: false,
1638 sources: slirp_files,
1639 c_args: slirp_cargs,
1640 include_directories: slirp_inc)
1641 slirp = declare_dependency(link_with: libslirp,
1642 dependencies: slirp_deps,
1643 include_directories: slirp_inc)
1647 # For CFI, we need to compile slirp as a static library together with qemu.
1648 # This is because we register slirp functions as callbacks for QEMU Timers.
1649 # When using a system-wide shared libslirp, the type information for the
1650 # callback is missing and the timer call produces a false positive with CFI.
1652 # Now that slirp_opt has been defined, check if the selected slirp is compatible
1653 # with control-flow integrity.
1654 if get_option('cfi') and slirp_opt == 'system'
1655 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
1656 + ' Please configure with --enable-slirp=git')
1660 fdt_opt = get_option('fdt')
1662 if fdt_opt in ['enabled', 'auto', 'system']
1663 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1664 fdt = cc.find_library('fdt', kwargs: static_kwargs,
1665 required: fdt_opt == 'system' or
1666 fdt_opt == 'enabled' and not have_internal)
1667 if fdt.found() and cc.links('''
1669 #include <libfdt_env.h>
1670 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1674 fdt_opt = 'internal'
1676 fdt_opt = 'disabled'
1679 if fdt_opt == 'internal'
1682 'dtc/libfdt/fdt_ro.c',
1683 'dtc/libfdt/fdt_wip.c',
1684 'dtc/libfdt/fdt_sw.c',
1685 'dtc/libfdt/fdt_rw.c',
1686 'dtc/libfdt/fdt_strerror.c',
1687 'dtc/libfdt/fdt_empty_tree.c',
1688 'dtc/libfdt/fdt_addresses.c',
1689 'dtc/libfdt/fdt_overlay.c',
1690 'dtc/libfdt/fdt_check.c',
1693 fdt_inc = include_directories('dtc/libfdt')
1694 libfdt = static_library('fdt',
1695 build_by_default: false,
1697 include_directories: fdt_inc)
1698 fdt = declare_dependency(link_with: libfdt,
1699 include_directories: fdt_inc)
1702 if not fdt.found() and fdt_required.length() > 0
1703 error('fdt not available but required by targets ' + ', '.join(fdt_required))
1706 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1707 config_host_data.set('CONFIG_FDT', fdt.found())
1708 config_host_data.set('CONFIG_SLIRP', slirp.found())
1710 #####################
1711 # Generated sources #
1712 #####################
1714 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1716 hxtool = find_program('scripts/hxtool')
1717 shaderinclude = find_program('scripts/shaderinclude.pl')
1718 qapi_gen = find_program('scripts/qapi-gen.py')
1719 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1720 meson.source_root() / 'scripts/qapi/commands.py',
1721 meson.source_root() / 'scripts/qapi/common.py',
1722 meson.source_root() / 'scripts/qapi/error.py',
1723 meson.source_root() / 'scripts/qapi/events.py',
1724 meson.source_root() / 'scripts/qapi/expr.py',
1725 meson.source_root() / 'scripts/qapi/gen.py',
1726 meson.source_root() / 'scripts/qapi/introspect.py',
1727 meson.source_root() / 'scripts/qapi/parser.py',
1728 meson.source_root() / 'scripts/qapi/schema.py',
1729 meson.source_root() / 'scripts/qapi/source.py',
1730 meson.source_root() / 'scripts/qapi/types.py',
1731 meson.source_root() / 'scripts/qapi/visit.py',
1732 meson.source_root() / 'scripts/qapi/common.py',
1733 meson.source_root() / 'scripts/qapi-gen.py'
1737 python, files('scripts/tracetool.py'),
1738 '--backend=' + config_host['TRACE_BACKENDS']
1740 tracetool_depends = files(
1741 'scripts/tracetool/backend/log.py',
1742 'scripts/tracetool/backend/__init__.py',
1743 'scripts/tracetool/backend/dtrace.py',
1744 'scripts/tracetool/backend/ftrace.py',
1745 'scripts/tracetool/backend/simple.py',
1746 'scripts/tracetool/backend/syslog.py',
1747 'scripts/tracetool/backend/ust.py',
1748 'scripts/tracetool/format/tcg_h.py',
1749 'scripts/tracetool/format/ust_events_c.py',
1750 'scripts/tracetool/format/ust_events_h.py',
1751 'scripts/tracetool/format/__init__.py',
1752 'scripts/tracetool/format/d.py',
1753 'scripts/tracetool/format/tcg_helper_c.py',
1754 'scripts/tracetool/format/simpletrace_stap.py',
1755 'scripts/tracetool/format/c.py',
1756 'scripts/tracetool/format/h.py',
1757 'scripts/tracetool/format/tcg_helper_h.py',
1758 'scripts/tracetool/format/log_stap.py',
1759 'scripts/tracetool/format/stap.py',
1760 'scripts/tracetool/format/tcg_helper_wrapper_h.py',
1761 'scripts/tracetool/__init__.py',
1762 'scripts/tracetool/transform.py',
1763 'scripts/tracetool/vcpu.py'
1766 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1767 meson.current_source_dir(),
1768 config_host['PKGVERSION'], meson.project_version()]
1769 qemu_version = custom_target('qemu-version.h',
1770 output: 'qemu-version.h',
1771 command: qemu_version_cmd,
1773 build_by_default: true,
1774 build_always_stale: true)
1775 genh += qemu_version
1779 ['qemu-options.hx', 'qemu-options.def'],
1780 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1784 ['hmp-commands.hx', 'hmp-commands.h'],
1785 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1788 foreach d : hx_headers
1789 hxdep += custom_target(d[1],
1793 build_by_default: true, # to be removed when added to a target
1794 command: [hxtool, '-h', '@INPUT0@'])
1802 authz_ss = ss.source_set()
1803 blockdev_ss = ss.source_set()
1804 block_ss = ss.source_set()
1805 bsd_user_ss = ss.source_set()
1806 chardev_ss = ss.source_set()
1807 common_ss = ss.source_set()
1808 crypto_ss = ss.source_set()
1809 io_ss = ss.source_set()
1810 linux_user_ss = ss.source_set()
1811 qmp_ss = ss.source_set()
1812 qom_ss = ss.source_set()
1813 softmmu_ss = ss.source_set()
1814 specific_fuzz_ss = ss.source_set()
1815 specific_ss = ss.source_set()
1816 stub_ss = ss.source_set()
1817 trace_ss = ss.source_set()
1818 user_ss = ss.source_set()
1819 util_ss = ss.source_set()
1824 target_softmmu_arch = {}
1825 target_user_arch = {}
1831 # TODO: add each directory to the subdirs from its own meson.build, once
1833 trace_events_subdirs = [
1841 trace_events_subdirs += [ 'linux-user' ]
1844 trace_events_subdirs += [
1853 trace_events_subdirs += [
1867 'hw/block/dataplane',
1915 if have_system or have_user
1916 trace_events_subdirs += [
1931 vhost_user = not_found
1932 if 'CONFIG_VHOST_USER' in config_host
1933 libvhost_user = subproject('libvhost-user')
1934 vhost_user = libvhost_user.get_variable('vhost_user_dep')
1949 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1950 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1953 stub_ss = stub_ss.apply(config_all, strict: false)
1955 util_ss.add_all(trace_ss)
1956 util_ss = util_ss.apply(config_all, strict: false)
1957 libqemuutil = static_library('qemuutil',
1958 sources: util_ss.sources() + stub_ss.sources() + genh,
1959 dependencies: [util_ss.dependencies(), libm, glib, socket, malloc, pixman])
1960 qemuutil = declare_dependency(link_with: libqemuutil,
1961 sources: genh + version_res)
1963 if have_system or have_user
1964 decodetree = generator(find_program('scripts/decodetree.py'),
1965 output: 'decode-@BASENAME@.c.inc',
1966 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1967 subdir('libdecnumber')
1984 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1990 blockdev_ss.add(files(
1997 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1998 # os-win32.c does not
1999 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2000 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2003 common_ss.add(files('cpus-common.c'))
2007 common_ss.add(capstone)
2008 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2010 # Work around a gcc bug/misfeature wherein constant propagation looks
2012 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2013 # to guess that a const variable is always zero. Without lto, this is
2014 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2015 # without lto, not even the alias is required -- we simply use different
2016 # declarations in different compilation units.
2017 pagevary = files('page-vary-common.c')
2018 if get_option('b_lto')
2019 pagevary_flags = ['-fno-lto']
2020 if get_option('cfi')
2021 pagevary_flags += '-fno-sanitize=cfi-icall'
2023 pagevary = static_library('page-vary-common', sources: pagevary,
2024 c_args: pagevary_flags)
2025 pagevary = declare_dependency(link_with: pagevary)
2027 common_ss.add(pagevary)
2028 specific_ss.add(files('page-vary.c'))
2036 subdir('semihosting')
2043 subdir('linux-user')
2046 common_ss.add(libbpf)
2048 bsd_user_ss.add(files('gdbstub.c'))
2049 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
2051 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
2052 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
2054 # needed for fuzzing binaries
2055 subdir('tests/qtest/libqos')
2056 subdir('tests/qtest/fuzz')
2058 ########################
2059 # Library dependencies #
2060 ########################
2064 foreach d, list : modules
2065 foreach m, module_ss : list
2066 if enable_modules and targetos != 'windows'
2067 module_ss = module_ss.apply(config_all, strict: false)
2068 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2069 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2077 block_ss.add_all(module_ss)
2079 softmmu_ss.add_all(module_ss)
2085 nm = find_program('nm')
2086 undefsym = find_program('scripts/undefsym.py')
2087 block_syms = custom_target('block.syms', output: 'block.syms',
2088 input: [libqemuutil, block_mods],
2090 command: [undefsym, nm, '@INPUT@'])
2091 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2092 input: [libqemuutil, softmmu_mods],
2094 command: [undefsym, nm, '@INPUT@'])
2096 qom_ss = qom_ss.apply(config_host, strict: false)
2097 libqom = static_library('qom', qom_ss.sources() + genh,
2098 dependencies: [qom_ss.dependencies()],
2101 qom = declare_dependency(link_whole: libqom)
2103 authz_ss = authz_ss.apply(config_host, strict: false)
2104 libauthz = static_library('authz', authz_ss.sources() + genh,
2105 dependencies: [authz_ss.dependencies()],
2107 build_by_default: false)
2109 authz = declare_dependency(link_whole: libauthz,
2112 crypto_ss = crypto_ss.apply(config_host, strict: false)
2113 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2114 dependencies: [crypto_ss.dependencies()],
2116 build_by_default: false)
2118 crypto = declare_dependency(link_whole: libcrypto,
2119 dependencies: [authz, qom])
2121 io_ss = io_ss.apply(config_host, strict: false)
2122 libio = static_library('io', io_ss.sources() + genh,
2123 dependencies: [io_ss.dependencies()],
2124 link_with: libqemuutil,
2126 build_by_default: false)
2128 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2130 libmigration = static_library('migration', sources: migration_files + genh,
2132 build_by_default: false)
2133 migration = declare_dependency(link_with: libmigration,
2134 dependencies: [zlib, qom, io])
2135 softmmu_ss.add(migration)
2137 block_ss = block_ss.apply(config_host, strict: false)
2138 libblock = static_library('block', block_ss.sources() + genh,
2139 dependencies: block_ss.dependencies(),
2140 link_depends: block_syms,
2142 build_by_default: false)
2144 block = declare_dependency(link_whole: [libblock],
2145 link_args: '@block.syms',
2146 dependencies: [crypto, io])
2148 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2149 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2150 dependencies: blockdev_ss.dependencies(),
2152 build_by_default: false)
2154 blockdev = declare_dependency(link_whole: [libblockdev],
2155 dependencies: [block])
2157 qmp_ss = qmp_ss.apply(config_host, strict: false)
2158 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2159 dependencies: qmp_ss.dependencies(),
2161 build_by_default: false)
2163 qmp = declare_dependency(link_whole: [libqmp])
2165 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2167 dependencies: [gnutls],
2168 build_by_default: false)
2170 chardev = declare_dependency(link_whole: libchardev)
2172 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2174 build_by_default: false)
2175 hwcore = declare_dependency(link_whole: libhwcore)
2176 common_ss.add(hwcore)
2182 foreach m : block_mods + softmmu_mods
2183 shared_module(m.name(),
2187 install_dir: qemu_moddir)
2190 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2191 common_ss.add(qom, qemuutil)
2193 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2194 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2196 common_all = common_ss.apply(config_all, strict: false)
2197 common_all = static_library('common',
2198 build_by_default: false,
2199 sources: common_all.sources() + genh,
2200 implicit_include_directories: false,
2201 dependencies: common_all.dependencies(),
2204 feature_to_c = find_program('scripts/feature_to_c.sh')
2207 foreach target : target_dirs
2208 config_target = config_target_mak[target]
2209 target_name = config_target['TARGET_NAME']
2210 arch = config_target['TARGET_BASE_ARCH']
2211 arch_srcs = [config_target_h[target]]
2213 c_args = ['-DNEED_CPU_H',
2214 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2215 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2216 link_args = emulator_link_args
2218 config_target += config_host
2219 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2220 if targetos == 'linux'
2221 target_inc += include_directories('linux-headers', is_system: true)
2223 if target.endswith('-softmmu')
2224 qemu_target_name = 'qemu-system-' + target_name
2225 target_type='system'
2226 t = target_softmmu_arch[arch].apply(config_target, strict: false)
2227 arch_srcs += t.sources()
2228 arch_deps += t.dependencies()
2230 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2231 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2232 arch_srcs += hw.sources()
2233 arch_deps += hw.dependencies()
2235 arch_srcs += config_devices_h[target]
2236 link_args += ['@block.syms', '@qemu.syms']
2238 abi = config_target['TARGET_ABI_DIR']
2240 qemu_target_name = 'qemu-' + target_name
2241 if arch in target_user_arch
2242 t = target_user_arch[arch].apply(config_target, strict: false)
2243 arch_srcs += t.sources()
2244 arch_deps += t.dependencies()
2246 if 'CONFIG_LINUX_USER' in config_target
2247 base_dir = 'linux-user'
2248 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2250 base_dir = 'bsd-user'
2251 target_inc += include_directories('bsd-user/freebsd')
2253 target_inc += include_directories(
2257 if 'CONFIG_LINUX_USER' in config_target
2258 dir = base_dir / abi
2259 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2260 if config_target.has_key('TARGET_SYSTBL_ABI')
2262 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2263 extra_args : config_target['TARGET_SYSTBL_ABI'])
2268 if 'TARGET_XML_FILES' in config_target
2269 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2270 output: target + '-gdbstub-xml.c',
2271 input: files(config_target['TARGET_XML_FILES'].split()),
2272 command: [feature_to_c, '@INPUT@'],
2274 arch_srcs += gdbstub_xml
2277 t = target_arch[arch].apply(config_target, strict: false)
2278 arch_srcs += t.sources()
2279 arch_deps += t.dependencies()
2281 target_common = common_ss.apply(config_target, strict: false)
2282 objects = common_all.extract_objects(target_common.sources())
2283 deps = target_common.dependencies()
2285 target_specific = specific_ss.apply(config_target, strict: false)
2286 arch_srcs += target_specific.sources()
2287 arch_deps += target_specific.dependencies()
2289 lib = static_library('qemu-' + target,
2290 sources: arch_srcs + genh,
2291 dependencies: arch_deps,
2293 include_directories: target_inc,
2295 build_by_default: false,
2298 if target.endswith('-softmmu')
2300 'name': 'qemu-system-' + target_name,
2302 'sources': files('softmmu/main.c'),
2305 if targetos == 'windows' and (sdl.found() or gtk.found())
2307 'name': 'qemu-system-' + target_name + 'w',
2309 'sources': files('softmmu/main.c'),
2313 if config_host.has_key('CONFIG_FUZZ')
2314 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2316 'name': 'qemu-fuzz-' + target_name,
2318 'sources': specific_fuzz.sources(),
2319 'dependencies': specific_fuzz.dependencies(),
2324 'name': 'qemu-' + target_name,
2331 exe_name = exe['name']
2332 exe_sign = 'CONFIG_HVF' in config_target
2334 exe_name += '-unsigned'
2337 emulator = executable(exe_name, exe['sources'],
2340 dependencies: arch_deps + deps + exe['dependencies'],
2341 objects: lib.extract_all_objects(recursive: true),
2342 link_language: link_language,
2343 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2344 link_args: link_args,
2345 gui_app: exe['gui'])
2348 emulators += {exe['name'] : custom_target(exe['name'],
2350 output: exe['name'],
2352 meson.current_source_dir() / 'scripts/entitlement.sh',
2353 meson.current_build_dir() / exe_name,
2354 meson.current_build_dir() / exe['name'],
2355 meson.current_source_dir() / 'accel/hvf/entitlements.plist'
2359 meson.add_install_script('scripts/entitlement.sh', '--install',
2360 get_option('bindir') / exe_name,
2361 get_option('bindir') / exe['name'],
2362 meson.current_source_dir() / 'accel/hvf/entitlements.plist')
2364 emulators += {exe['name']: emulator}
2367 if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2369 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2370 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2371 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2372 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2374 custom_target(exe['name'] + stp['ext'],
2375 input: trace_events_all,
2376 output: exe['name'] + stp['ext'],
2377 install: stp['install'],
2378 install_dir: get_option('datadir') / 'systemtap/tapset',
2380 tracetool, '--group=all', '--format=' + stp['fmt'],
2381 '--binary=' + stp['bin'],
2382 '--target-name=' + target_name,
2383 '--target-type=' + target_type,
2384 '--probe-prefix=qemu.' + target_type + '.' + target_name,
2385 '@INPUT@', '@OUTPUT@'
2387 depend_files: tracetool_depends)
2393 # Other build targets
2395 if 'CONFIG_PLUGIN' in config_host
2396 install_headers('include/qemu/qemu-plugin.h')
2399 if 'CONFIG_GUEST_AGENT' in config_host
2401 elif get_option('guest_agent_msi').enabled()
2402 error('Guest agent MSI requested, but the guest agent is not being built')
2405 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2406 # when we don't build tools or system
2407 if xkbcommon.found()
2408 # used for the update-keymaps target, so include rules even if !have_tools
2409 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2410 dependencies: [qemuutil, xkbcommon], install: have_tools)
2414 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2415 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2416 qemu_io = executable('qemu-io', files('qemu-io.c'),
2417 dependencies: [block, qemuutil], install: true)
2418 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2419 dependencies: [blockdev, qemuutil, gnutls], install: true)
2421 subdir('storage-daemon')
2422 subdir('contrib/rdmacm-mux')
2423 subdir('contrib/elf2dmp')
2425 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2426 dependencies: qemuutil,
2429 if 'CONFIG_VHOST_USER' in config_host
2430 subdir('contrib/vhost-user-blk')
2431 subdir('contrib/vhost-user-gpu')
2432 subdir('contrib/vhost-user-input')
2433 subdir('contrib/vhost-user-scsi')
2436 if targetos == 'linux'
2437 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2438 dependencies: [qemuutil, libcap_ng],
2440 install_dir: get_option('libexecdir'))
2442 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2443 dependencies: [authz, crypto, io, qom, qemuutil,
2444 libcap_ng, mpathpersist],
2448 if 'CONFIG_IVSHMEM' in config_host
2449 subdir('contrib/ivshmem-client')
2450 subdir('contrib/ivshmem-server')
2463 if host_machine.system() == 'windows'
2465 find_program('scripts/nsis.py'),
2467 get_option('prefix'),
2468 meson.current_source_dir(),
2471 '-DDISPLAYVERSION=' + meson.project_version(),
2474 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2477 nsis_cmd += '-DCONFIG_GTK=y'
2480 nsis = custom_target('nsis',
2481 output: 'qemu-setup-' + meson.project_version() + '.exe',
2482 input: files('qemu.nsi'),
2483 build_always_stale: true,
2484 command: nsis_cmd + ['@INPUT@'])
2485 alias_target('installer', nsis)
2488 #########################
2489 # Configuration summary #
2490 #########################
2494 summary_info += {'Install prefix': get_option('prefix')}
2495 summary_info += {'BIOS directory': qemu_datadir}
2496 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
2497 summary_info += {'binary directory': get_option('bindir')}
2498 summary_info += {'library directory': get_option('libdir')}
2499 summary_info += {'module directory': qemu_moddir}
2500 summary_info += {'libexec directory': get_option('libexecdir')}
2501 summary_info += {'include directory': get_option('includedir')}
2502 summary_info += {'config directory': get_option('sysconfdir')}
2503 if targetos != 'windows'
2504 summary_info += {'local state directory': get_option('localstatedir')}
2505 summary_info += {'Manual directory': get_option('mandir')}
2507 summary_info += {'local state directory': 'queried at runtime'}
2509 summary_info += {'Doc directory': get_option('docdir')}
2510 summary_info += {'Build directory': meson.current_build_dir()}
2511 summary_info += {'Source path': meson.current_source_dir()}
2512 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
2513 summary(summary_info, bool_yn: true, section: 'Directories')
2517 summary_info += {'git': config_host['GIT']}
2518 summary_info += {'make': config_host['MAKE']}
2519 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2520 summary_info += {'sphinx-build': sphinx_build.found()}
2521 if config_host.has_key('HAVE_GDB_BIN')
2522 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
2524 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
2525 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
2526 summary_info += {'wixl': wixl.found() ? wixl.full_path() : false}
2528 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
2529 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
2531 summary(summary_info, bool_yn: true, section: 'Host binaries')
2533 # Configurable features
2535 summary_info += {'Documentation': build_docs}
2536 summary_info += {'system-mode emulation': have_system}
2537 summary_info += {'user-mode emulation': have_user}
2538 summary_info += {'block layer': have_block}
2539 summary_info += {'Install blobs': get_option('install_blobs')}
2540 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
2541 if config_host.has_key('CONFIG_MODULES')
2542 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2544 summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')}
2545 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
2547 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
2549 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
2550 if config_host['TRACE_BACKENDS'].split().contains('simple')
2551 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2553 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2554 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2555 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2556 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2557 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2558 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2559 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2560 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2561 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2562 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2563 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2564 summary(summary_info, bool_yn: true, section: 'Configurable features')
2566 # Compilation information
2568 summary_info += {'host CPU': cpu}
2569 summary_info += {'host endianness': build_machine.endian()}
2570 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
2571 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
2572 if link_language == 'cpp'
2573 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
2575 summary_info += {'C++ compiler': false}
2577 if targetos == 'darwin'
2578 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
2580 if targetos == 'windows'
2581 if 'WIN_SDK' in config_host
2582 summary_info += {'Windows SDK': config_host['WIN_SDK']}
2585 summary_info += {'ARFLAGS': config_host['ARFLAGS']}
2586 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
2587 + ['-O' + get_option('optimization')]
2588 + (get_option('debug') ? ['-g'] : []))}
2589 if link_language == 'cpp'
2590 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
2591 + ['-O' + get_option('optimization')]
2592 + (get_option('debug') ? ['-g'] : []))}
2594 link_args = get_option(link_language + '_link_args')
2595 if link_args.length() > 0
2596 summary_info += {'LDFLAGS': ' '.join(link_args)}
2598 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
2599 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
2600 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
2601 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2602 summary_info += {'PIE': get_option('b_pie')}
2603 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
2604 summary_info += {'malloc trim support': has_malloc_trim}
2605 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
2606 summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
2607 summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
2608 summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
2609 summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2610 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2611 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
2612 summary_info += {'memory allocator': get_option('malloc')}
2613 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2614 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2615 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
2616 summary_info += {'gcov': get_option('b_coverage')}
2617 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
2618 summary_info += {'CFI support': get_option('cfi')}
2619 if get_option('cfi')
2620 summary_info += {'CFI debug support': get_option('cfi_debug')}
2622 summary_info += {'strip binaries': get_option('strip')}
2623 summary_info += {'sparse': sparse.found() ? sparse.full_path() : false}
2624 summary_info += {'mingw32 support': targetos == 'windows'}
2626 # snarf the cross-compilation information for tests
2627 foreach target: target_dirs
2628 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
2629 if fs.exists(tcg_mak)
2630 config_cross_tcg = keyval.load(tcg_mak)
2631 target = config_cross_tcg['TARGET_NAME']
2633 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
2634 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
2635 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
2636 elif 'CROSS_CC_GUEST' in config_cross_tcg
2637 summary_info += {target + ' tests'
2638 : config_cross_tcg['CROSS_CC_GUEST'] }
2643 summary(summary_info, bool_yn: true, section: 'Compilation')
2645 # Targets and accelerators
2648 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
2649 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
2650 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
2651 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
2652 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
2653 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
2654 if config_host.has_key('CONFIG_XEN_BACKEND')
2655 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2658 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
2659 if config_all.has_key('CONFIG_TCG')
2660 if get_option('tcg_interpreter')
2661 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, experimental and slow)'}
2663 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
2665 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2667 summary_info += {'target list': ' '.join(target_dirs)}
2669 summary_info += {'default devices': get_option('default_devices')}
2670 summary_info += {'out of process emulation': multiprocess_allowed}
2672 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
2676 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2677 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
2679 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2680 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2681 summary_info += {'VirtFS support': have_virtfs}
2682 summary_info += {'build virtiofs daemon': have_virtiofsd}
2683 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2684 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2685 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
2686 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
2687 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
2688 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
2689 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
2690 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
2691 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
2692 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2693 summary_info += {'FUSE exports': fuse.found()}
2695 summary(summary_info, bool_yn: true, section: 'Block layer support')
2699 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
2700 summary_info += {'GNUTLS support': gnutls.found()}
2701 # TODO: add back version
2702 summary_info += {'libgcrypt': gcrypt.found()}
2704 summary_info += {' XTS': xts != 'private'}
2706 # TODO: add back version
2707 summary_info += {'nettle': nettle.found()}
2709 summary_info += {' XTS': xts != 'private'}
2711 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
2712 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
2713 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
2714 summary(summary_info, bool_yn: true, section: 'Crypto')
2718 if targetos == 'darwin'
2719 summary_info += {'Cocoa support': cocoa.found()}
2721 # TODO: add back version
2722 summary_info += {'SDL support': sdl.found()}
2723 summary_info += {'SDL image support': sdl_image.found()}
2724 # TODO: add back version
2725 summary_info += {'GTK support': gtk.found()}
2726 summary_info += {'pixman': pixman.found()}
2727 # TODO: add back version
2728 summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')}
2729 # TODO: add back version
2730 summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt}
2731 summary_info += {'libtasn1': tasn1.found()}
2732 summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')}
2733 summary_info += {'iconv support': iconv.found()}
2734 summary_info += {'curses support': curses.found()}
2735 # TODO: add back version
2736 summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')}
2737 summary_info += {'curl support': curl.found()}
2738 summary_info += {'Multipath support': mpathpersist.found()}
2739 summary_info += {'VNC support': vnc.found()}
2741 summary_info += {'VNC SASL support': sasl.found()}
2742 summary_info += {'VNC JPEG support': jpeg.found()}
2743 summary_info += {'VNC PNG support': png.found()}
2745 summary_info += {'brlapi support': brlapi.found()}
2746 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
2747 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
2748 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2749 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2750 summary_info += {'ATTR/XATTR support': libattr.found()}
2751 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
2752 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
2753 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
2754 summary_info += {'libcap-ng support': libcap_ng.found()}
2755 summary_info += {'bpf support': libbpf.found()}
2756 # TODO: add back protocol and server version
2757 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
2758 summary_info += {'rbd support': rbd.found()}
2759 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
2760 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2761 summary_info += {'U2F support': u2f.found()}
2762 summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')}
2763 summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')}
2764 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
2765 summary_info += {'GBM': config_host.has_key('CONFIG_GBM')}
2766 summary_info += {'libiscsi support': libiscsi.found()}
2767 summary_info += {'libnfs support': libnfs.found()}
2768 if targetos == 'windows'
2769 if config_host.has_key('CONFIG_GUEST_AGENT')
2770 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
2771 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2774 summary_info += {'seccomp support': seccomp.found()}
2775 summary_info += {'GlusterFS support': glusterfs.found()}
2776 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
2777 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
2778 summary_info += {'lzo support': lzo.found()}
2779 summary_info += {'snappy support': snappy.found()}
2780 summary_info += {'bzip2 support': libbzip2.found()}
2781 summary_info += {'lzfse support': liblzfse.found()}
2782 summary_info += {'zstd support': zstd.found()}
2783 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2784 summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')}
2785 summary_info += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt}
2786 summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
2787 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2788 summary_info += {'libudev': libudev.found()}
2789 summary_info += {'FUSE lseek': fuse_lseek.found()}
2790 summary(summary_info, bool_yn: true, section: 'Dependencies')
2792 if not supported_cpus.contains(cpu)
2794 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2796 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2797 message('The QEMU project intends to remove support for this host CPU in')
2798 message('a future release if nobody volunteers to maintain it and to')
2799 message('provide a build host for our continuous integration setup.')
2800 message('configure has succeeded and you can continue to build, but')
2801 message('if you care about QEMU on this platform you should contact')
2802 message('us upstream at qemu-devel@nongnu.org.')
2805 if not supported_oses.contains(targetos)
2807 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2809 message('Host OS ' + targetos + 'support is not currently maintained.')
2810 message('The QEMU project intends to remove support for this host OS in')
2811 message('a future release if nobody volunteers to maintain it and to')
2812 message('provide a build host for our continuous integration setup.')
2813 message('configure has succeeded and you can continue to build, but')
2814 message('if you care about QEMU on this platform you should contact')
2815 message('us upstream at qemu-devel@nongnu.org.')