1 project('qemu', ['c'], meson_version: '>=0.55.0',
2 default_options: ['warning_level=1', 'c_std=gnu99', '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 # Temporary directory used for files created while
22 # configure runs. Since it is in the build directory
23 # we can safely blow away any previous version of it
24 # (and we need not jump through hoops to try to delete
25 # it when configure exits.)
26 tmpdir = meson.current_build_dir() / 'meson-private/temp'
28 if get_option('qemu_suffix').startswith('/')
29 error('qemu_suffix cannot start with a /')
32 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
33 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
34 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
35 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
37 qemu_desktopdir = get_option('datadir') / 'applications'
38 qemu_icondir = get_option('datadir') / 'icons'
40 config_host_data = configuration_data()
43 target_dirs = config_host['TARGET_DIRS'].split()
46 foreach target : target_dirs
47 have_user = have_user or target.endswith('-user')
48 have_system = have_system or target.endswith('-softmmu')
50 have_tools = 'CONFIG_TOOLS' in config_host
51 have_block = have_system or have_tools
53 python = import('python').find_installation()
55 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
56 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
57 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
59 cpu = host_machine.cpu_family()
60 targetos = host_machine.system()
62 if cpu in ['x86', 'x86_64']
63 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
65 kvm_targets = ['aarch64-softmmu']
67 kvm_targets = ['s390x-softmmu']
68 elif cpu in ['ppc', 'ppc64']
69 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
70 elif cpu in ['mips', 'mips64']
71 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
76 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
77 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
78 # i368 emulator provides xenpv machine type for multiple architectures
79 accelerator_targets += {
80 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
83 if cpu in ['x86', 'x86_64']
84 accelerator_targets += {
85 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
86 'CONFIG_HVF': ['x86_64-softmmu'],
87 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
91 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
92 install_edk2_blobs = false
93 if get_option('install_blobs')
94 foreach target : target_dirs
95 install_edk2_blobs = install_edk2_blobs or target in edk2_targets
103 # Specify linker-script with add_project_link_arguments so that it is not placed
104 # within a linker --start-group/--end-group pair
105 if 'CONFIG_FUZZ' in config_host
106 add_project_link_arguments(['-Wl,-T,',
107 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
108 native: false, language: ['c', 'cpp', 'objc'])
111 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
112 native: false, language: ['c', 'objc'])
113 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
114 native: false, language: 'cpp')
115 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
116 native: false, language: ['c', 'cpp', 'objc'])
118 if targetos == 'linux'
119 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
120 '-isystem', 'linux-headers',
121 language: ['c', 'cpp'])
124 add_project_arguments('-iquote', '.',
125 '-iquote', meson.current_source_dir(),
126 '-iquote', meson.current_source_dir() / 'include',
127 '-iquote', meson.current_source_dir() / 'disas/libvixl',
128 language: ['c', 'cpp', 'objc'])
130 link_language = meson.get_external_property('link_language', 'cpp')
131 if link_language == 'cpp'
132 add_languages('cpp', required: true, native: false)
134 if host_machine.system() == 'darwin'
135 add_languages('objc', required: false, native: false)
138 sparse = find_program('cgcc', required: get_option('sparse'))
141 command: [find_program('scripts/check_sparse.py'),
142 'compile_commands.json', sparse.full_path(), '-Wbitwise',
143 '-Wno-transparent-union', '-Wno-old-initializer',
144 '-Wno-non-pointer-null'])
147 ###########################################
148 # Target-specific checks and dependencies #
149 ###########################################
151 if targetos != 'linux' and get_option('mpath').enabled()
152 error('Multipath is supported only on Linux')
155 m = cc.find_library('m', required: false)
156 util = cc.find_library('util', required: false)
162 emulator_link_args = []
164 if targetos == 'windows'
165 socket = cc.find_library('ws2_32')
166 winmm = cc.find_library('winmm')
168 win = import('windows')
169 version_res = win.compile_resources('version.rc',
170 depend_files: files('pc-bios/qemu-nsis.ico'),
171 include_directories: include_directories('.'))
172 elif targetos == 'darwin'
173 coref = dependency('appleframeworks', modules: 'CoreFoundation')
174 iokit = dependency('appleframeworks', modules: 'IOKit')
175 elif targetos == 'sunos'
176 socket = [cc.find_library('socket'),
177 cc.find_library('nsl'),
178 cc.find_library('resolv')]
179 elif targetos == 'haiku'
180 socket = [cc.find_library('posix_error_mapper'),
181 cc.find_library('network'),
182 cc.find_library('bsd')]
183 elif targetos == 'openbsd'
184 if not get_option('tcg').disabled() and target_dirs.length() > 0
185 # Disable OpenBSD W^X if available
186 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
191 if not get_option('kvm').disabled() and targetos == 'linux'
192 accelerators += 'CONFIG_KVM'
194 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
195 accelerators += 'CONFIG_XEN'
196 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
198 have_xen_pci_passthrough = false
200 if not get_option('whpx').disabled() and targetos == 'windows'
201 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
202 error('WHPX requires 64-bit host')
203 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
204 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
205 accelerators += 'CONFIG_WHPX'
208 if not get_option('hvf').disabled()
209 hvf = dependency('appleframeworks', modules: 'Hypervisor',
210 required: get_option('hvf'))
212 accelerators += 'CONFIG_HVF'
215 if not get_option('hax').disabled()
216 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
217 accelerators += 'CONFIG_HAX'
221 tcg_arch = config_host['ARCH']
222 if not get_option('tcg').disabled()
223 if cpu not in supported_cpus
224 if get_option('tcg_interpreter')
225 warning('Unsupported CPU @0@, will use TCG with TCI (experimental)'.format(cpu))
227 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
230 if get_option('tcg_interpreter')
232 elif config_host['ARCH'] == 'sparc64'
234 elif config_host['ARCH'] == 's390x'
236 elif config_host['ARCH'] in ['x86_64', 'x32']
238 elif config_host['ARCH'] == 'ppc64'
240 elif config_host['ARCH'] in ['riscv32', 'riscv64']
243 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
244 '-iquote', meson.current_source_dir() / 'accel/tcg',
245 language: ['c', 'cpp', 'objc'])
247 accelerators += 'CONFIG_TCG'
248 config_host += { 'CONFIG_TCG': 'y' }
251 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
252 error('KVM not available on this platform')
254 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
255 error('HVF not available on this platform')
257 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
258 error('WHPX not available on this platform')
260 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
261 if 'CONFIG_XEN' in accelerators
262 error('Xen PCI passthrough not available on this platform')
264 error('Xen PCI passthrough requested but Xen not enabled')
272 # The path to glib.h is added to all compilation commands. This was
273 # grandfathered in from the QEMU Makefiles.
274 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
275 native: false, language: ['c', 'cpp', 'objc'])
276 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
277 link_args: config_host['GLIB_LIBS'].split())
278 # override glib dep with the configure results (for subprojects)
279 meson.override_dependency('glib-2.0', glib)
282 if 'CONFIG_GIO' in config_host
283 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
284 link_args: config_host['GIO_LIBS'].split())
287 if 'CONFIG_TRACE_UST' in config_host
288 lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
291 if 'CONFIG_TRACE_UST' in config_host
292 urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
295 if 'CONFIG_GCRYPT' in config_host
296 gcrypt = declare_dependency(compile_args: config_host['GCRYPT_CFLAGS'].split(),
297 link_args: config_host['GCRYPT_LIBS'].split())
300 if 'CONFIG_NETTLE' in config_host
301 nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
302 link_args: config_host['NETTLE_LIBS'].split())
305 if 'CONFIG_GNUTLS' in config_host
306 gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
307 link_args: config_host['GNUTLS_LIBS'].split())
310 if have_system or have_tools
311 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
312 method: 'pkg-config', static: enable_static)
315 if 'CONFIG_AUTH_PAM' in config_host
316 pam = cc.find_library('pam')
318 libaio = cc.find_library('aio', required: false)
319 zlib = dependency('zlib', required: true, static: enable_static)
320 linux_io_uring = not_found
321 if 'CONFIG_LINUX_IO_URING' in config_host
322 linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
323 link_args: config_host['LINUX_IO_URING_LIBS'].split())
326 if 'CONFIG_LIBXML2' in config_host
327 libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
328 link_args: config_host['LIBXML2_LIBS'].split())
331 if not get_option('libnfs').auto() or have_block
332 libnfs = dependency('libnfs', version: '>=1.9.3',
333 required: get_option('libnfs'),
334 method: 'pkg-config', static: enable_static)
339 #include <sys/types.h>
340 #ifdef CONFIG_LIBATTR
341 #include <attr/xattr.h>
343 #include <sys/xattr.h>
345 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
348 have_old_libattr = false
349 if not get_option('attr').disabled()
350 if cc.links(libattr_test)
351 libattr = declare_dependency()
353 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
354 required: get_option('attr'),
355 static: enable_static)
356 if libattr.found() and not \
357 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
359 if get_option('attr').enabled()
360 error('could not link libattr')
362 warning('could not link libattr, disabling')
365 have_old_libattr = libattr.found()
370 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
371 if cocoa.found() and get_option('sdl').enabled()
372 error('Cocoa and SDL cannot be enabled at the same time')
374 if cocoa.found() and get_option('gtk').enabled()
375 error('Cocoa and GTK+ cannot be enabled at the same time')
379 if not get_option('seccomp').auto() or have_system or have_tools
380 seccomp = dependency('libseccomp', version: '>=2.3.0',
381 required: get_option('seccomp'),
382 method: 'pkg-config', static: enable_static)
385 libcap_ng = not_found
386 if not get_option('cap_ng').auto() or have_system or have_tools
387 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
388 required: get_option('cap_ng'),
389 static: enable_static)
391 if libcap_ng.found() and not cc.links('''
395 capng_capability_to_name(CAPNG_EFFECTIVE);
397 }''', dependencies: libcap_ng)
398 libcap_ng = not_found
399 if get_option('cap_ng').enabled()
400 error('could not link libcap-ng')
402 warning('could not link libcap-ng, disabling')
406 if get_option('xkbcommon').auto() and not have_system and not have_tools
407 xkbcommon = not_found
409 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
410 method: 'pkg-config', static: enable_static)
413 if config_host.has_key('CONFIG_VDE')
414 vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
417 if 'CONFIG_LIBPULSE' in config_host
418 pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
419 link_args: config_host['PULSE_LIBS'].split())
422 if 'CONFIG_ALSA' in config_host
423 alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
424 link_args: config_host['ALSA_LIBS'].split())
427 if 'CONFIG_LIBJACK' in config_host
428 jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
431 spice_headers = not_found
432 if 'CONFIG_SPICE' in config_host
433 spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
434 link_args: config_host['SPICE_LIBS'].split())
435 spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
437 rt = cc.find_library('rt', required: false)
439 if 'CONFIG_PLUGIN' in config_host
440 libdl = cc.find_library('dl', required: true)
443 if not get_option('libiscsi').auto() or have_block
444 libiscsi = dependency('libiscsi', version: '>=1.9.0',
445 required: get_option('libiscsi'),
446 method: 'pkg-config', static: enable_static)
449 if not get_option('zstd').auto() or have_block
450 zstd = dependency('libzstd', version: '>=1.4.0',
451 required: get_option('zstd'),
452 method: 'pkg-config', static: enable_static)
455 if 'CONFIG_GBM' in config_host
456 gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
457 link_args: config_host['GBM_LIBS'].split())
460 if 'CONFIG_VIRGL' in config_host
461 virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
462 link_args: config_host['VIRGL_LIBS'].split())
465 if not get_option('curl').auto() or have_block
466 curl = dependency('libcurl', version: '>=7.29.0',
467 method: 'pkg-config',
468 required: get_option('curl'),
469 static: enable_static)
472 if targetos == 'linux' and (have_system or have_tools)
473 libudev = dependency('libudev',
474 method: 'pkg-config',
475 required: get_option('libudev'),
476 static: enable_static)
479 mpathlibs = [libudev]
480 mpathpersist = not_found
481 mpathpersist_new_api = false
482 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
483 mpath_test_source_new = '''
485 #include <mpath_persist.h>
486 unsigned mpath_mx_alloc_len = 1024;
488 static struct config *multipath_conf;
489 extern struct udev *udev;
490 extern struct config *get_multipath_config(void);
491 extern void put_multipath_config(struct config *conf);
493 struct config *get_multipath_config(void) { return multipath_conf; }
494 void put_multipath_config(struct config *conf) { }
497 multipath_conf = mpath_lib_init();
500 mpath_test_source_old = '''
502 #include <mpath_persist.h>
503 unsigned mpath_mx_alloc_len = 1024;
506 struct udev *udev = udev_new();
507 mpath_lib_init(udev);
510 libmpathpersist = cc.find_library('mpathpersist',
511 required: get_option('mpath'),
512 static: enable_static)
513 if libmpathpersist.found()
514 mpathlibs += libmpathpersist
516 mpathlibs += cc.find_library('devmapper',
517 required: get_option('mpath'),
518 static: enable_static)
520 mpathlibs += cc.find_library('multipath',
521 required: get_option('mpath'),
522 static: enable_static)
523 foreach lib: mpathlibs
529 if mpathlibs.length() == 0
530 msg = 'Dependencies missing for libmpathpersist'
531 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
532 mpathpersist = declare_dependency(dependencies: mpathlibs)
533 mpathpersist_new_api = true
534 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
535 mpathpersist = declare_dependency(dependencies: mpathlibs)
537 msg = 'Cannot detect libmpathpersist API'
539 if not mpathpersist.found()
540 if get_option('mpath').enabled()
543 warning(msg + ', disabling')
551 if have_system and not get_option('curses').disabled()
558 setlocale(LC_ALL, "");
560 addwstr(L"wide chars\n");
562 add_wch(WACS_DEGREE);
566 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
567 foreach curses_dep : curses_dep_list
568 if not curses.found()
569 curses = dependency(curses_dep,
571 method: 'pkg-config',
572 static: enable_static)
575 msg = get_option('curses').enabled() ? 'curses library not found' : ''
576 curses_compile_args = ['-DNCURSES_WIDECHAR']
578 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
579 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
581 msg = 'curses package not usable'
585 if not curses.found()
586 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
587 if targetos != 'windows' and not has_curses_h
588 message('Trying with /usr/include/ncursesw')
589 curses_compile_args += ['-I/usr/include/ncursesw']
590 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
593 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
594 foreach curses_libname : curses_libname_list
595 libcurses = cc.find_library(curses_libname,
597 static: enable_static)
599 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
600 curses = declare_dependency(compile_args: curses_compile_args,
601 dependencies: [libcurses])
604 msg = 'curses library not usable'
610 if not get_option('iconv').disabled()
611 foreach link_args : [ ['-liconv'], [] ]
612 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
613 # We need to use libiconv if available because mixing libiconv's headers with
614 # the system libc does not work.
615 # However, without adding glib to the dependencies -L/usr/local/lib will not be
616 # included in the command line and libiconv will not be found.
620 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
621 return conv != (iconv_t) -1;
622 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
623 iconv = declare_dependency(link_args: link_args, dependencies: glib)
628 if curses.found() and not iconv.found()
629 if get_option('iconv').enabled()
630 error('iconv not available')
632 msg = 'iconv required for curses UI but not available'
635 if not curses.found() and msg != ''
636 if get_option('curses').enabled()
639 warning(msg + ', disabling')
645 if not get_option('brlapi').auto() or have_system
646 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
647 required: get_option('brlapi'),
648 static: enable_static)
649 if brlapi.found() and not cc.links('''
652 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
654 if get_option('brlapi').enabled()
655 error('could not link brlapi')
657 warning('could not link brlapi, disabling')
663 if not get_option('sdl').auto() or (have_system and not cocoa.found())
664 sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
665 sdl_image = not_found
668 # work around 2.0.8 bug
669 sdl = declare_dependency(compile_args: '-Wno-undef',
671 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
672 method: 'pkg-config', static: enable_static)
674 if get_option('sdl_image').enabled()
675 error('sdl-image required, but SDL was @0@'.format(
676 get_option('sdl').disabled() ? 'disabled' : 'not found'))
678 sdl_image = not_found
682 if not get_option('rbd').auto() or have_block
683 librados = cc.find_library('rados', required: get_option('rbd'),
684 static: enable_static)
685 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
686 required: get_option('rbd'),
687 static: enable_static)
688 if librados.found() and librbd.found() and cc.links('''
690 #include <rbd/librbd.h>
693 rados_create(&cluster, NULL);
695 }''', dependencies: [librbd, librados])
696 rbd = declare_dependency(dependencies: [librbd, librados])
700 glusterfs = not_found
701 glusterfs_ftruncate_has_stat = false
702 glusterfs_iocb_has_stat = false
703 if not get_option('glusterfs').auto() or have_block
704 glusterfs = dependency('glusterfs-api', version: '>=3',
705 required: get_option('glusterfs'),
706 method: 'pkg-config', static: enable_static)
708 glusterfs_ftruncate_has_stat = cc.links('''
709 #include <glusterfs/api/glfs.h>
714 /* new glfs_ftruncate() passes two additional args */
715 return glfs_ftruncate(NULL, 0, NULL, NULL);
717 ''', dependencies: glusterfs)
718 glusterfs_iocb_has_stat = cc.links('''
719 #include <glusterfs/api/glfs.h>
721 /* new glfs_io_cbk() passes two additional glfs_stat structs */
723 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
729 glfs_io_cbk iocb = &glusterfs_iocb;
730 iocb(NULL, 0 , NULL, NULL, NULL);
733 ''', dependencies: glusterfs)
737 if 'CONFIG_LIBSSH' in config_host
738 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
739 link_args: config_host['LIBSSH_LIBS'].split())
742 if not get_option('bzip2').auto() or have_block
743 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
744 required: get_option('bzip2'),
745 static: enable_static)
746 if libbzip2.found() and not cc.links('''
748 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
750 if get_option('bzip2').enabled()
751 error('could not link libbzip2')
753 warning('could not link libbzip2, disabling')
759 if not get_option('lzfse').auto() or have_block
760 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
761 required: get_option('lzfse'),
762 static: enable_static)
764 if liblzfse.found() and not cc.links('''
766 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
768 if get_option('lzfse').enabled()
769 error('could not link liblzfse')
771 warning('could not link liblzfse, disabling')
776 if 'CONFIG_AUDIO_OSS' in config_host
777 oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
780 if 'CONFIG_AUDIO_DSOUND' in config_host
781 dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
783 coreaudio = not_found
784 if 'CONFIG_AUDIO_COREAUDIO' in config_host
785 coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
788 if 'CONFIG_OPENGL' in config_host
789 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
790 link_args: config_host['OPENGL_LIBS'].split())
795 if not get_option('gtk').auto() or (have_system and not cocoa.found())
796 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
797 method: 'pkg-config',
798 required: get_option('gtk'),
799 static: enable_static)
801 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
802 method: 'pkg-config',
804 static: enable_static)
805 gtk = declare_dependency(dependencies: [gtk, gtkx11])
810 if 'CONFIG_VTE' in config_host
811 vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
812 link_args: config_host['VTE_LIBS'].split())
815 if gtkx11.found() or 'lm32-softmmu' in target_dirs
816 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
817 static: enable_static)
823 if get_option('vnc').enabled()
824 vnc = declare_dependency() # dummy dependency
825 png = dependency('libpng', required: get_option('vnc_png'),
826 method: 'pkg-config', static: enable_static)
827 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
828 method: 'pkg-config', static: enable_static)
829 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
830 required: get_option('vnc_sasl'),
831 static: enable_static)
833 sasl = declare_dependency(dependencies: sasl,
834 compile_args: '-DSTRUCT_IOVEC_DEFINED')
839 if not get_option('snappy').auto() or have_system
840 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
841 required: get_option('snappy'),
842 static: enable_static)
844 if snappy.found() and not cc.links('''
845 #include <snappy-c.h>
846 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
848 if get_option('snappy').enabled()
849 error('could not link libsnappy')
851 warning('could not link libsnappy, disabling')
856 if not get_option('lzo').auto() or have_system
857 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
858 required: get_option('lzo'),
859 static: enable_static)
861 if lzo.found() and not cc.links('''
862 #include <lzo/lzo1x.h>
863 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
865 if get_option('lzo').enabled()
866 error('could not link liblzo2')
868 warning('could not link liblzo2, disabling')
873 if 'CONFIG_RDMA' in config_host
874 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
877 if 'CONFIG_NUMA' in config_host
878 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
881 if 'CONFIG_XEN_BACKEND' in config_host
882 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
883 link_args: config_host['XEN_LIBS'].split())
886 if 'CONFIG_SMARTCARD' in config_host
887 cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
888 link_args: config_host['SMARTCARD_LIBS'].split())
892 u2f = dependency('u2f-emu', required: get_option('u2f'),
893 method: 'pkg-config',
894 static: enable_static)
897 if 'CONFIG_USB_REDIR' in config_host
898 usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
899 link_args: config_host['USB_REDIR_LIBS'].split())
902 if 'CONFIG_USB_LIBUSB' in config_host
903 libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
904 link_args: config_host['LIBUSB_LIBS'].split())
907 if 'CONFIG_LIBPMEM' in config_host
908 libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
909 link_args: config_host['LIBPMEM_LIBS'].split())
911 libdaxctl = not_found
912 if 'CONFIG_LIBDAXCTL' in config_host
913 libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
916 if 'CONFIG_TASN1' in config_host
917 tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
918 link_args: config_host['TASN1_LIBS'].split())
920 keyutils = dependency('libkeyutils', required: false,
921 method: 'pkg-config', static: enable_static)
923 has_gettid = cc.has_function('gettid')
928 if get_option('malloc') == 'system'
930 not get_option('malloc_trim').disabled() and \
931 cc.links('''#include <malloc.h>
932 int main(void) { malloc_trim(0); return 0; }''')
934 has_malloc_trim = false
935 malloc = cc.find_library(get_option('malloc'), required: true)
937 if not has_malloc_trim and get_option('malloc_trim').enabled()
938 if get_option('malloc') == 'system'
939 error('malloc_trim not available on this platform.')
941 error('malloc_trim not available with non-libc memory allocator')
945 # Check whether the glibc provides statx()
951 #include <sys/stat.h>
953 struct statx statxbuf;
954 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
958 has_statx = cc.links(statx_test)
960 have_vhost_user_blk_server = (targetos == 'linux' and
961 'CONFIG_VHOST_USER' in config_host)
963 if get_option('vhost_user_blk_server').enabled()
964 if targetos != 'linux'
965 error('vhost_user_blk_server requires linux')
966 elif 'CONFIG_VHOST_USER' not in config_host
967 error('vhost_user_blk_server requires vhost-user support')
969 elif get_option('vhost_user_blk_server').disabled() or not have_system
970 have_vhost_user_blk_server = false
974 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
975 error('Cannot enable fuse-lseek while fuse is disabled')
978 fuse = dependency('fuse3', required: get_option('fuse'),
979 version: '>=3.1', method: 'pkg-config',
980 static: enable_static)
982 fuse_lseek = not_found
983 if not get_option('fuse_lseek').disabled()
984 if fuse.version().version_compare('>=3.8')
986 fuse_lseek = declare_dependency()
987 elif get_option('fuse_lseek').enabled()
989 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
991 error('fuse-lseek requires libfuse, which was not found')
998 # Check for dependency on LTO
999 if not get_option('b_lto')
1000 error('Selected Control-Flow Integrity but LTO is disabled')
1002 if config_host.has_key('CONFIG_MODULES')
1003 error('Selected Control-Flow Integrity is not compatible with modules')
1005 # Check for cfi flags. CFI requires LTO so we can't use
1006 # get_supported_arguments, but need a more complex "compiles" which allows
1008 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1009 args: ['-flto', '-fsanitize=cfi-icall'] )
1010 cfi_flags += '-fsanitize=cfi-icall'
1012 error('-fsanitize=cfi-icall is not supported by the compiler')
1014 if cc.compiles('int main () { return 0; }',
1015 name: '-fsanitize-cfi-icall-generalize-pointers',
1016 args: ['-flto', '-fsanitize=cfi-icall',
1017 '-fsanitize-cfi-icall-generalize-pointers'] )
1018 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1020 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1022 if get_option('cfi_debug')
1023 if cc.compiles('int main () { return 0; }',
1024 name: '-fno-sanitize-trap=cfi-icall',
1025 args: ['-flto', '-fsanitize=cfi-icall',
1026 '-fno-sanitize-trap=cfi-icall'] )
1027 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1029 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1032 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1033 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1040 have_virtfs = (targetos == 'linux' and
1045 have_virtfs_proxy_helper = have_virtfs and have_tools
1047 if get_option('virtfs').enabled()
1049 if targetos != 'linux'
1050 error('virtio-9p (virtfs) requires Linux')
1051 elif not libcap_ng.found() or not libattr.found()
1052 error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1053 elif not have_system
1054 error('virtio-9p (virtfs) needs system emulation support')
1057 elif get_option('virtfs').disabled()
1061 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1062 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1063 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1064 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1065 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1066 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1067 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1068 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1069 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1070 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1071 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1072 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1074 config_host_data.set('CONFIG_ATTR', libattr.found())
1075 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1076 config_host_data.set('CONFIG_COCOA', cocoa.found())
1077 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1078 config_host_data.set('CONFIG_LZO', lzo.found())
1079 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1080 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1081 config_host_data.set('CONFIG_CURL', curl.found())
1082 config_host_data.set('CONFIG_CURSES', curses.found())
1083 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1084 if glusterfs.found()
1085 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1086 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1087 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1088 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1089 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1090 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1092 config_host_data.set('CONFIG_GTK', gtk.found())
1093 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1094 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1095 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1096 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1097 config_host_data.set('CONFIG_RBD', rbd.found())
1098 config_host_data.set('CONFIG_SDL', sdl.found())
1099 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1100 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1101 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1102 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1103 config_host_data.set('CONFIG_VNC', vnc.found())
1104 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1105 config_host_data.set('CONFIG_VNC_PNG', png.found())
1106 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1107 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1108 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1109 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1110 config_host_data.set('CONFIG_GETTID', has_gettid)
1111 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1112 config_host_data.set('CONFIG_STATX', has_statx)
1113 config_host_data.set('CONFIG_ZSTD', zstd.found())
1114 config_host_data.set('CONFIG_FUSE', fuse.found())
1115 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1116 config_host_data.set('CONFIG_X11', x11.found())
1117 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1118 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1119 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1120 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1121 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1123 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1124 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1125 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1126 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1127 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1129 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
1130 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1131 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
1132 foreach k, v: config_host
1133 if ignored.contains(k)
1135 elif arrays.contains(k)
1137 v = '"' + '", "'.join(v.split()) + '", '
1139 config_host_data.set(k, v)
1141 config_host_data.set('HOST_' + v.to_upper(), 1)
1142 elif strings.contains(k)
1143 if not k.startswith('CONFIG_')
1144 k = 'CONFIG_' + k.to_upper()
1146 config_host_data.set_quoted(k, v)
1147 elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1148 config_host_data.set(k, v == 'y' ? 1 : v)
1152 ########################
1153 # Target configuration #
1154 ########################
1156 minikconf = find_program('scripts/minikconf.py')
1158 config_all_devices = {}
1159 config_all_disas = {}
1160 config_devices_mak_list = []
1161 config_devices_h = {}
1162 config_target_h = {}
1163 config_target_mak = {}
1166 'alpha' : ['CONFIG_ALPHA_DIS'],
1167 'arm' : ['CONFIG_ARM_DIS'],
1168 'avr' : ['CONFIG_AVR_DIS'],
1169 'cris' : ['CONFIG_CRIS_DIS'],
1170 'hppa' : ['CONFIG_HPPA_DIS'],
1171 'i386' : ['CONFIG_I386_DIS'],
1172 'x86_64' : ['CONFIG_I386_DIS'],
1173 'x32' : ['CONFIG_I386_DIS'],
1174 'lm32' : ['CONFIG_LM32_DIS'],
1175 'm68k' : ['CONFIG_M68K_DIS'],
1176 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1177 'mips' : ['CONFIG_MIPS_DIS'],
1178 'moxie' : ['CONFIG_MOXIE_DIS'],
1179 'nios2' : ['CONFIG_NIOS2_DIS'],
1180 'or1k' : ['CONFIG_OPENRISC_DIS'],
1181 'ppc' : ['CONFIG_PPC_DIS'],
1182 'riscv' : ['CONFIG_RISCV_DIS'],
1183 'rx' : ['CONFIG_RX_DIS'],
1184 's390' : ['CONFIG_S390_DIS'],
1185 'sh4' : ['CONFIG_SH4_DIS'],
1186 'sparc' : ['CONFIG_SPARC_DIS'],
1187 'xtensa' : ['CONFIG_XTENSA_DIS'],
1189 if link_language == 'cpp'
1191 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1192 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1193 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1198 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1199 ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1200 ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \
1201 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1202 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1203 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1204 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1205 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1206 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1207 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1208 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : [])
1210 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1212 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1213 actual_target_dirs = []
1215 foreach target : target_dirs
1216 config_target = { 'TARGET_NAME': target.split('-')[0] }
1217 if target.endswith('linux-user')
1218 if targetos != 'linux'
1222 error('Target @0@ is only available on a Linux host'.format(target))
1224 config_target += { 'CONFIG_LINUX_USER': 'y' }
1225 elif target.endswith('bsd-user')
1226 if 'CONFIG_BSD' not in config_host
1230 error('Target @0@ is only available on a BSD host'.format(target))
1232 config_target += { 'CONFIG_BSD_USER': 'y' }
1233 elif target.endswith('softmmu')
1234 config_target += { 'CONFIG_SOFTMMU': 'y' }
1236 if target.endswith('-user')
1238 'CONFIG_USER_ONLY': 'y',
1239 'CONFIG_QEMU_INTERP_PREFIX':
1240 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1245 foreach sym: accelerators
1246 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1247 config_target += { sym: 'y' }
1248 config_all += { sym: 'y' }
1249 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1250 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1251 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1252 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1254 accel_kconfig += [ sym + '=y' ]
1257 if accel_kconfig.length() == 0
1261 error('No accelerator available for target @0@'.format(target))
1264 actual_target_dirs += target
1265 config_target += keyval.load('default-configs/targets' / target + '.mak')
1266 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1268 if 'TARGET_NEED_FDT' in config_target
1269 fdt_required += target
1273 if 'TARGET_BASE_ARCH' not in config_target
1274 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1276 if 'TARGET_ABI_DIR' not in config_target
1277 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1280 foreach k, v: disassemblers
1281 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1283 config_target += { sym: 'y' }
1284 config_all_disas += { sym: 'y' }
1289 config_target_data = configuration_data()
1290 foreach k, v: config_target
1291 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1293 elif ignored.contains(k)
1295 elif k == 'TARGET_BASE_ARCH'
1296 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1297 # not used to select files from sourcesets.
1298 config_target_data.set('TARGET_' + v.to_upper(), 1)
1299 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1300 config_target_data.set_quoted(k, v)
1302 config_target_data.set(k, 1)
1304 config_target_data.set(k, v)
1307 config_target_h += {target: configure_file(output: target + '-config-target.h',
1308 configuration: config_target_data)}
1310 if target.endswith('-softmmu')
1311 config_devices_mak = target + '-config-devices.mak'
1312 config_devices_mak = configure_file(
1313 input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
1314 output: config_devices_mak,
1315 depfile: config_devices_mak + '.d',
1317 command: [minikconf,
1318 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1319 config_devices_mak, '@DEPFILE@', '@INPUT@',
1320 host_kconfig, accel_kconfig])
1322 config_devices_data = configuration_data()
1323 config_devices = keyval.load(config_devices_mak)
1324 foreach k, v: config_devices
1325 config_devices_data.set(k, 1)
1327 config_devices_mak_list += config_devices_mak
1328 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1329 configuration: config_devices_data)}
1330 config_target += config_devices
1331 config_all_devices += config_devices
1333 config_target_mak += {target: config_target}
1335 target_dirs = actual_target_dirs
1337 # This configuration is used to build files that are shared by
1338 # multiple binaries, and then extracted out of the "common"
1339 # static_library target.
1341 # We do not use all_sources()/all_dependencies(), because it would
1342 # build literally all source files, including devices only used by
1343 # targets that are not built for this compilation. The CONFIG_ALL
1344 # pseudo symbol replaces it.
1346 config_all += config_all_devices
1347 config_all += config_host
1348 config_all += config_all_disas
1350 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1351 'CONFIG_SOFTMMU': have_system,
1352 'CONFIG_USER_ONLY': have_user,
1360 capstone = not_found
1361 capstone_opt = get_option('capstone')
1362 if capstone_opt in ['enabled', 'auto', 'system']
1363 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1364 capstone = dependency('capstone', version: '>=4.0',
1365 static: enable_static, method: 'pkg-config',
1366 required: capstone_opt == 'system' or
1367 capstone_opt == 'enabled' and not have_internal)
1369 capstone_opt = 'system'
1371 capstone_opt = 'internal'
1373 capstone_opt = 'disabled'
1376 if capstone_opt == 'internal'
1377 capstone_data = configuration_data()
1378 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1380 capstone_files = files(
1382 'capstone/MCInst.c',
1383 'capstone/MCInstrDesc.c',
1384 'capstone/MCRegisterInfo.c',
1385 'capstone/SStream.c',
1389 if 'CONFIG_ARM_DIS' in config_all_disas
1390 capstone_data.set('CAPSTONE_HAS_ARM', '1')
1391 capstone_files += files(
1392 'capstone/arch/ARM/ARMDisassembler.c',
1393 'capstone/arch/ARM/ARMInstPrinter.c',
1394 'capstone/arch/ARM/ARMMapping.c',
1395 'capstone/arch/ARM/ARMModule.c'
1399 # FIXME: This config entry currently depends on a c++ compiler.
1400 # Which is needed for building libvixl, but not for capstone.
1401 if 'CONFIG_ARM_A64_DIS' in config_all_disas
1402 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1403 capstone_files += files(
1404 'capstone/arch/AArch64/AArch64BaseInfo.c',
1405 'capstone/arch/AArch64/AArch64Disassembler.c',
1406 'capstone/arch/AArch64/AArch64InstPrinter.c',
1407 'capstone/arch/AArch64/AArch64Mapping.c',
1408 'capstone/arch/AArch64/AArch64Module.c'
1412 if 'CONFIG_PPC_DIS' in config_all_disas
1413 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1414 capstone_files += files(
1415 'capstone/arch/PowerPC/PPCDisassembler.c',
1416 'capstone/arch/PowerPC/PPCInstPrinter.c',
1417 'capstone/arch/PowerPC/PPCMapping.c',
1418 'capstone/arch/PowerPC/PPCModule.c'
1422 if 'CONFIG_S390_DIS' in config_all_disas
1423 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1424 capstone_files += files(
1425 'capstone/arch/SystemZ/SystemZDisassembler.c',
1426 'capstone/arch/SystemZ/SystemZInstPrinter.c',
1427 'capstone/arch/SystemZ/SystemZMapping.c',
1428 'capstone/arch/SystemZ/SystemZModule.c',
1429 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1433 if 'CONFIG_I386_DIS' in config_all_disas
1434 capstone_data.set('CAPSTONE_HAS_X86', 1)
1435 capstone_files += files(
1436 'capstone/arch/X86/X86Disassembler.c',
1437 'capstone/arch/X86/X86DisassemblerDecoder.c',
1438 'capstone/arch/X86/X86ATTInstPrinter.c',
1439 'capstone/arch/X86/X86IntelInstPrinter.c',
1440 'capstone/arch/X86/X86InstPrinterCommon.c',
1441 'capstone/arch/X86/X86Mapping.c',
1442 'capstone/arch/X86/X86Module.c'
1446 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1449 # FIXME: There does not seem to be a way to completely replace the c_args
1450 # that come from add_project_arguments() -- we can only add to them.
1451 # So: disable all warnings with a big hammer.
1454 # Include all configuration defines via a header file, which will wind up
1455 # as a dependency on the object file, and thus changes here will result
1457 '-include', 'capstone-defs.h'
1460 libcapstone = static_library('capstone',
1461 sources: capstone_files,
1462 c_args: capstone_cargs,
1463 include_directories: 'capstone/include')
1464 capstone = declare_dependency(link_with: libcapstone,
1465 include_directories: 'capstone/include/capstone')
1469 slirp_opt = 'disabled'
1471 slirp_opt = get_option('slirp')
1472 if slirp_opt in ['enabled', 'auto', 'system']
1473 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1474 slirp = dependency('slirp', static: enable_static,
1475 method: 'pkg-config',
1476 required: slirp_opt == 'system' or
1477 slirp_opt == 'enabled' and not have_internal)
1479 slirp_opt = 'system'
1481 slirp_opt = 'internal'
1483 slirp_opt = 'disabled'
1486 if slirp_opt == 'internal'
1488 if targetos == 'windows'
1489 slirp_deps = cc.find_library('iphlpapi')
1491 slirp_conf = configuration_data()
1492 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1493 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1494 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1495 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1496 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1498 'slirp/src/arp_table.c',
1499 'slirp/src/bootp.c',
1500 'slirp/src/cksum.c',
1501 'slirp/src/dhcpv6.c',
1502 'slirp/src/dnssearch.c',
1504 'slirp/src/ip6_icmp.c',
1505 'slirp/src/ip6_input.c',
1506 'slirp/src/ip6_output.c',
1507 'slirp/src/ip_icmp.c',
1508 'slirp/src/ip_input.c',
1509 'slirp/src/ip_output.c',
1513 'slirp/src/ndp_table.c',
1515 'slirp/src/slirp.c',
1516 'slirp/src/socket.c',
1517 'slirp/src/state.c',
1518 'slirp/src/stream.c',
1519 'slirp/src/tcp_input.c',
1520 'slirp/src/tcp_output.c',
1521 'slirp/src/tcp_subr.c',
1522 'slirp/src/tcp_timer.c',
1527 'slirp/src/version.c',
1528 'slirp/src/vmstate.c',
1532 input : 'slirp/src/libslirp-version.h.in',
1533 output : 'libslirp-version.h',
1534 configuration: slirp_conf)
1536 slirp_inc = include_directories('slirp', 'slirp/src')
1537 libslirp = static_library('slirp',
1538 sources: slirp_files,
1539 c_args: slirp_cargs,
1540 include_directories: slirp_inc)
1541 slirp = declare_dependency(link_with: libslirp,
1542 dependencies: slirp_deps,
1543 include_directories: slirp_inc)
1548 fdt_opt = get_option('fdt')
1550 if fdt_opt in ['enabled', 'auto', 'system']
1551 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1552 fdt = cc.find_library('fdt', static: enable_static,
1553 required: fdt_opt == 'system' or
1554 fdt_opt == 'enabled' and not have_internal)
1555 if fdt.found() and cc.links('''
1557 #include <libfdt_env.h>
1558 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1562 fdt_opt = 'internal'
1564 fdt_opt = 'disabled'
1567 if fdt_opt == 'internal'
1570 'dtc/libfdt/fdt_ro.c',
1571 'dtc/libfdt/fdt_wip.c',
1572 'dtc/libfdt/fdt_sw.c',
1573 'dtc/libfdt/fdt_rw.c',
1574 'dtc/libfdt/fdt_strerror.c',
1575 'dtc/libfdt/fdt_empty_tree.c',
1576 'dtc/libfdt/fdt_addresses.c',
1577 'dtc/libfdt/fdt_overlay.c',
1578 'dtc/libfdt/fdt_check.c',
1581 fdt_inc = include_directories('dtc/libfdt')
1582 libfdt = static_library('fdt',
1584 include_directories: fdt_inc)
1585 fdt = declare_dependency(link_with: libfdt,
1586 include_directories: fdt_inc)
1589 if not fdt.found() and fdt_required.length() > 0
1590 error('fdt not available but required by targets ' + ', '.join(fdt_required))
1593 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1594 config_host_data.set('CONFIG_FDT', fdt.found())
1595 config_host_data.set('CONFIG_SLIRP', slirp.found())
1597 #####################
1598 # Generated sources #
1599 #####################
1601 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1603 hxtool = find_program('scripts/hxtool')
1604 shaderinclude = find_program('scripts/shaderinclude.pl')
1605 qapi_gen = find_program('scripts/qapi-gen.py')
1606 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1607 meson.source_root() / 'scripts/qapi/commands.py',
1608 meson.source_root() / 'scripts/qapi/common.py',
1609 meson.source_root() / 'scripts/qapi/error.py',
1610 meson.source_root() / 'scripts/qapi/events.py',
1611 meson.source_root() / 'scripts/qapi/expr.py',
1612 meson.source_root() / 'scripts/qapi/gen.py',
1613 meson.source_root() / 'scripts/qapi/introspect.py',
1614 meson.source_root() / 'scripts/qapi/parser.py',
1615 meson.source_root() / 'scripts/qapi/schema.py',
1616 meson.source_root() / 'scripts/qapi/source.py',
1617 meson.source_root() / 'scripts/qapi/types.py',
1618 meson.source_root() / 'scripts/qapi/visit.py',
1619 meson.source_root() / 'scripts/qapi/common.py',
1620 meson.source_root() / 'scripts/qapi-gen.py'
1624 python, files('scripts/tracetool.py'),
1625 '--backend=' + config_host['TRACE_BACKENDS']
1628 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1629 meson.current_source_dir(),
1630 config_host['PKGVERSION'], meson.project_version()]
1631 qemu_version = custom_target('qemu-version.h',
1632 output: 'qemu-version.h',
1633 command: qemu_version_cmd,
1635 build_by_default: true,
1636 build_always_stale: true)
1637 genh += qemu_version
1641 ['qemu-options.hx', 'qemu-options.def'],
1642 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1646 ['hmp-commands.hx', 'hmp-commands.h'],
1647 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1650 foreach d : hx_headers
1651 hxdep += custom_target(d[1],
1655 build_by_default: true, # to be removed when added to a target
1656 command: [hxtool, '-h', '@INPUT0@'])
1664 authz_ss = ss.source_set()
1665 blockdev_ss = ss.source_set()
1666 block_ss = ss.source_set()
1667 bsd_user_ss = ss.source_set()
1668 chardev_ss = ss.source_set()
1669 common_ss = ss.source_set()
1670 crypto_ss = ss.source_set()
1671 io_ss = ss.source_set()
1672 linux_user_ss = ss.source_set()
1673 qmp_ss = ss.source_set()
1674 qom_ss = ss.source_set()
1675 softmmu_ss = ss.source_set()
1676 specific_fuzz_ss = ss.source_set()
1677 specific_ss = ss.source_set()
1678 stub_ss = ss.source_set()
1679 trace_ss = ss.source_set()
1680 user_ss = ss.source_set()
1681 util_ss = ss.source_set()
1686 target_softmmu_arch = {}
1692 # TODO: add each directory to the subdirs from its own meson.build, once
1694 trace_events_subdirs = [
1701 trace_events_subdirs += [ 'linux-user' ]
1704 trace_events_subdirs += [
1713 trace_events_subdirs += [
1725 'hw/block/dataplane',
1771 trace_events_subdirs += [
1787 vhost_user = not_found
1788 if 'CONFIG_VHOST_USER' in config_host
1789 libvhost_user = subproject('libvhost-user')
1790 vhost_user = libvhost_user.get_variable('vhost_user_dep')
1805 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1806 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1809 stub_ss = stub_ss.apply(config_all, strict: false)
1811 util_ss.add_all(trace_ss)
1812 util_ss = util_ss.apply(config_all, strict: false)
1813 libqemuutil = static_library('qemuutil',
1814 sources: util_ss.sources() + stub_ss.sources() + genh,
1815 dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1816 qemuutil = declare_dependency(link_with: libqemuutil,
1817 sources: genh + version_res)
1819 decodetree = generator(find_program('scripts/decodetree.py'),
1821 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1827 subdir('libdecnumber')
1837 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1843 blockdev_ss.add(files(
1850 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1851 # os-win32.c does not
1852 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1853 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1855 common_ss.add(files('cpus-common.c'))
1859 common_ss.add(capstone)
1860 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1861 specific_ss.add(files('exec-vary.c'))
1862 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1866 'tcg/tcg-op-gvec.c',
1871 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1883 subdir('linux-user')
1885 bsd_user_ss.add(files('gdbstub.c'))
1886 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1888 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1889 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1891 # needed for fuzzing binaries
1892 subdir('tests/qtest/libqos')
1893 subdir('tests/qtest/fuzz')
1895 ########################
1896 # Library dependencies #
1897 ########################
1901 foreach d, list : modules
1902 foreach m, module_ss : list
1903 if enable_modules and targetos != 'windows'
1904 module_ss = module_ss.apply(config_all, strict: false)
1905 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1906 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1914 block_ss.add_all(module_ss)
1916 softmmu_ss.add_all(module_ss)
1922 nm = find_program('nm')
1923 undefsym = find_program('scripts/undefsym.py')
1924 block_syms = custom_target('block.syms', output: 'block.syms',
1925 input: [libqemuutil, block_mods],
1927 command: [undefsym, nm, '@INPUT@'])
1928 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1929 input: [libqemuutil, softmmu_mods],
1931 command: [undefsym, nm, '@INPUT@'])
1933 qom_ss = qom_ss.apply(config_host, strict: false)
1934 libqom = static_library('qom', qom_ss.sources() + genh,
1935 dependencies: [qom_ss.dependencies()],
1938 qom = declare_dependency(link_whole: libqom)
1940 authz_ss = authz_ss.apply(config_host, strict: false)
1941 libauthz = static_library('authz', authz_ss.sources() + genh,
1942 dependencies: [authz_ss.dependencies()],
1944 build_by_default: false)
1946 authz = declare_dependency(link_whole: libauthz,
1949 crypto_ss = crypto_ss.apply(config_host, strict: false)
1950 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1951 dependencies: [crypto_ss.dependencies()],
1953 build_by_default: false)
1955 crypto = declare_dependency(link_whole: libcrypto,
1956 dependencies: [authz, qom])
1958 io_ss = io_ss.apply(config_host, strict: false)
1959 libio = static_library('io', io_ss.sources() + genh,
1960 dependencies: [io_ss.dependencies()],
1961 link_with: libqemuutil,
1963 build_by_default: false)
1965 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1967 libmigration = static_library('migration', sources: migration_files + genh,
1969 build_by_default: false)
1970 migration = declare_dependency(link_with: libmigration,
1971 dependencies: [zlib, qom, io])
1972 softmmu_ss.add(migration)
1974 block_ss = block_ss.apply(config_host, strict: false)
1975 libblock = static_library('block', block_ss.sources() + genh,
1976 dependencies: block_ss.dependencies(),
1977 link_depends: block_syms,
1979 build_by_default: false)
1981 block = declare_dependency(link_whole: [libblock],
1982 link_args: '@block.syms',
1983 dependencies: [crypto, io])
1985 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
1986 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
1987 dependencies: blockdev_ss.dependencies(),
1989 build_by_default: false)
1991 blockdev = declare_dependency(link_whole: [libblockdev],
1992 dependencies: [block])
1994 qmp_ss = qmp_ss.apply(config_host, strict: false)
1995 libqmp = static_library('qmp', qmp_ss.sources() + genh,
1996 dependencies: qmp_ss.dependencies(),
1998 build_by_default: false)
2000 qmp = declare_dependency(link_whole: [libqmp])
2002 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2004 dependencies: [gnutls],
2005 build_by_default: false)
2007 chardev = declare_dependency(link_whole: libchardev)
2009 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2011 build_by_default: false)
2012 hwcore = declare_dependency(link_whole: libhwcore)
2013 common_ss.add(hwcore)
2019 foreach m : block_mods + softmmu_mods
2020 shared_module(m.name(),
2024 install_dir: qemu_moddir)
2027 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2028 common_ss.add(qom, qemuutil)
2030 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2031 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2033 common_all = common_ss.apply(config_all, strict: false)
2034 common_all = static_library('common',
2035 build_by_default: false,
2036 sources: common_all.sources() + genh,
2037 dependencies: common_all.dependencies(),
2040 feature_to_c = find_program('scripts/feature_to_c.sh')
2043 foreach target : target_dirs
2044 config_target = config_target_mak[target]
2045 target_name = config_target['TARGET_NAME']
2046 arch = config_target['TARGET_BASE_ARCH']
2047 arch_srcs = [config_target_h[target]]
2049 c_args = ['-DNEED_CPU_H',
2052 link_args = emulator_link_args
2054 config_target += config_host
2055 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2056 if targetos == 'linux'
2057 target_inc += include_directories('linux-headers', is_system: true)
2059 if target.endswith('-softmmu')
2060 qemu_target_name = 'qemu-system-' + target_name
2061 target_type='system'
2062 t = target_softmmu_arch[arch].apply(config_target, strict: false)
2063 arch_srcs += t.sources()
2064 arch_deps += t.dependencies()
2066 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2067 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2068 arch_srcs += hw.sources()
2069 arch_deps += hw.dependencies()
2071 arch_srcs += config_devices_h[target]
2072 link_args += ['@block.syms', '@qemu.syms']
2074 abi = config_target['TARGET_ABI_DIR']
2076 qemu_target_name = 'qemu-' + target_name
2077 if 'CONFIG_LINUX_USER' in config_target
2078 base_dir = 'linux-user'
2079 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2081 base_dir = 'bsd-user'
2082 target_inc += include_directories('bsd-user/freebsd')
2084 target_inc += include_directories(
2088 if 'CONFIG_LINUX_USER' in config_target
2089 dir = base_dir / abi
2090 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2091 if config_target.has_key('TARGET_SYSTBL_ABI')
2093 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2094 extra_args : config_target['TARGET_SYSTBL_ABI'])
2099 if 'TARGET_XML_FILES' in config_target
2100 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2101 output: target + '-gdbstub-xml.c',
2102 input: files(config_target['TARGET_XML_FILES'].split()),
2103 command: [feature_to_c, '@INPUT@'],
2105 arch_srcs += gdbstub_xml
2108 t = target_arch[arch].apply(config_target, strict: false)
2109 arch_srcs += t.sources()
2110 arch_deps += t.dependencies()
2112 target_common = common_ss.apply(config_target, strict: false)
2113 objects = common_all.extract_objects(target_common.sources())
2114 deps = target_common.dependencies()
2116 target_specific = specific_ss.apply(config_target, strict: false)
2117 arch_srcs += target_specific.sources()
2118 arch_deps += target_specific.dependencies()
2120 lib = static_library('qemu-' + target,
2121 sources: arch_srcs + genh,
2122 dependencies: arch_deps,
2124 include_directories: target_inc,
2126 build_by_default: false,
2129 if target.endswith('-softmmu')
2131 'name': 'qemu-system-' + target_name,
2133 'sources': files('softmmu/main.c'),
2136 if targetos == 'windows' and (sdl.found() or gtk.found())
2138 'name': 'qemu-system-' + target_name + 'w',
2140 'sources': files('softmmu/main.c'),
2144 if config_host.has_key('CONFIG_FUZZ')
2145 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2147 'name': 'qemu-fuzz-' + target_name,
2149 'sources': specific_fuzz.sources(),
2150 'dependencies': specific_fuzz.dependencies(),
2155 'name': 'qemu-' + target_name,
2162 emulators += {exe['name']:
2163 executable(exe['name'], exe['sources'],
2166 dependencies: arch_deps + deps + exe['dependencies'],
2167 objects: lib.extract_all_objects(recursive: true),
2168 link_language: link_language,
2169 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2170 link_args: link_args,
2171 gui_app: exe['gui'])
2174 if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2176 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2177 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2178 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2179 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2181 custom_target(exe['name'] + stp['ext'],
2182 input: trace_events_all,
2183 output: exe['name'] + stp['ext'],
2184 install: stp['install'],
2185 install_dir: get_option('datadir') / 'systemtap/tapset',
2187 tracetool, '--group=all', '--format=' + stp['fmt'],
2188 '--binary=' + stp['bin'],
2189 '--target-name=' + target_name,
2190 '--target-type=' + target_type,
2191 '--probe-prefix=qemu.' + target_type + '.' + target_name,
2192 '@INPUT@', '@OUTPUT@'
2199 # Other build targets
2201 if 'CONFIG_PLUGIN' in config_host
2202 install_headers('include/qemu/qemu-plugin.h')
2205 if 'CONFIG_GUEST_AGENT' in config_host
2207 elif get_option('guest_agent_msi').enabled()
2208 error('Guest agent MSI requested, but the guest agent is not being built')
2211 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2212 # when we don't build tools or system
2213 if xkbcommon.found()
2214 # used for the update-keymaps target, so include rules even if !have_tools
2215 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2216 dependencies: [qemuutil, xkbcommon], install: have_tools)
2220 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2221 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2222 qemu_io = executable('qemu-io', files('qemu-io.c'),
2223 dependencies: [block, qemuutil], install: true)
2224 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2225 dependencies: [blockdev, qemuutil, gnutls], install: true)
2227 subdir('storage-daemon')
2228 subdir('contrib/rdmacm-mux')
2229 subdir('contrib/elf2dmp')
2231 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2232 dependencies: qemuutil,
2235 if 'CONFIG_VHOST_USER' in config_host
2236 subdir('contrib/vhost-user-blk')
2237 subdir('contrib/vhost-user-gpu')
2238 subdir('contrib/vhost-user-input')
2239 subdir('contrib/vhost-user-scsi')
2242 if targetos == 'linux'
2243 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2244 dependencies: [qemuutil, libcap_ng],
2246 install_dir: get_option('libexecdir'))
2248 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2249 dependencies: [authz, crypto, io, qom, qemuutil,
2250 libcap_ng, mpathpersist],
2254 if 'CONFIG_IVSHMEM' in config_host
2255 subdir('contrib/ivshmem-client')
2256 subdir('contrib/ivshmem-server')
2269 if host_machine.system() == 'windows'
2271 find_program('scripts/nsis.py'),
2273 get_option('prefix'),
2274 meson.current_source_dir(),
2277 '-DDISPLAYVERSION=' + meson.project_version(),
2280 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2283 nsis_cmd += '-DCONFIG_GTK=y'
2286 nsis = custom_target('nsis',
2287 output: 'qemu-setup-' + meson.project_version() + '.exe',
2288 input: files('qemu.nsi'),
2289 build_always_stale: true,
2290 command: nsis_cmd + ['@INPUT@'])
2291 alias_target('installer', nsis)
2294 #########################
2295 # Configuration summary #
2296 #########################
2300 summary_info += {'Install prefix': get_option('prefix')}
2301 summary_info += {'BIOS directory': qemu_datadir}
2302 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
2303 summary_info += {'binary directory': get_option('bindir')}
2304 summary_info += {'library directory': get_option('libdir')}
2305 summary_info += {'module directory': qemu_moddir}
2306 summary_info += {'libexec directory': get_option('libexecdir')}
2307 summary_info += {'include directory': get_option('includedir')}
2308 summary_info += {'config directory': get_option('sysconfdir')}
2309 if targetos != 'windows'
2310 summary_info += {'local state directory': get_option('localstatedir')}
2311 summary_info += {'Manual directory': get_option('mandir')}
2313 summary_info += {'local state directory': 'queried at runtime'}
2315 summary_info += {'Doc directory': get_option('docdir')}
2316 summary_info += {'Build directory': meson.current_build_dir()}
2317 summary_info += {'Source path': meson.current_source_dir()}
2318 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
2319 summary(summary_info, bool_yn: true, section: 'Directories')
2323 summary_info += {'git': config_host['GIT']}
2324 summary_info += {'make': config_host['MAKE']}
2325 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2326 summary_info += {'sphinx-build': sphinx_build.found()}
2327 if config_host.has_key('HAVE_GDB_BIN')
2328 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
2330 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
2331 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
2332 summary_info += {'wixl': wixl.found() ? wixl.full_path() : false}
2334 if slirp_opt != 'disabled'
2335 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
2337 summary(summary_info, bool_yn: true, section: 'Host binaries')
2339 # Configurable features
2341 summary_info += {'Documentation': build_docs}
2342 summary_info += {'system-mode emulation': have_system}
2343 summary_info += {'user-mode emulation': have_user}
2344 summary_info += {'block layer': have_block}
2345 summary_info += {'Install blobs': get_option('install_blobs')}
2346 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
2347 if config_host.has_key('CONFIG_MODULES')
2348 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2350 summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')}
2351 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
2353 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
2355 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
2356 if config_host['TRACE_BACKENDS'].split().contains('simple')
2357 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2359 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2360 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2361 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2362 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2363 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2364 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2365 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2366 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2367 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2368 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2369 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2370 summary(summary_info, bool_yn: true, section: 'Configurable features')
2372 # Compilation information
2374 summary_info += {'host CPU': cpu}
2375 summary_info += {'host endianness': build_machine.endian()}
2376 summary_info += {'C compiler': meson.get_compiler('c').cmd_array()[0]}
2377 summary_info += {'Host C compiler': meson.get_compiler('c', native: true).cmd_array()[0]}
2378 if link_language == 'cpp'
2379 summary_info += {'C++ compiler': meson.get_compiler('cpp').cmd_array()[0]}
2381 summary_info += {'C++ compiler': false}
2383 if targetos == 'darwin'
2384 summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2386 if targetos == 'windows'
2387 if 'WIN_SDK' in config_host
2388 summary_info += {'Windows SDK': config_host['WIN_SDK']}
2391 summary_info += {'ARFLAGS': config_host['ARFLAGS']}
2392 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
2393 + ['-O' + get_option('optimization')]
2394 + (get_option('debug') ? ['-g'] : []))}
2395 if link_language == 'cpp'
2396 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
2397 + ['-O' + get_option('optimization')]
2398 + (get_option('debug') ? ['-g'] : []))}
2400 link_args = get_option(link_language + '_link_args')
2401 if link_args.length() > 0
2402 summary_info += {'LDFLAGS': ' '.join(link_args)}
2404 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
2405 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
2406 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
2407 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2408 summary_info += {'PIE': get_option('b_pie')}
2409 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
2410 summary_info += {'malloc trim support': has_malloc_trim}
2411 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
2412 summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
2413 summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
2414 summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
2415 summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
2416 summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2417 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2418 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
2419 summary_info += {'memory allocator': get_option('malloc')}
2420 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2421 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2422 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
2423 summary_info += {'gcov': get_option('b_coverage')}
2424 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
2425 summary_info += {'CFI support': get_option('cfi')}
2426 if get_option('cfi')
2427 summary_info += {'CFI debug support': get_option('cfi_debug')}
2429 summary_info += {'strip binaries': get_option('strip')}
2430 summary_info += {'sparse': sparse.found() ? sparse.full_path() : false}
2431 summary_info += {'mingw32 support': targetos == 'windows'}
2432 summary(summary_info, bool_yn: true, section: 'Compilation')
2434 # Targets and accelerators
2437 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
2438 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
2439 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
2440 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
2441 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
2442 if config_host.has_key('CONFIG_XEN_BACKEND')
2443 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2446 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
2447 if config_all.has_key('CONFIG_TCG')
2448 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2449 summary_info += {'TCG interpreter': tcg_arch == 'tci'}
2451 summary_info += {'target list': ' '.join(target_dirs)}
2453 summary_info += {'default devices': get_option('default_devices')}
2455 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
2459 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2460 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
2462 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2463 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2464 summary_info += {'VirtFS support': have_virtfs}
2465 summary_info += {'build virtiofs daemon': have_virtiofsd}
2466 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2467 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2468 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
2469 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
2470 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
2471 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
2472 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
2473 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
2474 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
2475 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2476 summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')}
2477 summary_info += {'FUSE exports': fuse.found()}
2479 summary(summary_info, bool_yn: true, section: 'Block layer support')
2483 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
2484 summary_info += {'GNUTLS support': config_host.has_key('CONFIG_GNUTLS')}
2485 # TODO: add back version
2486 summary_info += {'libgcrypt': config_host.has_key('CONFIG_GCRYPT')}
2487 if config_host.has_key('CONFIG_GCRYPT')
2488 summary_info += {' hmac': config_host.has_key('CONFIG_GCRYPT_HMAC')}
2489 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2491 # TODO: add back version
2492 summary_info += {'nettle': config_host.has_key('CONFIG_NETTLE')}
2493 if config_host.has_key('CONFIG_NETTLE')
2494 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2496 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
2497 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
2498 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
2499 summary(summary_info, bool_yn: true, section: 'Crypto')
2503 if targetos == 'darwin'
2504 summary_info += {'Cocoa support': cocoa.found()}
2506 # TODO: add back version
2507 summary_info += {'SDL support': sdl.found()}
2508 summary_info += {'SDL image support': sdl_image.found()}
2509 # TODO: add back version
2510 summary_info += {'GTK support': gtk.found()}
2511 summary_info += {'pixman': pixman.found()}
2512 # TODO: add back version
2513 summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')}
2514 # TODO: add back version
2515 summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt}
2516 summary_info += {'libtasn1': config_host.has_key('CONFIG_TASN1')}
2517 summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')}
2518 summary_info += {'iconv support': iconv.found()}
2519 summary_info += {'curses support': curses.found()}
2520 # TODO: add back version
2521 summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')}
2522 summary_info += {'curl support': curl.found()}
2523 summary_info += {'Multipath support': mpathpersist.found()}
2524 summary_info += {'VNC support': vnc.found()}
2526 summary_info += {'VNC SASL support': sasl.found()}
2527 summary_info += {'VNC JPEG support': jpeg.found()}
2528 summary_info += {'VNC PNG support': png.found()}
2530 summary_info += {'brlapi support': brlapi.found()}
2531 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
2532 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
2533 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2534 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2535 summary_info += {'ATTR/XATTR support': libattr.found()}
2536 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
2537 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
2538 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
2539 summary_info += {'libcap-ng support': libcap_ng.found()}
2540 # TODO: add back protocol and server version
2541 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
2542 summary_info += {'rbd support': rbd.found()}
2543 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
2544 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2545 summary_info += {'U2F support': u2f.found()}
2546 summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')}
2547 summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')}
2548 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
2549 summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')}
2550 summary_info += {'libiscsi support': libiscsi.found()}
2551 summary_info += {'libnfs support': libnfs.found()}
2552 if targetos == 'windows'
2553 if config_host.has_key('CONFIG_GUEST_AGENT')
2554 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
2555 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2558 summary_info += {'seccomp support': seccomp.found()}
2559 summary_info += {'GlusterFS support': glusterfs.found()}
2560 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
2561 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
2562 summary_info += {'lzo support': lzo.found()}
2563 summary_info += {'snappy support': snappy.found()}
2564 summary_info += {'bzip2 support': libbzip2.found()}
2565 summary_info += {'lzfse support': liblzfse.found()}
2566 summary_info += {'zstd support': zstd.found()}
2567 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2568 summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')}
2569 summary_info += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt}
2570 summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
2571 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2572 summary_info += {'libudev': libudev.found()}
2573 summary_info += {'FUSE lseek': fuse_lseek.found()}
2574 summary(summary_info, bool_yn: true, section: 'Dependencies')
2576 if not supported_cpus.contains(cpu)
2578 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2580 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2581 message('The QEMU project intends to remove support for this host CPU in')
2582 message('a future release if nobody volunteers to maintain it and to')
2583 message('provide a build host for our continuous integration setup.')
2584 message('configure has succeeded and you can continue to build, but')
2585 message('if you care about QEMU on this platform you should contact')
2589 if not supported_oses.contains(targetos)
2591 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2593 message('Host OS ' + targetos + 'support is not currently maintained.')
2594 message('The QEMU project intends to remove support for this host OS in')
2595 message('a future release if nobody volunteers to maintain it and to')
2596 message('provide a build host for our continuous integration setup.')
2597 message('configure has succeeded and you can continue to build, but')
2598 message('if you care about QEMU on this platform you should contact')