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 + '''
1423 #include <sys/signalfd.h>
1425 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1426 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1434 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1435 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1439 # Some versions of Mac OS X incorrectly define SIZE_MAX
1440 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1443 int main(int argc, char *argv[]) {
1444 return printf("%zu", SIZE_MAX);
1445 }''', args: ['-Werror']))
1448 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
1449 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1450 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
1451 foreach k, v: config_host
1452 if ignored.contains(k)
1454 elif arrays.contains(k)
1456 v = '"' + '", "'.join(v.split()) + '", '
1458 config_host_data.set(k, v)
1460 config_host_data.set('HOST_' + v.to_upper(), 1)
1461 elif strings.contains(k)
1462 if not k.startswith('CONFIG_')
1463 k = 'CONFIG_' + k.to_upper()
1465 config_host_data.set_quoted(k, v)
1466 elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1467 config_host_data.set(k, v == 'y' ? 1 : v)
1471 ########################
1472 # Target configuration #
1473 ########################
1475 minikconf = find_program('scripts/minikconf.py')
1477 config_all_devices = {}
1478 config_all_disas = {}
1479 config_devices_mak_list = []
1480 config_devices_h = {}
1481 config_target_h = {}
1482 config_target_mak = {}
1485 'alpha' : ['CONFIG_ALPHA_DIS'],
1486 'arm' : ['CONFIG_ARM_DIS'],
1487 'avr' : ['CONFIG_AVR_DIS'],
1488 'cris' : ['CONFIG_CRIS_DIS'],
1489 'hexagon' : ['CONFIG_HEXAGON_DIS'],
1490 'hppa' : ['CONFIG_HPPA_DIS'],
1491 'i386' : ['CONFIG_I386_DIS'],
1492 'x86_64' : ['CONFIG_I386_DIS'],
1493 'x32' : ['CONFIG_I386_DIS'],
1494 'm68k' : ['CONFIG_M68K_DIS'],
1495 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1496 'mips' : ['CONFIG_MIPS_DIS'],
1497 'nios2' : ['CONFIG_NIOS2_DIS'],
1498 'or1k' : ['CONFIG_OPENRISC_DIS'],
1499 'ppc' : ['CONFIG_PPC_DIS'],
1500 'riscv' : ['CONFIG_RISCV_DIS'],
1501 'rx' : ['CONFIG_RX_DIS'],
1502 's390' : ['CONFIG_S390_DIS'],
1503 'sh4' : ['CONFIG_SH4_DIS'],
1504 'sparc' : ['CONFIG_SPARC_DIS'],
1505 'xtensa' : ['CONFIG_XTENSA_DIS'],
1507 if link_language == 'cpp'
1509 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1510 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1511 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1515 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
1517 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1518 ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1519 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
1520 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1521 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1522 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1523 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1524 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1525 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1526 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1527 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1528 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1530 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1532 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1533 actual_target_dirs = []
1535 foreach target : target_dirs
1536 config_target = { 'TARGET_NAME': target.split('-')[0] }
1537 if target.endswith('linux-user')
1538 if targetos != 'linux'
1542 error('Target @0@ is only available on a Linux host'.format(target))
1544 config_target += { 'CONFIG_LINUX_USER': 'y' }
1545 elif target.endswith('bsd-user')
1546 if 'CONFIG_BSD' not in config_host
1550 error('Target @0@ is only available on a BSD host'.format(target))
1552 config_target += { 'CONFIG_BSD_USER': 'y' }
1553 elif target.endswith('softmmu')
1554 config_target += { 'CONFIG_SOFTMMU': 'y' }
1556 if target.endswith('-user')
1558 'CONFIG_USER_ONLY': 'y',
1559 'CONFIG_QEMU_INTERP_PREFIX':
1560 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1565 foreach sym: accelerators
1566 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1567 config_target += { sym: 'y' }
1568 config_all += { sym: 'y' }
1569 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1570 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1571 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1572 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1574 if target in modular_tcg
1575 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
1577 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
1579 accel_kconfig += [ sym + '=y' ]
1582 if accel_kconfig.length() == 0
1586 error('No accelerator available for target @0@'.format(target))
1589 actual_target_dirs += target
1590 config_target += keyval.load('configs/targets' / target + '.mak')
1591 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1593 if 'TARGET_NEED_FDT' in config_target
1594 fdt_required += target
1598 if 'TARGET_BASE_ARCH' not in config_target
1599 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1601 if 'TARGET_ABI_DIR' not in config_target
1602 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1605 foreach k, v: disassemblers
1606 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1608 config_target += { sym: 'y' }
1609 config_all_disas += { sym: 'y' }
1614 config_target_data = configuration_data()
1615 foreach k, v: config_target
1616 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1618 elif ignored.contains(k)
1620 elif k == 'TARGET_BASE_ARCH'
1621 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1622 # not used to select files from sourcesets.
1623 config_target_data.set('TARGET_' + v.to_upper(), 1)
1624 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1625 config_target_data.set_quoted(k, v)
1627 config_target_data.set(k, 1)
1629 config_target_data.set(k, v)
1632 config_target_data.set('QEMU_ARCH',
1633 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
1634 config_target_h += {target: configure_file(output: target + '-config-target.h',
1635 configuration: config_target_data)}
1637 if target.endswith('-softmmu')
1638 config_input = meson.get_external_property(target, 'default')
1639 config_devices_mak = target + '-config-devices.mak'
1640 config_devices_mak = configure_file(
1641 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
1642 output: config_devices_mak,
1643 depfile: config_devices_mak + '.d',
1645 command: [minikconf,
1646 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1647 config_devices_mak, '@DEPFILE@', '@INPUT@',
1648 host_kconfig, accel_kconfig,
1649 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
1651 config_devices_data = configuration_data()
1652 config_devices = keyval.load(config_devices_mak)
1653 foreach k, v: config_devices
1654 config_devices_data.set(k, 1)
1656 config_devices_mak_list += config_devices_mak
1657 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1658 configuration: config_devices_data)}
1659 config_target += config_devices
1660 config_all_devices += config_devices
1662 config_target_mak += {target: config_target}
1664 target_dirs = actual_target_dirs
1666 # This configuration is used to build files that are shared by
1667 # multiple binaries, and then extracted out of the "common"
1668 # static_library target.
1670 # We do not use all_sources()/all_dependencies(), because it would
1671 # build literally all source files, including devices only used by
1672 # targets that are not built for this compilation. The CONFIG_ALL
1673 # pseudo symbol replaces it.
1675 config_all += config_all_devices
1676 config_all += config_host
1677 config_all += config_all_disas
1679 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1680 'CONFIG_SOFTMMU': have_system,
1681 'CONFIG_USER_ONLY': have_user,
1689 capstone = not_found
1690 capstone_opt = get_option('capstone')
1691 if capstone_opt in ['enabled', 'auto', 'system']
1692 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1693 capstone = dependency('capstone', version: '>=4.0',
1694 kwargs: static_kwargs, method: 'pkg-config',
1695 required: capstone_opt == 'system' or
1696 capstone_opt == 'enabled' and not have_internal)
1698 # Some versions of capstone have broken pkg-config file
1699 # that reports a wrong -I path, causing the #include to
1700 # fail later. If the system has such a broken version
1702 if capstone.found() and not cc.compiles('#include <capstone.h>',
1703 dependencies: [capstone])
1704 capstone = not_found
1705 if capstone_opt == 'system'
1706 error('system capstone requested, it does not appear to work')
1711 capstone_opt = 'system'
1713 capstone_opt = 'internal'
1715 capstone_opt = 'disabled'
1718 if capstone_opt == 'internal'
1719 capstone_data = configuration_data()
1720 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1722 capstone_files = files(
1724 'capstone/MCInst.c',
1725 'capstone/MCInstrDesc.c',
1726 'capstone/MCRegisterInfo.c',
1727 'capstone/SStream.c',
1731 if 'CONFIG_ARM_DIS' in config_all_disas
1732 capstone_data.set('CAPSTONE_HAS_ARM', '1')
1733 capstone_files += files(
1734 'capstone/arch/ARM/ARMDisassembler.c',
1735 'capstone/arch/ARM/ARMInstPrinter.c',
1736 'capstone/arch/ARM/ARMMapping.c',
1737 'capstone/arch/ARM/ARMModule.c'
1741 # FIXME: This config entry currently depends on a c++ compiler.
1742 # Which is needed for building libvixl, but not for capstone.
1743 if 'CONFIG_ARM_A64_DIS' in config_all_disas
1744 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1745 capstone_files += files(
1746 'capstone/arch/AArch64/AArch64BaseInfo.c',
1747 'capstone/arch/AArch64/AArch64Disassembler.c',
1748 'capstone/arch/AArch64/AArch64InstPrinter.c',
1749 'capstone/arch/AArch64/AArch64Mapping.c',
1750 'capstone/arch/AArch64/AArch64Module.c'
1754 if 'CONFIG_PPC_DIS' in config_all_disas
1755 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1756 capstone_files += files(
1757 'capstone/arch/PowerPC/PPCDisassembler.c',
1758 'capstone/arch/PowerPC/PPCInstPrinter.c',
1759 'capstone/arch/PowerPC/PPCMapping.c',
1760 'capstone/arch/PowerPC/PPCModule.c'
1764 if 'CONFIG_S390_DIS' in config_all_disas
1765 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1766 capstone_files += files(
1767 'capstone/arch/SystemZ/SystemZDisassembler.c',
1768 'capstone/arch/SystemZ/SystemZInstPrinter.c',
1769 'capstone/arch/SystemZ/SystemZMapping.c',
1770 'capstone/arch/SystemZ/SystemZModule.c',
1771 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1775 if 'CONFIG_I386_DIS' in config_all_disas
1776 capstone_data.set('CAPSTONE_HAS_X86', 1)
1777 capstone_files += files(
1778 'capstone/arch/X86/X86Disassembler.c',
1779 'capstone/arch/X86/X86DisassemblerDecoder.c',
1780 'capstone/arch/X86/X86ATTInstPrinter.c',
1781 'capstone/arch/X86/X86IntelInstPrinter.c',
1782 'capstone/arch/X86/X86InstPrinterCommon.c',
1783 'capstone/arch/X86/X86Mapping.c',
1784 'capstone/arch/X86/X86Module.c'
1788 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1791 # FIXME: There does not seem to be a way to completely replace the c_args
1792 # that come from add_project_arguments() -- we can only add to them.
1793 # So: disable all warnings with a big hammer.
1796 # Include all configuration defines via a header file, which will wind up
1797 # as a dependency on the object file, and thus changes here will result
1799 '-include', 'capstone-defs.h'
1802 libcapstone = static_library('capstone',
1803 build_by_default: false,
1804 sources: capstone_files,
1805 c_args: capstone_cargs,
1806 include_directories: 'capstone/include')
1807 capstone = declare_dependency(link_with: libcapstone,
1808 include_directories: 'capstone/include/capstone')
1812 slirp_opt = 'disabled'
1814 slirp_opt = get_option('slirp')
1815 if slirp_opt in ['enabled', 'auto', 'system']
1816 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1817 slirp = dependency('slirp', kwargs: static_kwargs,
1818 method: 'pkg-config',
1819 required: slirp_opt == 'system' or
1820 slirp_opt == 'enabled' and not have_internal)
1822 slirp_opt = 'system'
1824 slirp_opt = 'internal'
1826 slirp_opt = 'disabled'
1829 if slirp_opt == 'internal'
1831 if targetos == 'windows'
1832 slirp_deps = cc.find_library('iphlpapi')
1833 elif targetos == 'darwin'
1834 slirp_deps = cc.find_library('resolv')
1836 slirp_conf = configuration_data()
1837 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1838 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1839 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1840 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1841 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1843 'slirp/src/arp_table.c',
1844 'slirp/src/bootp.c',
1845 'slirp/src/cksum.c',
1846 'slirp/src/dhcpv6.c',
1847 'slirp/src/dnssearch.c',
1849 'slirp/src/ip6_icmp.c',
1850 'slirp/src/ip6_input.c',
1851 'slirp/src/ip6_output.c',
1852 'slirp/src/ip_icmp.c',
1853 'slirp/src/ip_input.c',
1854 'slirp/src/ip_output.c',
1858 'slirp/src/ndp_table.c',
1860 'slirp/src/slirp.c',
1861 'slirp/src/socket.c',
1862 'slirp/src/state.c',
1863 'slirp/src/stream.c',
1864 'slirp/src/tcp_input.c',
1865 'slirp/src/tcp_output.c',
1866 'slirp/src/tcp_subr.c',
1867 'slirp/src/tcp_timer.c',
1872 'slirp/src/version.c',
1873 'slirp/src/vmstate.c',
1877 input : 'slirp/src/libslirp-version.h.in',
1878 output : 'libslirp-version.h',
1879 configuration: slirp_conf)
1881 slirp_inc = include_directories('slirp', 'slirp/src')
1882 libslirp = static_library('slirp',
1883 build_by_default: false,
1884 sources: slirp_files,
1885 c_args: slirp_cargs,
1886 include_directories: slirp_inc)
1887 slirp = declare_dependency(link_with: libslirp,
1888 dependencies: slirp_deps,
1889 include_directories: slirp_inc)
1893 # For CFI, we need to compile slirp as a static library together with qemu.
1894 # This is because we register slirp functions as callbacks for QEMU Timers.
1895 # When using a system-wide shared libslirp, the type information for the
1896 # callback is missing and the timer call produces a false positive with CFI.
1898 # Now that slirp_opt has been defined, check if the selected slirp is compatible
1899 # with control-flow integrity.
1900 if get_option('cfi') and slirp_opt == 'system'
1901 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
1902 + ' Please configure with --enable-slirp=git')
1906 fdt_opt = get_option('fdt')
1908 if fdt_opt in ['enabled', 'auto', 'system']
1909 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1910 fdt = cc.find_library('fdt', kwargs: static_kwargs,
1911 required: fdt_opt == 'system' or
1912 fdt_opt == 'enabled' and not have_internal)
1913 if fdt.found() and cc.links('''
1915 #include <libfdt_env.h>
1916 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1919 elif fdt_opt == 'system'
1920 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
1922 fdt_opt = 'internal'
1924 fdt_opt = 'disabled'
1928 if fdt_opt == 'internal'
1931 'dtc/libfdt/fdt_ro.c',
1932 'dtc/libfdt/fdt_wip.c',
1933 'dtc/libfdt/fdt_sw.c',
1934 'dtc/libfdt/fdt_rw.c',
1935 'dtc/libfdt/fdt_strerror.c',
1936 'dtc/libfdt/fdt_empty_tree.c',
1937 'dtc/libfdt/fdt_addresses.c',
1938 'dtc/libfdt/fdt_overlay.c',
1939 'dtc/libfdt/fdt_check.c',
1942 fdt_inc = include_directories('dtc/libfdt')
1943 libfdt = static_library('fdt',
1944 build_by_default: false,
1946 include_directories: fdt_inc)
1947 fdt = declare_dependency(link_with: libfdt,
1948 include_directories: fdt_inc)
1951 if not fdt.found() and fdt_required.length() > 0
1952 error('fdt not available but required by targets ' + ', '.join(fdt_required))
1955 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1956 config_host_data.set('CONFIG_FDT', fdt.found())
1957 config_host_data.set('CONFIG_SLIRP', slirp.found())
1959 #####################
1960 # Generated sources #
1961 #####################
1963 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1965 hxtool = find_program('scripts/hxtool')
1966 shaderinclude = find_program('scripts/shaderinclude.pl')
1967 qapi_gen = find_program('scripts/qapi-gen.py')
1968 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
1969 meson.current_source_dir() / 'scripts/qapi/commands.py',
1970 meson.current_source_dir() / 'scripts/qapi/common.py',
1971 meson.current_source_dir() / 'scripts/qapi/error.py',
1972 meson.current_source_dir() / 'scripts/qapi/events.py',
1973 meson.current_source_dir() / 'scripts/qapi/expr.py',
1974 meson.current_source_dir() / 'scripts/qapi/gen.py',
1975 meson.current_source_dir() / 'scripts/qapi/introspect.py',
1976 meson.current_source_dir() / 'scripts/qapi/parser.py',
1977 meson.current_source_dir() / 'scripts/qapi/schema.py',
1978 meson.current_source_dir() / 'scripts/qapi/source.py',
1979 meson.current_source_dir() / 'scripts/qapi/types.py',
1980 meson.current_source_dir() / 'scripts/qapi/visit.py',
1981 meson.current_source_dir() / 'scripts/qapi/common.py',
1982 meson.current_source_dir() / 'scripts/qapi-gen.py'
1986 python, files('scripts/tracetool.py'),
1987 '--backend=' + config_host['TRACE_BACKENDS']
1989 tracetool_depends = files(
1990 'scripts/tracetool/backend/log.py',
1991 'scripts/tracetool/backend/__init__.py',
1992 'scripts/tracetool/backend/dtrace.py',
1993 'scripts/tracetool/backend/ftrace.py',
1994 'scripts/tracetool/backend/simple.py',
1995 'scripts/tracetool/backend/syslog.py',
1996 'scripts/tracetool/backend/ust.py',
1997 'scripts/tracetool/format/tcg_h.py',
1998 'scripts/tracetool/format/ust_events_c.py',
1999 'scripts/tracetool/format/ust_events_h.py',
2000 'scripts/tracetool/format/__init__.py',
2001 'scripts/tracetool/format/d.py',
2002 'scripts/tracetool/format/tcg_helper_c.py',
2003 'scripts/tracetool/format/simpletrace_stap.py',
2004 'scripts/tracetool/format/c.py',
2005 'scripts/tracetool/format/h.py',
2006 'scripts/tracetool/format/tcg_helper_h.py',
2007 'scripts/tracetool/format/log_stap.py',
2008 'scripts/tracetool/format/stap.py',
2009 'scripts/tracetool/format/tcg_helper_wrapper_h.py',
2010 'scripts/tracetool/__init__.py',
2011 'scripts/tracetool/transform.py',
2012 'scripts/tracetool/vcpu.py'
2015 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2016 meson.current_source_dir(),
2017 config_host['PKGVERSION'], meson.project_version()]
2018 qemu_version = custom_target('qemu-version.h',
2019 output: 'qemu-version.h',
2020 command: qemu_version_cmd,
2022 build_by_default: true,
2023 build_always_stale: true)
2024 genh += qemu_version
2028 ['qemu-options.hx', 'qemu-options.def'],
2029 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2033 ['hmp-commands.hx', 'hmp-commands.h'],
2034 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2037 foreach d : hx_headers
2038 hxdep += custom_target(d[1],
2042 build_by_default: true, # to be removed when added to a target
2043 command: [hxtool, '-h', '@INPUT0@'])
2051 authz_ss = ss.source_set()
2052 blockdev_ss = ss.source_set()
2053 block_ss = ss.source_set()
2054 bsd_user_ss = ss.source_set()
2055 chardev_ss = ss.source_set()
2056 common_ss = ss.source_set()
2057 crypto_ss = ss.source_set()
2058 io_ss = ss.source_set()
2059 linux_user_ss = ss.source_set()
2060 qmp_ss = ss.source_set()
2061 qom_ss = ss.source_set()
2062 softmmu_ss = ss.source_set()
2063 specific_fuzz_ss = ss.source_set()
2064 specific_ss = ss.source_set()
2065 stub_ss = ss.source_set()
2066 trace_ss = ss.source_set()
2067 user_ss = ss.source_set()
2068 util_ss = ss.source_set()
2071 qtest_module_ss = ss.source_set()
2072 tcg_module_ss = ss.source_set()
2078 target_softmmu_arch = {}
2079 target_user_arch = {}
2085 # TODO: add each directory to the subdirs from its own meson.build, once
2087 trace_events_subdirs = [
2095 trace_events_subdirs += [ 'linux-user' ]
2098 trace_events_subdirs += [
2107 trace_events_subdirs += [
2121 'hw/block/dataplane',
2170 if have_system or have_user
2171 trace_events_subdirs += [
2188 vhost_user = not_found
2189 if 'CONFIG_VHOST_USER' in config_host
2190 libvhost_user = subproject('libvhost-user')
2191 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2206 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2207 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2210 stub_ss = stub_ss.apply(config_all, strict: false)
2212 util_ss.add_all(trace_ss)
2213 util_ss = util_ss.apply(config_all, strict: false)
2214 libqemuutil = static_library('qemuutil',
2215 sources: util_ss.sources() + stub_ss.sources() + genh,
2216 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2217 qemuutil = declare_dependency(link_with: libqemuutil,
2218 sources: genh + version_res)
2220 if have_system or have_user
2221 decodetree = generator(find_program('scripts/decodetree.py'),
2222 output: 'decode-@BASENAME@.c.inc',
2223 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2224 subdir('libdecnumber')
2241 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
2247 blockdev_ss.add(files(
2254 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2255 # os-win32.c does not
2256 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2257 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2260 common_ss.add(files('cpus-common.c'))
2264 common_ss.add(capstone)
2265 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2267 # Work around a gcc bug/misfeature wherein constant propagation looks
2269 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2270 # to guess that a const variable is always zero. Without lto, this is
2271 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2272 # without lto, not even the alias is required -- we simply use different
2273 # declarations in different compilation units.
2274 pagevary = files('page-vary-common.c')
2275 if get_option('b_lto')
2276 pagevary_flags = ['-fno-lto']
2277 if get_option('cfi')
2278 pagevary_flags += '-fno-sanitize=cfi-icall'
2280 pagevary = static_library('page-vary-common', sources: pagevary,
2281 c_args: pagevary_flags)
2282 pagevary = declare_dependency(link_with: pagevary)
2284 common_ss.add(pagevary)
2285 specific_ss.add(files('page-vary.c'))
2293 subdir('semihosting')
2300 subdir('linux-user')
2303 common_ss.add(libbpf)
2305 bsd_user_ss.add(files('gdbstub.c'))
2306 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
2308 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
2309 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
2311 # needed for fuzzing binaries
2312 subdir('tests/qtest/libqos')
2313 subdir('tests/qtest/fuzz')
2316 tcg_real_module_ss = ss.source_set()
2317 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
2318 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
2319 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
2320 'tcg': tcg_real_module_ss }}
2322 ########################
2323 # Library dependencies #
2324 ########################
2326 modinfo_collect = find_program('scripts/modinfo-collect.py')
2327 modinfo_generate = find_program('scripts/modinfo-generate.py')
2332 foreach d, list : modules
2333 foreach m, module_ss : list
2334 if enable_modules and targetos != 'windows'
2335 module_ss = module_ss.apply(config_all, strict: false)
2336 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2337 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2343 if module_ss.sources() != []
2344 # FIXME: Should use sl.extract_all_objects(recursive: true) as
2345 # input. Sources can be used multiple times but objects are
2346 # unique when it comes to lookup in compile_commands.json.
2347 # Depnds on a mesion version with
2348 # https://github.com/mesonbuild/meson/pull/8900
2349 modinfo_files += custom_target(d + '-' + m + '.modinfo',
2350 output: d + '-' + m + '.modinfo',
2351 input: module_ss.sources() + genh,
2353 command: [modinfo_collect, module_ss.sources()])
2357 block_ss.add_all(module_ss)
2359 softmmu_ss.add_all(module_ss)
2365 foreach d, list : target_modules
2366 foreach m, module_ss : list
2367 if enable_modules and targetos != 'windows'
2368 foreach target : target_dirs
2369 if target.endswith('-softmmu')
2370 config_target = config_target_mak[target]
2371 config_target += config_host
2372 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2373 c_args = ['-DNEED_CPU_H',
2374 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2375 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2376 target_module_ss = module_ss.apply(config_target, strict: false)
2377 if target_module_ss.sources() != []
2378 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
2379 sl = static_library(module_name,
2380 [genh, target_module_ss.sources()],
2381 dependencies: [modulecommon, target_module_ss.dependencies()],
2382 include_directories: target_inc,
2386 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
2387 modinfo_files += custom_target(module_name + '.modinfo',
2388 output: module_name + '.modinfo',
2389 input: target_module_ss.sources() + genh,
2391 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
2396 specific_ss.add_all(module_ss)
2402 modinfo_src = custom_target('modinfo.c',
2403 output: 'modinfo.c',
2404 input: modinfo_files,
2405 command: [modinfo_generate, '@INPUT@'],
2407 modinfo_lib = static_library('modinfo', modinfo_src)
2408 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
2409 softmmu_ss.add(modinfo_dep)
2412 nm = find_program('nm')
2413 undefsym = find_program('scripts/undefsym.py')
2414 block_syms = custom_target('block.syms', output: 'block.syms',
2415 input: [libqemuutil, block_mods],
2417 command: [undefsym, nm, '@INPUT@'])
2418 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2419 input: [libqemuutil, softmmu_mods],
2421 command: [undefsym, nm, '@INPUT@'])
2423 qom_ss = qom_ss.apply(config_host, strict: false)
2424 libqom = static_library('qom', qom_ss.sources() + genh,
2425 dependencies: [qom_ss.dependencies()],
2428 qom = declare_dependency(link_whole: libqom)
2430 authz_ss = authz_ss.apply(config_host, strict: false)
2431 libauthz = static_library('authz', authz_ss.sources() + genh,
2432 dependencies: [authz_ss.dependencies()],
2434 build_by_default: false)
2436 authz = declare_dependency(link_whole: libauthz,
2439 crypto_ss = crypto_ss.apply(config_host, strict: false)
2440 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2441 dependencies: [crypto_ss.dependencies()],
2443 build_by_default: false)
2445 crypto = declare_dependency(link_whole: libcrypto,
2446 dependencies: [authz, qom])
2448 io_ss = io_ss.apply(config_host, strict: false)
2449 libio = static_library('io', io_ss.sources() + genh,
2450 dependencies: [io_ss.dependencies()],
2451 link_with: libqemuutil,
2453 build_by_default: false)
2455 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2457 libmigration = static_library('migration', sources: migration_files + genh,
2459 build_by_default: false)
2460 migration = declare_dependency(link_with: libmigration,
2461 dependencies: [zlib, qom, io])
2462 softmmu_ss.add(migration)
2464 block_ss = block_ss.apply(config_host, strict: false)
2465 libblock = static_library('block', block_ss.sources() + genh,
2466 dependencies: block_ss.dependencies(),
2467 link_depends: block_syms,
2469 build_by_default: false)
2471 block = declare_dependency(link_whole: [libblock],
2472 link_args: '@block.syms',
2473 dependencies: [crypto, io])
2475 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2476 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2477 dependencies: blockdev_ss.dependencies(),
2479 build_by_default: false)
2481 blockdev = declare_dependency(link_whole: [libblockdev],
2482 dependencies: [block])
2484 qmp_ss = qmp_ss.apply(config_host, strict: false)
2485 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2486 dependencies: qmp_ss.dependencies(),
2488 build_by_default: false)
2490 qmp = declare_dependency(link_whole: [libqmp])
2492 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2494 dependencies: [gnutls],
2495 build_by_default: false)
2497 chardev = declare_dependency(link_whole: libchardev)
2499 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2501 build_by_default: false)
2502 hwcore = declare_dependency(link_whole: libhwcore)
2503 common_ss.add(hwcore)
2509 foreach m : block_mods + softmmu_mods
2510 shared_module(m.name(),
2514 install_dir: qemu_moddir)
2517 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2518 common_ss.add(qom, qemuutil)
2520 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2521 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2523 common_all = common_ss.apply(config_all, strict: false)
2524 common_all = static_library('common',
2525 build_by_default: false,
2526 sources: common_all.sources() + genh,
2527 implicit_include_directories: false,
2528 dependencies: common_all.dependencies(),
2531 feature_to_c = find_program('scripts/feature_to_c.sh')
2534 foreach target : target_dirs
2535 config_target = config_target_mak[target]
2536 target_name = config_target['TARGET_NAME']
2537 arch = config_target['TARGET_BASE_ARCH']
2538 arch_srcs = [config_target_h[target]]
2540 c_args = ['-DNEED_CPU_H',
2541 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2542 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2543 link_args = emulator_link_args
2545 config_target += config_host
2546 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2547 if targetos == 'linux'
2548 target_inc += include_directories('linux-headers', is_system: true)
2550 if target.endswith('-softmmu')
2551 qemu_target_name = 'qemu-system-' + target_name
2552 target_type='system'
2553 t = target_softmmu_arch[arch].apply(config_target, strict: false)
2554 arch_srcs += t.sources()
2555 arch_deps += t.dependencies()
2557 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2558 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2559 arch_srcs += hw.sources()
2560 arch_deps += hw.dependencies()
2562 arch_srcs += config_devices_h[target]
2563 link_args += ['@block.syms', '@qemu.syms']
2565 abi = config_target['TARGET_ABI_DIR']
2567 qemu_target_name = 'qemu-' + target_name
2568 if arch in target_user_arch
2569 t = target_user_arch[arch].apply(config_target, strict: false)
2570 arch_srcs += t.sources()
2571 arch_deps += t.dependencies()
2573 if 'CONFIG_LINUX_USER' in config_target
2574 base_dir = 'linux-user'
2575 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2577 if 'CONFIG_BSD_USER' in config_target
2578 base_dir = 'bsd-user'
2579 target_inc += include_directories('bsd-user/' / targetos)
2580 dir = base_dir / abi
2581 arch_srcs += files(dir / 'target_arch_cpu.c')
2583 target_inc += include_directories(
2587 if 'CONFIG_LINUX_USER' in config_target
2588 dir = base_dir / abi
2589 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2590 if config_target.has_key('TARGET_SYSTBL_ABI')
2592 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2593 extra_args : config_target['TARGET_SYSTBL_ABI'])
2598 if 'TARGET_XML_FILES' in config_target
2599 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2600 output: target + '-gdbstub-xml.c',
2601 input: files(config_target['TARGET_XML_FILES'].split()),
2602 command: [feature_to_c, '@INPUT@'],
2604 arch_srcs += gdbstub_xml
2607 t = target_arch[arch].apply(config_target, strict: false)
2608 arch_srcs += t.sources()
2609 arch_deps += t.dependencies()
2611 target_common = common_ss.apply(config_target, strict: false)
2612 objects = common_all.extract_objects(target_common.sources())
2613 deps = target_common.dependencies()
2615 target_specific = specific_ss.apply(config_target, strict: false)
2616 arch_srcs += target_specific.sources()
2617 arch_deps += target_specific.dependencies()
2619 lib = static_library('qemu-' + target,
2620 sources: arch_srcs + genh,
2621 dependencies: arch_deps,
2623 include_directories: target_inc,
2625 build_by_default: false,
2628 if target.endswith('-softmmu')
2630 'name': 'qemu-system-' + target_name,
2631 'win_subsystem': 'console',
2632 'sources': files('softmmu/main.c'),
2635 if targetos == 'windows' and (sdl.found() or gtk.found())
2637 'name': 'qemu-system-' + target_name + 'w',
2638 'win_subsystem': 'windows',
2639 'sources': files('softmmu/main.c'),
2643 if config_host.has_key('CONFIG_FUZZ')
2644 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2646 'name': 'qemu-fuzz-' + target_name,
2647 'win_subsystem': 'console',
2648 'sources': specific_fuzz.sources(),
2649 'dependencies': specific_fuzz.dependencies(),
2654 'name': 'qemu-' + target_name,
2655 'win_subsystem': 'console',
2661 exe_name = exe['name']
2662 if targetos == 'darwin'
2663 exe_name += '-unsigned'
2666 emulator = executable(exe_name, exe['sources'],
2669 dependencies: arch_deps + deps + exe['dependencies'],
2670 objects: lib.extract_all_objects(recursive: true),
2671 link_language: link_language,
2672 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2673 link_args: link_args,
2674 win_subsystem: exe['win_subsystem'])
2676 if targetos == 'darwin'
2677 icon = 'pc-bios/qemu.rsrc'
2678 build_input = [emulator, files(icon)]
2680 get_option('bindir') / exe_name,
2681 meson.current_source_dir() / icon
2683 if 'CONFIG_HVF' in config_target
2684 entitlements = 'accel/hvf/entitlements.plist'
2685 build_input += files(entitlements)
2686 install_input += meson.current_source_dir() / entitlements
2689 emulators += {exe['name'] : custom_target(exe['name'],
2691 output: exe['name'],
2693 files('scripts/entitlement.sh'),
2699 meson.add_install_script('scripts/entitlement.sh', '--install',
2700 get_option('bindir') / exe['name'],
2703 emulators += {exe['name']: emulator}
2706 if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2708 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2709 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2710 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2711 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2713 custom_target(exe['name'] + stp['ext'],
2714 input: trace_events_all,
2715 output: exe['name'] + stp['ext'],
2716 install: stp['install'],
2717 install_dir: get_option('datadir') / 'systemtap/tapset',
2719 tracetool, '--group=all', '--format=' + stp['fmt'],
2720 '--binary=' + stp['bin'],
2721 '--target-name=' + target_name,
2722 '--target-type=' + target_type,
2723 '--probe-prefix=qemu.' + target_type + '.' + target_name,
2724 '@INPUT@', '@OUTPUT@'
2726 depend_files: tracetool_depends)
2732 # Other build targets
2734 if 'CONFIG_PLUGIN' in config_host
2735 install_headers('include/qemu/qemu-plugin.h')
2738 if 'CONFIG_GUEST_AGENT' in config_host
2740 elif get_option('guest_agent_msi').enabled()
2741 error('Guest agent MSI requested, but the guest agent is not being built')
2744 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2745 # when we don't build tools or system
2746 if xkbcommon.found()
2747 # used for the update-keymaps target, so include rules even if !have_tools
2748 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2749 dependencies: [qemuutil, xkbcommon], install: have_tools)
2753 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2754 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2755 qemu_io = executable('qemu-io', files('qemu-io.c'),
2756 dependencies: [block, qemuutil], install: true)
2757 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2758 dependencies: [blockdev, qemuutil, gnutls], install: true)
2760 subdir('storage-daemon')
2761 subdir('contrib/rdmacm-mux')
2762 subdir('contrib/elf2dmp')
2764 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2765 dependencies: qemuutil,
2768 if 'CONFIG_VHOST_USER' in config_host
2769 subdir('contrib/vhost-user-blk')
2770 subdir('contrib/vhost-user-gpu')
2771 subdir('contrib/vhost-user-input')
2772 subdir('contrib/vhost-user-scsi')
2775 if targetos == 'linux'
2776 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2777 dependencies: [qemuutil, libcap_ng],
2779 install_dir: get_option('libexecdir'))
2781 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2782 dependencies: [authz, crypto, io, qom, qemuutil,
2783 libcap_ng, mpathpersist],
2788 subdir('contrib/ivshmem-client')
2789 subdir('contrib/ivshmem-server')
2802 if host_machine.system() == 'windows'
2804 find_program('scripts/nsis.py'),
2806 get_option('prefix'),
2807 meson.current_source_dir(),
2810 '-DDISPLAYVERSION=' + meson.project_version(),
2813 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2816 nsis_cmd += '-DCONFIG_GTK=y'
2819 nsis = custom_target('nsis',
2820 output: 'qemu-setup-' + meson.project_version() + '.exe',
2821 input: files('qemu.nsi'),
2822 build_always_stale: true,
2823 command: nsis_cmd + ['@INPUT@'])
2824 alias_target('installer', nsis)
2827 #########################
2828 # Configuration summary #
2829 #########################
2833 summary_info += {'Install prefix': get_option('prefix')}
2834 summary_info += {'BIOS directory': qemu_datadir}
2835 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
2836 summary_info += {'binary directory': get_option('bindir')}
2837 summary_info += {'library directory': get_option('libdir')}
2838 summary_info += {'module directory': qemu_moddir}
2839 summary_info += {'libexec directory': get_option('libexecdir')}
2840 summary_info += {'include directory': get_option('includedir')}
2841 summary_info += {'config directory': get_option('sysconfdir')}
2842 if targetos != 'windows'
2843 summary_info += {'local state directory': get_option('localstatedir')}
2844 summary_info += {'Manual directory': get_option('mandir')}
2846 summary_info += {'local state directory': 'queried at runtime'}
2848 summary_info += {'Doc directory': get_option('docdir')}
2849 summary_info += {'Build directory': meson.current_build_dir()}
2850 summary_info += {'Source path': meson.current_source_dir()}
2851 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
2852 summary(summary_info, bool_yn: true, section: 'Directories')
2856 summary_info += {'git': config_host['GIT']}
2857 summary_info += {'make': config_host['MAKE']}
2858 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2859 summary_info += {'sphinx-build': sphinx_build}
2860 if config_host.has_key('HAVE_GDB_BIN')
2861 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
2863 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
2864 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
2865 summary_info += {'wixl': wixl}
2867 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
2868 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
2870 summary(summary_info, bool_yn: true, section: 'Host binaries')
2872 # Configurable features
2874 summary_info += {'Documentation': build_docs}
2875 summary_info += {'system-mode emulation': have_system}
2876 summary_info += {'user-mode emulation': have_user}
2877 summary_info += {'block layer': have_block}
2878 summary_info += {'Install blobs': get_option('install_blobs')}
2879 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
2880 if config_host.has_key('CONFIG_MODULES')
2881 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2883 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
2885 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
2887 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
2888 if config_host['TRACE_BACKENDS'].split().contains('simple')
2889 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2891 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2892 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2893 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2894 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2895 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2896 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2897 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2898 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2899 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2900 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2901 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2902 summary(summary_info, bool_yn: true, section: 'Configurable features')
2904 # Compilation information
2906 summary_info += {'host CPU': cpu}
2907 summary_info += {'host endianness': build_machine.endian()}
2908 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
2909 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
2910 if link_language == 'cpp'
2911 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
2913 summary_info += {'C++ compiler': false}
2915 if targetos == 'darwin'
2916 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
2918 if targetos == 'windows'
2919 if 'WIN_SDK' in config_host
2920 summary_info += {'Windows SDK': config_host['WIN_SDK']}
2923 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
2924 + ['-O' + get_option('optimization')]
2925 + (get_option('debug') ? ['-g'] : []))}
2926 if link_language == 'cpp'
2927 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
2928 + ['-O' + get_option('optimization')]
2929 + (get_option('debug') ? ['-g'] : []))}
2931 link_args = get_option(link_language + '_link_args')
2932 if link_args.length() > 0
2933 summary_info += {'LDFLAGS': ' '.join(link_args)}
2935 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
2936 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
2937 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
2938 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2939 summary_info += {'PIE': get_option('b_pie')}
2940 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
2941 summary_info += {'malloc trim support': has_malloc_trim}
2942 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
2943 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2944 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
2945 summary_info += {'memory allocator': get_option('malloc')}
2946 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2947 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2948 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
2949 summary_info += {'gcov': get_option('b_coverage')}
2950 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
2951 summary_info += {'CFI support': get_option('cfi')}
2952 if get_option('cfi')
2953 summary_info += {'CFI debug support': get_option('cfi_debug')}
2955 summary_info += {'strip binaries': get_option('strip')}
2956 summary_info += {'sparse': sparse}
2957 summary_info += {'mingw32 support': targetos == 'windows'}
2959 # snarf the cross-compilation information for tests
2960 foreach target: target_dirs
2961 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
2962 if fs.exists(tcg_mak)
2963 config_cross_tcg = keyval.load(tcg_mak)
2964 target = config_cross_tcg['TARGET_NAME']
2966 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
2967 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
2968 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
2969 elif 'CROSS_CC_GUEST' in config_cross_tcg
2970 summary_info += {target + ' tests'
2971 : config_cross_tcg['CROSS_CC_GUEST'] }
2976 summary(summary_info, bool_yn: true, section: 'Compilation')
2978 # Targets and accelerators
2981 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
2982 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
2983 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
2984 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
2985 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
2986 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
2987 if config_host.has_key('CONFIG_XEN_BACKEND')
2988 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2991 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
2992 if config_all.has_key('CONFIG_TCG')
2993 if get_option('tcg_interpreter')
2994 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, experimental and slow)'}
2996 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
2998 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
2999 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3001 summary_info += {'target list': ' '.join(target_dirs)}
3003 summary_info += {'default devices': get_option('default_devices')}
3004 summary_info += {'out of process emulation': multiprocess_allowed}
3006 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3010 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3011 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
3013 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3014 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3015 summary_info += {'Use block whitelist in tools': config_host.has_key('CONFIG_BDRV_WHITELIST_TOOLS')}
3016 summary_info += {'VirtFS support': have_virtfs}
3017 summary_info += {'build virtiofs daemon': have_virtiofsd}
3018 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
3019 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
3020 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
3021 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
3022 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
3023 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
3024 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
3025 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
3026 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
3027 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
3028 summary_info += {'FUSE exports': fuse}
3030 summary(summary_info, bool_yn: true, section: 'Block layer support')
3034 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
3035 summary_info += {'GNUTLS support': gnutls}
3037 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3039 summary_info += {'libgcrypt': gcrypt}
3040 summary_info += {'nettle': nettle}
3042 summary_info += {' XTS': xts != 'private'}
3044 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
3045 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
3046 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
3047 summary(summary_info, bool_yn: true, section: 'Crypto')
3051 if targetos == 'darwin'
3052 summary_info += {'Cocoa support': cocoa}
3054 summary_info += {'SDL support': sdl}
3055 summary_info += {'SDL image support': sdl_image}
3056 summary_info += {'GTK support': gtk}
3057 summary_info += {'pixman': pixman}
3058 summary_info += {'VTE support': vte}
3059 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3060 summary_info += {'libtasn1': tasn1}
3061 summary_info += {'PAM': pam}
3062 summary_info += {'iconv support': iconv}
3063 summary_info += {'curses support': curses}
3064 summary_info += {'virgl support': virgl}
3065 summary_info += {'curl support': curl}
3066 summary_info += {'Multipath support': mpathpersist}
3067 summary_info += {'VNC support': vnc}
3069 summary_info += {'VNC SASL support': sasl}
3070 summary_info += {'VNC JPEG support': jpeg}
3071 summary_info += {'VNC PNG support': png}
3073 summary_info += {'brlapi support': brlapi}
3074 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
3075 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
3076 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
3077 summary_info += {'Linux io_uring support': linux_io_uring}
3078 summary_info += {'ATTR/XATTR support': libattr}
3079 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
3080 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
3081 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3082 summary_info += {'libcap-ng support': libcap_ng}
3083 summary_info += {'bpf support': libbpf}
3084 # TODO: add back protocol and server version
3085 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
3086 summary_info += {'rbd support': rbd}
3087 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
3088 summary_info += {'smartcard support': cacard}
3089 summary_info += {'U2F support': u2f}
3090 summary_info += {'libusb': libusb}
3091 summary_info += {'usb net redir': usbredir}
3092 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
3093 summary_info += {'GBM': gbm}
3094 summary_info += {'libiscsi support': libiscsi}
3095 summary_info += {'libnfs support': libnfs}
3096 if targetos == 'windows'
3097 if config_host.has_key('CONFIG_GUEST_AGENT')
3098 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
3099 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
3102 summary_info += {'seccomp support': seccomp}
3103 summary_info += {'GlusterFS support': glusterfs}
3104 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
3105 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
3106 summary_info += {'lzo support': lzo}
3107 summary_info += {'snappy support': snappy}
3108 summary_info += {'bzip2 support': libbzip2}
3109 summary_info += {'lzfse support': liblzfse}
3110 summary_info += {'zstd support': zstd}
3111 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
3112 summary_info += {'libxml2': libxml2}
3113 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3114 summary_info += {'libpmem support': libpmem}
3115 summary_info += {'libdaxctl support': libdaxctl}
3116 summary_info += {'libudev': libudev}
3117 # Dummy dependency, keep .found()
3118 summary_info += {'FUSE lseek': fuse_lseek.found()}
3119 summary(summary_info, bool_yn: true, section: 'Dependencies')
3121 if not supported_cpus.contains(cpu)
3123 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3125 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3126 message('The QEMU project intends to remove support for this host CPU in')
3127 message('a future release if nobody volunteers to maintain it and to')
3128 message('provide a build host for our continuous integration setup.')
3129 message('configure has succeeded and you can continue to build, but')
3130 message('if you care about QEMU on this platform you should contact')
3131 message('us upstream at qemu-devel@nongnu.org.')
3134 if not supported_oses.contains(targetos)
3136 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3138 message('Host OS ' + targetos + 'support is not currently maintained.')
3139 message('The QEMU project intends to remove support for this host OS in')
3140 message('a future release if nobody volunteers to maintain it and to')
3141 message('provide a build host for our continuous integration setup.')
3142 message('configure has succeeded and you can continue to build, but')
3143 message('if you care about QEMU on this platform you should contact')
3144 message('us upstream at qemu-devel@nongnu.org.')