1 project('qemu', ['c'], meson_version: '>=0.55.0',
2 default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto'] +
3 (meson.version().version_compare('>=0.56.0') ? [ 'b_staticpic=false' ] : []),
4 version: run_command('head', meson.source_root() / 'VERSION').stdout().strip())
6 not_found = dependency('', required: false)
7 if meson.version().version_compare('>=0.56.0')
8 keyval = import('keyval')
10 keyval = import('unstable-keyval')
12 ss = import('sourceset')
15 sh = find_program('sh')
16 cc = meson.get_compiler('c')
17 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
18 enable_modules = 'CONFIG_MODULES' in config_host
19 enable_static = 'CONFIG_STATIC' in config_host
21 # Allow both shared and static libraries unless --enable-static
22 static_kwargs = enable_static ? {'static': true} : {}
24 # Temporary directory used for files created while
25 # configure runs. Since it is in the build directory
26 # we can safely blow away any previous version of it
27 # (and we need not jump through hoops to try to delete
28 # it when configure exits.)
29 tmpdir = meson.current_build_dir() / 'meson-private/temp'
31 if get_option('qemu_suffix').startswith('/')
32 error('qemu_suffix cannot start with a /')
35 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
36 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
37 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
38 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
40 qemu_desktopdir = get_option('datadir') / 'applications'
41 qemu_icondir = get_option('datadir') / 'icons'
43 config_host_data = configuration_data()
46 target_dirs = config_host['TARGET_DIRS'].split()
49 foreach target : target_dirs
50 have_user = have_user or target.endswith('-user')
51 have_system = have_system or target.endswith('-softmmu')
53 have_tools = 'CONFIG_TOOLS' in config_host
54 have_block = have_system or have_tools
56 python = import('python').find_installation()
58 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
59 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
60 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
62 cpu = host_machine.cpu_family()
63 targetos = host_machine.system()
65 if cpu in ['x86', 'x86_64']
66 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
68 kvm_targets = ['aarch64-softmmu']
70 kvm_targets = ['s390x-softmmu']
71 elif cpu in ['ppc', 'ppc64']
72 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
73 elif cpu in ['mips', 'mips64']
74 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
79 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
80 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
81 # i368 emulator provides xenpv machine type for multiple architectures
82 accelerator_targets += {
83 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
86 if cpu in ['x86', 'x86_64']
87 accelerator_targets += {
88 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
89 'CONFIG_HVF': ['x86_64-softmmu'],
90 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
91 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
96 # Darwin does not support references to thread-local variables in modules
97 if targetos != 'darwin'
98 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
101 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
102 install_edk2_blobs = false
103 if get_option('install_blobs')
104 foreach target : target_dirs
105 install_edk2_blobs = install_edk2_blobs or target in edk2_targets
109 bzip2 = find_program('bzip2', required: install_edk2_blobs)
115 # Specify linker-script with add_project_link_arguments so that it is not placed
116 # within a linker --start-group/--end-group pair
117 if 'CONFIG_FUZZ' in config_host
118 add_project_link_arguments(['-Wl,-T,',
119 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
120 native: false, language: ['c', 'cpp', 'objc'])
123 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
124 native: false, language: ['c', 'objc'])
125 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
126 native: false, language: 'cpp')
127 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
128 native: false, language: ['c', 'cpp', 'objc'])
130 if targetos == 'linux'
131 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
132 '-isystem', 'linux-headers',
133 language: ['c', 'cpp'])
136 add_project_arguments('-iquote', '.',
137 '-iquote', meson.current_source_dir(),
138 '-iquote', meson.current_source_dir() / 'include',
139 '-iquote', meson.current_source_dir() / 'disas/libvixl',
140 language: ['c', 'cpp', 'objc'])
142 link_language = meson.get_external_property('link_language', 'cpp')
143 if link_language == 'cpp'
144 add_languages('cpp', required: true, native: false)
146 if host_machine.system() == 'darwin'
147 add_languages('objc', required: false, native: false)
150 sparse = find_program('cgcc', required: get_option('sparse'))
153 command: [find_program('scripts/check_sparse.py'),
154 'compile_commands.json', sparse.full_path(), '-Wbitwise',
155 '-Wno-transparent-union', '-Wno-old-initializer',
156 '-Wno-non-pointer-null'])
159 ###########################################
160 # Target-specific checks and dependencies #
161 ###########################################
163 if targetos != 'linux' and get_option('mpath').enabled()
164 error('Multipath is supported only on Linux')
167 if targetos != 'linux' and get_option('multiprocess').enabled()
168 error('Multiprocess QEMU is supported only on Linux')
170 multiprocess_allowed = targetos == 'linux' and not get_option('multiprocess').disabled()
172 libm = cc.find_library('m', required: false)
173 threads = dependency('threads')
174 util = cc.find_library('util', required: false)
180 emulator_link_args = []
183 if targetos == 'windows'
184 socket = cc.find_library('ws2_32')
185 winmm = cc.find_library('winmm')
187 win = import('windows')
188 version_res = win.compile_resources('version.rc',
189 depend_files: files('pc-bios/qemu-nsis.ico'),
190 include_directories: include_directories('.'))
191 elif targetos == 'darwin'
192 coref = dependency('appleframeworks', modules: 'CoreFoundation')
193 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
194 elif targetos == 'sunos'
195 socket = [cc.find_library('socket'),
196 cc.find_library('nsl'),
197 cc.find_library('resolv')]
198 elif targetos == 'haiku'
199 socket = [cc.find_library('posix_error_mapper'),
200 cc.find_library('network'),
201 cc.find_library('bsd')]
202 elif targetos == 'openbsd'
203 if not get_option('tcg').disabled() and target_dirs.length() > 0
204 # Disable OpenBSD W^X if available
205 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
210 if not get_option('kvm').disabled() and targetos == 'linux'
211 accelerators += 'CONFIG_KVM'
213 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
214 accelerators += 'CONFIG_XEN'
215 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
217 have_xen_pci_passthrough = false
219 if not get_option('whpx').disabled() and targetos == 'windows'
220 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
221 error('WHPX requires 64-bit host')
222 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
223 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
224 accelerators += 'CONFIG_WHPX'
227 if not get_option('hvf').disabled()
228 hvf = dependency('appleframeworks', modules: 'Hypervisor',
229 required: get_option('hvf'))
231 accelerators += 'CONFIG_HVF'
234 if not get_option('hax').disabled()
235 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
236 accelerators += 'CONFIG_HAX'
239 if targetos == 'netbsd'
240 if cc.has_header_symbol('nvmm.h', 'nvmm_cpu_stop', required: get_option('nvmm'))
241 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
244 accelerators += 'CONFIG_NVMM'
248 tcg_arch = config_host['ARCH']
249 if not get_option('tcg').disabled()
250 if cpu not in supported_cpus
251 if get_option('tcg_interpreter')
252 warning('Unsupported CPU @0@, will use TCG with TCI (experimental and slow)'.format(cpu))
254 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
256 elif get_option('tcg_interpreter')
257 warning('Use of the TCG interpretor is not recommended on this host')
258 warning('architecture. There is a native TCG execution backend available')
259 warning('which provides substantially better performance and reliability.')
260 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
261 warning('configuration option on this architecture to use the native')
264 if get_option('tcg_interpreter')
266 elif config_host['ARCH'] == 'sparc64'
268 elif config_host['ARCH'] == 's390x'
270 elif config_host['ARCH'] in ['x86_64', 'x32']
272 elif config_host['ARCH'] == 'ppc64'
274 elif config_host['ARCH'] in ['riscv32', 'riscv64']
277 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
278 language: ['c', 'cpp', 'objc'])
280 accelerators += 'CONFIG_TCG'
281 config_host += { 'CONFIG_TCG': 'y' }
284 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
285 error('KVM not available on this platform')
287 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
288 error('HVF not available on this platform')
290 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
291 error('NVMM not available on this platform')
293 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
294 error('WHPX not available on this platform')
296 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
297 if 'CONFIG_XEN' in accelerators
298 error('Xen PCI passthrough not available on this platform')
300 error('Xen PCI passthrough requested but Xen not enabled')
308 # The path to glib.h is added to all compilation commands. This was
309 # grandfathered in from the QEMU Makefiles.
310 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
311 native: false, language: ['c', 'cpp', 'objc'])
312 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
313 link_args: config_host['GLIB_LIBS'].split())
314 # override glib dep with the configure results (for subprojects)
315 meson.override_dependency('glib-2.0', glib)
318 if 'CONFIG_GIO' in config_host
319 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
320 link_args: config_host['GIO_LIBS'].split())
323 if 'CONFIG_TRACE_UST' in config_host
324 lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
327 if have_system or have_tools
328 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
329 method: 'pkg-config', kwargs: static_kwargs)
331 libaio = cc.find_library('aio', required: false)
332 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
334 linux_io_uring = not_found
335 if not get_option('linux_io_uring').auto() or have_block
336 linux_io_uring = dependency('liburing', required: get_option('linux_io_uring'),
337 method: 'pkg-config', kwargs: static_kwargs)
340 if not get_option('libxml2').auto() or have_block
341 libxml2 = dependency('libxml-2.0', required: get_option('libxml2'),
342 method: 'pkg-config', kwargs: static_kwargs)
345 if not get_option('libnfs').auto() or have_block
346 libnfs = dependency('libnfs', version: '>=1.9.3',
347 required: get_option('libnfs'),
348 method: 'pkg-config', kwargs: static_kwargs)
353 #include <sys/types.h>
354 #ifdef CONFIG_LIBATTR
355 #include <attr/xattr.h>
357 #include <sys/xattr.h>
359 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
362 have_old_libattr = false
363 if not get_option('attr').disabled()
364 if cc.links(libattr_test)
365 libattr = declare_dependency()
367 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
368 required: get_option('attr'),
369 kwargs: static_kwargs)
370 if libattr.found() and not \
371 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
373 if get_option('attr').enabled()
374 error('could not link libattr')
376 warning('could not link libattr, disabling')
379 have_old_libattr = libattr.found()
384 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
385 if cocoa.found() and get_option('sdl').enabled()
386 error('Cocoa and SDL cannot be enabled at the same time')
388 if cocoa.found() and get_option('gtk').enabled()
389 error('Cocoa and GTK+ cannot be enabled at the same time')
393 if not get_option('seccomp').auto() or have_system or have_tools
394 seccomp = dependency('libseccomp', version: '>=2.3.0',
395 required: get_option('seccomp'),
396 method: 'pkg-config', kwargs: static_kwargs)
399 libcap_ng = not_found
400 if not get_option('cap_ng').auto() or have_system or have_tools
401 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
402 required: get_option('cap_ng'),
403 kwargs: static_kwargs)
405 if libcap_ng.found() and not cc.links('''
409 capng_capability_to_name(CAPNG_EFFECTIVE);
411 }''', dependencies: libcap_ng)
412 libcap_ng = not_found
413 if get_option('cap_ng').enabled()
414 error('could not link libcap-ng')
416 warning('could not link libcap-ng, disabling')
420 if get_option('xkbcommon').auto() and not have_system and not have_tools
421 xkbcommon = not_found
423 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
424 method: 'pkg-config', kwargs: static_kwargs)
427 if config_host.has_key('CONFIG_VDE')
428 vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
431 if 'CONFIG_LIBPULSE' in config_host
432 pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
433 link_args: config_host['PULSE_LIBS'].split())
436 if 'CONFIG_ALSA' in config_host
437 alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
438 link_args: config_host['ALSA_LIBS'].split())
441 if 'CONFIG_LIBJACK' in config_host
442 jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
445 spice_headers = not_found
446 spice_protocol = not_found
447 if 'CONFIG_SPICE' in config_host
448 spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
449 link_args: config_host['SPICE_LIBS'].split())
450 spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
452 if 'CONFIG_SPICE_PROTOCOL' in config_host
453 spice_protocol = declare_dependency(compile_args: config_host['SPICE_PROTOCOL_CFLAGS'].split())
455 rt = cc.find_library('rt', required: false)
457 if 'CONFIG_PLUGIN' in config_host
458 libdl = cc.find_library('dl', required: false)
459 if not cc.has_function('dlopen', dependencies: libdl)
460 error('dlopen not found')
464 if not get_option('libiscsi').auto() or have_block
465 libiscsi = dependency('libiscsi', version: '>=1.9.0',
466 required: get_option('libiscsi'),
467 method: 'pkg-config', kwargs: static_kwargs)
470 if not get_option('zstd').auto() or have_block
471 zstd = dependency('libzstd', version: '>=1.4.0',
472 required: get_option('zstd'),
473 method: 'pkg-config', kwargs: static_kwargs)
476 if not get_option('virglrenderer').auto() or have_system
477 virgl = dependency('virglrenderer',
478 method: 'pkg-config',
479 required: get_option('virglrenderer'),
480 kwargs: static_kwargs)
483 if not get_option('curl').auto() or have_block
484 curl = dependency('libcurl', version: '>=7.29.0',
485 method: 'pkg-config',
486 required: get_option('curl'),
487 kwargs: static_kwargs)
490 if targetos == 'linux' and (have_system or have_tools)
491 libudev = dependency('libudev',
492 method: 'pkg-config',
493 required: get_option('libudev'),
494 kwargs: static_kwargs)
497 mpathlibs = [libudev]
498 mpathpersist = not_found
499 mpathpersist_new_api = false
500 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
501 mpath_test_source_new = '''
503 #include <mpath_persist.h>
504 unsigned mpath_mx_alloc_len = 1024;
506 static struct config *multipath_conf;
507 extern struct udev *udev;
508 extern struct config *get_multipath_config(void);
509 extern void put_multipath_config(struct config *conf);
511 struct config *get_multipath_config(void) { return multipath_conf; }
512 void put_multipath_config(struct config *conf) { }
515 multipath_conf = mpath_lib_init();
518 mpath_test_source_old = '''
520 #include <mpath_persist.h>
521 unsigned mpath_mx_alloc_len = 1024;
524 struct udev *udev = udev_new();
525 mpath_lib_init(udev);
528 libmpathpersist = cc.find_library('mpathpersist',
529 required: get_option('mpath'),
530 kwargs: static_kwargs)
531 if libmpathpersist.found()
532 mpathlibs += libmpathpersist
534 mpathlibs += cc.find_library('devmapper',
535 required: get_option('mpath'),
536 kwargs: static_kwargs)
538 mpathlibs += cc.find_library('multipath',
539 required: get_option('mpath'),
540 kwargs: static_kwargs)
541 foreach lib: mpathlibs
547 if mpathlibs.length() == 0
548 msg = 'Dependencies missing for libmpathpersist'
549 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
550 mpathpersist = declare_dependency(dependencies: mpathlibs)
551 mpathpersist_new_api = true
552 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
553 mpathpersist = declare_dependency(dependencies: mpathlibs)
555 msg = 'Cannot detect libmpathpersist API'
557 if not mpathpersist.found()
558 if get_option('mpath').enabled()
561 warning(msg + ', disabling')
569 if have_system and not get_option('curses').disabled()
576 setlocale(LC_ALL, "");
578 addwstr(L"wide chars\n");
580 add_wch(WACS_DEGREE);
584 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
585 foreach curses_dep : curses_dep_list
586 if not curses.found()
587 curses = dependency(curses_dep,
589 method: 'pkg-config',
590 kwargs: static_kwargs)
593 msg = get_option('curses').enabled() ? 'curses library not found' : ''
594 curses_compile_args = ['-DNCURSES_WIDECHAR']
596 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
597 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
599 msg = 'curses package not usable'
603 if not curses.found()
604 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
605 if targetos != 'windows' and not has_curses_h
606 message('Trying with /usr/include/ncursesw')
607 curses_compile_args += ['-I/usr/include/ncursesw']
608 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
611 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
612 foreach curses_libname : curses_libname_list
613 libcurses = cc.find_library(curses_libname,
615 kwargs: static_kwargs)
617 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
618 curses = declare_dependency(compile_args: curses_compile_args,
619 dependencies: [libcurses])
622 msg = 'curses library not usable'
628 if not get_option('iconv').disabled()
629 foreach link_args : [ ['-liconv'], [] ]
630 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
631 # We need to use libiconv if available because mixing libiconv's headers with
632 # the system libc does not work.
633 # However, without adding glib to the dependencies -L/usr/local/lib will not be
634 # included in the command line and libiconv will not be found.
638 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
639 return conv != (iconv_t) -1;
640 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
641 iconv = declare_dependency(link_args: link_args, dependencies: glib)
646 if curses.found() and not iconv.found()
647 if get_option('iconv').enabled()
648 error('iconv not available')
650 msg = 'iconv required for curses UI but not available'
653 if not curses.found() and msg != ''
654 if get_option('curses').enabled()
657 warning(msg + ', disabling')
663 if not get_option('brlapi').auto() or have_system
664 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
665 required: get_option('brlapi'),
666 kwargs: static_kwargs)
667 if brlapi.found() and not cc.links('''
670 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
672 if get_option('brlapi').enabled()
673 error('could not link brlapi')
675 warning('could not link brlapi, disabling')
681 if not get_option('sdl').auto() or (have_system and not cocoa.found())
682 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
683 sdl_image = not_found
686 # work around 2.0.8 bug
687 sdl = declare_dependency(compile_args: '-Wno-undef',
689 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
690 method: 'pkg-config', kwargs: static_kwargs)
692 if get_option('sdl_image').enabled()
693 error('sdl-image required, but SDL was @0@'.format(
694 get_option('sdl').disabled() ? 'disabled' : 'not found'))
696 sdl_image = not_found
700 if not get_option('rbd').auto() or have_block
701 librados = cc.find_library('rados', required: get_option('rbd'),
702 kwargs: static_kwargs)
703 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
704 required: get_option('rbd'),
705 kwargs: static_kwargs)
706 if librados.found() and librbd.found()
709 #include <rbd/librbd.h>
712 rados_create(&cluster, NULL);
713 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
717 }''', dependencies: [librbd, librados])
718 rbd = declare_dependency(dependencies: [librbd, librados])
719 elif get_option('rbd').enabled()
720 error('librbd >= 1.12.0 required')
722 warning('librbd >= 1.12.0 not found, disabling')
727 glusterfs = not_found
728 glusterfs_ftruncate_has_stat = false
729 glusterfs_iocb_has_stat = false
730 if not get_option('glusterfs').auto() or have_block
731 glusterfs = dependency('glusterfs-api', version: '>=3',
732 required: get_option('glusterfs'),
733 method: 'pkg-config', kwargs: static_kwargs)
735 glusterfs_ftruncate_has_stat = cc.links('''
736 #include <glusterfs/api/glfs.h>
741 /* new glfs_ftruncate() passes two additional args */
742 return glfs_ftruncate(NULL, 0, NULL, NULL);
744 ''', dependencies: glusterfs)
745 glusterfs_iocb_has_stat = cc.links('''
746 #include <glusterfs/api/glfs.h>
748 /* new glfs_io_cbk() passes two additional glfs_stat structs */
750 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
756 glfs_io_cbk iocb = &glusterfs_iocb;
757 iocb(NULL, 0 , NULL, NULL, NULL);
760 ''', dependencies: glusterfs)
764 if 'CONFIG_LIBSSH' in config_host
765 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
766 link_args: config_host['LIBSSH_LIBS'].split())
769 if not get_option('bzip2').auto() or have_block
770 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
771 required: get_option('bzip2'),
772 kwargs: static_kwargs)
773 if libbzip2.found() and not cc.links('''
775 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
777 if get_option('bzip2').enabled()
778 error('could not link libbzip2')
780 warning('could not link libbzip2, disabling')
786 if not get_option('lzfse').auto() or have_block
787 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
788 required: get_option('lzfse'),
789 kwargs: static_kwargs)
791 if liblzfse.found() and not cc.links('''
793 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
795 if get_option('lzfse').enabled()
796 error('could not link liblzfse')
798 warning('could not link liblzfse, disabling')
803 if 'CONFIG_AUDIO_OSS' in config_host
804 oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
807 if 'CONFIG_AUDIO_DSOUND' in config_host
808 dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
810 coreaudio = not_found
811 if 'CONFIG_AUDIO_COREAUDIO' in config_host
812 coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
816 if 'CONFIG_OPENGL' in config_host
817 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
818 link_args: config_host['OPENGL_LIBS'].split())
821 if (have_system or have_tools) and (virgl.found() or opengl.found())
822 gbm = dependency('gbm', method: 'pkg-config', required: false,
823 kwargs: static_kwargs)
827 gnutls_crypto = not_found
828 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
829 # For general TLS support our min gnutls matches
830 # that implied by our platform support matrix
832 # For the crypto backends, we look for a newer
835 # Version 3.6.8 is needed to get XTS
836 # Version 3.6.13 is needed to get PBKDF
837 # Version 3.6.14 is needed to get HW accelerated XTS
839 # If newer enough gnutls isn't available, we can
840 # still use a different crypto backend to satisfy
841 # the platform support requirements
842 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
843 method: 'pkg-config',
845 kwargs: static_kwargs)
846 if gnutls_crypto.found()
847 gnutls = gnutls_crypto
849 # Our min version if all we need is TLS
850 gnutls = dependency('gnutls', version: '>=3.5.18',
851 method: 'pkg-config',
852 required: get_option('gnutls'),
853 kwargs: static_kwargs)
857 # We prefer use of gnutls for crypto, unless the options
858 # explicitly asked for nettle or gcrypt.
860 # If gnutls isn't available for crypto, then we'll prefer
861 # gcrypt over nettle for performance reasons.
866 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
867 error('Only one of gcrypt & nettle can be enabled')
870 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
871 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
872 gnutls_crypto = not_found
875 if not gnutls_crypto.found()
876 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
877 gcrypt = dependency('libgcrypt', version: '>=1.8',
878 method: 'config-tool',
879 required: get_option('gcrypt'),
880 kwargs: static_kwargs)
881 # Debian has removed -lgpg-error from libgcrypt-config
882 # as it "spreads unnecessary dependencies" which in
883 # turn breaks static builds...
884 if gcrypt.found() and enable_static
885 gcrypt = declare_dependency(dependencies: [
887 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
890 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
891 nettle = dependency('nettle', version: '>=3.4',
892 method: 'pkg-config',
893 required: get_option('nettle'),
894 kwargs: static_kwargs)
895 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
904 if not get_option('gtk').auto() or (have_system and not cocoa.found())
905 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
906 method: 'pkg-config',
907 required: get_option('gtk'),
908 kwargs: static_kwargs)
910 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
911 method: 'pkg-config',
913 kwargs: static_kwargs)
914 gtk = declare_dependency(dependencies: [gtk, gtkx11])
916 if not get_option('vte').auto() or have_system
917 vte = dependency('vte-2.91',
918 method: 'pkg-config',
919 required: get_option('vte'),
920 kwargs: static_kwargs)
927 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
928 kwargs: static_kwargs)
934 if have_system and not get_option('vnc').disabled()
935 vnc = declare_dependency() # dummy dependency
936 png = dependency('libpng', required: get_option('vnc_png'),
937 method: 'pkg-config', kwargs: static_kwargs)
938 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
939 method: 'pkg-config', kwargs: static_kwargs)
940 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
941 required: get_option('vnc_sasl'),
942 kwargs: static_kwargs)
944 sasl = declare_dependency(dependencies: sasl,
945 compile_args: '-DSTRUCT_IOVEC_DEFINED')
950 if not get_option('auth_pam').auto() or have_system
951 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
952 required: get_option('auth_pam'),
953 kwargs: static_kwargs)
955 if pam.found() and not cc.links('''
957 #include <security/pam_appl.h>
959 const char *service_name = "qemu";
960 const char *user = "frank";
961 const struct pam_conv pam_conv = { 0 };
962 pam_handle_t *pamh = NULL;
963 pam_start(service_name, user, &pam_conv, &pamh);
965 }''', dependencies: pam)
967 if get_option('auth_pam').enabled()
968 error('could not link libpam')
970 warning('could not link libpam, disabling')
975 if not get_option('snappy').auto() or have_system
976 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
977 required: get_option('snappy'),
978 kwargs: static_kwargs)
980 if snappy.found() and not cc.links('''
981 #include <snappy-c.h>
982 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
984 if get_option('snappy').enabled()
985 error('could not link libsnappy')
987 warning('could not link libsnappy, disabling')
992 if not get_option('lzo').auto() or have_system
993 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
994 required: get_option('lzo'),
995 kwargs: static_kwargs)
997 if lzo.found() and not cc.links('''
998 #include <lzo/lzo1x.h>
999 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1001 if get_option('lzo').enabled()
1002 error('could not link liblzo2')
1004 warning('could not link liblzo2, disabling')
1009 if 'CONFIG_RDMA' in config_host
1010 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
1013 if 'CONFIG_NUMA' in config_host
1014 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
1017 if 'CONFIG_XEN_BACKEND' in config_host
1018 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
1019 link_args: config_host['XEN_LIBS'].split())
1022 if not get_option('smartcard').auto() or have_system
1023 cacard = dependency('libcacard', required: get_option('smartcard'),
1024 version: '>=2.5.1', method: 'pkg-config',
1025 kwargs: static_kwargs)
1029 u2f = dependency('u2f-emu', required: get_option('u2f'),
1030 method: 'pkg-config',
1031 kwargs: static_kwargs)
1033 usbredir = not_found
1034 if not get_option('usb_redir').auto() or have_system
1035 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1036 version: '>=0.6', method: 'pkg-config',
1037 kwargs: static_kwargs)
1040 if not get_option('libusb').auto() or have_system
1041 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1042 version: '>=1.0.13', method: 'pkg-config',
1043 kwargs: static_kwargs)
1047 if not get_option('libpmem').auto() or have_system
1048 libpmem = dependency('libpmem', required: get_option('libpmem'),
1049 method: 'pkg-config', kwargs: static_kwargs)
1051 libdaxctl = not_found
1052 if not get_option('libdaxctl').auto() or have_system
1053 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1054 version: '>=57', method: 'pkg-config',
1055 kwargs: static_kwargs)
1059 tasn1 = dependency('libtasn1',
1060 method: 'pkg-config',
1061 kwargs: static_kwargs)
1063 keyutils = dependency('libkeyutils', required: false,
1064 method: 'pkg-config', kwargs: static_kwargs)
1066 has_gettid = cc.has_function('gettid')
1071 if get_option('malloc') == 'system'
1073 not get_option('malloc_trim').disabled() and \
1074 cc.links('''#include <malloc.h>
1075 int main(void) { malloc_trim(0); return 0; }''')
1077 has_malloc_trim = false
1078 malloc = cc.find_library(get_option('malloc'), required: true)
1080 if not has_malloc_trim and get_option('malloc_trim').enabled()
1081 if get_option('malloc') == 'system'
1082 error('malloc_trim not available on this platform.')
1084 error('malloc_trim not available with non-libc memory allocator')
1088 # Check whether the glibc provides statx()
1090 gnu_source_prefix = '''
1095 statx_test = gnu_source_prefix + '''
1096 #include <sys/stat.h>
1098 struct statx statxbuf;
1099 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1103 has_statx = cc.links(statx_test)
1105 have_vhost_user_blk_server = (targetos == 'linux' and
1106 'CONFIG_VHOST_USER' in config_host)
1108 if get_option('vhost_user_blk_server').enabled()
1109 if targetos != 'linux'
1110 error('vhost_user_blk_server requires linux')
1111 elif 'CONFIG_VHOST_USER' not in config_host
1112 error('vhost_user_blk_server requires vhost-user support')
1114 elif get_option('vhost_user_blk_server').disabled() or not have_system
1115 have_vhost_user_blk_server = false
1119 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1120 error('Cannot enable fuse-lseek while fuse is disabled')
1123 fuse = dependency('fuse3', required: get_option('fuse'),
1124 version: '>=3.1', method: 'pkg-config',
1125 kwargs: static_kwargs)
1127 fuse_lseek = not_found
1128 if not get_option('fuse_lseek').disabled()
1129 if fuse.version().version_compare('>=3.8')
1131 fuse_lseek = declare_dependency()
1132 elif get_option('fuse_lseek').enabled()
1134 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1136 error('fuse-lseek requires libfuse, which was not found')
1142 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1143 if libbpf.found() and not cc.links('''
1144 #include <bpf/libbpf.h>
1147 bpf_object__destroy_skeleton(NULL);
1149 }''', dependencies: libbpf)
1151 if get_option('bpf').enabled()
1152 error('libbpf skeleton test failed')
1154 warning('libbpf skeleton test failed, disabling')
1158 if get_option('cfi')
1160 # Check for dependency on LTO
1161 if not get_option('b_lto')
1162 error('Selected Control-Flow Integrity but LTO is disabled')
1164 if config_host.has_key('CONFIG_MODULES')
1165 error('Selected Control-Flow Integrity is not compatible with modules')
1167 # Check for cfi flags. CFI requires LTO so we can't use
1168 # get_supported_arguments, but need a more complex "compiles" which allows
1170 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1171 args: ['-flto', '-fsanitize=cfi-icall'] )
1172 cfi_flags += '-fsanitize=cfi-icall'
1174 error('-fsanitize=cfi-icall is not supported by the compiler')
1176 if cc.compiles('int main () { return 0; }',
1177 name: '-fsanitize-cfi-icall-generalize-pointers',
1178 args: ['-flto', '-fsanitize=cfi-icall',
1179 '-fsanitize-cfi-icall-generalize-pointers'] )
1180 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1182 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1184 if get_option('cfi_debug')
1185 if cc.compiles('int main () { return 0; }',
1186 name: '-fno-sanitize-trap=cfi-icall',
1187 args: ['-flto', '-fsanitize=cfi-icall',
1188 '-fno-sanitize-trap=cfi-icall'] )
1189 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1191 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1194 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1195 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1198 have_host_block_device = (targetos != 'darwin' or
1199 cc.has_header('IOKit/storage/IOMedia.h'))
1205 have_virtfs = (targetos == 'linux' and
1210 have_virtfs_proxy_helper = have_virtfs and have_tools
1212 if get_option('virtfs').enabled()
1214 if targetos != 'linux'
1215 error('virtio-9p (virtfs) requires Linux')
1216 elif not libcap_ng.found() or not libattr.found()
1217 error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1218 elif not have_system
1219 error('virtio-9p (virtfs) needs system emulation support')
1222 elif get_option('virtfs').disabled()
1226 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1227 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1228 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1229 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1230 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1231 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1232 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1233 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1234 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1235 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1236 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1237 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1239 config_host_data.set('CONFIG_ATTR', libattr.found())
1240 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1241 config_host_data.set('CONFIG_COCOA', cocoa.found())
1242 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1243 config_host_data.set('CONFIG_LZO', lzo.found())
1244 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1245 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1246 config_host_data.set('CONFIG_CURL', curl.found())
1247 config_host_data.set('CONFIG_CURSES', curses.found())
1248 config_host_data.set('CONFIG_GBM', gbm.found())
1249 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1250 if glusterfs.found()
1251 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1252 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1253 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1254 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1255 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1256 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1258 config_host_data.set('CONFIG_GTK', gtk.found())
1259 config_host_data.set('CONFIG_VTE', vte.found())
1260 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1261 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1262 config_host_data.set('CONFIG_EBPF', libbpf.found())
1263 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1264 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1265 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1266 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1267 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1268 config_host_data.set('CONFIG_RBD', rbd.found())
1269 config_host_data.set('CONFIG_SDL', sdl.found())
1270 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1271 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1272 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1273 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1274 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1275 config_host_data.set('CONFIG_VNC', vnc.found())
1276 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1277 config_host_data.set('CONFIG_VNC_PNG', png.found())
1278 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1279 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1280 config_host_data.set('CONFIG_VTE', vte.found())
1281 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1282 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1283 config_host_data.set('CONFIG_GETTID', has_gettid)
1284 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1285 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1286 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1287 config_host_data.set('CONFIG_NETTLE', nettle.found())
1288 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1289 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1290 config_host_data.set('CONFIG_STATX', has_statx)
1291 config_host_data.set('CONFIG_ZSTD', zstd.found())
1292 config_host_data.set('CONFIG_FUSE', fuse.found())
1293 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1294 config_host_data.set('CONFIG_X11', x11.found())
1295 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1296 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1297 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1298 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1299 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1301 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1304 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1305 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1306 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1307 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1308 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1309 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1310 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1311 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1312 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1315 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1316 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1317 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1318 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1319 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1320 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
1321 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1322 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1323 config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
1324 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1325 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1326 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1327 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1328 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1329 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1330 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1331 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1332 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1335 config_host_data.set('CONFIG_BYTESWAP_H',
1336 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1337 config_host_data.set('CONFIG_EPOLL_CREATE1',
1338 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1339 config_host_data.set('CONFIG_HAS_ENVIRON',
1340 cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix))
1341 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1342 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1343 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1344 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1345 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1346 config_host_data.set('CONFIG_FIEMAP',
1347 cc.has_header('linux/fiemap.h') and
1348 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1349 config_host_data.set('CONFIG_GETRANDOM',
1350 cc.has_function('getrandom') and
1351 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1352 config_host_data.set('CONFIG_INOTIFY',
1353 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1354 config_host_data.set('CONFIG_INOTIFY1',
1355 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1356 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1357 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1358 prefix: '''#include <sys/endian.h>
1359 #include <sys/types.h>'''))
1360 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1361 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1362 config_host_data.set('CONFIG_RTNETLINK',
1363 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1364 config_host_data.set('CONFIG_SYSMACROS',
1365 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1366 config_host_data.set('HAVE_OPTRESET',
1367 cc.has_header_symbol('getopt.h', 'optreset'))
1368 config_host_data.set('HAVE_UTMPX',
1369 cc.has_header_symbol('utmpx.h', 'struct utmpx'))
1372 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1373 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1374 prefix: '#include <signal.h>'))
1375 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1376 cc.has_member('struct stat', 'st_atim',
1377 prefix: '#include <sys/stat.h>'))
1379 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1380 #include <sys/eventfd.h>
1381 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1382 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1385 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1386 return fdatasync(0);
1388 #error Not supported
1391 config_host_data.set('CONFIG_MADVISE', cc.links(gnu_source_prefix + '''
1392 #include <sys/types.h>
1393 #include <sys/mman.h>
1395 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }'''))
1396 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1397 #include <sys/mman.h>
1398 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1399 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1401 #if !defined(AT_EMPTY_PATH)
1402 # error missing definition
1404 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1406 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1413 return pipe2(pipefd, O_CLOEXEC);
1415 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1416 #include <sys/mman.h>
1418 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1419 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1421 #include <sys/syscall.h>
1423 int main(void) { return syscall(SYS_signalfd, -1, NULL, _NSIG / 8); }'''))
1424 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1432 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1433 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1437 # Some versions of Mac OS X incorrectly define SIZE_MAX
1438 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1441 int main(int argc, char *argv[]) {
1442 return printf("%zu", SIZE_MAX);
1443 }''', args: ['-Werror']))
1446 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
1447 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1448 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
1449 foreach k, v: config_host
1450 if ignored.contains(k)
1452 elif arrays.contains(k)
1454 v = '"' + '", "'.join(v.split()) + '", '
1456 config_host_data.set(k, v)
1458 config_host_data.set('HOST_' + v.to_upper(), 1)
1459 elif strings.contains(k)
1460 if not k.startswith('CONFIG_')
1461 k = 'CONFIG_' + k.to_upper()
1463 config_host_data.set_quoted(k, v)
1464 elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1465 config_host_data.set(k, v == 'y' ? 1 : v)
1469 ########################
1470 # Target configuration #
1471 ########################
1473 minikconf = find_program('scripts/minikconf.py')
1475 config_all_devices = {}
1476 config_all_disas = {}
1477 config_devices_mak_list = []
1478 config_devices_h = {}
1479 config_target_h = {}
1480 config_target_mak = {}
1483 'alpha' : ['CONFIG_ALPHA_DIS'],
1484 'arm' : ['CONFIG_ARM_DIS'],
1485 'avr' : ['CONFIG_AVR_DIS'],
1486 'cris' : ['CONFIG_CRIS_DIS'],
1487 'hexagon' : ['CONFIG_HEXAGON_DIS'],
1488 'hppa' : ['CONFIG_HPPA_DIS'],
1489 'i386' : ['CONFIG_I386_DIS'],
1490 'x86_64' : ['CONFIG_I386_DIS'],
1491 'x32' : ['CONFIG_I386_DIS'],
1492 'm68k' : ['CONFIG_M68K_DIS'],
1493 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1494 'mips' : ['CONFIG_MIPS_DIS'],
1495 'nios2' : ['CONFIG_NIOS2_DIS'],
1496 'or1k' : ['CONFIG_OPENRISC_DIS'],
1497 'ppc' : ['CONFIG_PPC_DIS'],
1498 'riscv' : ['CONFIG_RISCV_DIS'],
1499 'rx' : ['CONFIG_RX_DIS'],
1500 's390' : ['CONFIG_S390_DIS'],
1501 'sh4' : ['CONFIG_SH4_DIS'],
1502 'sparc' : ['CONFIG_SPARC_DIS'],
1503 'xtensa' : ['CONFIG_XTENSA_DIS'],
1505 if link_language == 'cpp'
1507 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1508 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1509 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1513 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
1515 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1516 ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1517 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
1518 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1519 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1520 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1521 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1522 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1523 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1524 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1525 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1526 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1528 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1530 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1531 actual_target_dirs = []
1533 foreach target : target_dirs
1534 config_target = { 'TARGET_NAME': target.split('-')[0] }
1535 if target.endswith('linux-user')
1536 if targetos != 'linux'
1540 error('Target @0@ is only available on a Linux host'.format(target))
1542 config_target += { 'CONFIG_LINUX_USER': 'y' }
1543 elif target.endswith('bsd-user')
1544 if 'CONFIG_BSD' not in config_host
1548 error('Target @0@ is only available on a BSD host'.format(target))
1550 config_target += { 'CONFIG_BSD_USER': 'y' }
1551 elif target.endswith('softmmu')
1552 config_target += { 'CONFIG_SOFTMMU': 'y' }
1554 if target.endswith('-user')
1556 'CONFIG_USER_ONLY': 'y',
1557 'CONFIG_QEMU_INTERP_PREFIX':
1558 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1563 foreach sym: accelerators
1564 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1565 config_target += { sym: 'y' }
1566 config_all += { sym: 'y' }
1567 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1568 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1569 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1570 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1572 if target in modular_tcg
1573 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
1575 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
1577 accel_kconfig += [ sym + '=y' ]
1580 if accel_kconfig.length() == 0
1584 error('No accelerator available for target @0@'.format(target))
1587 actual_target_dirs += target
1588 config_target += keyval.load('configs/targets' / target + '.mak')
1589 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1591 if 'TARGET_NEED_FDT' in config_target
1592 fdt_required += target
1596 if 'TARGET_BASE_ARCH' not in config_target
1597 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1599 if 'TARGET_ABI_DIR' not in config_target
1600 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1603 foreach k, v: disassemblers
1604 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1606 config_target += { sym: 'y' }
1607 config_all_disas += { sym: 'y' }
1612 config_target_data = configuration_data()
1613 foreach k, v: config_target
1614 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1616 elif ignored.contains(k)
1618 elif k == 'TARGET_BASE_ARCH'
1619 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1620 # not used to select files from sourcesets.
1621 config_target_data.set('TARGET_' + v.to_upper(), 1)
1622 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1623 config_target_data.set_quoted(k, v)
1625 config_target_data.set(k, 1)
1627 config_target_data.set(k, v)
1630 config_target_data.set('QEMU_ARCH',
1631 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
1632 config_target_h += {target: configure_file(output: target + '-config-target.h',
1633 configuration: config_target_data)}
1635 if target.endswith('-softmmu')
1636 config_input = meson.get_external_property(target, 'default')
1637 config_devices_mak = target + '-config-devices.mak'
1638 config_devices_mak = configure_file(
1639 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
1640 output: config_devices_mak,
1641 depfile: config_devices_mak + '.d',
1643 command: [minikconf,
1644 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1645 config_devices_mak, '@DEPFILE@', '@INPUT@',
1646 host_kconfig, accel_kconfig,
1647 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
1649 config_devices_data = configuration_data()
1650 config_devices = keyval.load(config_devices_mak)
1651 foreach k, v: config_devices
1652 config_devices_data.set(k, 1)
1654 config_devices_mak_list += config_devices_mak
1655 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1656 configuration: config_devices_data)}
1657 config_target += config_devices
1658 config_all_devices += config_devices
1660 config_target_mak += {target: config_target}
1662 target_dirs = actual_target_dirs
1664 # This configuration is used to build files that are shared by
1665 # multiple binaries, and then extracted out of the "common"
1666 # static_library target.
1668 # We do not use all_sources()/all_dependencies(), because it would
1669 # build literally all source files, including devices only used by
1670 # targets that are not built for this compilation. The CONFIG_ALL
1671 # pseudo symbol replaces it.
1673 config_all += config_all_devices
1674 config_all += config_host
1675 config_all += config_all_disas
1677 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1678 'CONFIG_SOFTMMU': have_system,
1679 'CONFIG_USER_ONLY': have_user,
1687 capstone = not_found
1688 capstone_opt = get_option('capstone')
1689 if capstone_opt in ['enabled', 'auto', 'system']
1690 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1691 capstone = dependency('capstone', version: '>=4.0',
1692 kwargs: static_kwargs, method: 'pkg-config',
1693 required: capstone_opt == 'system' or
1694 capstone_opt == 'enabled' and not have_internal)
1696 # Some versions of capstone have broken pkg-config file
1697 # that reports a wrong -I path, causing the #include to
1698 # fail later. If the system has such a broken version
1700 if capstone.found() and not cc.compiles('#include <capstone.h>',
1701 dependencies: [capstone])
1702 capstone = not_found
1703 if capstone_opt == 'system'
1704 error('system capstone requested, it does not appear to work')
1709 capstone_opt = 'system'
1711 capstone_opt = 'internal'
1713 capstone_opt = 'disabled'
1716 if capstone_opt == 'internal'
1717 capstone_data = configuration_data()
1718 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1720 capstone_files = files(
1722 'capstone/MCInst.c',
1723 'capstone/MCInstrDesc.c',
1724 'capstone/MCRegisterInfo.c',
1725 'capstone/SStream.c',
1729 if 'CONFIG_ARM_DIS' in config_all_disas
1730 capstone_data.set('CAPSTONE_HAS_ARM', '1')
1731 capstone_files += files(
1732 'capstone/arch/ARM/ARMDisassembler.c',
1733 'capstone/arch/ARM/ARMInstPrinter.c',
1734 'capstone/arch/ARM/ARMMapping.c',
1735 'capstone/arch/ARM/ARMModule.c'
1739 # FIXME: This config entry currently depends on a c++ compiler.
1740 # Which is needed for building libvixl, but not for capstone.
1741 if 'CONFIG_ARM_A64_DIS' in config_all_disas
1742 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1743 capstone_files += files(
1744 'capstone/arch/AArch64/AArch64BaseInfo.c',
1745 'capstone/arch/AArch64/AArch64Disassembler.c',
1746 'capstone/arch/AArch64/AArch64InstPrinter.c',
1747 'capstone/arch/AArch64/AArch64Mapping.c',
1748 'capstone/arch/AArch64/AArch64Module.c'
1752 if 'CONFIG_PPC_DIS' in config_all_disas
1753 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1754 capstone_files += files(
1755 'capstone/arch/PowerPC/PPCDisassembler.c',
1756 'capstone/arch/PowerPC/PPCInstPrinter.c',
1757 'capstone/arch/PowerPC/PPCMapping.c',
1758 'capstone/arch/PowerPC/PPCModule.c'
1762 if 'CONFIG_S390_DIS' in config_all_disas
1763 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1764 capstone_files += files(
1765 'capstone/arch/SystemZ/SystemZDisassembler.c',
1766 'capstone/arch/SystemZ/SystemZInstPrinter.c',
1767 'capstone/arch/SystemZ/SystemZMapping.c',
1768 'capstone/arch/SystemZ/SystemZModule.c',
1769 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1773 if 'CONFIG_I386_DIS' in config_all_disas
1774 capstone_data.set('CAPSTONE_HAS_X86', 1)
1775 capstone_files += files(
1776 'capstone/arch/X86/X86Disassembler.c',
1777 'capstone/arch/X86/X86DisassemblerDecoder.c',
1778 'capstone/arch/X86/X86ATTInstPrinter.c',
1779 'capstone/arch/X86/X86IntelInstPrinter.c',
1780 'capstone/arch/X86/X86InstPrinterCommon.c',
1781 'capstone/arch/X86/X86Mapping.c',
1782 'capstone/arch/X86/X86Module.c'
1786 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1789 # FIXME: There does not seem to be a way to completely replace the c_args
1790 # that come from add_project_arguments() -- we can only add to them.
1791 # So: disable all warnings with a big hammer.
1794 # Include all configuration defines via a header file, which will wind up
1795 # as a dependency on the object file, and thus changes here will result
1797 '-include', 'capstone-defs.h'
1800 libcapstone = static_library('capstone',
1801 build_by_default: false,
1802 sources: capstone_files,
1803 c_args: capstone_cargs,
1804 include_directories: 'capstone/include')
1805 capstone = declare_dependency(link_with: libcapstone,
1806 include_directories: 'capstone/include/capstone')
1810 slirp_opt = 'disabled'
1812 slirp_opt = get_option('slirp')
1813 if slirp_opt in ['enabled', 'auto', 'system']
1814 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1815 slirp = dependency('slirp', kwargs: static_kwargs,
1816 method: 'pkg-config',
1817 required: slirp_opt == 'system' or
1818 slirp_opt == 'enabled' and not have_internal)
1820 slirp_opt = 'system'
1822 slirp_opt = 'internal'
1824 slirp_opt = 'disabled'
1827 if slirp_opt == 'internal'
1829 if targetos == 'windows'
1830 slirp_deps = cc.find_library('iphlpapi')
1831 elif targetos == 'darwin'
1832 slirp_deps = cc.find_library('resolv')
1834 slirp_conf = configuration_data()
1835 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1836 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1837 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1838 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1839 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1841 'slirp/src/arp_table.c',
1842 'slirp/src/bootp.c',
1843 'slirp/src/cksum.c',
1844 'slirp/src/dhcpv6.c',
1845 'slirp/src/dnssearch.c',
1847 'slirp/src/ip6_icmp.c',
1848 'slirp/src/ip6_input.c',
1849 'slirp/src/ip6_output.c',
1850 'slirp/src/ip_icmp.c',
1851 'slirp/src/ip_input.c',
1852 'slirp/src/ip_output.c',
1856 'slirp/src/ndp_table.c',
1858 'slirp/src/slirp.c',
1859 'slirp/src/socket.c',
1860 'slirp/src/state.c',
1861 'slirp/src/stream.c',
1862 'slirp/src/tcp_input.c',
1863 'slirp/src/tcp_output.c',
1864 'slirp/src/tcp_subr.c',
1865 'slirp/src/tcp_timer.c',
1870 'slirp/src/version.c',
1871 'slirp/src/vmstate.c',
1875 input : 'slirp/src/libslirp-version.h.in',
1876 output : 'libslirp-version.h',
1877 configuration: slirp_conf)
1879 slirp_inc = include_directories('slirp', 'slirp/src')
1880 libslirp = static_library('slirp',
1881 build_by_default: false,
1882 sources: slirp_files,
1883 c_args: slirp_cargs,
1884 include_directories: slirp_inc)
1885 slirp = declare_dependency(link_with: libslirp,
1886 dependencies: slirp_deps,
1887 include_directories: slirp_inc)
1891 # For CFI, we need to compile slirp as a static library together with qemu.
1892 # This is because we register slirp functions as callbacks for QEMU Timers.
1893 # When using a system-wide shared libslirp, the type information for the
1894 # callback is missing and the timer call produces a false positive with CFI.
1896 # Now that slirp_opt has been defined, check if the selected slirp is compatible
1897 # with control-flow integrity.
1898 if get_option('cfi') and slirp_opt == 'system'
1899 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
1900 + ' Please configure with --enable-slirp=git')
1904 fdt_opt = get_option('fdt')
1906 if fdt_opt in ['enabled', 'auto', 'system']
1907 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1908 fdt = cc.find_library('fdt', kwargs: static_kwargs,
1909 required: fdt_opt == 'system' or
1910 fdt_opt == 'enabled' and not have_internal)
1911 if fdt.found() and cc.links('''
1913 #include <libfdt_env.h>
1914 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1917 elif fdt_opt == 'system'
1918 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
1920 fdt_opt = 'internal'
1922 fdt_opt = 'disabled'
1926 if fdt_opt == 'internal'
1929 'dtc/libfdt/fdt_ro.c',
1930 'dtc/libfdt/fdt_wip.c',
1931 'dtc/libfdt/fdt_sw.c',
1932 'dtc/libfdt/fdt_rw.c',
1933 'dtc/libfdt/fdt_strerror.c',
1934 'dtc/libfdt/fdt_empty_tree.c',
1935 'dtc/libfdt/fdt_addresses.c',
1936 'dtc/libfdt/fdt_overlay.c',
1937 'dtc/libfdt/fdt_check.c',
1940 fdt_inc = include_directories('dtc/libfdt')
1941 libfdt = static_library('fdt',
1942 build_by_default: false,
1944 include_directories: fdt_inc)
1945 fdt = declare_dependency(link_with: libfdt,
1946 include_directories: fdt_inc)
1949 if not fdt.found() and fdt_required.length() > 0
1950 error('fdt not available but required by targets ' + ', '.join(fdt_required))
1953 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1954 config_host_data.set('CONFIG_FDT', fdt.found())
1955 config_host_data.set('CONFIG_SLIRP', slirp.found())
1957 #####################
1958 # Generated sources #
1959 #####################
1961 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1963 hxtool = find_program('scripts/hxtool')
1964 shaderinclude = find_program('scripts/shaderinclude.pl')
1965 qapi_gen = find_program('scripts/qapi-gen.py')
1966 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1967 meson.source_root() / 'scripts/qapi/commands.py',
1968 meson.source_root() / 'scripts/qapi/common.py',
1969 meson.source_root() / 'scripts/qapi/error.py',
1970 meson.source_root() / 'scripts/qapi/events.py',
1971 meson.source_root() / 'scripts/qapi/expr.py',
1972 meson.source_root() / 'scripts/qapi/gen.py',
1973 meson.source_root() / 'scripts/qapi/introspect.py',
1974 meson.source_root() / 'scripts/qapi/parser.py',
1975 meson.source_root() / 'scripts/qapi/schema.py',
1976 meson.source_root() / 'scripts/qapi/source.py',
1977 meson.source_root() / 'scripts/qapi/types.py',
1978 meson.source_root() / 'scripts/qapi/visit.py',
1979 meson.source_root() / 'scripts/qapi/common.py',
1980 meson.source_root() / 'scripts/qapi-gen.py'
1984 python, files('scripts/tracetool.py'),
1985 '--backend=' + config_host['TRACE_BACKENDS']
1987 tracetool_depends = files(
1988 'scripts/tracetool/backend/log.py',
1989 'scripts/tracetool/backend/__init__.py',
1990 'scripts/tracetool/backend/dtrace.py',
1991 'scripts/tracetool/backend/ftrace.py',
1992 'scripts/tracetool/backend/simple.py',
1993 'scripts/tracetool/backend/syslog.py',
1994 'scripts/tracetool/backend/ust.py',
1995 'scripts/tracetool/format/tcg_h.py',
1996 'scripts/tracetool/format/ust_events_c.py',
1997 'scripts/tracetool/format/ust_events_h.py',
1998 'scripts/tracetool/format/__init__.py',
1999 'scripts/tracetool/format/d.py',
2000 'scripts/tracetool/format/tcg_helper_c.py',
2001 'scripts/tracetool/format/simpletrace_stap.py',
2002 'scripts/tracetool/format/c.py',
2003 'scripts/tracetool/format/h.py',
2004 'scripts/tracetool/format/tcg_helper_h.py',
2005 'scripts/tracetool/format/log_stap.py',
2006 'scripts/tracetool/format/stap.py',
2007 'scripts/tracetool/format/tcg_helper_wrapper_h.py',
2008 'scripts/tracetool/__init__.py',
2009 'scripts/tracetool/transform.py',
2010 'scripts/tracetool/vcpu.py'
2013 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2014 meson.current_source_dir(),
2015 config_host['PKGVERSION'], meson.project_version()]
2016 qemu_version = custom_target('qemu-version.h',
2017 output: 'qemu-version.h',
2018 command: qemu_version_cmd,
2020 build_by_default: true,
2021 build_always_stale: true)
2022 genh += qemu_version
2026 ['qemu-options.hx', 'qemu-options.def'],
2027 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2031 ['hmp-commands.hx', 'hmp-commands.h'],
2032 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2035 foreach d : hx_headers
2036 hxdep += custom_target(d[1],
2040 build_by_default: true, # to be removed when added to a target
2041 command: [hxtool, '-h', '@INPUT0@'])
2049 authz_ss = ss.source_set()
2050 blockdev_ss = ss.source_set()
2051 block_ss = ss.source_set()
2052 bsd_user_ss = ss.source_set()
2053 chardev_ss = ss.source_set()
2054 common_ss = ss.source_set()
2055 crypto_ss = ss.source_set()
2056 io_ss = ss.source_set()
2057 linux_user_ss = ss.source_set()
2058 qmp_ss = ss.source_set()
2059 qom_ss = ss.source_set()
2060 softmmu_ss = ss.source_set()
2061 specific_fuzz_ss = ss.source_set()
2062 specific_ss = ss.source_set()
2063 stub_ss = ss.source_set()
2064 trace_ss = ss.source_set()
2065 user_ss = ss.source_set()
2066 util_ss = ss.source_set()
2069 qtest_module_ss = ss.source_set()
2070 tcg_module_ss = ss.source_set()
2076 target_softmmu_arch = {}
2077 target_user_arch = {}
2083 # TODO: add each directory to the subdirs from its own meson.build, once
2085 trace_events_subdirs = [
2093 trace_events_subdirs += [ 'linux-user' ]
2096 trace_events_subdirs += [
2105 trace_events_subdirs += [
2119 'hw/block/dataplane',
2167 if have_system or have_user
2168 trace_events_subdirs += [
2184 vhost_user = not_found
2185 if 'CONFIG_VHOST_USER' in config_host
2186 libvhost_user = subproject('libvhost-user')
2187 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2202 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2203 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2206 stub_ss = stub_ss.apply(config_all, strict: false)
2208 util_ss.add_all(trace_ss)
2209 util_ss = util_ss.apply(config_all, strict: false)
2210 libqemuutil = static_library('qemuutil',
2211 sources: util_ss.sources() + stub_ss.sources() + genh,
2212 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2213 qemuutil = declare_dependency(link_with: libqemuutil,
2214 sources: genh + version_res)
2216 if have_system or have_user
2217 decodetree = generator(find_program('scripts/decodetree.py'),
2218 output: 'decode-@BASENAME@.c.inc',
2219 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2220 subdir('libdecnumber')
2237 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
2243 blockdev_ss.add(files(
2250 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2251 # os-win32.c does not
2252 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2253 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2256 common_ss.add(files('cpus-common.c'))
2260 common_ss.add(capstone)
2261 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2263 # Work around a gcc bug/misfeature wherein constant propagation looks
2265 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2266 # to guess that a const variable is always zero. Without lto, this is
2267 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2268 # without lto, not even the alias is required -- we simply use different
2269 # declarations in different compilation units.
2270 pagevary = files('page-vary-common.c')
2271 if get_option('b_lto')
2272 pagevary_flags = ['-fno-lto']
2273 if get_option('cfi')
2274 pagevary_flags += '-fno-sanitize=cfi-icall'
2276 pagevary = static_library('page-vary-common', sources: pagevary,
2277 c_args: pagevary_flags)
2278 pagevary = declare_dependency(link_with: pagevary)
2280 common_ss.add(pagevary)
2281 specific_ss.add(files('page-vary.c'))
2289 subdir('semihosting')
2296 subdir('linux-user')
2299 common_ss.add(libbpf)
2301 bsd_user_ss.add(files('gdbstub.c'))
2302 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
2304 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
2305 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
2307 # needed for fuzzing binaries
2308 subdir('tests/qtest/libqos')
2309 subdir('tests/qtest/fuzz')
2312 tcg_real_module_ss = ss.source_set()
2313 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
2314 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
2315 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
2316 'tcg': tcg_real_module_ss }}
2318 ########################
2319 # Library dependencies #
2320 ########################
2322 modinfo_collect = find_program('scripts/modinfo-collect.py')
2323 modinfo_generate = find_program('scripts/modinfo-generate.py')
2328 foreach d, list : modules
2329 foreach m, module_ss : list
2330 if enable_modules and targetos != 'windows'
2331 module_ss = module_ss.apply(config_all, strict: false)
2332 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2333 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2339 if module_ss.sources() != []
2340 # FIXME: Should use sl.extract_all_objects(recursive: true) as
2341 # input. Sources can be used multiple times but objects are
2342 # unique when it comes to lookup in compile_commands.json.
2343 # Depnds on a mesion version with
2344 # https://github.com/mesonbuild/meson/pull/8900
2345 modinfo_files += custom_target(d + '-' + m + '.modinfo',
2346 output: d + '-' + m + '.modinfo',
2347 input: module_ss.sources() + genh,
2349 command: [modinfo_collect, module_ss.sources()])
2353 block_ss.add_all(module_ss)
2355 softmmu_ss.add_all(module_ss)
2361 foreach d, list : target_modules
2362 foreach m, module_ss : list
2363 if enable_modules and targetos != 'windows'
2364 foreach target : target_dirs
2365 if target.endswith('-softmmu')
2366 config_target = config_target_mak[target]
2367 config_target += config_host
2368 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2369 c_args = ['-DNEED_CPU_H',
2370 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2371 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2372 target_module_ss = module_ss.apply(config_target, strict: false)
2373 if target_module_ss.sources() != []
2374 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
2375 sl = static_library(module_name,
2376 [genh, target_module_ss.sources()],
2377 dependencies: [modulecommon, target_module_ss.dependencies()],
2378 include_directories: target_inc,
2382 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
2383 modinfo_files += custom_target(module_name + '.modinfo',
2384 output: module_name + '.modinfo',
2385 input: target_module_ss.sources() + genh,
2387 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
2392 specific_ss.add_all(module_ss)
2398 modinfo_src = custom_target('modinfo.c',
2399 output: 'modinfo.c',
2400 input: modinfo_files,
2401 command: [modinfo_generate, '@INPUT@'],
2403 modinfo_lib = static_library('modinfo', modinfo_src)
2404 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
2405 softmmu_ss.add(modinfo_dep)
2408 nm = find_program('nm')
2409 undefsym = find_program('scripts/undefsym.py')
2410 block_syms = custom_target('block.syms', output: 'block.syms',
2411 input: [libqemuutil, block_mods],
2413 command: [undefsym, nm, '@INPUT@'])
2414 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2415 input: [libqemuutil, softmmu_mods],
2417 command: [undefsym, nm, '@INPUT@'])
2419 qom_ss = qom_ss.apply(config_host, strict: false)
2420 libqom = static_library('qom', qom_ss.sources() + genh,
2421 dependencies: [qom_ss.dependencies()],
2424 qom = declare_dependency(link_whole: libqom)
2426 authz_ss = authz_ss.apply(config_host, strict: false)
2427 libauthz = static_library('authz', authz_ss.sources() + genh,
2428 dependencies: [authz_ss.dependencies()],
2430 build_by_default: false)
2432 authz = declare_dependency(link_whole: libauthz,
2435 crypto_ss = crypto_ss.apply(config_host, strict: false)
2436 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2437 dependencies: [crypto_ss.dependencies()],
2439 build_by_default: false)
2441 crypto = declare_dependency(link_whole: libcrypto,
2442 dependencies: [authz, qom])
2444 io_ss = io_ss.apply(config_host, strict: false)
2445 libio = static_library('io', io_ss.sources() + genh,
2446 dependencies: [io_ss.dependencies()],
2447 link_with: libqemuutil,
2449 build_by_default: false)
2451 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2453 libmigration = static_library('migration', sources: migration_files + genh,
2455 build_by_default: false)
2456 migration = declare_dependency(link_with: libmigration,
2457 dependencies: [zlib, qom, io])
2458 softmmu_ss.add(migration)
2460 block_ss = block_ss.apply(config_host, strict: false)
2461 libblock = static_library('block', block_ss.sources() + genh,
2462 dependencies: block_ss.dependencies(),
2463 link_depends: block_syms,
2465 build_by_default: false)
2467 block = declare_dependency(link_whole: [libblock],
2468 link_args: '@block.syms',
2469 dependencies: [crypto, io])
2471 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2472 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2473 dependencies: blockdev_ss.dependencies(),
2475 build_by_default: false)
2477 blockdev = declare_dependency(link_whole: [libblockdev],
2478 dependencies: [block])
2480 qmp_ss = qmp_ss.apply(config_host, strict: false)
2481 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2482 dependencies: qmp_ss.dependencies(),
2484 build_by_default: false)
2486 qmp = declare_dependency(link_whole: [libqmp])
2488 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2490 dependencies: [gnutls],
2491 build_by_default: false)
2493 chardev = declare_dependency(link_whole: libchardev)
2495 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2497 build_by_default: false)
2498 hwcore = declare_dependency(link_whole: libhwcore)
2499 common_ss.add(hwcore)
2505 foreach m : block_mods + softmmu_mods
2506 shared_module(m.name(),
2510 install_dir: qemu_moddir)
2513 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2514 common_ss.add(qom, qemuutil)
2516 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2517 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2519 common_all = common_ss.apply(config_all, strict: false)
2520 common_all = static_library('common',
2521 build_by_default: false,
2522 sources: common_all.sources() + genh,
2523 implicit_include_directories: false,
2524 dependencies: common_all.dependencies(),
2527 feature_to_c = find_program('scripts/feature_to_c.sh')
2530 foreach target : target_dirs
2531 config_target = config_target_mak[target]
2532 target_name = config_target['TARGET_NAME']
2533 arch = config_target['TARGET_BASE_ARCH']
2534 arch_srcs = [config_target_h[target]]
2536 c_args = ['-DNEED_CPU_H',
2537 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2538 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2539 link_args = emulator_link_args
2541 config_target += config_host
2542 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2543 if targetos == 'linux'
2544 target_inc += include_directories('linux-headers', is_system: true)
2546 if target.endswith('-softmmu')
2547 qemu_target_name = 'qemu-system-' + target_name
2548 target_type='system'
2549 t = target_softmmu_arch[arch].apply(config_target, strict: false)
2550 arch_srcs += t.sources()
2551 arch_deps += t.dependencies()
2553 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2554 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2555 arch_srcs += hw.sources()
2556 arch_deps += hw.dependencies()
2558 arch_srcs += config_devices_h[target]
2559 link_args += ['@block.syms', '@qemu.syms']
2561 abi = config_target['TARGET_ABI_DIR']
2563 qemu_target_name = 'qemu-' + target_name
2564 if arch in target_user_arch
2565 t = target_user_arch[arch].apply(config_target, strict: false)
2566 arch_srcs += t.sources()
2567 arch_deps += t.dependencies()
2569 if 'CONFIG_LINUX_USER' in config_target
2570 base_dir = 'linux-user'
2571 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2573 if 'CONFIG_BSD_USER' in config_target
2574 base_dir = 'bsd-user'
2575 target_inc += include_directories('bsd-user/' / targetos)
2576 dir = base_dir / abi
2577 arch_srcs += files(dir / 'target_arch_cpu.c')
2579 target_inc += include_directories(
2583 if 'CONFIG_LINUX_USER' in config_target
2584 dir = base_dir / abi
2585 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2586 if config_target.has_key('TARGET_SYSTBL_ABI')
2588 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2589 extra_args : config_target['TARGET_SYSTBL_ABI'])
2594 if 'TARGET_XML_FILES' in config_target
2595 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2596 output: target + '-gdbstub-xml.c',
2597 input: files(config_target['TARGET_XML_FILES'].split()),
2598 command: [feature_to_c, '@INPUT@'],
2600 arch_srcs += gdbstub_xml
2603 t = target_arch[arch].apply(config_target, strict: false)
2604 arch_srcs += t.sources()
2605 arch_deps += t.dependencies()
2607 target_common = common_ss.apply(config_target, strict: false)
2608 objects = common_all.extract_objects(target_common.sources())
2609 deps = target_common.dependencies()
2611 target_specific = specific_ss.apply(config_target, strict: false)
2612 arch_srcs += target_specific.sources()
2613 arch_deps += target_specific.dependencies()
2615 lib = static_library('qemu-' + target,
2616 sources: arch_srcs + genh,
2617 dependencies: arch_deps,
2619 include_directories: target_inc,
2621 build_by_default: false,
2624 if target.endswith('-softmmu')
2626 'name': 'qemu-system-' + target_name,
2628 'sources': files('softmmu/main.c'),
2631 if targetos == 'windows' and (sdl.found() or gtk.found())
2633 'name': 'qemu-system-' + target_name + 'w',
2635 'sources': files('softmmu/main.c'),
2639 if config_host.has_key('CONFIG_FUZZ')
2640 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2642 'name': 'qemu-fuzz-' + target_name,
2644 'sources': specific_fuzz.sources(),
2645 'dependencies': specific_fuzz.dependencies(),
2650 'name': 'qemu-' + target_name,
2657 exe_name = exe['name']
2658 if targetos == 'darwin'
2659 exe_name += '-unsigned'
2662 emulator = executable(exe_name, exe['sources'],
2665 dependencies: arch_deps + deps + exe['dependencies'],
2666 objects: lib.extract_all_objects(recursive: true),
2667 link_language: link_language,
2668 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2669 link_args: link_args,
2670 gui_app: exe['gui'])
2672 if targetos == 'darwin'
2673 icon = 'pc-bios/qemu.rsrc'
2674 build_input = [emulator, files(icon)]
2676 get_option('bindir') / exe_name,
2677 meson.current_source_dir() / icon
2679 if 'CONFIG_HVF' in config_target
2680 entitlements = 'accel/hvf/entitlements.plist'
2681 build_input += files(entitlements)
2682 install_input += meson.current_source_dir() / entitlements
2685 emulators += {exe['name'] : custom_target(exe['name'],
2687 output: exe['name'],
2689 files('scripts/entitlement.sh'),
2695 meson.add_install_script('scripts/entitlement.sh', '--install',
2696 get_option('bindir') / exe['name'],
2699 emulators += {exe['name']: emulator}
2702 if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2704 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2705 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2706 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2707 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2709 custom_target(exe['name'] + stp['ext'],
2710 input: trace_events_all,
2711 output: exe['name'] + stp['ext'],
2712 install: stp['install'],
2713 install_dir: get_option('datadir') / 'systemtap/tapset',
2715 tracetool, '--group=all', '--format=' + stp['fmt'],
2716 '--binary=' + stp['bin'],
2717 '--target-name=' + target_name,
2718 '--target-type=' + target_type,
2719 '--probe-prefix=qemu.' + target_type + '.' + target_name,
2720 '@INPUT@', '@OUTPUT@'
2722 depend_files: tracetool_depends)
2728 # Other build targets
2730 if 'CONFIG_PLUGIN' in config_host
2731 install_headers('include/qemu/qemu-plugin.h')
2734 if 'CONFIG_GUEST_AGENT' in config_host
2736 elif get_option('guest_agent_msi').enabled()
2737 error('Guest agent MSI requested, but the guest agent is not being built')
2740 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2741 # when we don't build tools or system
2742 if xkbcommon.found()
2743 # used for the update-keymaps target, so include rules even if !have_tools
2744 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2745 dependencies: [qemuutil, xkbcommon], install: have_tools)
2749 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2750 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2751 qemu_io = executable('qemu-io', files('qemu-io.c'),
2752 dependencies: [block, qemuutil], install: true)
2753 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2754 dependencies: [blockdev, qemuutil, gnutls], install: true)
2756 subdir('storage-daemon')
2757 subdir('contrib/rdmacm-mux')
2758 subdir('contrib/elf2dmp')
2760 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2761 dependencies: qemuutil,
2764 if 'CONFIG_VHOST_USER' in config_host
2765 subdir('contrib/vhost-user-blk')
2766 subdir('contrib/vhost-user-gpu')
2767 subdir('contrib/vhost-user-input')
2768 subdir('contrib/vhost-user-scsi')
2771 if targetos == 'linux'
2772 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2773 dependencies: [qemuutil, libcap_ng],
2775 install_dir: get_option('libexecdir'))
2777 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2778 dependencies: [authz, crypto, io, qom, qemuutil,
2779 libcap_ng, mpathpersist],
2784 subdir('contrib/ivshmem-client')
2785 subdir('contrib/ivshmem-server')
2798 if host_machine.system() == 'windows'
2800 find_program('scripts/nsis.py'),
2802 get_option('prefix'),
2803 meson.current_source_dir(),
2806 '-DDISPLAYVERSION=' + meson.project_version(),
2809 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2812 nsis_cmd += '-DCONFIG_GTK=y'
2815 nsis = custom_target('nsis',
2816 output: 'qemu-setup-' + meson.project_version() + '.exe',
2817 input: files('qemu.nsi'),
2818 build_always_stale: true,
2819 command: nsis_cmd + ['@INPUT@'])
2820 alias_target('installer', nsis)
2823 #########################
2824 # Configuration summary #
2825 #########################
2829 summary_info += {'Install prefix': get_option('prefix')}
2830 summary_info += {'BIOS directory': qemu_datadir}
2831 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
2832 summary_info += {'binary directory': get_option('bindir')}
2833 summary_info += {'library directory': get_option('libdir')}
2834 summary_info += {'module directory': qemu_moddir}
2835 summary_info += {'libexec directory': get_option('libexecdir')}
2836 summary_info += {'include directory': get_option('includedir')}
2837 summary_info += {'config directory': get_option('sysconfdir')}
2838 if targetos != 'windows'
2839 summary_info += {'local state directory': get_option('localstatedir')}
2840 summary_info += {'Manual directory': get_option('mandir')}
2842 summary_info += {'local state directory': 'queried at runtime'}
2844 summary_info += {'Doc directory': get_option('docdir')}
2845 summary_info += {'Build directory': meson.current_build_dir()}
2846 summary_info += {'Source path': meson.current_source_dir()}
2847 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
2848 summary(summary_info, bool_yn: true, section: 'Directories')
2852 summary_info += {'git': config_host['GIT']}
2853 summary_info += {'make': config_host['MAKE']}
2854 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2855 summary_info += {'sphinx-build': sphinx_build.found()}
2856 if config_host.has_key('HAVE_GDB_BIN')
2857 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
2859 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
2860 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
2861 summary_info += {'wixl': wixl.found() ? wixl.full_path() : false}
2863 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
2864 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
2866 summary(summary_info, bool_yn: true, section: 'Host binaries')
2868 # Configurable features
2870 summary_info += {'Documentation': build_docs}
2871 summary_info += {'system-mode emulation': have_system}
2872 summary_info += {'user-mode emulation': have_user}
2873 summary_info += {'block layer': have_block}
2874 summary_info += {'Install blobs': get_option('install_blobs')}
2875 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
2876 if config_host.has_key('CONFIG_MODULES')
2877 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2879 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
2881 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
2883 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
2884 if config_host['TRACE_BACKENDS'].split().contains('simple')
2885 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2887 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2888 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2889 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2890 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2891 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2892 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2893 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2894 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2895 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2896 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2897 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2898 summary(summary_info, bool_yn: true, section: 'Configurable features')
2900 # Compilation information
2902 summary_info += {'host CPU': cpu}
2903 summary_info += {'host endianness': build_machine.endian()}
2904 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
2905 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
2906 if link_language == 'cpp'
2907 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
2909 summary_info += {'C++ compiler': false}
2911 if targetos == 'darwin'
2912 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
2914 if targetos == 'windows'
2915 if 'WIN_SDK' in config_host
2916 summary_info += {'Windows SDK': config_host['WIN_SDK']}
2919 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
2920 + ['-O' + get_option('optimization')]
2921 + (get_option('debug') ? ['-g'] : []))}
2922 if link_language == 'cpp'
2923 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
2924 + ['-O' + get_option('optimization')]
2925 + (get_option('debug') ? ['-g'] : []))}
2927 link_args = get_option(link_language + '_link_args')
2928 if link_args.length() > 0
2929 summary_info += {'LDFLAGS': ' '.join(link_args)}
2931 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
2932 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
2933 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
2934 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2935 summary_info += {'PIE': get_option('b_pie')}
2936 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
2937 summary_info += {'malloc trim support': has_malloc_trim}
2938 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
2939 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2940 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
2941 summary_info += {'memory allocator': get_option('malloc')}
2942 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2943 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2944 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
2945 summary_info += {'gcov': get_option('b_coverage')}
2946 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
2947 summary_info += {'CFI support': get_option('cfi')}
2948 if get_option('cfi')
2949 summary_info += {'CFI debug support': get_option('cfi_debug')}
2951 summary_info += {'strip binaries': get_option('strip')}
2952 summary_info += {'sparse': sparse.found() ? sparse.full_path() : false}
2953 summary_info += {'mingw32 support': targetos == 'windows'}
2955 # snarf the cross-compilation information for tests
2956 foreach target: target_dirs
2957 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
2958 if fs.exists(tcg_mak)
2959 config_cross_tcg = keyval.load(tcg_mak)
2960 target = config_cross_tcg['TARGET_NAME']
2962 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
2963 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
2964 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
2965 elif 'CROSS_CC_GUEST' in config_cross_tcg
2966 summary_info += {target + ' tests'
2967 : config_cross_tcg['CROSS_CC_GUEST'] }
2972 summary(summary_info, bool_yn: true, section: 'Compilation')
2974 # Targets and accelerators
2977 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
2978 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
2979 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
2980 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
2981 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
2982 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
2983 if config_host.has_key('CONFIG_XEN_BACKEND')
2984 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2987 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
2988 if config_all.has_key('CONFIG_TCG')
2989 if get_option('tcg_interpreter')
2990 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, experimental and slow)'}
2992 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
2994 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
2995 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2997 summary_info += {'target list': ' '.join(target_dirs)}
2999 summary_info += {'default devices': get_option('default_devices')}
3000 summary_info += {'out of process emulation': multiprocess_allowed}
3002 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3006 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3007 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
3009 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3010 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3011 summary_info += {'Use block whitelist in tools': config_host.has_key('CONFIG_BDRV_WHITELIST_TOOLS')}
3012 summary_info += {'VirtFS support': have_virtfs}
3013 summary_info += {'build virtiofs daemon': have_virtiofsd}
3014 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
3015 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
3016 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
3017 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
3018 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
3019 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
3020 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
3021 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
3022 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
3023 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
3024 summary_info += {'FUSE exports': fuse.found()}
3026 summary(summary_info, bool_yn: true, section: 'Block layer support')
3030 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
3031 summary_info += {'GNUTLS support': gnutls.found()}
3032 summary_info += {'GNUTLS crypto': gnutls_crypto.found()}
3033 # TODO: add back version
3034 summary_info += {'libgcrypt': gcrypt.found()}
3035 # TODO: add back version
3036 summary_info += {'nettle': nettle.found()}
3038 summary_info += {' XTS': xts != 'private'}
3040 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
3041 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
3042 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
3043 summary(summary_info, bool_yn: true, section: 'Crypto')
3047 if targetos == 'darwin'
3048 summary_info += {'Cocoa support': cocoa.found()}
3050 # TODO: add back version
3051 summary_info += {'SDL support': sdl.found()}
3052 summary_info += {'SDL image support': sdl_image.found()}
3053 # TODO: add back version
3054 summary_info += {'GTK support': gtk.found()}
3055 summary_info += {'pixman': pixman.found()}
3056 # TODO: add back version
3057 summary_info += {'VTE support': vte.found()}
3058 # TODO: add back version
3059 summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt}
3060 summary_info += {'libtasn1': tasn1.found()}
3061 summary_info += {'PAM': pam.found()}
3062 summary_info += {'iconv support': iconv.found()}
3063 summary_info += {'curses support': curses.found()}
3064 # TODO: add back version
3065 summary_info += {'virgl support': virgl.found()}
3066 summary_info += {'curl support': curl.found()}
3067 summary_info += {'Multipath support': mpathpersist.found()}
3068 summary_info += {'VNC support': vnc.found()}
3070 summary_info += {'VNC SASL support': sasl.found()}
3071 summary_info += {'VNC JPEG support': jpeg.found()}
3072 summary_info += {'VNC PNG support': png.found()}
3074 summary_info += {'brlapi support': brlapi.found()}
3075 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
3076 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
3077 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
3078 summary_info += {'Linux io_uring support': linux_io_uring.found()}
3079 summary_info += {'ATTR/XATTR support': libattr.found()}
3080 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
3081 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
3082 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3083 summary_info += {'libcap-ng support': libcap_ng.found()}
3084 summary_info += {'bpf support': libbpf.found()}
3085 # TODO: add back protocol and server version
3086 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
3087 summary_info += {'rbd support': rbd.found()}
3088 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
3089 summary_info += {'smartcard support': cacard.found()}
3090 summary_info += {'U2F support': u2f.found()}
3091 summary_info += {'libusb': libusb.found()}
3092 summary_info += {'usb net redir': usbredir.found()}
3093 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
3094 summary_info += {'GBM': gbm.found()}
3095 summary_info += {'libiscsi support': libiscsi.found()}
3096 summary_info += {'libnfs support': libnfs.found()}
3097 if targetos == 'windows'
3098 if config_host.has_key('CONFIG_GUEST_AGENT')
3099 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
3100 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
3103 summary_info += {'seccomp support': seccomp.found()}
3104 summary_info += {'GlusterFS support': glusterfs.found()}
3105 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
3106 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
3107 summary_info += {'lzo support': lzo.found()}
3108 summary_info += {'snappy support': snappy.found()}
3109 summary_info += {'bzip2 support': libbzip2.found()}
3110 summary_info += {'lzfse support': liblzfse.found()}
3111 summary_info += {'zstd support': zstd.found()}
3112 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
3113 summary_info += {'libxml2': libxml2.found()}
3114 summary_info += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt}
3115 summary_info += {'libpmem support': libpmem.found()}
3116 summary_info += {'libdaxctl support': libdaxctl.found()}
3117 summary_info += {'libudev': libudev.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.')