1 project('qemu', ['c'], meson_version: '>=0.58.2',
2 default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
4 version: files('VERSION'))
6 not_found = dependency('', required: false)
7 keyval = import('keyval')
8 ss = import('sourceset')
11 sh = find_program('sh')
12 cc = meson.get_compiler('c')
13 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
14 enable_modules = 'CONFIG_MODULES' in config_host
15 enable_static = 'CONFIG_STATIC' in config_host
17 # Allow both shared and static libraries unless --enable-static
18 static_kwargs = enable_static ? {'static': true} : {}
20 # Temporary directory used for files created while
21 # configure runs. Since it is in the build directory
22 # we can safely blow away any previous version of it
23 # (and we need not jump through hoops to try to delete
24 # it when configure exits.)
25 tmpdir = meson.current_build_dir() / 'meson-private/temp'
27 if get_option('qemu_suffix').startswith('/')
28 error('qemu_suffix cannot start with a /')
31 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
32 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
33 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
34 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
36 qemu_desktopdir = get_option('datadir') / 'applications'
37 qemu_icondir = get_option('datadir') / 'icons'
39 config_host_data = configuration_data()
42 target_dirs = config_host['TARGET_DIRS'].split()
45 foreach target : target_dirs
46 have_user = have_user or target.endswith('-user')
47 have_system = have_system or target.endswith('-softmmu')
49 have_tools = 'CONFIG_TOOLS' in config_host
50 have_block = have_system or have_tools
52 python = import('python').find_installation()
54 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
55 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
56 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
58 cpu = host_machine.cpu_family()
59 targetos = host_machine.system()
61 if cpu in ['x86', 'x86_64']
62 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
64 kvm_targets = ['aarch64-softmmu']
66 kvm_targets = ['s390x-softmmu']
67 elif cpu in ['ppc', 'ppc64']
68 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
69 elif cpu in ['mips', 'mips64']
70 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
75 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
78 accelerator_targets += {
79 'CONFIG_HVF': ['aarch64-softmmu']
83 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
84 # i386 emulator provides xenpv machine type for multiple architectures
85 accelerator_targets += {
86 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
89 if cpu in ['x86', 'x86_64']
90 accelerator_targets += {
91 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
92 'CONFIG_HVF': ['x86_64-softmmu'],
93 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
94 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
99 # Darwin does not support references to thread-local variables in modules
100 if targetos != 'darwin'
101 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
104 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
105 unpack_edk2_blobs = false
106 foreach target : edk2_targets
107 if target in target_dirs
108 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
109 unpack_edk2_blobs = bzip2.found()
118 # Specify linker-script with add_project_link_arguments so that it is not placed
119 # within a linker --start-group/--end-group pair
120 if 'CONFIG_FUZZ' in config_host
121 add_project_link_arguments(['-Wl,-T,',
122 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
123 native: false, language: ['c', 'cpp', 'objc'])
126 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
127 native: false, language: ['c', 'objc'])
128 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
129 native: false, language: 'cpp')
130 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
131 native: false, language: ['c', 'cpp', 'objc'])
133 if targetos == 'linux'
134 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
135 '-isystem', 'linux-headers',
136 language: ['c', 'cpp'])
139 add_project_arguments('-iquote', '.',
140 '-iquote', meson.current_source_dir(),
141 '-iquote', meson.current_source_dir() / 'include',
142 '-iquote', meson.current_source_dir() / 'disas/libvixl',
143 language: ['c', 'cpp', 'objc'])
145 link_language = meson.get_external_property('link_language', 'cpp')
146 if link_language == 'cpp'
147 add_languages('cpp', required: true, native: false)
149 if host_machine.system() == 'darwin'
150 add_languages('objc', required: false, native: false)
153 sparse = find_program('cgcc', required: get_option('sparse'))
156 command: [find_program('scripts/check_sparse.py'),
157 'compile_commands.json', sparse.full_path(), '-Wbitwise',
158 '-Wno-transparent-union', '-Wno-old-initializer',
159 '-Wno-non-pointer-null'])
162 ###########################################
163 # Target-specific checks and dependencies #
164 ###########################################
166 if targetos != 'linux' and get_option('mpath').enabled()
167 error('Multipath is supported only on Linux')
170 if targetos != 'linux' and get_option('multiprocess').enabled()
171 error('Multiprocess QEMU is supported only on Linux')
173 multiprocess_allowed = targetos == 'linux' and not get_option('multiprocess').disabled()
175 libm = cc.find_library('m', required: false)
176 threads = dependency('threads')
177 util = cc.find_library('util', required: false)
183 emulator_link_args = []
186 if targetos == 'windows'
187 socket = cc.find_library('ws2_32')
188 winmm = cc.find_library('winmm')
190 win = import('windows')
191 version_res = win.compile_resources('version.rc',
192 depend_files: files('pc-bios/qemu-nsis.ico'),
193 include_directories: include_directories('.'))
194 elif targetos == 'darwin'
195 coref = dependency('appleframeworks', modules: 'CoreFoundation')
196 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
197 elif targetos == 'sunos'
198 socket = [cc.find_library('socket'),
199 cc.find_library('nsl'),
200 cc.find_library('resolv')]
201 elif targetos == 'haiku'
202 socket = [cc.find_library('posix_error_mapper'),
203 cc.find_library('network'),
204 cc.find_library('bsd')]
205 elif targetos == 'openbsd'
206 if not get_option('tcg').disabled() and target_dirs.length() > 0
207 # Disable OpenBSD W^X if available
208 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
213 if not get_option('kvm').disabled() and targetos == 'linux'
214 accelerators += 'CONFIG_KVM'
216 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
217 accelerators += 'CONFIG_XEN'
218 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
220 have_xen_pci_passthrough = false
222 if not get_option('whpx').disabled() and targetos == 'windows'
223 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
224 error('WHPX requires 64-bit host')
225 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
226 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
227 accelerators += 'CONFIG_WHPX'
230 if not get_option('hvf').disabled()
231 hvf = dependency('appleframeworks', modules: 'Hypervisor',
232 required: get_option('hvf'))
234 accelerators += 'CONFIG_HVF'
237 if not get_option('hax').disabled()
238 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
239 accelerators += 'CONFIG_HAX'
242 if targetos == 'netbsd'
243 if cc.has_header_symbol('nvmm.h', 'nvmm_cpu_stop', required: get_option('nvmm'))
244 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
247 accelerators += 'CONFIG_NVMM'
251 tcg_arch = config_host['ARCH']
252 if not get_option('tcg').disabled()
253 if cpu not in supported_cpus
254 if get_option('tcg_interpreter')
255 warning('Unsupported CPU @0@, will use TCG with TCI (experimental and slow)'.format(cpu))
257 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
259 elif get_option('tcg_interpreter')
260 warning('Use of the TCG interpretor is not recommended on this host')
261 warning('architecture. There is a native TCG execution backend available')
262 warning('which provides substantially better performance and reliability.')
263 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
264 warning('configuration option on this architecture to use the native')
267 if get_option('tcg_interpreter')
269 elif config_host['ARCH'] == 'sparc64'
271 elif config_host['ARCH'] in ['x86_64', 'x32']
273 elif config_host['ARCH'] == 'ppc64'
275 elif config_host['ARCH'] in ['riscv32', 'riscv64']
278 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
279 language: ['c', 'cpp', 'objc'])
281 accelerators += 'CONFIG_TCG'
282 config_host += { 'CONFIG_TCG': 'y' }
285 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
286 error('KVM not available on this platform')
288 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
289 error('HVF not available on this platform')
291 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
292 error('NVMM not available on this platform')
294 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
295 error('WHPX not available on this platform')
297 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
298 if 'CONFIG_XEN' in accelerators
299 error('Xen PCI passthrough not available on this platform')
301 error('Xen PCI passthrough requested but Xen not enabled')
309 # The path to glib.h is added to all compilation commands. This was
310 # grandfathered in from the QEMU Makefiles.
311 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
312 native: false, language: ['c', 'cpp', 'objc'])
313 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
314 link_args: config_host['GLIB_LIBS'].split())
315 # override glib dep with the configure results (for subprojects)
316 meson.override_dependency('glib-2.0', glib)
319 if 'CONFIG_GIO' in config_host
320 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
321 link_args: config_host['GIO_LIBS'].split())
324 if 'CONFIG_TRACE_UST' in config_host
325 lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
328 if have_system or have_tools
329 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
330 method: 'pkg-config', kwargs: static_kwargs)
332 libaio = cc.find_library('aio', required: false)
333 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
335 linux_io_uring = not_found
336 if not get_option('linux_io_uring').auto() or have_block
337 linux_io_uring = dependency('liburing', required: get_option('linux_io_uring'),
338 method: 'pkg-config', kwargs: static_kwargs)
341 if not get_option('libxml2').auto() or have_block
342 libxml2 = dependency('libxml-2.0', required: get_option('libxml2'),
343 method: 'pkg-config', kwargs: static_kwargs)
346 if not get_option('libnfs').auto() or have_block
347 libnfs = dependency('libnfs', version: '>=1.9.3',
348 required: get_option('libnfs'),
349 method: 'pkg-config', kwargs: static_kwargs)
354 #include <sys/types.h>
355 #ifdef CONFIG_LIBATTR
356 #include <attr/xattr.h>
358 #include <sys/xattr.h>
360 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
363 have_old_libattr = false
364 if not get_option('attr').disabled()
365 if cc.links(libattr_test)
366 libattr = declare_dependency()
368 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
369 required: get_option('attr'),
370 kwargs: static_kwargs)
371 if libattr.found() and not \
372 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
374 if get_option('attr').enabled()
375 error('could not link libattr')
377 warning('could not link libattr, disabling')
380 have_old_libattr = libattr.found()
385 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
386 if cocoa.found() and get_option('sdl').enabled()
387 error('Cocoa and SDL cannot be enabled at the same time')
389 if cocoa.found() and get_option('gtk').enabled()
390 error('Cocoa and GTK+ cannot be enabled at the same time')
394 if not get_option('seccomp').auto() or have_system or have_tools
395 seccomp = dependency('libseccomp', version: '>=2.3.0',
396 required: get_option('seccomp'),
397 method: 'pkg-config', kwargs: static_kwargs)
400 libcap_ng = not_found
401 if not get_option('cap_ng').auto() or have_system or have_tools
402 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
403 required: get_option('cap_ng'),
404 kwargs: static_kwargs)
406 if libcap_ng.found() and not cc.links('''
410 capng_capability_to_name(CAPNG_EFFECTIVE);
412 }''', dependencies: libcap_ng)
413 libcap_ng = not_found
414 if get_option('cap_ng').enabled()
415 error('could not link libcap-ng')
417 warning('could not link libcap-ng, disabling')
421 if get_option('xkbcommon').auto() and not have_system and not have_tools
422 xkbcommon = not_found
424 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
425 method: 'pkg-config', kwargs: static_kwargs)
428 if config_host.has_key('CONFIG_VDE')
429 vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
432 if 'CONFIG_LIBPULSE' in config_host
433 pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
434 link_args: config_host['PULSE_LIBS'].split())
437 if 'CONFIG_ALSA' in config_host
438 alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
439 link_args: config_host['ALSA_LIBS'].split())
442 if 'CONFIG_LIBJACK' in config_host
443 jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
446 spice_headers = not_found
447 spice_protocol = not_found
448 if 'CONFIG_SPICE' in config_host
449 spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
450 link_args: config_host['SPICE_LIBS'].split())
451 spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
453 if 'CONFIG_SPICE_PROTOCOL' in config_host
454 spice_protocol = declare_dependency(compile_args: config_host['SPICE_PROTOCOL_CFLAGS'].split())
456 rt = cc.find_library('rt', required: false)
458 if 'CONFIG_PLUGIN' in config_host
459 libdl = cc.find_library('dl', required: false)
460 if not cc.has_function('dlopen', dependencies: libdl)
461 error('dlopen not found')
465 if not get_option('libiscsi').auto() or have_block
466 libiscsi = dependency('libiscsi', version: '>=1.9.0',
467 required: get_option('libiscsi'),
468 method: 'pkg-config', kwargs: static_kwargs)
471 if not get_option('zstd').auto() or have_block
472 zstd = dependency('libzstd', version: '>=1.4.0',
473 required: get_option('zstd'),
474 method: 'pkg-config', kwargs: static_kwargs)
477 if not get_option('virglrenderer').auto() or have_system
478 virgl = dependency('virglrenderer',
479 method: 'pkg-config',
480 required: get_option('virglrenderer'),
481 kwargs: static_kwargs)
484 if not get_option('curl').auto() or have_block
485 curl = dependency('libcurl', version: '>=7.29.0',
486 method: 'pkg-config',
487 required: get_option('curl'),
488 kwargs: static_kwargs)
491 if targetos == 'linux' and (have_system or have_tools)
492 libudev = dependency('libudev',
493 method: 'pkg-config',
494 required: get_option('libudev'),
495 kwargs: static_kwargs)
498 mpathlibs = [libudev]
499 mpathpersist = not_found
500 mpathpersist_new_api = false
501 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
502 mpath_test_source_new = '''
504 #include <mpath_persist.h>
505 unsigned mpath_mx_alloc_len = 1024;
507 static struct config *multipath_conf;
508 extern struct udev *udev;
509 extern struct config *get_multipath_config(void);
510 extern void put_multipath_config(struct config *conf);
512 struct config *get_multipath_config(void) { return multipath_conf; }
513 void put_multipath_config(struct config *conf) { }
516 multipath_conf = mpath_lib_init();
519 mpath_test_source_old = '''
521 #include <mpath_persist.h>
522 unsigned mpath_mx_alloc_len = 1024;
525 struct udev *udev = udev_new();
526 mpath_lib_init(udev);
529 libmpathpersist = cc.find_library('mpathpersist',
530 required: get_option('mpath'),
531 kwargs: static_kwargs)
532 if libmpathpersist.found()
533 mpathlibs += libmpathpersist
535 mpathlibs += cc.find_library('devmapper',
536 required: get_option('mpath'),
537 kwargs: static_kwargs)
539 mpathlibs += cc.find_library('multipath',
540 required: get_option('mpath'),
541 kwargs: static_kwargs)
542 foreach lib: mpathlibs
548 if mpathlibs.length() == 0
549 msg = 'Dependencies missing for libmpathpersist'
550 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
551 mpathpersist = declare_dependency(dependencies: mpathlibs)
552 mpathpersist_new_api = true
553 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
554 mpathpersist = declare_dependency(dependencies: mpathlibs)
556 msg = 'Cannot detect libmpathpersist API'
558 if not mpathpersist.found()
559 if get_option('mpath').enabled()
562 warning(msg + ', disabling')
570 if have_system and not get_option('curses').disabled()
577 setlocale(LC_ALL, "");
579 addwstr(L"wide chars\n");
581 add_wch(WACS_DEGREE);
585 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
586 foreach curses_dep : curses_dep_list
587 if not curses.found()
588 curses = dependency(curses_dep,
590 method: 'pkg-config',
591 kwargs: static_kwargs)
594 msg = get_option('curses').enabled() ? 'curses library not found' : ''
595 curses_compile_args = ['-DNCURSES_WIDECHAR']
597 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
598 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
600 msg = 'curses package not usable'
604 if not curses.found()
605 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
606 if targetos != 'windows' and not has_curses_h
607 message('Trying with /usr/include/ncursesw')
608 curses_compile_args += ['-I/usr/include/ncursesw']
609 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
612 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
613 foreach curses_libname : curses_libname_list
614 libcurses = cc.find_library(curses_libname,
616 kwargs: static_kwargs)
618 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
619 curses = declare_dependency(compile_args: curses_compile_args,
620 dependencies: [libcurses])
623 msg = 'curses library not usable'
629 if not get_option('iconv').disabled()
630 foreach link_args : [ ['-liconv'], [] ]
631 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
632 # We need to use libiconv if available because mixing libiconv's headers with
633 # the system libc does not work.
634 # However, without adding glib to the dependencies -L/usr/local/lib will not be
635 # included in the command line and libiconv will not be found.
639 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
640 return conv != (iconv_t) -1;
641 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
642 iconv = declare_dependency(link_args: link_args, dependencies: glib)
647 if curses.found() and not iconv.found()
648 if get_option('iconv').enabled()
649 error('iconv not available')
651 msg = 'iconv required for curses UI but not available'
654 if not curses.found() and msg != ''
655 if get_option('curses').enabled()
658 warning(msg + ', disabling')
664 if not get_option('brlapi').auto() or have_system
665 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
666 required: get_option('brlapi'),
667 kwargs: static_kwargs)
668 if brlapi.found() and not cc.links('''
671 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
673 if get_option('brlapi').enabled()
674 error('could not link brlapi')
676 warning('could not link brlapi, disabling')
682 if not get_option('sdl').auto() or (have_system and not cocoa.found())
683 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
684 sdl_image = not_found
687 # work around 2.0.8 bug
688 sdl = declare_dependency(compile_args: '-Wno-undef',
690 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
691 method: 'pkg-config', kwargs: static_kwargs)
693 if get_option('sdl_image').enabled()
694 error('sdl-image required, but SDL was @0@'.format(
695 get_option('sdl').disabled() ? 'disabled' : 'not found'))
697 sdl_image = not_found
701 if not get_option('rbd').auto() or have_block
702 librados = cc.find_library('rados', required: get_option('rbd'),
703 kwargs: static_kwargs)
704 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
705 required: get_option('rbd'),
706 kwargs: static_kwargs)
707 if librados.found() and librbd.found()
710 #include <rbd/librbd.h>
713 rados_create(&cluster, NULL);
714 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
718 }''', dependencies: [librbd, librados])
719 rbd = declare_dependency(dependencies: [librbd, librados])
720 elif get_option('rbd').enabled()
721 error('librbd >= 1.12.0 required')
723 warning('librbd >= 1.12.0 not found, disabling')
728 glusterfs = not_found
729 glusterfs_ftruncate_has_stat = false
730 glusterfs_iocb_has_stat = false
731 if not get_option('glusterfs').auto() or have_block
732 glusterfs = dependency('glusterfs-api', version: '>=3',
733 required: get_option('glusterfs'),
734 method: 'pkg-config', kwargs: static_kwargs)
736 glusterfs_ftruncate_has_stat = cc.links('''
737 #include <glusterfs/api/glfs.h>
742 /* new glfs_ftruncate() passes two additional args */
743 return glfs_ftruncate(NULL, 0, NULL, NULL);
745 ''', dependencies: glusterfs)
746 glusterfs_iocb_has_stat = cc.links('''
747 #include <glusterfs/api/glfs.h>
749 /* new glfs_io_cbk() passes two additional glfs_stat structs */
751 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
757 glfs_io_cbk iocb = &glusterfs_iocb;
758 iocb(NULL, 0 , NULL, NULL, NULL);
761 ''', dependencies: glusterfs)
765 if 'CONFIG_LIBSSH' in config_host
766 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
767 link_args: config_host['LIBSSH_LIBS'].split())
770 if not get_option('bzip2').auto() or have_block
771 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
772 required: get_option('bzip2'),
773 kwargs: static_kwargs)
774 if libbzip2.found() and not cc.links('''
776 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
778 if get_option('bzip2').enabled()
779 error('could not link libbzip2')
781 warning('could not link libbzip2, disabling')
787 if not get_option('lzfse').auto() or have_block
788 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
789 required: get_option('lzfse'),
790 kwargs: static_kwargs)
792 if liblzfse.found() and not cc.links('''
794 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
796 if get_option('lzfse').enabled()
797 error('could not link liblzfse')
799 warning('could not link liblzfse, disabling')
804 if 'CONFIG_AUDIO_OSS' in config_host
805 oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
808 if 'CONFIG_AUDIO_DSOUND' in config_host
809 dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
811 coreaudio = not_found
812 if 'CONFIG_AUDIO_COREAUDIO' in config_host
813 coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
817 if 'CONFIG_OPENGL' in config_host
818 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
819 link_args: config_host['OPENGL_LIBS'].split())
822 if (have_system or have_tools) and (virgl.found() or opengl.found())
823 gbm = dependency('gbm', method: 'pkg-config', required: false,
824 kwargs: static_kwargs)
828 gnutls_crypto = not_found
829 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
830 # For general TLS support our min gnutls matches
831 # that implied by our platform support matrix
833 # For the crypto backends, we look for a newer
836 # Version 3.6.8 is needed to get XTS
837 # Version 3.6.13 is needed to get PBKDF
838 # Version 3.6.14 is needed to get HW accelerated XTS
840 # If newer enough gnutls isn't available, we can
841 # still use a different crypto backend to satisfy
842 # the platform support requirements
843 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
844 method: 'pkg-config',
846 kwargs: static_kwargs)
847 if gnutls_crypto.found()
848 gnutls = gnutls_crypto
850 # Our min version if all we need is TLS
851 gnutls = dependency('gnutls', version: '>=3.5.18',
852 method: 'pkg-config',
853 required: get_option('gnutls'),
854 kwargs: static_kwargs)
858 # We prefer use of gnutls for crypto, unless the options
859 # explicitly asked for nettle or gcrypt.
861 # If gnutls isn't available for crypto, then we'll prefer
862 # gcrypt over nettle for performance reasons.
867 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
868 error('Only one of gcrypt & nettle can be enabled')
871 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
872 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
873 gnutls_crypto = not_found
876 if not gnutls_crypto.found()
877 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
878 gcrypt = dependency('libgcrypt', version: '>=1.8',
879 method: 'config-tool',
880 required: get_option('gcrypt'),
881 kwargs: static_kwargs)
882 # Debian has removed -lgpg-error from libgcrypt-config
883 # as it "spreads unnecessary dependencies" which in
884 # turn breaks static builds...
885 if gcrypt.found() and enable_static
886 gcrypt = declare_dependency(dependencies: [
888 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
891 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
892 nettle = dependency('nettle', version: '>=3.4',
893 method: 'pkg-config',
894 required: get_option('nettle'),
895 kwargs: static_kwargs)
896 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
905 if not get_option('gtk').auto() or (have_system and not cocoa.found())
906 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
907 method: 'pkg-config',
908 required: get_option('gtk'),
909 kwargs: static_kwargs)
911 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
912 method: 'pkg-config',
914 kwargs: static_kwargs)
915 gtk = declare_dependency(dependencies: [gtk, gtkx11])
917 if not get_option('vte').auto() or have_system
918 vte = dependency('vte-2.91',
919 method: 'pkg-config',
920 required: get_option('vte'),
921 kwargs: static_kwargs)
928 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
929 kwargs: static_kwargs)
935 if have_system and not get_option('vnc').disabled()
936 vnc = declare_dependency() # dummy dependency
937 png = dependency('libpng', required: get_option('vnc_png'),
938 method: 'pkg-config', kwargs: static_kwargs)
939 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
940 method: 'pkg-config', kwargs: static_kwargs)
941 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
942 required: get_option('vnc_sasl'),
943 kwargs: static_kwargs)
945 sasl = declare_dependency(dependencies: sasl,
946 compile_args: '-DSTRUCT_IOVEC_DEFINED')
951 if not get_option('auth_pam').auto() or have_system
952 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
953 required: get_option('auth_pam'),
954 kwargs: static_kwargs)
956 if pam.found() and not cc.links('''
958 #include <security/pam_appl.h>
960 const char *service_name = "qemu";
961 const char *user = "frank";
962 const struct pam_conv pam_conv = { 0 };
963 pam_handle_t *pamh = NULL;
964 pam_start(service_name, user, &pam_conv, &pamh);
966 }''', dependencies: pam)
968 if get_option('auth_pam').enabled()
969 error('could not link libpam')
971 warning('could not link libpam, disabling')
976 if not get_option('snappy').auto() or have_system
977 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
978 required: get_option('snappy'),
979 kwargs: static_kwargs)
981 if snappy.found() and not cc.links('''
982 #include <snappy-c.h>
983 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
985 if get_option('snappy').enabled()
986 error('could not link libsnappy')
988 warning('could not link libsnappy, disabling')
993 if not get_option('lzo').auto() or have_system
994 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
995 required: get_option('lzo'),
996 kwargs: static_kwargs)
998 if lzo.found() and not cc.links('''
999 #include <lzo/lzo1x.h>
1000 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1002 if get_option('lzo').enabled()
1003 error('could not link liblzo2')
1005 warning('could not link liblzo2, disabling')
1010 if 'CONFIG_RDMA' in config_host
1011 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
1014 if 'CONFIG_NUMA' in config_host
1015 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
1018 if 'CONFIG_XEN_BACKEND' in config_host
1019 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
1020 link_args: config_host['XEN_LIBS'].split())
1023 if not get_option('smartcard').auto() or have_system
1024 cacard = dependency('libcacard', required: get_option('smartcard'),
1025 version: '>=2.5.1', method: 'pkg-config',
1026 kwargs: static_kwargs)
1030 u2f = dependency('u2f-emu', required: get_option('u2f'),
1031 method: 'pkg-config',
1032 kwargs: static_kwargs)
1034 usbredir = not_found
1035 if not get_option('usb_redir').auto() or have_system
1036 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1037 version: '>=0.6', method: 'pkg-config',
1038 kwargs: static_kwargs)
1041 if not get_option('libusb').auto() or have_system
1042 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1043 version: '>=1.0.13', method: 'pkg-config',
1044 kwargs: static_kwargs)
1048 if not get_option('libpmem').auto() or have_system
1049 libpmem = dependency('libpmem', required: get_option('libpmem'),
1050 method: 'pkg-config', kwargs: static_kwargs)
1052 libdaxctl = not_found
1053 if not get_option('libdaxctl').auto() or have_system
1054 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1055 version: '>=57', method: 'pkg-config',
1056 kwargs: static_kwargs)
1060 tasn1 = dependency('libtasn1',
1061 method: 'pkg-config',
1062 kwargs: static_kwargs)
1064 keyutils = dependency('libkeyutils', required: false,
1065 method: 'pkg-config', kwargs: static_kwargs)
1067 has_gettid = cc.has_function('gettid')
1072 if get_option('malloc') == 'system'
1074 not get_option('malloc_trim').disabled() and \
1075 cc.links('''#include <malloc.h>
1076 int main(void) { malloc_trim(0); return 0; }''')
1078 has_malloc_trim = false
1079 malloc = cc.find_library(get_option('malloc'), required: true)
1081 if not has_malloc_trim and get_option('malloc_trim').enabled()
1082 if get_option('malloc') == 'system'
1083 error('malloc_trim not available on this platform.')
1085 error('malloc_trim not available with non-libc memory allocator')
1089 # Check whether the glibc provides statx()
1091 gnu_source_prefix = '''
1096 statx_test = gnu_source_prefix + '''
1097 #include <sys/stat.h>
1099 struct statx statxbuf;
1100 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1104 has_statx = cc.links(statx_test)
1106 have_vhost_user_blk_server = (targetos == 'linux' and
1107 'CONFIG_VHOST_USER' in config_host)
1109 if get_option('vhost_user_blk_server').enabled()
1110 if targetos != 'linux'
1111 error('vhost_user_blk_server requires linux')
1112 elif 'CONFIG_VHOST_USER' not in config_host
1113 error('vhost_user_blk_server requires vhost-user support')
1115 elif get_option('vhost_user_blk_server').disabled() or not have_system
1116 have_vhost_user_blk_server = false
1120 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1121 error('Cannot enable fuse-lseek while fuse is disabled')
1124 fuse = dependency('fuse3', required: get_option('fuse'),
1125 version: '>=3.1', method: 'pkg-config',
1126 kwargs: static_kwargs)
1128 fuse_lseek = not_found
1129 if not get_option('fuse_lseek').disabled()
1130 if fuse.version().version_compare('>=3.8')
1132 fuse_lseek = declare_dependency()
1133 elif get_option('fuse_lseek').enabled()
1135 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1137 error('fuse-lseek requires libfuse, which was not found')
1143 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1144 if libbpf.found() and not cc.links('''
1145 #include <bpf/libbpf.h>
1148 bpf_object__destroy_skeleton(NULL);
1150 }''', dependencies: libbpf)
1152 if get_option('bpf').enabled()
1153 error('libbpf skeleton test failed')
1155 warning('libbpf skeleton test failed, disabling')
1159 if get_option('cfi')
1161 # Check for dependency on LTO
1162 if not get_option('b_lto')
1163 error('Selected Control-Flow Integrity but LTO is disabled')
1165 if config_host.has_key('CONFIG_MODULES')
1166 error('Selected Control-Flow Integrity is not compatible with modules')
1168 # Check for cfi flags. CFI requires LTO so we can't use
1169 # get_supported_arguments, but need a more complex "compiles" which allows
1171 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1172 args: ['-flto', '-fsanitize=cfi-icall'] )
1173 cfi_flags += '-fsanitize=cfi-icall'
1175 error('-fsanitize=cfi-icall is not supported by the compiler')
1177 if cc.compiles('int main () { return 0; }',
1178 name: '-fsanitize-cfi-icall-generalize-pointers',
1179 args: ['-flto', '-fsanitize=cfi-icall',
1180 '-fsanitize-cfi-icall-generalize-pointers'] )
1181 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1183 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1185 if get_option('cfi_debug')
1186 if cc.compiles('int main () { return 0; }',
1187 name: '-fno-sanitize-trap=cfi-icall',
1188 args: ['-flto', '-fsanitize=cfi-icall',
1189 '-fno-sanitize-trap=cfi-icall'] )
1190 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1192 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1195 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1196 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1199 have_host_block_device = (targetos != 'darwin' or
1200 cc.has_header('IOKit/storage/IOMedia.h'))
1206 have_virtfs = (targetos == 'linux' and
1211 have_virtfs_proxy_helper = have_virtfs and have_tools
1213 if get_option('virtfs').enabled()
1215 if targetos != 'linux'
1216 error('virtio-9p (virtfs) requires Linux')
1217 elif not libcap_ng.found() or not libattr.found()
1218 error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1219 elif not have_system
1220 error('virtio-9p (virtfs) needs system emulation support')
1223 elif get_option('virtfs').disabled()
1227 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1228 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1229 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1230 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1231 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1232 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1233 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1234 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1235 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1236 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1237 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1238 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1240 config_host_data.set('CONFIG_ATTR', libattr.found())
1241 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1242 config_host_data.set('CONFIG_COCOA', cocoa.found())
1243 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1244 config_host_data.set('CONFIG_LZO', lzo.found())
1245 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1246 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1247 config_host_data.set('CONFIG_CURL', curl.found())
1248 config_host_data.set('CONFIG_CURSES', curses.found())
1249 config_host_data.set('CONFIG_GBM', gbm.found())
1250 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1251 if glusterfs.found()
1252 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1253 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1254 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1255 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1256 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1257 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1259 config_host_data.set('CONFIG_GTK', gtk.found())
1260 config_host_data.set('CONFIG_VTE', vte.found())
1261 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1262 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1263 config_host_data.set('CONFIG_EBPF', libbpf.found())
1264 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1265 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1266 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1267 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1268 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1269 config_host_data.set('CONFIG_RBD', rbd.found())
1270 config_host_data.set('CONFIG_SDL', sdl.found())
1271 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1272 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1273 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1274 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1275 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1276 config_host_data.set('CONFIG_VNC', vnc.found())
1277 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1278 config_host_data.set('CONFIG_VNC_PNG', png.found())
1279 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1280 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1281 config_host_data.set('CONFIG_VTE', vte.found())
1282 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1283 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1284 config_host_data.set('CONFIG_GETTID', has_gettid)
1285 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1286 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1287 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1288 config_host_data.set('CONFIG_NETTLE', nettle.found())
1289 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1290 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1291 config_host_data.set('CONFIG_STATX', has_statx)
1292 config_host_data.set('CONFIG_ZSTD', zstd.found())
1293 config_host_data.set('CONFIG_FUSE', fuse.found())
1294 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1295 config_host_data.set('CONFIG_X11', x11.found())
1296 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1297 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1298 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1299 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1300 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1302 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1305 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1306 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1307 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1308 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1309 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1310 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1311 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1312 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1313 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1316 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1317 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1318 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1319 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1320 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1321 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
1322 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1323 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1324 config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
1325 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1326 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1327 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1328 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1329 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1330 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1331 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1332 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1333 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1336 config_host_data.set('CONFIG_BYTESWAP_H',
1337 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1338 config_host_data.set('CONFIG_EPOLL_CREATE1',
1339 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1340 config_host_data.set('CONFIG_HAS_ENVIRON',
1341 cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix))
1342 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1343 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1344 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1345 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1346 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1347 config_host_data.set('CONFIG_FIEMAP',
1348 cc.has_header('linux/fiemap.h') and
1349 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1350 config_host_data.set('CONFIG_GETRANDOM',
1351 cc.has_function('getrandom') and
1352 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1353 config_host_data.set('CONFIG_INOTIFY',
1354 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1355 config_host_data.set('CONFIG_INOTIFY1',
1356 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1357 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1358 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1359 prefix: '''#include <sys/endian.h>
1360 #include <sys/types.h>'''))
1361 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1362 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1363 config_host_data.set('CONFIG_RTNETLINK',
1364 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1365 config_host_data.set('CONFIG_SYSMACROS',
1366 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1367 config_host_data.set('HAVE_OPTRESET',
1368 cc.has_header_symbol('getopt.h', 'optreset'))
1369 config_host_data.set('HAVE_UTMPX',
1370 cc.has_header_symbol('utmpx.h', 'struct utmpx'))
1371 config_host_data.set('HAVE_IPPROTO_MPTCP',
1372 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1375 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1376 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1377 prefix: '#include <signal.h>'))
1378 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1379 cc.has_member('struct stat', 'st_atim',
1380 prefix: '#include <sys/stat.h>'))
1382 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1383 #include <sys/eventfd.h>
1384 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1385 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1388 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1389 return fdatasync(0);
1391 #error Not supported
1394 config_host_data.set('CONFIG_MADVISE', cc.links(gnu_source_prefix + '''
1395 #include <sys/types.h>
1396 #include <sys/mman.h>
1398 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }'''))
1399 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1400 #include <sys/mman.h>
1401 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1402 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1404 #if !defined(AT_EMPTY_PATH)
1405 # error missing definition
1407 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1409 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1416 return pipe2(pipefd, O_CLOEXEC);
1418 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1419 #include <sys/mman.h>
1421 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1422 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1424 #include <sys/syscall.h>
1426 int main(void) { return syscall(SYS_signalfd, -1, NULL, _NSIG / 8); }'''))
1427 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1435 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1436 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1440 # Some versions of Mac OS X incorrectly define SIZE_MAX
1441 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1444 int main(int argc, char *argv[]) {
1445 return printf("%zu", SIZE_MAX);
1446 }''', args: ['-Werror']))
1449 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
1450 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1451 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
1452 foreach k, v: config_host
1453 if ignored.contains(k)
1455 elif arrays.contains(k)
1457 v = '"' + '", "'.join(v.split()) + '", '
1459 config_host_data.set(k, v)
1461 config_host_data.set('HOST_' + v.to_upper(), 1)
1462 elif strings.contains(k)
1463 if not k.startswith('CONFIG_')
1464 k = 'CONFIG_' + k.to_upper()
1466 config_host_data.set_quoted(k, v)
1467 elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1468 config_host_data.set(k, v == 'y' ? 1 : v)
1472 ########################
1473 # Target configuration #
1474 ########################
1476 minikconf = find_program('scripts/minikconf.py')
1478 config_all_devices = {}
1479 config_all_disas = {}
1480 config_devices_mak_list = []
1481 config_devices_h = {}
1482 config_target_h = {}
1483 config_target_mak = {}
1486 'alpha' : ['CONFIG_ALPHA_DIS'],
1487 'arm' : ['CONFIG_ARM_DIS'],
1488 'avr' : ['CONFIG_AVR_DIS'],
1489 'cris' : ['CONFIG_CRIS_DIS'],
1490 'hexagon' : ['CONFIG_HEXAGON_DIS'],
1491 'hppa' : ['CONFIG_HPPA_DIS'],
1492 'i386' : ['CONFIG_I386_DIS'],
1493 'x86_64' : ['CONFIG_I386_DIS'],
1494 'x32' : ['CONFIG_I386_DIS'],
1495 'm68k' : ['CONFIG_M68K_DIS'],
1496 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1497 'mips' : ['CONFIG_MIPS_DIS'],
1498 'nios2' : ['CONFIG_NIOS2_DIS'],
1499 'or1k' : ['CONFIG_OPENRISC_DIS'],
1500 'ppc' : ['CONFIG_PPC_DIS'],
1501 'riscv' : ['CONFIG_RISCV_DIS'],
1502 'rx' : ['CONFIG_RX_DIS'],
1503 's390' : ['CONFIG_S390_DIS'],
1504 'sh4' : ['CONFIG_SH4_DIS'],
1505 'sparc' : ['CONFIG_SPARC_DIS'],
1506 'xtensa' : ['CONFIG_XTENSA_DIS'],
1508 if link_language == 'cpp'
1510 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1511 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1512 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1516 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
1518 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1519 ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1520 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
1521 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1522 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1523 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1524 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1525 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1526 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1527 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1528 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1529 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1531 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1533 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1534 actual_target_dirs = []
1536 foreach target : target_dirs
1537 config_target = { 'TARGET_NAME': target.split('-')[0] }
1538 if target.endswith('linux-user')
1539 if targetos != 'linux'
1543 error('Target @0@ is only available on a Linux host'.format(target))
1545 config_target += { 'CONFIG_LINUX_USER': 'y' }
1546 elif target.endswith('bsd-user')
1547 if 'CONFIG_BSD' not in config_host
1551 error('Target @0@ is only available on a BSD host'.format(target))
1553 config_target += { 'CONFIG_BSD_USER': 'y' }
1554 elif target.endswith('softmmu')
1555 config_target += { 'CONFIG_SOFTMMU': 'y' }
1557 if target.endswith('-user')
1559 'CONFIG_USER_ONLY': 'y',
1560 'CONFIG_QEMU_INTERP_PREFIX':
1561 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1566 foreach sym: accelerators
1567 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1568 config_target += { sym: 'y' }
1569 config_all += { sym: 'y' }
1570 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1571 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1572 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1573 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1575 if target in modular_tcg
1576 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
1578 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
1580 accel_kconfig += [ sym + '=y' ]
1583 if accel_kconfig.length() == 0
1587 error('No accelerator available for target @0@'.format(target))
1590 actual_target_dirs += target
1591 config_target += keyval.load('configs/targets' / target + '.mak')
1592 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1594 if 'TARGET_NEED_FDT' in config_target
1595 fdt_required += target
1599 if 'TARGET_BASE_ARCH' not in config_target
1600 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1602 if 'TARGET_ABI_DIR' not in config_target
1603 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1606 foreach k, v: disassemblers
1607 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1609 config_target += { sym: 'y' }
1610 config_all_disas += { sym: 'y' }
1615 config_target_data = configuration_data()
1616 foreach k, v: config_target
1617 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1619 elif ignored.contains(k)
1621 elif k == 'TARGET_BASE_ARCH'
1622 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1623 # not used to select files from sourcesets.
1624 config_target_data.set('TARGET_' + v.to_upper(), 1)
1625 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1626 config_target_data.set_quoted(k, v)
1628 config_target_data.set(k, 1)
1630 config_target_data.set(k, v)
1633 config_target_data.set('QEMU_ARCH',
1634 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
1635 config_target_h += {target: configure_file(output: target + '-config-target.h',
1636 configuration: config_target_data)}
1638 if target.endswith('-softmmu')
1639 config_input = meson.get_external_property(target, 'default')
1640 config_devices_mak = target + '-config-devices.mak'
1641 config_devices_mak = configure_file(
1642 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
1643 output: config_devices_mak,
1644 depfile: config_devices_mak + '.d',
1646 command: [minikconf,
1647 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1648 config_devices_mak, '@DEPFILE@', '@INPUT@',
1649 host_kconfig, accel_kconfig,
1650 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
1652 config_devices_data = configuration_data()
1653 config_devices = keyval.load(config_devices_mak)
1654 foreach k, v: config_devices
1655 config_devices_data.set(k, 1)
1657 config_devices_mak_list += config_devices_mak
1658 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1659 configuration: config_devices_data)}
1660 config_target += config_devices
1661 config_all_devices += config_devices
1663 config_target_mak += {target: config_target}
1665 target_dirs = actual_target_dirs
1667 # This configuration is used to build files that are shared by
1668 # multiple binaries, and then extracted out of the "common"
1669 # static_library target.
1671 # We do not use all_sources()/all_dependencies(), because it would
1672 # build literally all source files, including devices only used by
1673 # targets that are not built for this compilation. The CONFIG_ALL
1674 # pseudo symbol replaces it.
1676 config_all += config_all_devices
1677 config_all += config_host
1678 config_all += config_all_disas
1680 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1681 'CONFIG_SOFTMMU': have_system,
1682 'CONFIG_USER_ONLY': have_user,
1690 capstone = not_found
1691 capstone_opt = get_option('capstone')
1692 if capstone_opt in ['enabled', 'auto', 'system']
1693 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1694 capstone = dependency('capstone', version: '>=4.0',
1695 kwargs: static_kwargs, method: 'pkg-config',
1696 required: capstone_opt == 'system' or
1697 capstone_opt == 'enabled' and not have_internal)
1699 # Some versions of capstone have broken pkg-config file
1700 # that reports a wrong -I path, causing the #include to
1701 # fail later. If the system has such a broken version
1703 if capstone.found() and not cc.compiles('#include <capstone.h>',
1704 dependencies: [capstone])
1705 capstone = not_found
1706 if capstone_opt == 'system'
1707 error('system capstone requested, it does not appear to work')
1712 capstone_opt = 'system'
1714 capstone_opt = 'internal'
1716 capstone_opt = 'disabled'
1719 if capstone_opt == 'internal'
1720 capstone_data = configuration_data()
1721 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1723 capstone_files = files(
1725 'capstone/MCInst.c',
1726 'capstone/MCInstrDesc.c',
1727 'capstone/MCRegisterInfo.c',
1728 'capstone/SStream.c',
1732 if 'CONFIG_ARM_DIS' in config_all_disas
1733 capstone_data.set('CAPSTONE_HAS_ARM', '1')
1734 capstone_files += files(
1735 'capstone/arch/ARM/ARMDisassembler.c',
1736 'capstone/arch/ARM/ARMInstPrinter.c',
1737 'capstone/arch/ARM/ARMMapping.c',
1738 'capstone/arch/ARM/ARMModule.c'
1742 # FIXME: This config entry currently depends on a c++ compiler.
1743 # Which is needed for building libvixl, but not for capstone.
1744 if 'CONFIG_ARM_A64_DIS' in config_all_disas
1745 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1746 capstone_files += files(
1747 'capstone/arch/AArch64/AArch64BaseInfo.c',
1748 'capstone/arch/AArch64/AArch64Disassembler.c',
1749 'capstone/arch/AArch64/AArch64InstPrinter.c',
1750 'capstone/arch/AArch64/AArch64Mapping.c',
1751 'capstone/arch/AArch64/AArch64Module.c'
1755 if 'CONFIG_PPC_DIS' in config_all_disas
1756 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1757 capstone_files += files(
1758 'capstone/arch/PowerPC/PPCDisassembler.c',
1759 'capstone/arch/PowerPC/PPCInstPrinter.c',
1760 'capstone/arch/PowerPC/PPCMapping.c',
1761 'capstone/arch/PowerPC/PPCModule.c'
1765 if 'CONFIG_S390_DIS' in config_all_disas
1766 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1767 capstone_files += files(
1768 'capstone/arch/SystemZ/SystemZDisassembler.c',
1769 'capstone/arch/SystemZ/SystemZInstPrinter.c',
1770 'capstone/arch/SystemZ/SystemZMapping.c',
1771 'capstone/arch/SystemZ/SystemZModule.c',
1772 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1776 if 'CONFIG_I386_DIS' in config_all_disas
1777 capstone_data.set('CAPSTONE_HAS_X86', 1)
1778 capstone_files += files(
1779 'capstone/arch/X86/X86Disassembler.c',
1780 'capstone/arch/X86/X86DisassemblerDecoder.c',
1781 'capstone/arch/X86/X86ATTInstPrinter.c',
1782 'capstone/arch/X86/X86IntelInstPrinter.c',
1783 'capstone/arch/X86/X86InstPrinterCommon.c',
1784 'capstone/arch/X86/X86Mapping.c',
1785 'capstone/arch/X86/X86Module.c'
1789 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1792 # FIXME: There does not seem to be a way to completely replace the c_args
1793 # that come from add_project_arguments() -- we can only add to them.
1794 # So: disable all warnings with a big hammer.
1797 # Include all configuration defines via a header file, which will wind up
1798 # as a dependency on the object file, and thus changes here will result
1800 '-include', 'capstone-defs.h'
1803 libcapstone = static_library('capstone',
1804 build_by_default: false,
1805 sources: capstone_files,
1806 c_args: capstone_cargs,
1807 include_directories: 'capstone/include')
1808 capstone = declare_dependency(link_with: libcapstone,
1809 include_directories: 'capstone/include/capstone')
1813 slirp_opt = 'disabled'
1815 slirp_opt = get_option('slirp')
1816 if slirp_opt in ['enabled', 'auto', 'system']
1817 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1818 slirp = dependency('slirp', kwargs: static_kwargs,
1819 method: 'pkg-config',
1820 required: slirp_opt == 'system' or
1821 slirp_opt == 'enabled' and not have_internal)
1823 slirp_opt = 'system'
1825 slirp_opt = 'internal'
1827 slirp_opt = 'disabled'
1830 if slirp_opt == 'internal'
1832 if targetos == 'windows'
1833 slirp_deps = cc.find_library('iphlpapi')
1834 elif targetos == 'darwin'
1835 slirp_deps = cc.find_library('resolv')
1837 slirp_conf = configuration_data()
1838 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1839 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1840 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1841 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1842 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1844 'slirp/src/arp_table.c',
1845 'slirp/src/bootp.c',
1846 'slirp/src/cksum.c',
1847 'slirp/src/dhcpv6.c',
1848 'slirp/src/dnssearch.c',
1850 'slirp/src/ip6_icmp.c',
1851 'slirp/src/ip6_input.c',
1852 'slirp/src/ip6_output.c',
1853 'slirp/src/ip_icmp.c',
1854 'slirp/src/ip_input.c',
1855 'slirp/src/ip_output.c',
1859 'slirp/src/ndp_table.c',
1861 'slirp/src/slirp.c',
1862 'slirp/src/socket.c',
1863 'slirp/src/state.c',
1864 'slirp/src/stream.c',
1865 'slirp/src/tcp_input.c',
1866 'slirp/src/tcp_output.c',
1867 'slirp/src/tcp_subr.c',
1868 'slirp/src/tcp_timer.c',
1873 'slirp/src/version.c',
1874 'slirp/src/vmstate.c',
1878 input : 'slirp/src/libslirp-version.h.in',
1879 output : 'libslirp-version.h',
1880 configuration: slirp_conf)
1882 slirp_inc = include_directories('slirp', 'slirp/src')
1883 libslirp = static_library('slirp',
1884 build_by_default: false,
1885 sources: slirp_files,
1886 c_args: slirp_cargs,
1887 include_directories: slirp_inc)
1888 slirp = declare_dependency(link_with: libslirp,
1889 dependencies: slirp_deps,
1890 include_directories: slirp_inc)
1894 # For CFI, we need to compile slirp as a static library together with qemu.
1895 # This is because we register slirp functions as callbacks for QEMU Timers.
1896 # When using a system-wide shared libslirp, the type information for the
1897 # callback is missing and the timer call produces a false positive with CFI.
1899 # Now that slirp_opt has been defined, check if the selected slirp is compatible
1900 # with control-flow integrity.
1901 if get_option('cfi') and slirp_opt == 'system'
1902 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
1903 + ' Please configure with --enable-slirp=git')
1907 fdt_opt = get_option('fdt')
1909 if fdt_opt in ['enabled', 'auto', 'system']
1910 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1911 fdt = cc.find_library('fdt', kwargs: static_kwargs,
1912 required: fdt_opt == 'system' or
1913 fdt_opt == 'enabled' and not have_internal)
1914 if fdt.found() and cc.links('''
1916 #include <libfdt_env.h>
1917 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1920 elif fdt_opt == 'system'
1921 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
1923 fdt_opt = 'internal'
1925 fdt_opt = 'disabled'
1929 if fdt_opt == 'internal'
1932 'dtc/libfdt/fdt_ro.c',
1933 'dtc/libfdt/fdt_wip.c',
1934 'dtc/libfdt/fdt_sw.c',
1935 'dtc/libfdt/fdt_rw.c',
1936 'dtc/libfdt/fdt_strerror.c',
1937 'dtc/libfdt/fdt_empty_tree.c',
1938 'dtc/libfdt/fdt_addresses.c',
1939 'dtc/libfdt/fdt_overlay.c',
1940 'dtc/libfdt/fdt_check.c',
1943 fdt_inc = include_directories('dtc/libfdt')
1944 libfdt = static_library('fdt',
1945 build_by_default: false,
1947 include_directories: fdt_inc)
1948 fdt = declare_dependency(link_with: libfdt,
1949 include_directories: fdt_inc)
1952 if not fdt.found() and fdt_required.length() > 0
1953 error('fdt not available but required by targets ' + ', '.join(fdt_required))
1956 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1957 config_host_data.set('CONFIG_FDT', fdt.found())
1958 config_host_data.set('CONFIG_SLIRP', slirp.found())
1960 #####################
1961 # Generated sources #
1962 #####################
1964 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1966 hxtool = find_program('scripts/hxtool')
1967 shaderinclude = find_program('scripts/shaderinclude.pl')
1968 qapi_gen = find_program('scripts/qapi-gen.py')
1969 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
1970 meson.current_source_dir() / 'scripts/qapi/commands.py',
1971 meson.current_source_dir() / 'scripts/qapi/common.py',
1972 meson.current_source_dir() / 'scripts/qapi/error.py',
1973 meson.current_source_dir() / 'scripts/qapi/events.py',
1974 meson.current_source_dir() / 'scripts/qapi/expr.py',
1975 meson.current_source_dir() / 'scripts/qapi/gen.py',
1976 meson.current_source_dir() / 'scripts/qapi/introspect.py',
1977 meson.current_source_dir() / 'scripts/qapi/parser.py',
1978 meson.current_source_dir() / 'scripts/qapi/schema.py',
1979 meson.current_source_dir() / 'scripts/qapi/source.py',
1980 meson.current_source_dir() / 'scripts/qapi/types.py',
1981 meson.current_source_dir() / 'scripts/qapi/visit.py',
1982 meson.current_source_dir() / 'scripts/qapi/common.py',
1983 meson.current_source_dir() / 'scripts/qapi-gen.py'
1987 python, files('scripts/tracetool.py'),
1988 '--backend=' + config_host['TRACE_BACKENDS']
1990 tracetool_depends = files(
1991 'scripts/tracetool/backend/log.py',
1992 'scripts/tracetool/backend/__init__.py',
1993 'scripts/tracetool/backend/dtrace.py',
1994 'scripts/tracetool/backend/ftrace.py',
1995 'scripts/tracetool/backend/simple.py',
1996 'scripts/tracetool/backend/syslog.py',
1997 'scripts/tracetool/backend/ust.py',
1998 'scripts/tracetool/format/tcg_h.py',
1999 'scripts/tracetool/format/ust_events_c.py',
2000 'scripts/tracetool/format/ust_events_h.py',
2001 'scripts/tracetool/format/__init__.py',
2002 'scripts/tracetool/format/d.py',
2003 'scripts/tracetool/format/tcg_helper_c.py',
2004 'scripts/tracetool/format/simpletrace_stap.py',
2005 'scripts/tracetool/format/c.py',
2006 'scripts/tracetool/format/h.py',
2007 'scripts/tracetool/format/tcg_helper_h.py',
2008 'scripts/tracetool/format/log_stap.py',
2009 'scripts/tracetool/format/stap.py',
2010 'scripts/tracetool/format/tcg_helper_wrapper_h.py',
2011 'scripts/tracetool/__init__.py',
2012 'scripts/tracetool/transform.py',
2013 'scripts/tracetool/vcpu.py'
2016 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2017 meson.current_source_dir(),
2018 config_host['PKGVERSION'], meson.project_version()]
2019 qemu_version = custom_target('qemu-version.h',
2020 output: 'qemu-version.h',
2021 command: qemu_version_cmd,
2023 build_by_default: true,
2024 build_always_stale: true)
2025 genh += qemu_version
2029 ['qemu-options.hx', 'qemu-options.def'],
2030 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2034 ['hmp-commands.hx', 'hmp-commands.h'],
2035 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2038 foreach d : hx_headers
2039 hxdep += custom_target(d[1],
2043 build_by_default: true, # to be removed when added to a target
2044 command: [hxtool, '-h', '@INPUT0@'])
2052 authz_ss = ss.source_set()
2053 blockdev_ss = ss.source_set()
2054 block_ss = ss.source_set()
2055 bsd_user_ss = ss.source_set()
2056 chardev_ss = ss.source_set()
2057 common_ss = ss.source_set()
2058 crypto_ss = ss.source_set()
2059 io_ss = ss.source_set()
2060 linux_user_ss = ss.source_set()
2061 qmp_ss = ss.source_set()
2062 qom_ss = ss.source_set()
2063 softmmu_ss = ss.source_set()
2064 specific_fuzz_ss = ss.source_set()
2065 specific_ss = ss.source_set()
2066 stub_ss = ss.source_set()
2067 trace_ss = ss.source_set()
2068 user_ss = ss.source_set()
2069 util_ss = ss.source_set()
2072 qtest_module_ss = ss.source_set()
2073 tcg_module_ss = ss.source_set()
2079 target_softmmu_arch = {}
2080 target_user_arch = {}
2086 # TODO: add each directory to the subdirs from its own meson.build, once
2088 trace_events_subdirs = [
2096 trace_events_subdirs += [ 'linux-user' ]
2099 trace_events_subdirs += [
2108 trace_events_subdirs += [
2122 'hw/block/dataplane',
2171 if have_system or have_user
2172 trace_events_subdirs += [
2189 vhost_user = not_found
2190 if 'CONFIG_VHOST_USER' in config_host
2191 libvhost_user = subproject('libvhost-user')
2192 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2207 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2208 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2211 stub_ss = stub_ss.apply(config_all, strict: false)
2213 util_ss.add_all(trace_ss)
2214 util_ss = util_ss.apply(config_all, strict: false)
2215 libqemuutil = static_library('qemuutil',
2216 sources: util_ss.sources() + stub_ss.sources() + genh,
2217 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2218 qemuutil = declare_dependency(link_with: libqemuutil,
2219 sources: genh + version_res)
2221 if have_system or have_user
2222 decodetree = generator(find_program('scripts/decodetree.py'),
2223 output: 'decode-@BASENAME@.c.inc',
2224 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2225 subdir('libdecnumber')
2242 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
2248 blockdev_ss.add(files(
2255 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2256 # os-win32.c does not
2257 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2258 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2261 common_ss.add(files('cpus-common.c'))
2265 common_ss.add(capstone)
2266 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2268 # Work around a gcc bug/misfeature wherein constant propagation looks
2270 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2271 # to guess that a const variable is always zero. Without lto, this is
2272 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2273 # without lto, not even the alias is required -- we simply use different
2274 # declarations in different compilation units.
2275 pagevary = files('page-vary-common.c')
2276 if get_option('b_lto')
2277 pagevary_flags = ['-fno-lto']
2278 if get_option('cfi')
2279 pagevary_flags += '-fno-sanitize=cfi-icall'
2281 pagevary = static_library('page-vary-common', sources: pagevary,
2282 c_args: pagevary_flags)
2283 pagevary = declare_dependency(link_with: pagevary)
2285 common_ss.add(pagevary)
2286 specific_ss.add(files('page-vary.c'))
2294 subdir('semihosting')
2301 subdir('linux-user')
2304 common_ss.add(libbpf)
2306 bsd_user_ss.add(files('gdbstub.c'))
2307 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
2309 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
2310 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
2312 # needed for fuzzing binaries
2313 subdir('tests/qtest/libqos')
2314 subdir('tests/qtest/fuzz')
2317 tcg_real_module_ss = ss.source_set()
2318 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
2319 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
2320 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
2321 'tcg': tcg_real_module_ss }}
2323 ########################
2324 # Library dependencies #
2325 ########################
2327 modinfo_collect = find_program('scripts/modinfo-collect.py')
2328 modinfo_generate = find_program('scripts/modinfo-generate.py')
2333 foreach d, list : modules
2334 foreach m, module_ss : list
2335 if enable_modules and targetos != 'windows'
2336 module_ss = module_ss.apply(config_all, strict: false)
2337 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2338 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2344 if module_ss.sources() != []
2345 # FIXME: Should use sl.extract_all_objects(recursive: true) as
2346 # input. Sources can be used multiple times but objects are
2347 # unique when it comes to lookup in compile_commands.json.
2348 # Depnds on a mesion version with
2349 # https://github.com/mesonbuild/meson/pull/8900
2350 modinfo_files += custom_target(d + '-' + m + '.modinfo',
2351 output: d + '-' + m + '.modinfo',
2352 input: module_ss.sources() + genh,
2354 command: [modinfo_collect, module_ss.sources()])
2358 block_ss.add_all(module_ss)
2360 softmmu_ss.add_all(module_ss)
2366 foreach d, list : target_modules
2367 foreach m, module_ss : list
2368 if enable_modules and targetos != 'windows'
2369 foreach target : target_dirs
2370 if target.endswith('-softmmu')
2371 config_target = config_target_mak[target]
2372 config_target += config_host
2373 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2374 c_args = ['-DNEED_CPU_H',
2375 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2376 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2377 target_module_ss = module_ss.apply(config_target, strict: false)
2378 if target_module_ss.sources() != []
2379 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
2380 sl = static_library(module_name,
2381 [genh, target_module_ss.sources()],
2382 dependencies: [modulecommon, target_module_ss.dependencies()],
2383 include_directories: target_inc,
2387 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
2388 modinfo_files += custom_target(module_name + '.modinfo',
2389 output: module_name + '.modinfo',
2390 input: target_module_ss.sources() + genh,
2392 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
2397 specific_ss.add_all(module_ss)
2403 modinfo_src = custom_target('modinfo.c',
2404 output: 'modinfo.c',
2405 input: modinfo_files,
2406 command: [modinfo_generate, '@INPUT@'],
2408 modinfo_lib = static_library('modinfo', modinfo_src)
2409 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
2410 softmmu_ss.add(modinfo_dep)
2413 nm = find_program('nm')
2414 undefsym = find_program('scripts/undefsym.py')
2415 block_syms = custom_target('block.syms', output: 'block.syms',
2416 input: [libqemuutil, block_mods],
2418 command: [undefsym, nm, '@INPUT@'])
2419 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2420 input: [libqemuutil, softmmu_mods],
2422 command: [undefsym, nm, '@INPUT@'])
2424 qom_ss = qom_ss.apply(config_host, strict: false)
2425 libqom = static_library('qom', qom_ss.sources() + genh,
2426 dependencies: [qom_ss.dependencies()],
2429 qom = declare_dependency(link_whole: libqom)
2431 authz_ss = authz_ss.apply(config_host, strict: false)
2432 libauthz = static_library('authz', authz_ss.sources() + genh,
2433 dependencies: [authz_ss.dependencies()],
2435 build_by_default: false)
2437 authz = declare_dependency(link_whole: libauthz,
2440 crypto_ss = crypto_ss.apply(config_host, strict: false)
2441 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2442 dependencies: [crypto_ss.dependencies()],
2444 build_by_default: false)
2446 crypto = declare_dependency(link_whole: libcrypto,
2447 dependencies: [authz, qom])
2449 io_ss = io_ss.apply(config_host, strict: false)
2450 libio = static_library('io', io_ss.sources() + genh,
2451 dependencies: [io_ss.dependencies()],
2452 link_with: libqemuutil,
2454 build_by_default: false)
2456 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2458 libmigration = static_library('migration', sources: migration_files + genh,
2460 build_by_default: false)
2461 migration = declare_dependency(link_with: libmigration,
2462 dependencies: [zlib, qom, io])
2463 softmmu_ss.add(migration)
2465 block_ss = block_ss.apply(config_host, strict: false)
2466 libblock = static_library('block', block_ss.sources() + genh,
2467 dependencies: block_ss.dependencies(),
2468 link_depends: block_syms,
2470 build_by_default: false)
2472 block = declare_dependency(link_whole: [libblock],
2473 link_args: '@block.syms',
2474 dependencies: [crypto, io])
2476 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2477 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2478 dependencies: blockdev_ss.dependencies(),
2480 build_by_default: false)
2482 blockdev = declare_dependency(link_whole: [libblockdev],
2483 dependencies: [block])
2485 qmp_ss = qmp_ss.apply(config_host, strict: false)
2486 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2487 dependencies: qmp_ss.dependencies(),
2489 build_by_default: false)
2491 qmp = declare_dependency(link_whole: [libqmp])
2493 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2495 dependencies: [gnutls],
2496 build_by_default: false)
2498 chardev = declare_dependency(link_whole: libchardev)
2500 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2502 build_by_default: false)
2503 hwcore = declare_dependency(link_whole: libhwcore)
2504 common_ss.add(hwcore)
2510 foreach m : block_mods + softmmu_mods
2511 shared_module(m.name(),
2515 install_dir: qemu_moddir)
2518 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2519 common_ss.add(qom, qemuutil)
2521 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2522 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2524 common_all = common_ss.apply(config_all, strict: false)
2525 common_all = static_library('common',
2526 build_by_default: false,
2527 sources: common_all.sources() + genh,
2528 implicit_include_directories: false,
2529 dependencies: common_all.dependencies(),
2532 feature_to_c = find_program('scripts/feature_to_c.sh')
2535 foreach target : target_dirs
2536 config_target = config_target_mak[target]
2537 target_name = config_target['TARGET_NAME']
2538 arch = config_target['TARGET_BASE_ARCH']
2539 arch_srcs = [config_target_h[target]]
2541 c_args = ['-DNEED_CPU_H',
2542 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2543 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2544 link_args = emulator_link_args
2546 config_target += config_host
2547 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2548 if targetos == 'linux'
2549 target_inc += include_directories('linux-headers', is_system: true)
2551 if target.endswith('-softmmu')
2552 qemu_target_name = 'qemu-system-' + target_name
2553 target_type='system'
2554 t = target_softmmu_arch[arch].apply(config_target, strict: false)
2555 arch_srcs += t.sources()
2556 arch_deps += t.dependencies()
2558 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2559 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2560 arch_srcs += hw.sources()
2561 arch_deps += hw.dependencies()
2563 arch_srcs += config_devices_h[target]
2564 link_args += ['@block.syms', '@qemu.syms']
2566 abi = config_target['TARGET_ABI_DIR']
2568 qemu_target_name = 'qemu-' + target_name
2569 if arch in target_user_arch
2570 t = target_user_arch[arch].apply(config_target, strict: false)
2571 arch_srcs += t.sources()
2572 arch_deps += t.dependencies()
2574 if 'CONFIG_LINUX_USER' in config_target
2575 base_dir = 'linux-user'
2576 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2578 if 'CONFIG_BSD_USER' in config_target
2579 base_dir = 'bsd-user'
2580 target_inc += include_directories('bsd-user/' / targetos)
2581 dir = base_dir / abi
2582 arch_srcs += files(dir / 'target_arch_cpu.c')
2584 target_inc += include_directories(
2588 if 'CONFIG_LINUX_USER' in config_target
2589 dir = base_dir / abi
2590 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2591 if config_target.has_key('TARGET_SYSTBL_ABI')
2593 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2594 extra_args : config_target['TARGET_SYSTBL_ABI'])
2599 if 'TARGET_XML_FILES' in config_target
2600 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2601 output: target + '-gdbstub-xml.c',
2602 input: files(config_target['TARGET_XML_FILES'].split()),
2603 command: [feature_to_c, '@INPUT@'],
2605 arch_srcs += gdbstub_xml
2608 t = target_arch[arch].apply(config_target, strict: false)
2609 arch_srcs += t.sources()
2610 arch_deps += t.dependencies()
2612 target_common = common_ss.apply(config_target, strict: false)
2613 objects = common_all.extract_objects(target_common.sources())
2614 deps = target_common.dependencies()
2616 target_specific = specific_ss.apply(config_target, strict: false)
2617 arch_srcs += target_specific.sources()
2618 arch_deps += target_specific.dependencies()
2620 lib = static_library('qemu-' + target,
2621 sources: arch_srcs + genh,
2622 dependencies: arch_deps,
2624 include_directories: target_inc,
2626 build_by_default: false,
2629 if target.endswith('-softmmu')
2631 'name': 'qemu-system-' + target_name,
2632 'win_subsystem': 'console',
2633 'sources': files('softmmu/main.c'),
2636 if targetos == 'windows' and (sdl.found() or gtk.found())
2638 'name': 'qemu-system-' + target_name + 'w',
2639 'win_subsystem': 'windows',
2640 'sources': files('softmmu/main.c'),
2644 if config_host.has_key('CONFIG_FUZZ')
2645 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2647 'name': 'qemu-fuzz-' + target_name,
2648 'win_subsystem': 'console',
2649 'sources': specific_fuzz.sources(),
2650 'dependencies': specific_fuzz.dependencies(),
2655 'name': 'qemu-' + target_name,
2656 'win_subsystem': 'console',
2662 exe_name = exe['name']
2663 if targetos == 'darwin'
2664 exe_name += '-unsigned'
2667 emulator = executable(exe_name, exe['sources'],
2670 dependencies: arch_deps + deps + exe['dependencies'],
2671 objects: lib.extract_all_objects(recursive: true),
2672 link_language: link_language,
2673 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2674 link_args: link_args,
2675 win_subsystem: exe['win_subsystem'])
2677 if targetos == 'darwin'
2678 icon = 'pc-bios/qemu.rsrc'
2679 build_input = [emulator, files(icon)]
2681 get_option('bindir') / exe_name,
2682 meson.current_source_dir() / icon
2684 if 'CONFIG_HVF' in config_target
2685 entitlements = 'accel/hvf/entitlements.plist'
2686 build_input += files(entitlements)
2687 install_input += meson.current_source_dir() / entitlements
2690 emulators += {exe['name'] : custom_target(exe['name'],
2692 output: exe['name'],
2694 files('scripts/entitlement.sh'),
2700 meson.add_install_script('scripts/entitlement.sh', '--install',
2701 get_option('bindir') / exe['name'],
2704 emulators += {exe['name']: emulator}
2707 if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2709 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2710 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2711 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2712 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2714 custom_target(exe['name'] + stp['ext'],
2715 input: trace_events_all,
2716 output: exe['name'] + stp['ext'],
2717 install: stp['install'],
2718 install_dir: get_option('datadir') / 'systemtap/tapset',
2720 tracetool, '--group=all', '--format=' + stp['fmt'],
2721 '--binary=' + stp['bin'],
2722 '--target-name=' + target_name,
2723 '--target-type=' + target_type,
2724 '--probe-prefix=qemu.' + target_type + '.' + target_name,
2725 '@INPUT@', '@OUTPUT@'
2727 depend_files: tracetool_depends)
2733 # Other build targets
2735 if 'CONFIG_PLUGIN' in config_host
2736 install_headers('include/qemu/qemu-plugin.h')
2739 if 'CONFIG_GUEST_AGENT' in config_host
2741 elif get_option('guest_agent_msi').enabled()
2742 error('Guest agent MSI requested, but the guest agent is not being built')
2745 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2746 # when we don't build tools or system
2747 if xkbcommon.found()
2748 # used for the update-keymaps target, so include rules even if !have_tools
2749 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2750 dependencies: [qemuutil, xkbcommon], install: have_tools)
2754 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2755 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2756 qemu_io = executable('qemu-io', files('qemu-io.c'),
2757 dependencies: [block, qemuutil], install: true)
2758 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2759 dependencies: [blockdev, qemuutil, gnutls], install: true)
2761 subdir('storage-daemon')
2762 subdir('contrib/rdmacm-mux')
2763 subdir('contrib/elf2dmp')
2765 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2766 dependencies: qemuutil,
2769 if 'CONFIG_VHOST_USER' in config_host
2770 subdir('contrib/vhost-user-blk')
2771 subdir('contrib/vhost-user-gpu')
2772 subdir('contrib/vhost-user-input')
2773 subdir('contrib/vhost-user-scsi')
2776 if targetos == 'linux'
2777 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2778 dependencies: [qemuutil, libcap_ng],
2780 install_dir: get_option('libexecdir'))
2782 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2783 dependencies: [authz, crypto, io, qom, qemuutil,
2784 libcap_ng, mpathpersist],
2789 subdir('contrib/ivshmem-client')
2790 subdir('contrib/ivshmem-server')
2803 if host_machine.system() == 'windows'
2805 find_program('scripts/nsis.py'),
2807 get_option('prefix'),
2808 meson.current_source_dir(),
2811 '-DDISPLAYVERSION=' + meson.project_version(),
2814 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2817 nsis_cmd += '-DCONFIG_GTK=y'
2820 nsis = custom_target('nsis',
2821 output: 'qemu-setup-' + meson.project_version() + '.exe',
2822 input: files('qemu.nsi'),
2823 build_always_stale: true,
2824 command: nsis_cmd + ['@INPUT@'])
2825 alias_target('installer', nsis)
2828 #########################
2829 # Configuration summary #
2830 #########################
2834 summary_info += {'Install prefix': get_option('prefix')}
2835 summary_info += {'BIOS directory': qemu_datadir}
2836 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
2837 summary_info += {'binary directory': get_option('bindir')}
2838 summary_info += {'library directory': get_option('libdir')}
2839 summary_info += {'module directory': qemu_moddir}
2840 summary_info += {'libexec directory': get_option('libexecdir')}
2841 summary_info += {'include directory': get_option('includedir')}
2842 summary_info += {'config directory': get_option('sysconfdir')}
2843 if targetos != 'windows'
2844 summary_info += {'local state directory': get_option('localstatedir')}
2845 summary_info += {'Manual directory': get_option('mandir')}
2847 summary_info += {'local state directory': 'queried at runtime'}
2849 summary_info += {'Doc directory': get_option('docdir')}
2850 summary_info += {'Build directory': meson.current_build_dir()}
2851 summary_info += {'Source path': meson.current_source_dir()}
2852 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
2853 summary(summary_info, bool_yn: true, section: 'Directories')
2857 summary_info += {'git': config_host['GIT']}
2858 summary_info += {'make': config_host['MAKE']}
2859 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2860 summary_info += {'sphinx-build': sphinx_build}
2861 if config_host.has_key('HAVE_GDB_BIN')
2862 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
2864 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
2865 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
2866 summary_info += {'wixl': wixl}
2868 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
2869 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
2871 summary(summary_info, bool_yn: true, section: 'Host binaries')
2873 # Configurable features
2875 summary_info += {'Documentation': build_docs}
2876 summary_info += {'system-mode emulation': have_system}
2877 summary_info += {'user-mode emulation': have_user}
2878 summary_info += {'block layer': have_block}
2879 summary_info += {'Install blobs': get_option('install_blobs')}
2880 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
2881 if config_host.has_key('CONFIG_MODULES')
2882 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2884 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
2886 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
2888 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
2889 if config_host['TRACE_BACKENDS'].split().contains('simple')
2890 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2892 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2893 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2894 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2895 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2896 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2897 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2898 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2899 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2900 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2901 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2902 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2903 summary(summary_info, bool_yn: true, section: 'Configurable features')
2905 # Compilation information
2907 summary_info += {'host CPU': cpu}
2908 summary_info += {'host endianness': build_machine.endian()}
2909 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
2910 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
2911 if link_language == 'cpp'
2912 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
2914 summary_info += {'C++ compiler': false}
2916 if targetos == 'darwin'
2917 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
2919 if targetos == 'windows'
2920 if 'WIN_SDK' in config_host
2921 summary_info += {'Windows SDK': config_host['WIN_SDK']}
2924 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
2925 + ['-O' + get_option('optimization')]
2926 + (get_option('debug') ? ['-g'] : []))}
2927 if link_language == 'cpp'
2928 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
2929 + ['-O' + get_option('optimization')]
2930 + (get_option('debug') ? ['-g'] : []))}
2932 link_args = get_option(link_language + '_link_args')
2933 if link_args.length() > 0
2934 summary_info += {'LDFLAGS': ' '.join(link_args)}
2936 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
2937 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
2938 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
2939 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2940 summary_info += {'PIE': get_option('b_pie')}
2941 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
2942 summary_info += {'malloc trim support': has_malloc_trim}
2943 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
2944 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2945 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
2946 summary_info += {'memory allocator': get_option('malloc')}
2947 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2948 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2949 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
2950 summary_info += {'gcov': get_option('b_coverage')}
2951 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
2952 summary_info += {'CFI support': get_option('cfi')}
2953 if get_option('cfi')
2954 summary_info += {'CFI debug support': get_option('cfi_debug')}
2956 summary_info += {'strip binaries': get_option('strip')}
2957 summary_info += {'sparse': sparse}
2958 summary_info += {'mingw32 support': targetos == 'windows'}
2960 # snarf the cross-compilation information for tests
2961 foreach target: target_dirs
2962 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
2963 if fs.exists(tcg_mak)
2964 config_cross_tcg = keyval.load(tcg_mak)
2965 target = config_cross_tcg['TARGET_NAME']
2967 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
2968 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
2969 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
2970 elif 'CROSS_CC_GUEST' in config_cross_tcg
2971 summary_info += {target + ' tests'
2972 : config_cross_tcg['CROSS_CC_GUEST'] }
2977 summary(summary_info, bool_yn: true, section: 'Compilation')
2979 # Targets and accelerators
2982 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
2983 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
2984 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
2985 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
2986 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
2987 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
2988 if config_host.has_key('CONFIG_XEN_BACKEND')
2989 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2992 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
2993 if config_all.has_key('CONFIG_TCG')
2994 if get_option('tcg_interpreter')
2995 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, experimental and slow)'}
2997 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
2999 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3000 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3002 summary_info += {'target list': ' '.join(target_dirs)}
3004 summary_info += {'default devices': get_option('default_devices')}
3005 summary_info += {'out of process emulation': multiprocess_allowed}
3007 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3011 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3012 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
3014 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3015 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3016 summary_info += {'Use block whitelist in tools': config_host.has_key('CONFIG_BDRV_WHITELIST_TOOLS')}
3017 summary_info += {'VirtFS support': have_virtfs}
3018 summary_info += {'build virtiofs daemon': have_virtiofsd}
3019 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
3020 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
3021 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
3022 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
3023 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
3024 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
3025 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
3026 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
3027 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
3028 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
3029 summary_info += {'FUSE exports': fuse}
3031 summary(summary_info, bool_yn: true, section: 'Block layer support')
3035 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
3036 summary_info += {'GNUTLS support': gnutls}
3038 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3040 summary_info += {'libgcrypt': gcrypt}
3041 summary_info += {'nettle': nettle}
3043 summary_info += {' XTS': xts != 'private'}
3045 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
3046 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
3047 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
3048 summary(summary_info, bool_yn: true, section: 'Crypto')
3052 if targetos == 'darwin'
3053 summary_info += {'Cocoa support': cocoa}
3055 summary_info += {'SDL support': sdl}
3056 summary_info += {'SDL image support': sdl_image}
3057 summary_info += {'GTK support': gtk}
3058 summary_info += {'pixman': pixman}
3059 summary_info += {'VTE support': vte}
3060 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3061 summary_info += {'libtasn1': tasn1}
3062 summary_info += {'PAM': pam}
3063 summary_info += {'iconv support': iconv}
3064 summary_info += {'curses support': curses}
3065 summary_info += {'virgl support': virgl}
3066 summary_info += {'curl support': curl}
3067 summary_info += {'Multipath support': mpathpersist}
3068 summary_info += {'VNC support': vnc}
3070 summary_info += {'VNC SASL support': sasl}
3071 summary_info += {'VNC JPEG support': jpeg}
3072 summary_info += {'VNC PNG support': png}
3074 summary_info += {'brlapi support': brlapi}
3075 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
3076 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
3077 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
3078 summary_info += {'Linux io_uring support': linux_io_uring}
3079 summary_info += {'ATTR/XATTR support': libattr}
3080 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
3081 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
3082 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3083 summary_info += {'libcap-ng support': libcap_ng}
3084 summary_info += {'bpf support': libbpf}
3085 # TODO: add back protocol and server version
3086 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
3087 summary_info += {'rbd support': rbd}
3088 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
3089 summary_info += {'smartcard support': cacard}
3090 summary_info += {'U2F support': u2f}
3091 summary_info += {'libusb': libusb}
3092 summary_info += {'usb net redir': usbredir}
3093 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
3094 summary_info += {'GBM': gbm}
3095 summary_info += {'libiscsi support': libiscsi}
3096 summary_info += {'libnfs support': libnfs}
3097 if targetos == 'windows'
3098 if config_host.has_key('CONFIG_GUEST_AGENT')
3099 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
3100 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
3103 summary_info += {'seccomp support': seccomp}
3104 summary_info += {'GlusterFS support': glusterfs}
3105 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
3106 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
3107 summary_info += {'lzo support': lzo}
3108 summary_info += {'snappy support': snappy}
3109 summary_info += {'bzip2 support': libbzip2}
3110 summary_info += {'lzfse support': liblzfse}
3111 summary_info += {'zstd support': zstd}
3112 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
3113 summary_info += {'libxml2': libxml2}
3114 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3115 summary_info += {'libpmem support': libpmem}
3116 summary_info += {'libdaxctl support': libdaxctl}
3117 summary_info += {'libudev': libudev}
3118 # Dummy dependency, keep .found()
3119 summary_info += {'FUSE lseek': fuse_lseek.found()}
3120 summary(summary_info, bool_yn: true, section: 'Dependencies')
3122 if not supported_cpus.contains(cpu)
3124 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3126 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3127 message('The QEMU project intends to remove support for this host CPU in')
3128 message('a future release if nobody volunteers to maintain it and to')
3129 message('provide a build host for our continuous integration setup.')
3130 message('configure has succeeded and you can continue to build, but')
3131 message('if you care about QEMU on this platform you should contact')
3132 message('us upstream at qemu-devel@nongnu.org.')
3135 if not supported_oses.contains(targetos)
3137 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3139 message('Host OS ' + targetos + 'support is not currently maintained.')
3140 message('The QEMU project intends to remove support for this host OS in')
3141 message('a future release if nobody volunteers to maintain it and to')
3142 message('provide a build host for our continuous integration setup.')
3143 message('configure has succeeded and you can continue to build, but')
3144 message('if you care about QEMU on this platform you should contact')
3145 message('us upstream at qemu-devel@nongnu.org.')